compile: implement compilation of doubles and arrays
This commit is contained in:
+12
-1
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
+27
-4
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
+4
-2
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user