.
This commit is contained in:
2
Makefile
2
Makefile
@@ -87,7 +87,7 @@ lib/compiler.o: lib/compiler.c lib/compiler/compiler.lua.h
|
|||||||
# executable files
|
# executable files
|
||||||
#
|
#
|
||||||
|
|
||||||
LIB_SRC=lib/value.o lib/stack.o lib/array.o lib/table.o lib/heap.o lib/vm.o lib/step.o lib/compiler.o lib/code.o lib/utils.o
|
LIB_SRC=lib/value.o lib/stack.o lib/array.o lib/table.o lib/heap.o lib/vm.o lib/compiler.o lib/code.o lib/utils.o
|
||||||
|
|
||||||
tyche: CFLAGS += ${RELEASE_CFLAGS}
|
tyche: CFLAGS += ${RELEASE_CFLAGS}
|
||||||
tyche: LDFLAGS += ${RELEASE_LDFLAGS}
|
tyche: LDFLAGS += ${RELEASE_LDFLAGS}
|
||||||
|
|||||||
@@ -225,10 +225,4 @@ const char* code_const_string(Code const* code, size_t n);
|
|||||||
uint32_t code_n_functions(Code const* code);
|
uint32_t code_n_functions(Code const* code);
|
||||||
Instruction code_next_instruction(Code const* code, uint32_t function_id, uint32_t pc);
|
Instruction code_next_instruction(Code const* code, uint32_t function_id, uint32_t pc);
|
||||||
|
|
||||||
//
|
|
||||||
// VM
|
|
||||||
//
|
|
||||||
|
|
||||||
TYC_RESULT step(TycheVM* T);
|
|
||||||
|
|
||||||
#endif //TYCHE_PRIV_H
|
#endif //TYCHE_PRIV_H
|
||||||
|
|||||||
10
lib/step.c
10
lib/step.c
@@ -1,10 +0,0 @@
|
|||||||
#include "priv.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
TYC_RESULT step(TycheVM* T)
|
|
||||||
{
|
|
||||||
abort();
|
|
||||||
return T_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ typedef enum {
|
|||||||
T_ERR_TABLE_KEY_NOT_FOUND = -20,
|
T_ERR_TABLE_KEY_NOT_FOUND = -20,
|
||||||
T_ERR_ASSEMBLER_SYNTAX_ERROR = -30,
|
T_ERR_ASSEMBLER_SYNTAX_ERROR = -30,
|
||||||
T_ERR_BYTECODE_TOO_SMALL = -40, T_ERR_BYTECODE_INVALID_MAGIC = -41,
|
T_ERR_BYTECODE_TOO_SMALL = -40, T_ERR_BYTECODE_INVALID_MAGIC = -41,
|
||||||
T_ERR_TYPE_UNEXPECTED = -50,
|
T_ERR_TYPE_UNEXPECTED = -50, T_ERR_INVALID_OPCODE = -51,
|
||||||
} TYC_RESULT;
|
} TYC_RESULT;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
90
lib/vm.c
90
lib/vm.c
@@ -20,6 +20,10 @@ struct TycheVM {
|
|||||||
LocationStack location_stack;
|
LocationStack location_stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static TYC_RESULT step(TycheVM* T);
|
||||||
|
|
||||||
|
#define TRY(x) if ((r = (x)) != T_OK) { return r; }
|
||||||
|
|
||||||
//
|
//
|
||||||
// CREATE/DESTROY VM
|
// CREATE/DESTROY VM
|
||||||
//
|
//
|
||||||
@@ -65,6 +69,22 @@ static void push_location(TycheVM* T, uint32_t function_id, uint32_t pc)
|
|||||||
++T->location_stack.sz;
|
++T->location_stack.sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Location* location_top(TycheVM* T)
|
||||||
|
{
|
||||||
|
if (T->location_stack.sz == 0)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
return &T->location_stack.locations[T->location_stack.sz - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void location_pop(TycheVM* T)
|
||||||
|
{
|
||||||
|
if (T->location_stack.sz == 0)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
--T->location_stack.sz;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// CODE LOADING AND EXECUTION
|
// CODE LOADING AND EXECUTION
|
||||||
//
|
//
|
||||||
@@ -72,10 +92,8 @@ static void push_location(TycheVM* T, uint32_t function_id, uint32_t pc)
|
|||||||
TYC_RESULT tyc_load_bytecode(TycheVM* T, uint8_t const* bytecode, size_t bytecode_sz)
|
TYC_RESULT tyc_load_bytecode(TycheVM* T, uint8_t const* bytecode, size_t bytecode_sz)
|
||||||
{
|
{
|
||||||
TYC_RESULT r;
|
TYC_RESULT r;
|
||||||
if ((r = code_load_bytecode(T->code, bytecode, bytecode_sz)) != T_OK)
|
TRY(code_load_bytecode(T->code, bytecode, bytecode_sz))
|
||||||
return r;
|
TRY(stack_push(T->stack, create_value_idx(TT_FUNCTION, 0 /* main */)))
|
||||||
if ((r = stack_push(T->stack, create_value_idx(TT_FUNCTION, 0 /* main */))) != T_OK)
|
|
||||||
return r;
|
|
||||||
return T_OK;
|
return T_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,13 +104,11 @@ static TYC_RESULT enter_function(TycheVM* T, uint16_t n_pars)
|
|||||||
// get parameters
|
// get parameters
|
||||||
VALUE params[n_pars + 1];
|
VALUE params[n_pars + 1];
|
||||||
for (uint16_t i = 0; i < n_pars; ++i)
|
for (uint16_t i = 0; i < n_pars; ++i)
|
||||||
if ((r = stack_pop(T->stack, ¶ms[i])) != T_OK)
|
TRY(stack_pop(T->stack, ¶ms[i]))
|
||||||
return r;
|
|
||||||
|
|
||||||
// get function
|
// get function
|
||||||
VALUE function;
|
VALUE function;
|
||||||
if ((r = stack_pop(T->stack, &function)) != T_OK)
|
TRY(stack_pop(T->stack, &function))
|
||||||
return r;
|
|
||||||
if (value_type(function) != TT_FUNCTION)
|
if (value_type(function) != TT_FUNCTION)
|
||||||
return T_ERR_TYPE_UNEXPECTED;
|
return T_ERR_TYPE_UNEXPECTED;
|
||||||
|
|
||||||
@@ -102,8 +118,7 @@ static TYC_RESULT enter_function(TycheVM* T, uint16_t n_pars)
|
|||||||
|
|
||||||
// pass parameters
|
// pass parameters
|
||||||
for (int i = n_pars-1; i >= 0; --i)
|
for (int i = n_pars-1; i >= 0; --i)
|
||||||
if ((r = stack_push(T->stack, params[i])) != T_OK)
|
TRY(stack_push(T->stack, params[i]))
|
||||||
return r;
|
|
||||||
|
|
||||||
return T_OK;
|
return T_OK;
|
||||||
}
|
}
|
||||||
@@ -114,8 +129,7 @@ static TYC_RESULT run_until_return(TycheVM* T)
|
|||||||
|
|
||||||
size_t level = stack_fp_level(T->stack);
|
size_t level = stack_fp_level(T->stack);
|
||||||
while (stack_fp_level(T->stack) >= level)
|
while (stack_fp_level(T->stack) >= level)
|
||||||
if ((r = step(T)) != T_OK)
|
TRY(step(T))
|
||||||
return r;
|
|
||||||
|
|
||||||
return T_OK;
|
return T_OK;
|
||||||
}
|
}
|
||||||
@@ -123,10 +137,8 @@ static TYC_RESULT run_until_return(TycheVM* T)
|
|||||||
TYC_RESULT tyc_call(TycheVM* T, uint16_t n_pars)
|
TYC_RESULT tyc_call(TycheVM* T, uint16_t n_pars)
|
||||||
{
|
{
|
||||||
TYC_RESULT r;
|
TYC_RESULT r;
|
||||||
if ((r = enter_function(T, n_pars)) != T_OK)
|
TRY(enter_function(T, n_pars))
|
||||||
return r;
|
TRY(run_until_return(T))
|
||||||
if ((r = run_until_return(T)) != T_OK)
|
|
||||||
return r;
|
|
||||||
return T_OK;
|
return T_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,4 +185,48 @@ TYC_RESULT tyc_expr(TycheVM* T, TYC_EXPR expr)
|
|||||||
stack_pop(T->stack, &v1);
|
stack_pop(T->stack, &v1);
|
||||||
stack_push(T->stack, create_value_integer(value_integer(v1) + value_integer(v2)));
|
stack_push(T->stack, create_value_integer(value_integer(v1) + value_integer(v2)));
|
||||||
return T_OK;
|
return T_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// STEP
|
||||||
|
//
|
||||||
|
|
||||||
|
static TYC_RESULT step(TycheVM* T)
|
||||||
|
{
|
||||||
|
VALUE a, b;
|
||||||
|
TYC_RESULT r;
|
||||||
|
|
||||||
|
Location* loc = location_top(T);
|
||||||
|
Instruction inst = code_next_instruction(T->code, loc->function_id, loc->pc);
|
||||||
|
|
||||||
|
// TODO - debug instruction
|
||||||
|
|
||||||
|
switch (inst.operator) {
|
||||||
|
|
||||||
|
case TO_PUSHI:
|
||||||
|
tyc_pushinteger(T, inst.operand);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TO_SUM:
|
||||||
|
TRY(stack_pop(T->stack, &b))
|
||||||
|
TRY(stack_pop(T->stack, &a))
|
||||||
|
TRY(tyc_expr(T, TX_SUM))
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TO_RET:
|
||||||
|
TRY(stack_pop(T->stack, &a))
|
||||||
|
TRY(stack_pop_fp(T->stack))
|
||||||
|
TRY(stack_push(T->stack, a))
|
||||||
|
location_pop(T);
|
||||||
|
// TODO - print stack
|
||||||
|
return T_OK;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return T_ERR_INVALID_OPCODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO - print stack
|
||||||
|
loc->pc += inst.sz;
|
||||||
|
|
||||||
|
return T_OK;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user