diff --git a/bshell/compile/array.c b/bshell/compile/array.c index 82d61bd..b51c6dc 100644 --- a/bshell/compile/array.c +++ b/bshell/compile/array.c @@ -1,13 +1,24 @@ #include "compile-node.h" +static const struct compile_value_type array_type = {}; +static const struct compile_value_type array_item_type = {}; + struct compile_result compile_array( struct compile_ctx *ctx, struct ast_node *src) { struct array_ast_node *array = (struct array_ast_node *)src; + size_t nr_items = fx_queue_length(&array->n_items); + for (size_t i = 0; i < nr_items; i++) { + struct compile_value *item = compile_pop_value(ctx); + compile_value_load(ctx, item); + compile_value_destroy(item); + } + bshell_scriptblock_push_instruction( ctx->c_block, OPCODE_MK_ARRAY, - fx_queue_length(&array->n_items)); + nr_items); + compile_push_value(ctx, &array_type, src); return COMPILE_OK(0); } diff --git a/bshell/compile/compile-node.h b/bshell/compile/compile-node.h index 6fb89a7..75e3358 100644 --- a/bshell/compile/compile-node.h +++ b/bshell/compile/compile-node.h @@ -45,6 +45,8 @@ struct compile_value { const struct compile_value_type *v_type; enum operator_id v_op; struct compile_value *v_left, *v_right; + struct compile_value **v_args; + size_t v_nr_args; struct ast_node *v_node; unsigned long v_pool; fx_queue_entry v_entry; @@ -93,12 +95,19 @@ extern enum bshell_status compile_push_value( struct compile_ctx *ctx, const struct compile_value_type *type, struct ast_node *node); +extern enum bshell_status compile_push_value_array( + struct compile_ctx *ctx, + const struct compile_value_type *type, + struct ast_node *node, + struct compile_value **values, + size_t nr_values); extern enum bshell_status compile_push_pool_value( struct compile_ctx *ctx, const struct compile_value_type *type, unsigned long pool_slot); extern enum bshell_status compile_push_op( struct compile_ctx *ctx, + struct ast_node *node, const struct compile_value_type *type, enum operator_id op, struct compile_value *left, @@ -120,6 +129,9 @@ extern enum bshell_status compile_resolve_labels(struct compile_ctx *ctx); extern struct compile_result compile_int( struct compile_ctx *ctx, struct ast_node *src); +extern struct compile_result compile_double( + struct compile_ctx *ctx, + struct ast_node *src); extern struct compile_result compile_string( struct compile_ctx *ctx, struct ast_node *src); diff --git a/bshell/compile/const.c b/bshell/compile/const.c index 7ac74bf..d657184 100644 --- a/bshell/compile/const.c +++ b/bshell/compile/const.c @@ -5,10 +5,21 @@ enum bshell_status int_load( struct compile_value *value) { struct int_ast_node *i = (struct int_ast_node *)value->v_node; - bshell_scriptblock_push_instruction( - ctx->c_block, - OPCODE_LDC_INT, - i->n_value->tok_int); + long long v; + fx_value_get_longlong(&i->n_value->tok_number, &v); + bshell_scriptblock_push_instruction(ctx->c_block, OPCODE_LDC_INT, v); + return BSHELL_SUCCESS; +} + +enum bshell_status double_load( + struct compile_ctx *ctx, + struct compile_value *value) +{ + struct double_ast_node *d = (struct double_ast_node *)value->v_node; + double v; + fx_value_get_double(&d->n_value->tok_number, &v); + unsigned long index = bshell_scriptblock_get_double(ctx->c_block, v); + bshell_scriptblock_push_instruction(ctx->c_block, OPCODE_LDC_FP, index); return BSHELL_SUCCESS; } @@ -54,6 +65,10 @@ static const struct compile_value_type int_type = { .v_load = int_load, }; +static const struct compile_value_type double_type = { + .v_load = double_load, +}; + static const struct compile_value_type string_type = { .v_load = string_load, }; @@ -68,6 +83,14 @@ struct compile_result compile_int(struct compile_ctx *ctx, struct ast_node *src) return COMPILE_OK(0); } +struct compile_result compile_double( + struct compile_ctx *ctx, + struct ast_node *src) +{ + compile_push_value(ctx, &double_type, src); + return COMPILE_OK(0); +} + struct compile_result compile_string( struct compile_ctx *ctx, struct ast_node *src) diff --git a/bshell/compile/normal.c b/bshell/compile/normal.c index fe21bc9..4c52cd1 100644 --- a/bshell/compile/normal.c +++ b/bshell/compile/normal.c @@ -2,6 +2,7 @@ static const compile_node_impl node_compilers[] = { [AST_INT] = compile_int, + [AST_DOUBLE] = compile_double, [AST_STRING] = compile_string, [AST_WORD] = compile_word, [AST_OP] = compile_op, diff --git a/bshell/compile/op.c b/bshell/compile/op.c index 0f87eeb..dc78062 100644 --- a/bshell/compile/op.c +++ b/bshell/compile/op.c @@ -76,6 +76,8 @@ static enum bshell_opcode opcode_for_op(enum operator_id op) return OPCODE_IS; case OP_AS: return OPCODE_AS; + case OP_ACCESS: + return OPCODE_LDPROP; default: return OPCODE_NOP; } @@ -114,8 +116,8 @@ struct compile_result compile_op(struct compile_ctx *ctx, struct ast_node *src) { struct op_ast_node *op = (struct op_ast_node *)src; struct compile_value *left = NULL, *right = NULL; - right = compile_pop_value(ctx); left = compile_pop_value(ctx); - compile_push_op(ctx, &op_type, op->n_op->op_id, left, right); + right = compile_pop_value(ctx); + compile_push_op(ctx, src, &op_type, op->n_op->op_id, left, right); return COMPILE_OK(0); } diff --git a/bshell/compile/stack.c b/bshell/compile/stack.c index 9028217..fc94fcf 100644 --- a/bshell/compile/stack.c +++ b/bshell/compile/stack.c @@ -19,6 +19,29 @@ enum bshell_status compile_push_value( return BSHELL_SUCCESS; } +enum bshell_status compile_push_value_array( + struct compile_ctx *ctx, + const struct compile_value_type *type, + struct ast_node *node, + struct compile_value **values, + size_t nr_values) +{ + struct compile_value *item = malloc(sizeof *item); + if (!item) { + return BSHELL_ERR_NO_MEMORY; + } + + memset(item, 0x0, sizeof *item); + + item->v_type = type; + item->v_node = node; + item->v_args = values; + item->v_nr_args = nr_values; + fx_queue_push_back(&ctx->c_stack, &item->v_entry); + + return BSHELL_SUCCESS; +} + enum bshell_status compile_push_pool_value( struct compile_ctx *ctx, const struct compile_value_type *type, @@ -40,6 +63,7 @@ enum bshell_status compile_push_pool_value( enum bshell_status compile_push_op( struct compile_ctx *ctx, + struct ast_node *node, const struct compile_value_type *type, enum operator_id op, struct compile_value *left, @@ -53,6 +77,7 @@ enum bshell_status compile_push_op( memset(item, 0x0, sizeof *item); item->v_type = type; + item->v_node = node; item->v_op = op; item->v_left = left; item->v_right = right; @@ -87,5 +112,21 @@ void compile_value_store(struct compile_ctx *ctx, struct compile_value *item) void compile_value_destroy(struct compile_value *value) { + if (value->v_left) { + compile_value_destroy(value->v_left); + } + + if (value->v_right) { + compile_value_destroy(value->v_right); + } + + for (size_t i = 0; i < value->v_nr_args; i++) { + compile_value_destroy(value->v_args[i]); + } + + if (value->v_args) { + free(value->v_args); + } + free(value); }