lang: codegen: implement message-send code generation and global var references
This commit is contained in:
@@ -19,7 +19,8 @@
|
||||
*/
|
||||
|
||||
enum ivy_status codegen_push_generator(
|
||||
struct ivy_codegen *gen, enum code_generator_type gen_type, void *arg)
|
||||
struct ivy_codegen *gen, enum code_generator_type gen_type,
|
||||
uintptr_t argv, void *argp)
|
||||
{
|
||||
const struct code_generator *generator = get_code_generator(gen_type);
|
||||
if (!generator) {
|
||||
@@ -38,12 +39,11 @@ enum ivy_status codegen_push_generator(
|
||||
memset(state, 0x0, generator->g_state_size);
|
||||
|
||||
state->s_gen = generator;
|
||||
state->s_arg = arg;
|
||||
|
||||
enum ivy_status status = IVY_OK;
|
||||
|
||||
if (generator->g_state_init) {
|
||||
status = generator->g_state_init(gen, state);
|
||||
status = generator->g_state_init(gen, state, argv, argp);
|
||||
}
|
||||
|
||||
if (status != IVY_OK) {
|
||||
@@ -201,6 +201,8 @@ struct codegen_var *codegen_resolve_variable(
|
||||
if (code_generator_scope_is_top_level(scope)) {
|
||||
break;
|
||||
}
|
||||
|
||||
cur = b_queue_prev(cur);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -303,7 +305,8 @@ struct mie_module *ivy_codegen_get_current_module(struct ivy_codegen *gen)
|
||||
return gen->c_module;
|
||||
}
|
||||
|
||||
static enum ivy_status pop_generator_recurse(struct ivy_codegen *gen)
|
||||
static enum ivy_status pop_generator_recurse(
|
||||
struct ivy_codegen *gen, size_t node_depth)
|
||||
{
|
||||
while (1) {
|
||||
struct mie_value *value = NULL;
|
||||
@@ -318,14 +321,46 @@ static enum ivy_status pop_generator_recurse(struct ivy_codegen *gen)
|
||||
struct code_generator_result result
|
||||
= state->s_gen->g_value_received(gen, state, value);
|
||||
|
||||
if (!(result.r_flags & CODEGEN_POP_GENERATOR)) {
|
||||
bool should_pop = ((result.r_flags & CODEGEN_R_POP_GENERATOR) != 0)
|
||||
|| node_depth <= state->s_depth;
|
||||
|
||||
if (result.r_status != IVY_OK) {
|
||||
return result.r_status;
|
||||
}
|
||||
|
||||
if (!should_pop) {
|
||||
return IVY_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
static bool node_is_expr(struct ivy_ast_node *node)
|
||||
{
|
||||
switch (node->n_type) {
|
||||
case IVY_AST_OP:
|
||||
case IVY_AST_MSG:
|
||||
case IVY_AST_LAMBDA:
|
||||
case IVY_AST_DISCARD:
|
||||
case IVY_AST_INT:
|
||||
case IVY_AST_DOUBLE:
|
||||
case IVY_AST_STRING:
|
||||
case IVY_AST_FSTRING:
|
||||
case IVY_AST_ATOM:
|
||||
case IVY_AST_IDENT:
|
||||
case IVY_AST_CASCADE:
|
||||
case IVY_AST_MATCH:
|
||||
case IVY_AST_COND_GROUP:
|
||||
case IVY_AST_TUPLE:
|
||||
case IVY_AST_PKG_STATIC:
|
||||
case IVY_AST_PKG_DYNAMIC:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
enum ivy_status ivy_codegen_push_node(
|
||||
struct ivy_codegen *gen, struct ivy_ast_node *node, size_t node_depth)
|
||||
{
|
||||
@@ -340,7 +375,7 @@ enum ivy_status ivy_codegen_push_node(
|
||||
return IVY_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
codegen_push_generator(gen, generator->g_type, 0);
|
||||
codegen_push_generator(gen, generator->g_type, 0, NULL);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
@@ -358,7 +393,7 @@ enum ivy_status ivy_codegen_push_node(
|
||||
state->s_root = node;
|
||||
state->s_depth = node_depth;
|
||||
} else if (node_depth <= state->s_depth) {
|
||||
status = pop_generator_recurse(gen);
|
||||
status = pop_generator_recurse(gen, node_depth);
|
||||
}
|
||||
|
||||
if (status != IVY_OK) {
|
||||
@@ -368,16 +403,21 @@ enum ivy_status ivy_codegen_push_node(
|
||||
state = get_current_generator_state(gen);
|
||||
const struct code_generator *generator = state->s_gen;
|
||||
|
||||
bool is_expr = node_is_expr(node);
|
||||
code_generator_node_callback func
|
||||
= generator->g_node_generators[node->n_type];
|
||||
|
||||
if (!func && is_expr) {
|
||||
func = generator->g_expr_generator;
|
||||
}
|
||||
|
||||
if (!func) {
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
result = func(gen, state, node, node_depth);
|
||||
|
||||
if (result.r_flags & CODEGEN_REPEAT_NODE) {
|
||||
if (result.r_flags & CODEGEN_R_REPEAT_NODE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
#include <ivy/lang/lex.h>
|
||||
#include <mie/builder.h>
|
||||
|
||||
struct ivy_codegen;
|
||||
struct ivy_ast_node;
|
||||
|
||||
struct mie_value;
|
||||
struct mie_func;
|
||||
|
||||
#define CODEGEN_RESULT_OK(flags) \
|
||||
(struct code_generator_result) \
|
||||
{ \
|
||||
@@ -17,11 +23,8 @@
|
||||
.r_status = (status), .r_flags = (0) \
|
||||
}
|
||||
|
||||
struct ivy_codegen;
|
||||
struct ivy_ast_node;
|
||||
|
||||
struct mie_value;
|
||||
struct mie_func;
|
||||
#define __AST_INDEX(type) IVY_AST_##type
|
||||
#define NODE_CODEGEN(type, func) [__AST_INDEX(type)] = func
|
||||
|
||||
struct codegen_value {
|
||||
b_queue_entry v_entry;
|
||||
@@ -35,11 +38,16 @@ struct codegen_var {
|
||||
struct mie_value *v_ptr;
|
||||
};
|
||||
|
||||
enum code_generator_flags {
|
||||
CODEGEN_F_IGNORE_RESULT = 0x01u,
|
||||
};
|
||||
|
||||
enum code_generator_type {
|
||||
CODE_GENERATOR_NONE = 0,
|
||||
CODE_GENERATOR_UNIT,
|
||||
CODE_GENERATOR_EXPR,
|
||||
CODE_GENERATOR_VAR,
|
||||
CODE_GENERATOR_MSG,
|
||||
};
|
||||
|
||||
enum code_generator_scope_type {
|
||||
@@ -53,15 +61,15 @@ struct code_generator_result {
|
||||
enum ivy_status r_status;
|
||||
|
||||
enum code_generator_result_flags {
|
||||
CODEGEN_REPEAT_NODE = 0x01u,
|
||||
CODEGEN_POP_GENERATOR = 0x02u,
|
||||
CODEGEN_R_REPEAT_NODE = 0x01u,
|
||||
CODEGEN_R_POP_GENERATOR = 0x02u,
|
||||
} r_flags;
|
||||
};
|
||||
|
||||
struct code_generator_state;
|
||||
|
||||
typedef enum ivy_status (*code_generator_state_init_callback)(
|
||||
struct ivy_codegen *, struct code_generator_state *);
|
||||
struct ivy_codegen *, struct code_generator_state *, uintptr_t, void *);
|
||||
typedef enum ivy_status (*code_generator_state_fini_callback)(
|
||||
struct ivy_codegen *, struct code_generator_state *, struct mie_value **);
|
||||
typedef struct code_generator_result (*code_generator_callback)(
|
||||
@@ -79,12 +87,14 @@ struct code_generator {
|
||||
code_generator_state_init_callback g_state_init;
|
||||
code_generator_state_fini_callback g_state_fini;
|
||||
code_generator_node_callback g_node_generators[IVY_AST_TYPE_COUNT];
|
||||
code_generator_node_callback g_expr_generator;
|
||||
code_generator_value_received_callback g_value_received;
|
||||
};
|
||||
|
||||
struct code_generator_state {
|
||||
b_queue_entry s_entry;
|
||||
void *s_arg;
|
||||
uintptr_t s_argv;
|
||||
void *s_argp;
|
||||
const struct code_generator *s_gen;
|
||||
struct ivy_ast_node *s_root;
|
||||
size_t s_depth;
|
||||
@@ -112,7 +122,8 @@ extern const struct code_generator *get_root_code_generator(
|
||||
enum ivy_ast_node_type type);
|
||||
|
||||
extern enum ivy_status codegen_push_generator(
|
||||
struct ivy_codegen *gen, enum code_generator_type gen_type, void *arg);
|
||||
struct ivy_codegen *gen, enum code_generator_type gen_type,
|
||||
uintptr_t argv, void *argp);
|
||||
extern enum ivy_status codegen_pop_generator(
|
||||
struct ivy_codegen *gen, struct mie_value **result);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ struct expr_item {
|
||||
struct expr_codegen_state {
|
||||
struct code_generator_state s_base;
|
||||
struct ivy_ast_node *s_expr_root;
|
||||
uintptr_t s_flags;
|
||||
b_queue s_item_queue;
|
||||
};
|
||||
|
||||
@@ -107,6 +108,24 @@ static struct code_generator_result gen_op(
|
||||
return CODEGEN_RESULT_OK(0);
|
||||
}
|
||||
|
||||
static struct code_generator_result gen_msg(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct ivy_ast_node *node, size_t depth)
|
||||
{
|
||||
debug_printf("codegen: got msg\n");
|
||||
struct expr_codegen_state *expr = (struct expr_codegen_state *)state;
|
||||
|
||||
int flags = 0;
|
||||
if (b_queue_empty(&expr->s_item_queue)
|
||||
&& (expr->s_flags & CODEGEN_F_IGNORE_RESULT)) {
|
||||
flags |= CODEGEN_F_IGNORE_RESULT;
|
||||
}
|
||||
|
||||
codegen_push_generator(gen, CODE_GENERATOR_MSG, flags, NULL);
|
||||
|
||||
return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE);
|
||||
}
|
||||
|
||||
static struct code_generator_result gen_var_reference(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct ivy_ast_node *node, size_t depth)
|
||||
@@ -124,7 +143,8 @@ static struct code_generator_result gen_var_reference(
|
||||
var_ptr = var->v_ptr;
|
||||
} else {
|
||||
/* this is a global variable, and needs to be loaded via a data ptr */
|
||||
/* TODO */
|
||||
var_ptr = mie_builder_get_data_ptr(
|
||||
gen->c_builder, ident->n_content->t_str);
|
||||
}
|
||||
|
||||
struct mie_type *id = mie_ctx_get_type(gen->c_ctx, MIE_TYPE_ID);
|
||||
@@ -257,7 +277,8 @@ static struct code_generator_result cancel_expr(
|
||||
#endif
|
||||
|
||||
static enum ivy_status state_init(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state)
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
uintptr_t argv, void *argp)
|
||||
{
|
||||
debug_printf("codegen: start of expression\n");
|
||||
return IVY_OK;
|
||||
@@ -339,14 +360,31 @@ static enum ivy_status state_fini(
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
static struct code_generator_result value_received(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct mie_value *value)
|
||||
{
|
||||
struct expr_codegen_state *expr = (struct expr_codegen_state *)state;
|
||||
|
||||
debug_printf("codegen: got sub-expr\n");
|
||||
enum ivy_status status = push_operand(expr, NULL, value);
|
||||
if (status != IVY_OK) {
|
||||
return CODEGEN_RESULT_ERR(status);
|
||||
}
|
||||
|
||||
return CODEGEN_RESULT_OK(0);
|
||||
}
|
||||
|
||||
struct code_generator expr_generator = {
|
||||
.g_type = CODE_GENERATOR_EXPR,
|
||||
.g_state_size = sizeof(struct expr_codegen_state),
|
||||
.g_state_init = state_init,
|
||||
.g_state_fini = state_fini,
|
||||
.g_value_received = value_received,
|
||||
.g_node_generators = {
|
||||
[IVY_AST_INT] = gen_int,
|
||||
[IVY_AST_OP] = gen_op,
|
||||
[IVY_AST_IDENT] = gen_var_reference,
|
||||
NODE_CODEGEN(INT, gen_int),
|
||||
NODE_CODEGEN(OP, gen_op),
|
||||
NODE_CODEGEN(MSG, gen_msg),
|
||||
NODE_CODEGEN(IDENT, gen_var_reference),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
extern const struct code_generator unit_generator;
|
||||
extern const struct code_generator expr_generator;
|
||||
extern const struct code_generator var_generator;
|
||||
extern const struct code_generator msg_generator;
|
||||
|
||||
static const struct code_generator *code_generators[] = {
|
||||
[CODE_GENERATOR_UNIT] = &unit_generator,
|
||||
[CODE_GENERATOR_EXPR] = &expr_generator,
|
||||
[CODE_GENERATOR_VAR] = &var_generator,
|
||||
[CODE_GENERATOR_MSG] = &msg_generator,
|
||||
};
|
||||
static const size_t nr_code_generators
|
||||
= sizeof code_generators / sizeof code_generators[0];
|
||||
|
||||
213
lang/codegen/msg.c
Normal file
213
lang/codegen/msg.c
Normal file
@@ -0,0 +1,213 @@
|
||||
#include "../debug.h"
|
||||
#include "codegen.h"
|
||||
|
||||
#include <blue/core/stringstream.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
enum msg_part {
|
||||
MSG_NONE = 0,
|
||||
MSG_START,
|
||||
MSG_RECIPIENT,
|
||||
MSG_SELECTOR,
|
||||
MSG_ARG,
|
||||
};
|
||||
|
||||
struct msg_codegen_state {
|
||||
struct code_generator_state s_base;
|
||||
enum msg_part s_prev_part;
|
||||
|
||||
enum code_generator_flags s_flags;
|
||||
struct mie_value *s_recipient;
|
||||
struct ivy_ast_selector_node *s_selector;
|
||||
struct mie_value **s_args;
|
||||
/* the number of args we've collected so far */
|
||||
size_t s_nr_args;
|
||||
/* the number of args we're expecting based on the selector */
|
||||
size_t s_max_args;
|
||||
};
|
||||
|
||||
#if 0
|
||||
static struct code_generator_result check_expr_root(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct ivy_ast_node *node)
|
||||
{
|
||||
struct expr_codegen_state *expr = (struct expr_codegen_state *)state;
|
||||
if (!expr->s_expr_root) {
|
||||
expr->s_expr_root = node;
|
||||
}
|
||||
|
||||
return CODEGEN_RESULT_OK(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct code_generator_result gen_msg(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct ivy_ast_node *node, size_t depth)
|
||||
{
|
||||
struct msg_codegen_state *msg = (struct msg_codegen_state *)state;
|
||||
if (msg->s_prev_part == MSG_NONE) {
|
||||
msg->s_prev_part = MSG_START;
|
||||
return CODEGEN_RESULT_OK(0);
|
||||
}
|
||||
|
||||
codegen_push_generator(gen, CODE_GENERATOR_MSG, 0, NULL);
|
||||
|
||||
return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE);
|
||||
}
|
||||
|
||||
static struct code_generator_result gen_expr(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct ivy_ast_node *node, size_t depth)
|
||||
{
|
||||
struct msg_codegen_state *msg = (struct msg_codegen_state *)state;
|
||||
if (msg->s_prev_part == MSG_RECIPIENT) {
|
||||
/* expected message selector */
|
||||
return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX);
|
||||
}
|
||||
|
||||
codegen_push_generator(gen, CODE_GENERATOR_EXPR, 0, NULL);
|
||||
|
||||
return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE);
|
||||
}
|
||||
|
||||
static struct code_generator_result gen_selector(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct ivy_ast_node *node, size_t depth)
|
||||
{
|
||||
struct msg_codegen_state *msg = (struct msg_codegen_state *)state;
|
||||
if (msg->s_prev_part != MSG_RECIPIENT) {
|
||||
/* expected something else */
|
||||
return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX);
|
||||
}
|
||||
|
||||
msg->s_selector = (struct ivy_ast_selector_node *)node;
|
||||
msg->s_prev_part = MSG_SELECTOR;
|
||||
|
||||
msg->s_nr_args = 0;
|
||||
msg->s_max_args = b_queue_length(&msg->s_selector->n_arg_labels);
|
||||
msg->s_args = calloc(msg->s_max_args, sizeof(struct mie_value *));
|
||||
|
||||
if (!msg->s_args) {
|
||||
return CODEGEN_RESULT_ERR(IVY_ERR_NO_MEMORY);
|
||||
}
|
||||
|
||||
return CODEGEN_RESULT_OK(0);
|
||||
}
|
||||
|
||||
static enum ivy_status state_init(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
uintptr_t argv, void *argp)
|
||||
{
|
||||
debug_printf("codegen: start of msg\n");
|
||||
struct msg_codegen_state *msg = (struct msg_codegen_state *)state;
|
||||
msg->s_flags = argv;
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
static void serialise_selector(
|
||||
struct ivy_ast_selector_node *sel, b_stringstream *out)
|
||||
{
|
||||
b_stringstream_add(out, "_M");
|
||||
|
||||
if (sel->n_msg_name) {
|
||||
const char *msg_name = sel->n_msg_name->t_str;
|
||||
b_stringstream_addf(out, "%zu%s", strlen(msg_name), msg_name);
|
||||
} else {
|
||||
b_stringstream_add(out, "0");
|
||||
}
|
||||
|
||||
b_queue_iterator it;
|
||||
b_queue_foreach (&it, &sel->n_arg_labels) {
|
||||
struct ivy_token *arg
|
||||
= b_unbox(struct ivy_token, it.entry, t_entry);
|
||||
const char *label = arg->t_str;
|
||||
|
||||
b_stringstream_addf(out, "%zu%s", strlen(label), label);
|
||||
}
|
||||
|
||||
b_stringstream_add(out, "E");
|
||||
}
|
||||
|
||||
static enum ivy_status state_fini(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct mie_value **result)
|
||||
{
|
||||
debug_printf("codegen: end of msg\n");
|
||||
|
||||
struct msg_codegen_state *msg = (struct msg_codegen_state *)state;
|
||||
|
||||
b_stringstream str;
|
||||
b_stringstream_begin_dynamic(&str);
|
||||
serialise_selector(msg->s_selector, &str);
|
||||
char *sel = b_stringstream_end(&str);
|
||||
struct mie_value *sel_value = mie_ctx_get_selector(gen->c_ctx, sel);
|
||||
free(sel);
|
||||
|
||||
enum mie_builder_flags flags = 0;
|
||||
struct mie_type *ret_type = NULL;
|
||||
const char *value_name = NULL;
|
||||
|
||||
if (msg->s_flags & CODEGEN_F_IGNORE_RESULT) {
|
||||
ret_type = mie_ctx_get_type(gen->c_ctx, MIE_TYPE_VOID);
|
||||
flags = MIE_BUILDER_IGNORE_RESULT;
|
||||
} else {
|
||||
ret_type = mie_ctx_get_type(gen->c_ctx, MIE_TYPE_ID);
|
||||
value_name = "msgtmp";
|
||||
}
|
||||
|
||||
struct mie_value *msg_send = mie_builder_msg(
|
||||
gen->c_builder, ret_type, msg->s_recipient, sel_value,
|
||||
msg->s_args, msg->s_nr_args, flags, value_name);
|
||||
|
||||
if (msg->s_args) {
|
||||
free(msg->s_args);
|
||||
}
|
||||
|
||||
*result = msg_send;
|
||||
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
static struct code_generator_result value_received(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct mie_value *value)
|
||||
{
|
||||
struct msg_codegen_state *msg = (struct msg_codegen_state *)state;
|
||||
switch (msg->s_prev_part) {
|
||||
case MSG_START:
|
||||
msg->s_recipient = value;
|
||||
msg->s_prev_part = MSG_RECIPIENT;
|
||||
break;
|
||||
case MSG_RECIPIENT:
|
||||
return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX);
|
||||
case MSG_SELECTOR:
|
||||
msg->s_prev_part = MSG_ARG;
|
||||
case MSG_ARG:
|
||||
if (msg->s_nr_args == msg->s_max_args) {
|
||||
/* too many args */
|
||||
return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX);
|
||||
}
|
||||
|
||||
msg->s_args[msg->s_nr_args++] = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CODEGEN_RESULT_OK(0);
|
||||
}
|
||||
|
||||
struct code_generator msg_generator = {
|
||||
.g_type = CODE_GENERATOR_MSG,
|
||||
.g_state_size = sizeof(struct msg_codegen_state),
|
||||
.g_state_init = state_init,
|
||||
.g_state_fini = state_fini,
|
||||
.g_expr_generator = gen_expr,
|
||||
.g_node_generators = {
|
||||
NODE_CODEGEN(MSG, gen_msg),
|
||||
NODE_CODEGEN(SELECTOR, gen_selector),
|
||||
},
|
||||
.g_value_received = value_received,
|
||||
};
|
||||
@@ -83,8 +83,9 @@ static struct code_generator_result gen_expr(
|
||||
return CODEGEN_RESULT_ERR(status);
|
||||
}
|
||||
|
||||
codegen_push_generator(gen, CODE_GENERATOR_EXPR, NULL);
|
||||
return CODEGEN_RESULT_OK(CODEGEN_REPEAT_NODE);
|
||||
codegen_push_generator(
|
||||
gen, CODE_GENERATOR_EXPR, CODEGEN_F_IGNORE_RESULT, NULL);
|
||||
return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE);
|
||||
}
|
||||
|
||||
static struct code_generator_result gen_var_declaration(
|
||||
@@ -104,8 +105,8 @@ static struct code_generator_result gen_var_declaration(
|
||||
return CODEGEN_RESULT_ERR(status);
|
||||
}
|
||||
|
||||
codegen_push_generator(gen, CODE_GENERATOR_VAR, NULL);
|
||||
return CODEGEN_RESULT_OK(CODEGEN_REPEAT_NODE);
|
||||
codegen_push_generator(gen, CODE_GENERATOR_VAR, 0, NULL);
|
||||
return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -146,7 +147,8 @@ static struct code_generator_result gen_var_declaration(
|
||||
#endif
|
||||
|
||||
static enum ivy_status state_init(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state)
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
uintptr_t argv, void *argp)
|
||||
{
|
||||
struct unit_codegen_state *unit = (struct unit_codegen_state *)state;
|
||||
unit->s_scope = codegen_push_scope(gen);
|
||||
@@ -169,9 +171,7 @@ struct code_generator unit_generator = {
|
||||
.g_state_init = state_init,
|
||||
.g_state_fini = state_fini,
|
||||
.g_node_generators = {
|
||||
[IVY_AST_INT] = gen_expr,
|
||||
[IVY_AST_OP] = gen_expr,
|
||||
[IVY_AST_IDENT] = gen_expr,
|
||||
[IVY_AST_VAR] = gen_var_declaration,
|
||||
NODE_CODEGEN(VAR, gen_var_declaration),
|
||||
},
|
||||
.g_expr_generator = gen_expr,
|
||||
};
|
||||
|
||||
@@ -27,14 +27,27 @@ static struct code_generator_result gen_var(
|
||||
return CODEGEN_RESULT_OK(0);
|
||||
}
|
||||
|
||||
static struct code_generator_result gen_value_expr(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct ivy_ast_node *node, size_t depth)
|
||||
{
|
||||
struct var_codegen_state *var = (struct var_codegen_state *)state;
|
||||
if (var->s_prev_node != IVY_AST_IDENT && var->s_prev_node != IVY_AST_TUPLE) {
|
||||
return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX);
|
||||
}
|
||||
|
||||
codegen_push_generator(gen, CODE_GENERATOR_EXPR, 0, NULL);
|
||||
|
||||
return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE);
|
||||
}
|
||||
|
||||
static struct code_generator_result gen_ident(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct ivy_ast_node *node, size_t depth)
|
||||
{
|
||||
struct var_codegen_state *var = (struct var_codegen_state *)state;
|
||||
if (var->s_prev_node != IVY_AST_VAR) {
|
||||
/* TODO support tuple assignment */
|
||||
return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX);
|
||||
return gen_value_expr(gen, state, node, depth);
|
||||
}
|
||||
|
||||
struct ivy_ast_ident_node *ident = (struct ivy_ast_ident_node *)node;
|
||||
@@ -52,20 +65,6 @@ static struct code_generator_result gen_ident(
|
||||
return CODEGEN_RESULT_OK(0);
|
||||
}
|
||||
|
||||
static struct code_generator_result gen_value_expr(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct ivy_ast_node *node, size_t depth)
|
||||
{
|
||||
struct var_codegen_state *var = (struct var_codegen_state *)state;
|
||||
if (var->s_prev_node != IVY_AST_IDENT && var->s_prev_node != IVY_AST_TUPLE) {
|
||||
return CODEGEN_RESULT_ERR(IVY_ERR_BAD_SYNTAX);
|
||||
}
|
||||
|
||||
codegen_push_generator(gen, CODE_GENERATOR_EXPR, 0);
|
||||
|
||||
return CODEGEN_RESULT_OK(CODEGEN_REPEAT_NODE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static struct code_generator_result gen_var_ref(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
@@ -93,9 +92,10 @@ static struct code_generator_result gen_var_ref(
|
||||
#endif
|
||||
|
||||
static enum ivy_status state_init(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state)
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
uintptr_t argv, void *argp)
|
||||
{
|
||||
printf("codegen: start of var decl\n");
|
||||
debug_printf("codegen: start of var decl\n");
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ static enum ivy_status state_fini(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct mie_value **result)
|
||||
{
|
||||
printf("codegen: end of var decl\n");
|
||||
debug_printf("codegen: end of var decl\n");
|
||||
struct var_codegen_state *var = (struct var_codegen_state *)state;
|
||||
|
||||
struct code_generator_scope *scope = codegen_get_current_scope(gen);
|
||||
@@ -112,6 +112,7 @@ static enum ivy_status state_fini(
|
||||
if (var->s_value) {
|
||||
mie_builder_store(gen->c_builder, var->s_value, var->s_var_ptr);
|
||||
}
|
||||
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
@@ -119,7 +120,7 @@ static struct code_generator_result value_received(
|
||||
struct ivy_codegen *gen, struct code_generator_state *state,
|
||||
struct mie_value *value)
|
||||
{
|
||||
printf("codegen: var decl value received\n");
|
||||
debug_printf("codegen: var decl value received\n");
|
||||
|
||||
struct var_codegen_state *var = (struct var_codegen_state *)state;
|
||||
if (!var->s_var_ptr) {
|
||||
@@ -128,7 +129,7 @@ static struct code_generator_result value_received(
|
||||
|
||||
var->s_value = value;
|
||||
|
||||
return CODEGEN_RESULT_OK(CODEGEN_POP_GENERATOR);
|
||||
return CODEGEN_RESULT_OK(CODEGEN_R_POP_GENERATOR);
|
||||
}
|
||||
|
||||
struct code_generator var_generator = {
|
||||
@@ -137,10 +138,9 @@ struct code_generator var_generator = {
|
||||
.g_state_init = state_init,
|
||||
.g_state_fini = state_fini,
|
||||
.g_value_received = value_received,
|
||||
.g_expr_generator = gen_value_expr,
|
||||
.g_node_generators = {
|
||||
[IVY_AST_VAR] = gen_var,
|
||||
[IVY_AST_IDENT] = gen_ident,
|
||||
[IVY_AST_INT] = gen_value_expr,
|
||||
[IVY_AST_OP] = gen_value_expr,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user