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