.
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/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/expr.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}
|
||||||
|
|||||||
35
lib/expr.c
Normal file
35
lib/expr.c
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#include "priv.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
static bool was_init = false;
|
||||||
|
|
||||||
|
typedef TYC_RESULT(*BIN_EXPR_FN)(VALUE, VALUE, VALUE*);
|
||||||
|
static BIN_EXPR_FN bin_expr_fn[TX_COUNT__][TT_COUNT__][TT_COUNT__];
|
||||||
|
|
||||||
|
static TYC_RESULT default_bin_op(VALUE a, VALUE b, VALUE* r) { (void) a; (void) b, (void) r; return T_ERR_EXPR_INCORRECT_TYPES; }
|
||||||
|
|
||||||
|
#define BIN_OP(name) static TYC_RESULT name(VALUE a, VALUE b, VALUE* r)
|
||||||
|
BIN_OP(sum_int) { *r = create_value_integer(value_integer(a) + value_integer(b)); return T_OK; }
|
||||||
|
BIN_OP(sub_int) { *r = create_value_integer(value_integer(a) - value_integer(b)); return T_OK; }
|
||||||
|
|
||||||
|
void expr_init(void)
|
||||||
|
{
|
||||||
|
if (was_init)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < TX_COUNT__; ++i)
|
||||||
|
for (size_t j = 0; j < TT_COUNT__; ++j)
|
||||||
|
for (size_t k = 0; k < TT_COUNT__; ++k)
|
||||||
|
bin_expr_fn[i][j][k] = default_bin_op;
|
||||||
|
|
||||||
|
bin_expr_fn[TX_SUM][TT_INTEGER][TT_INTEGER] = sum_int;
|
||||||
|
bin_expr_fn[TX_SUBTRACT][TT_INTEGER][TT_INTEGER] = sub_int;
|
||||||
|
|
||||||
|
was_init = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TYC_RESULT binary_expr(TYC_EXPR op, VALUE a, VALUE b, VALUE* result)
|
||||||
|
{
|
||||||
|
return bin_expr_fn[op][value_type(a)][value_type(b)](a, b, result);
|
||||||
|
}
|
||||||
@@ -225,4 +225,11 @@ 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);
|
||||||
|
|
||||||
|
//
|
||||||
|
// EXPRESSIONS
|
||||||
|
//
|
||||||
|
|
||||||
|
void expr_init(void);
|
||||||
|
TYC_RESULT binary_expr(TYC_EXPR op, VALUE a, VALUE b, VALUE* result);
|
||||||
|
|
||||||
#endif //TYCHE_PRIV_H
|
#endif //TYCHE_PRIV_H
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ static TABLE_HASH value_hash(VALUE v)
|
|||||||
case TT_NATIVE_PTR:
|
case TT_NATIVE_PTR:
|
||||||
return (TABLE_HASH) value_idx(v) | ((TABLE_HASH) 1 << 37);
|
return (TABLE_HASH) value_idx(v) | ((TABLE_HASH) 1 << 37);
|
||||||
case TT_STRING:
|
case TT_STRING:
|
||||||
|
case TT_COUNT__:
|
||||||
default:
|
default:
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TT_NIL, TT_INTEGER, TT_REAL, TT_STRING, TT_STRING_CONST, TT_ARRAY, TT_TABLE, TT_FUNCTION, TT_NATIVE_PTR,
|
TT_NIL, TT_INTEGER, TT_REAL, TT_STRING, TT_STRING_CONST, TT_ARRAY, TT_TABLE, TT_FUNCTION, TT_NATIVE_PTR,
|
||||||
|
TT_COUNT__
|
||||||
} TYC_TYPE;
|
} TYC_TYPE;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -15,11 +16,12 @@ 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_TYPE_UNEXPECTED = -50, T_ERR_INVALID_OPCODE = -51, T_ERR_EXPR_INCORRECT_TYPES = -52,
|
||||||
} TYC_RESULT;
|
} TYC_RESULT;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TX_SUM,
|
TX_SUM, TX_SUBTRACT,
|
||||||
|
TX_COUNT__
|
||||||
} TYC_EXPR;
|
} TYC_EXPR;
|
||||||
|
|
||||||
#define T_REAL float
|
#define T_REAL float
|
||||||
|
|||||||
31
lib/vm.c
31
lib/vm.c
@@ -39,6 +39,9 @@ TycheVM* tyc_new(void)
|
|||||||
.cap = 4,
|
.cap = 4,
|
||||||
.sz = 0,
|
.sz = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
expr_init();
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,13 +180,16 @@ TYC_RESULT tyc_tointeger(TycheVM* T, int idx, int32_t* value)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYC_RESULT tyc_expr(TycheVM* T, TYC_EXPR expr)
|
TYC_RESULT tyc_expr(TycheVM* T, TYC_EXPR op)
|
||||||
{
|
{
|
||||||
// TODO
|
TYC_RESULT r;
|
||||||
VALUE v1, v2;
|
VALUE v1, v2, result;
|
||||||
|
|
||||||
stack_pop(T->stack, &v2);
|
stack_pop(T->stack, &v2);
|
||||||
stack_pop(T->stack, &v1);
|
stack_pop(T->stack, &v1);
|
||||||
stack_push(T->stack, create_value_integer(value_integer(v1) + value_integer(v2)));
|
TRY(binary_expr(op, v1, v2, &result))
|
||||||
|
stack_push(T->stack, result);
|
||||||
|
|
||||||
return T_OK;
|
return T_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,13 +209,24 @@ static TYC_RESULT step(TycheVM* T)
|
|||||||
|
|
||||||
switch (inst.operator) {
|
switch (inst.operator) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// stack manipulation
|
||||||
|
//
|
||||||
|
|
||||||
case TO_PUSHI:
|
case TO_PUSHI:
|
||||||
tyc_pushinteger(T, inst.operand);
|
tyc_pushinteger(T, inst.operand);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TO_SUM:
|
//
|
||||||
TRY(tyc_expr(T, TX_SUM))
|
// expressions
|
||||||
break;
|
//
|
||||||
|
|
||||||
|
case TO_SUM: TRY(tyc_expr(T, TX_SUM)); break;
|
||||||
|
case TO_SUB: TRY(tyc_expr(T, TX_SUBTRACT)); break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// function calls
|
||||||
|
//
|
||||||
|
|
||||||
case TO_RET:
|
case TO_RET:
|
||||||
TRY(stack_pop(T->stack, &a))
|
TRY(stack_pop(T->stack, &a))
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ int main(void)
|
|||||||
|
|
||||||
tyc_pushinteger(T, 2);
|
tyc_pushinteger(T, 2);
|
||||||
tyc_pushinteger(T, 3);
|
tyc_pushinteger(T, 3);
|
||||||
tyc_expr(T, TX_SUM);
|
assert(tyc_expr(T, TX_SUM) == T_OK);
|
||||||
int32_t result; assert(tyc_tointeger(T, -1, &result) == T_OK);
|
int32_t result; assert(tyc_tointeger(T, -1, &result) == T_OK);
|
||||||
assert(result == 5);
|
assert(result == 5);
|
||||||
|
|
||||||
@@ -408,7 +408,7 @@ static void run_assembly_test_code(lua_State* L)
|
|||||||
static void run_assembly_test_template(lua_State* L)
|
static void run_assembly_test_template(lua_State* L)
|
||||||
{
|
{
|
||||||
lua_getfield(L, -1, "template");
|
lua_getfield(L, -1, "template");
|
||||||
const char* template = strdup(lua_tostring(L, -1));
|
char* template = strdup(lua_tostring(L, -1));
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
lua_getfield(L, -1, "scenarios");
|
lua_getfield(L, -1, "scenarios");
|
||||||
@@ -430,12 +430,12 @@ static void run_assembly_test_template(lua_State* L)
|
|||||||
lua_getfield(L, -3, "parameters");
|
lua_getfield(L, -3, "parameters");
|
||||||
assert(!lua_isnil(L, -1));
|
assert(!lua_isnil(L, -1));
|
||||||
int n_params = (int) luaL_len(L, -1);
|
int n_params = (int) luaL_len(L, -1);
|
||||||
for (long j = 0; j < n_params; ++j)
|
for (int j = 0; j < n_params; ++j)
|
||||||
lua_geti(L, -(j + 1), j + 1);
|
lua_geti(L, -(j + 1), j + 1);
|
||||||
lua_remove(L, -(n_params + 1));
|
lua_remove(L, -(n_params + 1));
|
||||||
|
|
||||||
lua_call(L, n_params + 1, 1);
|
lua_call(L, n_params + 1, 1);
|
||||||
const char* formatted_code = strdup(lua_tostring(L, -1));
|
char* formatted_code = strdup(lua_tostring(L, -1));
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
// run code
|
// run code
|
||||||
|
|||||||
Reference in New Issue
Block a user