.
This commit is contained in:
2
TODO.md
2
TODO.md
@@ -23,7 +23,7 @@ Decisions:
|
|||||||
- [x] Execution loop (fast)
|
- [x] Execution loop (fast)
|
||||||
- [ ] VM operations
|
- [ ] VM operations
|
||||||
- [x] Expressions
|
- [x] Expressions
|
||||||
- [ ] Local variables
|
- [x] Local variables
|
||||||
- [ ] Functions
|
- [ ] Functions
|
||||||
- [ ] With parameters
|
- [ ] With parameters
|
||||||
- [ ] Control flow
|
- [ ] Control flow
|
||||||
|
|||||||
@@ -16,7 +16,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_INVALID_OPCODE = -51, T_ERR_EXPR_INCORRECT_TYPES = -52,
|
T_ERR_TYPE_UNEXPECTED = -50, T_ERR_INVALID_OPCODE = -51, T_ERR_EXPR_INCORRECT_TYPES = -52, T_ERR_VALUE_OUT_OF_RANGE = -53,
|
||||||
} TYC_RESULT;
|
} TYC_RESULT;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -39,6 +39,7 @@ TYC_RESULT tyc_call(TycheVM* t, uint16_t n_pars);
|
|||||||
|
|
||||||
// stack manipulation and query
|
// stack manipulation and query
|
||||||
size_t tyc_stack_size(TycheVM* T);
|
size_t tyc_stack_size(TycheVM* T);
|
||||||
|
void tyc_pushnil(TycheVM* T);
|
||||||
void tyc_pushinteger(TycheVM* T, int32_t value);
|
void tyc_pushinteger(TycheVM* T, int32_t value);
|
||||||
TYC_RESULT tyc_type(TycheVM* T, int idx, TYC_TYPE* type);
|
TYC_RESULT tyc_type(TycheVM* T, int idx, TYC_TYPE* type);
|
||||||
TYC_RESULT tyc_tointeger(TycheVM* T, int idx, int32_t* value);
|
TYC_RESULT tyc_tointeger(TycheVM* T, int idx, int32_t* value);
|
||||||
|
|||||||
44
lib/vm.c
44
lib/vm.c
@@ -154,6 +154,11 @@ size_t tyc_stack_size(TycheVM* T)
|
|||||||
return stack_len(T->stack);
|
return stack_len(T->stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tyc_pushnil(TycheVM* T)
|
||||||
|
{
|
||||||
|
stack_push(T->stack, create_value_nil());
|
||||||
|
}
|
||||||
|
|
||||||
void tyc_pushinteger(TycheVM* T, int32_t value)
|
void tyc_pushinteger(TycheVM* T, int32_t value)
|
||||||
{
|
{
|
||||||
stack_push(T->stack, create_value_integer(value));
|
stack_push(T->stack, create_value_integer(value));
|
||||||
@@ -213,10 +218,49 @@ static TYC_RESULT step(TycheVM* T)
|
|||||||
// stack manipulation
|
// stack manipulation
|
||||||
//
|
//
|
||||||
|
|
||||||
|
case TO_PUSHN:
|
||||||
|
tyc_pushnil(T);
|
||||||
|
break;
|
||||||
|
|
||||||
case TO_PUSHI:
|
case TO_PUSHI:
|
||||||
tyc_pushinteger(T, inst.operand);
|
tyc_pushinteger(T, inst.operand);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TO_PUSHF:
|
||||||
|
if (inst.operand < 0 || inst.operand > code_n_functions(T->code))
|
||||||
|
return T_ERR_VALUE_OUT_OF_RANGE;
|
||||||
|
TRY(stack_push(T->stack, create_value_idx(TT_FUNCTION, inst.operand)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TO_POP:
|
||||||
|
TRY(stack_pop(T->stack, NULL))
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// local variables
|
||||||
|
//
|
||||||
|
|
||||||
|
case TO_PUSHV:
|
||||||
|
if (inst.operand <= 0)
|
||||||
|
return T_ERR_VALUE_OUT_OF_RANGE;
|
||||||
|
for (size_t i = 0; i < inst.operand; ++i)
|
||||||
|
tyc_pushnil(T);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TO_SET:
|
||||||
|
if (inst.operand < 0)
|
||||||
|
return T_ERR_VALUE_OUT_OF_RANGE;
|
||||||
|
TRY(stack_pop(T->stack, &a))
|
||||||
|
TRY(stack_set(T->stack, inst.operand, a))
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TO_DUPV:
|
||||||
|
if (inst.operand < 0)
|
||||||
|
return T_ERR_VALUE_OUT_OF_RANGE;
|
||||||
|
TRY(stack_at(T->stack, inst.operand, &a))
|
||||||
|
stack_push(T->stack, a);
|
||||||
|
break;
|
||||||
|
|
||||||
//
|
//
|
||||||
// expressions
|
// expressions
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -41,5 +41,20 @@ return {
|
|||||||
{ parameters = { 20, 3, 'shr' }, name = "Shift right", expected_stack_top = 2},
|
{ parameters = { 20, 3, 'shr' }, name = "Shift right", expected_stack_top = 2},
|
||||||
{ parameters = { 20, 3, 'mod' }, name = "Modulo", expected_stack_top = 2 },
|
{ parameters = { 20, 3, 'mod' }, name = "Modulo", expected_stack_top = 2 },
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
name = "VM: local variables",
|
||||||
|
code = [[
|
||||||
|
.func 0
|
||||||
|
pushv 2 ; local a, b
|
||||||
|
pushi 3 ; a = 3
|
||||||
|
set 0
|
||||||
|
pushi 4 ; b = 4
|
||||||
|
set 1
|
||||||
|
dupv 0 ; return a
|
||||||
|
ret
|
||||||
|
]],
|
||||||
|
expected_stack_size = 1,
|
||||||
|
expected_stack_top = 3,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
@@ -462,6 +462,6 @@ static void run_assembly_test_template(lua_State* L)
|
|||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 1);
|
||||||
free(template);
|
free(template);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user