compile: implement compilation of doubles and arrays

This commit is contained in:
2026-05-24 20:17:35 +01:00
parent e679c41725
commit c3bf6dcee6
6 changed files with 97 additions and 7 deletions
+12 -1
View File
@@ -1,13 +1,24 @@
#include "compile-node.h" #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_result compile_array(
struct compile_ctx *ctx, struct compile_ctx *ctx,
struct ast_node *src) struct ast_node *src)
{ {
struct array_ast_node *array = (struct array_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( bshell_scriptblock_push_instruction(
ctx->c_block, ctx->c_block,
OPCODE_MK_ARRAY, OPCODE_MK_ARRAY,
fx_queue_length(&array->n_items)); nr_items);
compile_push_value(ctx, &array_type, src);
return COMPILE_OK(0); return COMPILE_OK(0);
} }
+12
View File
@@ -45,6 +45,8 @@ struct compile_value {
const struct compile_value_type *v_type; const struct compile_value_type *v_type;
enum operator_id v_op; enum operator_id v_op;
struct compile_value *v_left, *v_right; struct compile_value *v_left, *v_right;
struct compile_value **v_args;
size_t v_nr_args;
struct ast_node *v_node; struct ast_node *v_node;
unsigned long v_pool; unsigned long v_pool;
fx_queue_entry v_entry; fx_queue_entry v_entry;
@@ -93,12 +95,19 @@ extern enum bshell_status compile_push_value(
struct compile_ctx *ctx, struct compile_ctx *ctx,
const struct compile_value_type *type, const struct compile_value_type *type,
struct ast_node *node); 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( extern enum bshell_status compile_push_pool_value(
struct compile_ctx *ctx, struct compile_ctx *ctx,
const struct compile_value_type *type, const struct compile_value_type *type,
unsigned long pool_slot); unsigned long pool_slot);
extern enum bshell_status compile_push_op( extern enum bshell_status compile_push_op(
struct compile_ctx *ctx, struct compile_ctx *ctx,
struct ast_node *node,
const struct compile_value_type *type, const struct compile_value_type *type,
enum operator_id op, enum operator_id op,
struct compile_value *left, 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( extern struct compile_result compile_int(
struct compile_ctx *ctx, struct compile_ctx *ctx,
struct ast_node *src); struct ast_node *src);
extern struct compile_result compile_double(
struct compile_ctx *ctx,
struct ast_node *src);
extern struct compile_result compile_string( extern struct compile_result compile_string(
struct compile_ctx *ctx, struct compile_ctx *ctx,
struct ast_node *src); struct ast_node *src);
+27 -4
View File
@@ -5,10 +5,21 @@ enum bshell_status int_load(
struct compile_value *value) struct compile_value *value)
{ {
struct int_ast_node *i = (struct int_ast_node *)value->v_node; struct int_ast_node *i = (struct int_ast_node *)value->v_node;
bshell_scriptblock_push_instruction( long long v;
ctx->c_block, fx_value_get_longlong(&i->n_value->tok_number, &v);
OPCODE_LDC_INT, bshell_scriptblock_push_instruction(ctx->c_block, OPCODE_LDC_INT, v);
i->n_value->tok_int); 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; return BSHELL_SUCCESS;
} }
@@ -54,6 +65,10 @@ static const struct compile_value_type int_type = {
.v_load = int_load, .v_load = int_load,
}; };
static const struct compile_value_type double_type = {
.v_load = double_load,
};
static const struct compile_value_type string_type = { static const struct compile_value_type string_type = {
.v_load = string_load, .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); 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_result compile_string(
struct compile_ctx *ctx, struct compile_ctx *ctx,
struct ast_node *src) struct ast_node *src)
+1
View File
@@ -2,6 +2,7 @@
static const compile_node_impl node_compilers[] = { static const compile_node_impl node_compilers[] = {
[AST_INT] = compile_int, [AST_INT] = compile_int,
[AST_DOUBLE] = compile_double,
[AST_STRING] = compile_string, [AST_STRING] = compile_string,
[AST_WORD] = compile_word, [AST_WORD] = compile_word,
[AST_OP] = compile_op, [AST_OP] = compile_op,
+4 -2
View File
@@ -76,6 +76,8 @@ static enum bshell_opcode opcode_for_op(enum operator_id op)
return OPCODE_IS; return OPCODE_IS;
case OP_AS: case OP_AS:
return OPCODE_AS; return OPCODE_AS;
case OP_ACCESS:
return OPCODE_LDPROP;
default: default:
return OPCODE_NOP; 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 op_ast_node *op = (struct op_ast_node *)src;
struct compile_value *left = NULL, *right = NULL; struct compile_value *left = NULL, *right = NULL;
right = compile_pop_value(ctx);
left = 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); return COMPILE_OK(0);
} }
+41
View File
@@ -19,6 +19,29 @@ enum bshell_status compile_push_value(
return BSHELL_SUCCESS; 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( enum bshell_status compile_push_pool_value(
struct compile_ctx *ctx, struct compile_ctx *ctx,
const struct compile_value_type *type, const struct compile_value_type *type,
@@ -40,6 +63,7 @@ enum bshell_status compile_push_pool_value(
enum bshell_status compile_push_op( enum bshell_status compile_push_op(
struct compile_ctx *ctx, struct compile_ctx *ctx,
struct ast_node *node,
const struct compile_value_type *type, const struct compile_value_type *type,
enum operator_id op, enum operator_id op,
struct compile_value *left, struct compile_value *left,
@@ -53,6 +77,7 @@ enum bshell_status compile_push_op(
memset(item, 0x0, sizeof *item); memset(item, 0x0, sizeof *item);
item->v_type = type; item->v_type = type;
item->v_node = node;
item->v_op = op; item->v_op = op;
item->v_left = left; item->v_left = left;
item->v_right = right; 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) 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); free(value);
} }