SCF_OP_IF, // if statement
SCF_OP_FOR, // for statement
SCF_OP_WHILE, // while statement
+ SCF_OP_REPEAT, // repeat statement
SCF_OP_RETURN, // return statement
SCF_OP_BREAK, // break statement
SCF_OP_CONTINUE, // continue statement
return e;
}
+int scf_expr_copy(scf_node_t* e2, scf_node_t* e)
+{
+ scf_node_t* node;
+
+ int i;
+ for (i = 0; i < e->nb_nodes; i++) {
+
+ node = scf_node_clone(e->nodes[i]);
+
+ if (!node)
+ return -ENOMEM;
+
+ scf_node_add_child(e2, node);
+
+ int ret = scf_expr_copy(e2->nodes[i], e->nodes[i]);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+scf_expr_t* scf_expr_clone(scf_node_t* e)
+{
+ scf_expr_t* e2 = scf_expr_alloc();
+
+ if (!e2)
+ return NULL;
+
+ if (scf_expr_copy(e2, e) < 0) {
+ scf_expr_free(e2);
+ return NULL;
+ }
+
+ return e2;
+}
+
void scf_expr_free(scf_expr_t* e)
{
if (e) {
typedef scf_node_t scf_expr_t; // expr is a node
scf_expr_t* scf_expr_alloc();
+scf_expr_t* scf_expr_clone(scf_expr_t* e);
void scf_expr_free(scf_expr_t* expr);
int scf_expr_add_node(scf_expr_t* expr, scf_node_t* node);
SCF_LEX_WORD_KEY_ELSIF, // else if
SCF_LEX_WORD_KEY_END_IF, // end if
- SCF_LEX_WORD_KEY_FOR, // for
- SCF_LEX_WORD_KEY_WHILE, // while
+ SCF_LEX_WORD_KEY_FOR, // for
+ SCF_LEX_WORD_KEY_TO, // to
+ SCF_LEX_WORD_KEY_BY, // by
+ SCF_LEX_WORD_KEY_DO, // do
+ SCF_LEX_WORD_KEY_END_FOR, // end for
+
+ SCF_LEX_WORD_KEY_WHILE, // while
+ SCF_LEX_WORD_KEY_END_WHILE, // end while
SCF_LEX_WORD_KEY_REPEAT, // repeat
SCF_LEX_WORD_KEY_UNTIL, // until
+ SCF_LEX_WORD_KEY_END_REPEAT,//
- SCF_LEX_WORD_KEY_BREAK, // break
- SCF_LEX_WORD_KEY_CONTINUE, // continue
+ SCF_LEX_WORD_KEY_BREAK, // break
+ SCF_LEX_WORD_KEY_CONTINUE, // continue
+ SCF_LEX_WORD_KEY_EXIT, // exit
SCF_LEX_WORD_KEY_SWITCH, // switch
SCF_LEX_WORD_KEY_CASE, // case
SCF_LEX_WORD_KEY_DEFAULT, // default
+ SCF_LEX_WORD_KEY_END_CASE, // end case
SCF_LEX_WORD_KEY_RETURN, // return
SCF_LEX_WORD_KEY_CREATE, // create class object
SCF_LEX_WORD_KEY_CONTAINER, // container_of
+ SCF_LEX_WORD_KEY_OF, // of
+ SCF_LEX_WORD_KEY_AT, // at
+ SCF_LEX_WORD_KEY_EN, // enable
+ SCF_LEX_WORD_KEY_ENO, // enable output
SCF_LEX_WORD_KEY_OPERATOR, // operator
SCF_LEX_WORD_KEY_CHAR, // char
SCF_LEX_WORD_KEY_BIT, // bit
- SCF_LEX_WORD_ST_TIME, // time
- SCF_LEX_WORD_ST_TIME_OF_DATE, // time of date
- SCF_LEX_WORD_ST_DATE, // date
- SCF_LEX_WORD_ST_DATE_AND_TIME, // date and time
- SCF_LEX_WORD_ST_STRING, // string
+ SCF_LEX_WORD_KEY_TIME, // time
+ SCF_LEX_WORD_KEY_TIME_OF_DATE, // time of date
+ SCF_LEX_WORD_KEY_DATE, // date
+ SCF_LEX_WORD_KEY_DATE_AND_TIME, // date and time
+ SCF_LEX_WORD_KEY_STRING, // string
SCF_LEX_WORD_KEY_INT, // int
SCF_LEX_WORD_KEY_FLOAT, // float
SCF_LEX_WORD_KEY_UNION, // union
SCF_LEX_WORD_KEY_STRUCT, // struct
+ SCF_LEX_WORD_KEY_END_STRUCT,// end struct
SCF_LEX_WORD_KEY_ARRAY, // array
- SCF_LEX_WORD_KEY_OF, // of
+
+ SCF_LEX_WORD_KEY_TASK, // task
+
+ SCF_LEX_WORD_KEY_TON, // ton
+ SCF_LEX_WORD_KEY_F_TRIG, // f trig
+
+ SCF_LEX_WORD_KEY_CONFIG, // config
+ SCF_LEX_WORD_KEY_END_CONFIG, // end config
+
+ SCF_LEX_WORD_KEY_RESOURCE, // config
+ SCF_LEX_WORD_KEY_END_RESOURCE, // end config
+
+ SCF_LEX_WORD_KEY_PROGRAM, // program
+ SCF_LEX_WORD_KEY_END_PROGRAM,
+
+ SCF_LEX_WORD_KEY_FUNCTION, // function
+ SCF_LEX_WORD_KEY_END_FUNCTION,
+
+ SCF_LEX_WORD_KEY_FUNCTION_BLOCK, // function block
+ SCF_LEX_WORD_KEY_END_FUNCTION_BLOCK,
+
+ SCF_LEX_WORD_KEY_VAR, // var
+ SCF_LEX_WORD_KEY_VAR_INPUT, // var input
+ SCF_LEX_WORD_KEY_VAR_OUTPUT, // var output
+ SCF_LEX_WORD_KEY_VAR_IN_OUT, // var in out
+ SCF_LEX_WORD_KEY_VAR_GLOBAL, // var global
+ SCF_LEX_WORD_KEY_VAR_EXTERNAL, // var external
+ SCF_LEX_WORD_KEY_VAR_TEMP, // var temp
+ SCF_LEX_WORD_KEY_VAR_CONSTANT, // var const
+ SCF_LEX_WORD_KEY_END_VAR,
// const literal value
SCF_LEX_WORD_CONST_CHAR,
return NULL;
}
+scf_node_t* scf_node_clone(scf_node_t* node)
+{
+ scf_node_t* node2 = calloc(1, sizeof(scf_node_t));
+ if (!node2)
+ return NULL;
+
+ if (scf_type_is_var(node->type)) {
+
+ node2->var = scf_variable_ref(node->var);
+ if (!node2->var)
+ goto _failed;
+
+ } else if (SCF_LABEL == node->type) {
+ node2->label = node->label;
+
+ } else {
+ if (node->w) {
+ node2->w = scf_lex_word_clone(node->w);
+ if (!node2->w)
+ goto _failed;
+
+ } else
+ node2->w = NULL;
+ }
+
+ if (node->debug_w) {
+ node2->debug_w = scf_lex_word_clone(node->debug_w);
+
+ if (!node2->debug_w)
+ goto _failed;
+ }
+
+ node2->type = node->type;
+
+ node2->root_flag = node->root_flag;
+ node2->file_flag = node->file_flag;
+ node2->class_flag = node->class_flag;
+ node2->union_flag = node->union_flag;
+ node2->define_flag = node->define_flag;
+ node2->const_flag = node->const_flag;
+ node2->split_flag = node->split_flag;
+ node2->semi_flag = node->semi_flag;
+
+ scf_logd("node: %p, node->type: %d\n", node, node->type);
+ return node;
+
+_failed:
+ scf_node_free(node);
+ return NULL;
+}
+
scf_node_t* scf_node_alloc_label(scf_label_t* l)
{
scf_node_t* node = calloc(1, sizeof(scf_node_t));
scf_node_t* scf_node_alloc(scf_lex_word_t* w, int type, scf_variable_t* var);
scf_node_t* scf_node_alloc_label(scf_label_t* l);
+scf_node_t* scf_node_clone(scf_node_t* node);
+
int scf_node_add_child(scf_node_t* parent, scf_node_t* child);
void scf_node_free(scf_node_t* node);
{SCF_OP_IF, "if", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
{SCF_OP_WHILE, "while", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
+ {SCF_OP_REPEAT, "repeat", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
{SCF_OP_FOR, "for", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT},
};
return 0;
}
+static int _scf_op_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ assert(2 == nb_nodes);
+
+ scf_handler_data_t* d = data;
+ scf_expr_t* e = nodes[1];
+
+ assert(SCF_OP_EXPR == e->type);
+
+ scf_list_t* start_prev = scf_list_tail(d->_3ac_list_head);
+
+ int jmp_op = _scf_op_cond(ast, e, d);
+ if (jmp_op < 0) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ scf_list_t* l;
+ scf_3ac_code_t* c;
+ scf_3ac_code_t* jmp_end = scf_branch_ops_code(jmp_op, NULL, NULL);
+
+ scf_list_add_tail(d->_3ac_list_head, &jmp_end->list);
+
+ scf_branch_ops_t* local_branch_ops = scf_branch_ops_alloc();
+ scf_branch_ops_t* up_branch_ops = d->branch_ops;
+ d->branch_ops = local_branch_ops;
+
+ if (_scf_op_node(ast, nodes[0], d) < 0) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ if (_scf_op_end_loop(start_prev, NULL, jmp_end, up_branch_ops, d) < 0) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ d->branch_ops = up_branch_ops;
+ scf_branch_ops_free(local_branch_ops);
+ local_branch_ops = NULL;
+
+ // delete 'cond check' at 'start of loop'
+ scf_vector_del(d->branch_ops->_breaks, jmp_end);
+
+ for (l = scf_list_next(start_prev); l != &jmp_end->list; ) {
+ c = scf_list_data(l, scf_3ac_code_t, list);
+ l = scf_list_next(l);
+
+ scf_list_del(&c->list);
+ scf_3ac_code_free(c);
+ c = NULL;
+ }
+
+ scf_list_del(&jmp_end->list);
+ scf_3ac_code_free(jmp_end);
+ jmp_end = NULL;
+
+ return 0;
+}
+
static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(2 == nb_nodes || 1 == nb_nodes);
scf_expr_t* e = nodes[0];
assert(SCF_OP_EXPR == e->type);
- scf_block_t* b = (scf_block_t*)(e->parent);
-
// we don't know the real start of the while loop here,
// we only know it's the next of 'start_prev'
scf_list_t* start_prev = scf_list_tail(d->_3ac_list_head);
{{NULL, NULL}, SCF_OP_IF, -1, -1, -1, _scf_op_if},
{{NULL, NULL}, SCF_OP_WHILE, -1, -1, -1, _scf_op_while},
+ {{NULL, NULL}, SCF_OP_REPEAT, -1, -1, -1, _scf_op_repeat},
{{NULL, NULL}, SCF_OP_FOR, -1, -1, -1, _scf_op_for},
};
else
t->w = NULL;
- t->size = size;
+ t->size = size;
return t;
}
uint32_t arg_flag :1;
uint32_t auto_gc_flag:1;
+
+ uint32_t input_flag :1;
+ uint32_t output_flag :1;
};
struct scf_index_s
{"for", SCF_LEX_WORD_KEY_FOR},
{"while", SCF_LEX_WORD_KEY_WHILE},
+ {"do", SCF_LEX_WORD_KEY_DO},
{"break", SCF_LEX_WORD_KEY_BREAK},
{"continue", SCF_LEX_WORD_KEY_CONTINUE},
CFILES += ../lex/scf_lex_util.c
CFILES += scf_parse_util.c
-#CFILES += scf_parse.c
-CFILES += scf_parse2.c
+CFILES += scf_parse.c
CFILES += main.c
CFILES += scf_operator_handler_semantic.c
CFILES += scf_operator_handler_expr.c
CFILES += scf_dfa_if.c
CFILES += scf_dfa_while.c
+CFILES += scf_dfa_repeat.c
CFILES += scf_dfa_for.c
CFILES += scf_dfa_break.c
continue;
}
- scf_logi("pre hook: %s\n", hook->node->name);
+ scf_logi("\033[32mpre hook: %s\033[0m\n", hook->node->name);
// delete all hooks before it, and itself.
scf_dfa_clear_hooks(&(dfa->hooks[SCF_DFA_HOOK_PRE]), hook->next);
return words->size > 0 ? SCF_DFA_CONTINUE : SCF_DFA_NEXT_WORD;
}
+static inline int scf_dfa_action_next(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ return SCF_DFA_NEXT_WORD;
+}
+
#define SCF_DFA_MODULE_NODE(dfa, module, node, is, action) \
{ \
char str[256]; \
SCF_DFA_GET_MODULE_NODE(dfa, if, _if, _if);
SCF_DFA_GET_MODULE_NODE(dfa, while, _while, _while);
+ SCF_DFA_GET_MODULE_NODE(dfa, repeat, _do, _do);
SCF_DFA_GET_MODULE_NODE(dfa, for, _for, _for);
SCF_DFA_GET_MODULE_NODE(dfa, break, _break, _break);
scf_dfa_node_add_child(entry, _if);
scf_dfa_node_add_child(entry, _while);
+ scf_dfa_node_add_child(entry, _do);
scf_dfa_node_add_child(entry, _for);
scf_dfa_node_add_child(entry, _break);
#include"scf_dfa.h"
#include"scf_parse.h"
+extern scf_dfa_module_t dfa_module_include;
+
+extern scf_dfa_module_t dfa_module_identity;
+
+extern scf_dfa_module_t dfa_module_expr;
+extern scf_dfa_module_t dfa_module_create;
+extern scf_dfa_module_t dfa_module_call;
+extern scf_dfa_module_t dfa_module_sizeof;
+extern scf_dfa_module_t dfa_module_container;
+extern scf_dfa_module_t dfa_module_init_data;
+extern scf_dfa_module_t dfa_module_va_arg;
+
+extern scf_dfa_module_t dfa_module_union;
+extern scf_dfa_module_t dfa_module_class;
+
+extern scf_dfa_module_t dfa_module_type;
+
+extern scf_dfa_module_t dfa_module_var;
+
+extern scf_dfa_module_t dfa_module_function;
+extern scf_dfa_module_t dfa_module_operator;
+
+extern scf_dfa_module_t dfa_module_if;
+extern scf_dfa_module_t dfa_module_while;
+extern scf_dfa_module_t dfa_module_repeat;
+extern scf_dfa_module_t dfa_module_for;
+
+#if 1
+extern scf_dfa_module_t dfa_module_break;
+extern scf_dfa_module_t dfa_module_continue;
+extern scf_dfa_module_t dfa_module_return;
+extern scf_dfa_module_t dfa_module_goto;
+extern scf_dfa_module_t dfa_module_label;
+extern scf_dfa_module_t dfa_module_error;
+extern scf_dfa_module_t dfa_module_async;
+#endif
+extern scf_dfa_module_t dfa_module_block;
+
+scf_dfa_module_t* dfa_modules[] =
+{
+ &dfa_module_include,
+
+ &dfa_module_identity,
+
+ &dfa_module_expr,
+ &dfa_module_create,
+ &dfa_module_call,
+ &dfa_module_sizeof,
+ &dfa_module_container,
+ &dfa_module_init_data,
+ &dfa_module_va_arg,
+
+ &dfa_module_union,
+ &dfa_module_class,
+
+ &dfa_module_type,
+
+ &dfa_module_var,
+
+ &dfa_module_function,
+ &dfa_module_operator,
+
+ &dfa_module_if,
+ &dfa_module_while,
+ &dfa_module_repeat,
+ &dfa_module_for,
+
+#if 1
+ &dfa_module_break,
+ &dfa_module_continue,
+ &dfa_module_goto,
+ &dfa_module_return,
+ &dfa_module_label,
+ &dfa_module_error,
+ &dfa_module_async,
+#endif
+ &dfa_module_block,
+};
+
+int scf_parse_dfa_init(scf_parse_t* parse)
+{
+ if (scf_dfa_open(&parse->dfa, "parse", parse) < 0) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ int nb_modules = sizeof(dfa_modules) / sizeof(dfa_modules[0]);
+
+ parse->dfa_data = calloc(1, sizeof(dfa_parse_data_t));
+ if (!parse->dfa_data) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ parse->dfa_data->module_datas = calloc(nb_modules, sizeof(void*));
+ if (!parse->dfa_data->module_datas) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ parse->dfa_data->current_identities = scf_stack_alloc();
+ if (!parse->dfa_data->current_identities) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ int i;
+ for (i = 0; i < nb_modules; i++) {
+
+ scf_dfa_module_t* m = dfa_modules[i];
+
+ if (!m)
+ continue;
+
+ m->index = i;
+
+ if (!m->init_module)
+ continue;
+
+ if (m->init_module(parse->dfa) < 0) {
+ scf_loge("init module: %s\n", m->name);
+ return -1;
+ }
+ }
+
+ for (i = 0; i < nb_modules; i++) {
+
+ scf_dfa_module_t* m = dfa_modules[i];
+
+ if (!m || !m->init_syntax)
+ continue;
+
+ if (m->init_syntax(parse->dfa) < 0) {
+ scf_loge("init syntax: %s\n", m->name);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static void* dfa_pop_word(scf_dfa_t* dfa)
{
scf_parse_t* parse = dfa->priv;
--- /dev/null
+#include"scf_dfa.h"
+#include"scf_dfa_util.h"
+#include"scf_parse.h"
+#include"scf_stack.h"
+
+extern scf_dfa_module_t dfa_module_repeat;
+
+typedef struct {
+ int nb_lps;
+ int nb_rps;
+
+ scf_block_t* parent_block;
+ scf_node_t* parent_node;
+
+ scf_node_t* repeat;
+
+ scf_dfa_hook_t* hook_end;
+
+} dfa_repeat_data_t;
+
+
+static int _repeat_action_do(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ scf_parse_t* parse = dfa->priv;
+ dfa_parse_data_t* d = data;
+ scf_lex_word_t* w = words->data[words->size - 1];
+ scf_stack_t* s = d->module_datas[dfa_module_repeat.index];
+ scf_block_t* b = NULL;
+
+ scf_node_t* repeat = scf_node_alloc(w, SCF_OP_REPEAT, NULL);
+ if (!repeat) {
+ scf_loge("node alloc failed\n");
+ return SCF_DFA_ERROR;
+ }
+
+ dfa_repeat_data_t* rd = calloc(1, sizeof(dfa_repeat_data_t));
+ if (!rd) {
+ scf_loge("module data alloc failed\n");
+ return SCF_DFA_ERROR;
+ }
+
+ if (d->current_node)
+ scf_node_add_child(d->current_node, repeat);
+ else
+ scf_node_add_child((scf_node_t*)parse->ast->current_block, repeat);
+
+ rd->repeat = repeat;
+ rd->parent_block = parse->ast->current_block;
+ rd->parent_node = d->current_node;
+ d->current_node = repeat;
+
+ scf_stack_push(s, rd);
+
+ SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat__while"), SCF_DFA_HOOK_END);
+
+ return SCF_DFA_NEXT_WORD;
+}
+
+static int _repeat_action_while(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ scf_lex_word_t* w = dfa->ops->pop_word(dfa);
+
+ if (SCF_LEX_WORD_KEY_WHILE != w->type)
+ return SCF_DFA_ERROR;
+
+ return SCF_DFA_SWITCH_TO;
+}
+
+static int _repeat_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ scf_parse_t* parse = dfa->priv;
+ dfa_parse_data_t* d = data;
+ scf_lex_word_t* w = words->data[words->size - 1];
+ scf_stack_t* s = d->module_datas[dfa_module_repeat.index];
+ dfa_repeat_data_t* rd = scf_stack_top(s);
+
+ assert(!d->expr);
+ d->expr_local_flag = 1;
+
+ SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_rp"), SCF_DFA_HOOK_POST);
+ SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_lp_stat"), SCF_DFA_HOOK_POST);
+
+ return SCF_DFA_NEXT_WORD;
+}
+
+static int _repeat_action_lp_stat(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ dfa_parse_data_t* d = data;
+ scf_stack_t* s = d->module_datas[dfa_module_repeat.index];
+ dfa_repeat_data_t* rd = scf_stack_top(s);
+
+ SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_lp_stat"), SCF_DFA_HOOK_POST);
+
+ rd->nb_lps++;
+
+ return SCF_DFA_NEXT_WORD;
+}
+
+static int _repeat_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ scf_parse_t* parse = dfa->priv;
+ dfa_parse_data_t* d = data;
+ scf_lex_word_t* w = words->data[words->size - 1];
+ scf_stack_t* s = d->module_datas[dfa_module_repeat.index];
+ dfa_repeat_data_t* rd = scf_stack_top(s);
+
+ if (!d->expr) {
+ scf_loge("\n");
+ return SCF_DFA_ERROR;
+ }
+
+ rd->nb_rps++;
+
+ if (rd->nb_rps == rd->nb_lps) {
+
+ assert(1 == rd->repeat->nb_nodes);
+
+ scf_node_add_child(rd->repeat, d->expr);
+ d->expr = NULL;
+
+ d->expr_local_flag = 0;
+
+ return SCF_DFA_SWITCH_TO;
+ }
+
+ SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_rp"), SCF_DFA_HOOK_POST);
+ SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_lp_stat"), SCF_DFA_HOOK_POST);
+
+ return SCF_DFA_NEXT_WORD;
+}
+
+static int _repeat_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ scf_parse_t* parse = dfa->priv;
+ dfa_parse_data_t* d = data;
+ scf_stack_t* s = d->module_datas[dfa_module_repeat.index];
+ dfa_repeat_data_t* rd = scf_stack_pop(s);
+
+ assert(parse->ast->current_block == rd->parent_block);
+
+ d->current_node = rd->parent_node;
+
+ scf_logi("\033[31m repeat: %d, rd: %p, s->size: %d\033[0m\n", rd->repeat->w->line, rd, s->size);
+
+ free(rd);
+ rd = NULL;
+
+ assert(s->size >= 0);
+
+ return SCF_DFA_OK;
+}
+
+static int _dfa_init_module_repeat(scf_dfa_t* dfa)
+{
+ SCF_DFA_MODULE_NODE(dfa, repeat, semicolon, scf_dfa_is_semicolon, _repeat_action_semicolon);
+
+ SCF_DFA_MODULE_NODE(dfa, repeat, lp, scf_dfa_is_lp, _repeat_action_lp);
+ SCF_DFA_MODULE_NODE(dfa, repeat, rp, scf_dfa_is_rp, _repeat_action_rp);
+ SCF_DFA_MODULE_NODE(dfa, repeat, lp_stat, scf_dfa_is_lp, _repeat_action_lp_stat);
+
+ SCF_DFA_MODULE_NODE(dfa, repeat, _do, scf_dfa_is_do, _repeat_action_do);
+ SCF_DFA_MODULE_NODE(dfa, repeat, _while, scf_dfa_is_while, _repeat_action_while);
+
+ scf_parse_t* parse = dfa->priv;
+ dfa_parse_data_t* d = parse->dfa_data;
+ scf_stack_t* s = d->module_datas[dfa_module_repeat.index];
+
+ assert(!s);
+
+ s = scf_stack_alloc();
+ if (!s) {
+ scf_logi("\n");
+ return SCF_DFA_ERROR;
+ }
+
+ d->module_datas[dfa_module_repeat.index] = s;
+
+ return SCF_DFA_OK;
+}
+
+static int _dfa_fini_module_repeat(scf_dfa_t* dfa)
+{
+ scf_parse_t* parse = dfa->priv;
+ dfa_parse_data_t* d = parse->dfa_data;
+ scf_stack_t* s = d->module_datas[dfa_module_repeat.index];
+
+ if (s) {
+ scf_stack_free(s);
+ s = NULL;
+ d->module_datas[dfa_module_repeat.index] = NULL;
+ }
+
+ return SCF_DFA_OK;
+}
+
+static int _dfa_init_syntax_repeat(scf_dfa_t* dfa)
+{
+ SCF_DFA_GET_MODULE_NODE(dfa, repeat, lp, lp);
+ SCF_DFA_GET_MODULE_NODE(dfa, repeat, rp, rp);
+ SCF_DFA_GET_MODULE_NODE(dfa, repeat, lp_stat, lp_stat);
+ SCF_DFA_GET_MODULE_NODE(dfa, repeat, _do, _do);
+ SCF_DFA_GET_MODULE_NODE(dfa, repeat, _while, _while);
+ SCF_DFA_GET_MODULE_NODE(dfa, repeat, semicolon, semicolon);
+
+ SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr);
+ SCF_DFA_GET_MODULE_NODE(dfa, block, entry, block);
+
+ // repeat start
+ scf_vector_add(dfa->syntaxes, _do);
+
+ scf_dfa_node_add_child(_do, block);
+ scf_dfa_node_add_child(block, _while);
+
+ scf_dfa_node_add_child(_while, lp);
+ scf_dfa_node_add_child(lp, expr);
+ scf_dfa_node_add_child(expr, rp);
+ scf_dfa_node_add_child(rp, semicolon);
+
+ scf_logi("\n");
+ return 0;
+}
+
+scf_dfa_module_t dfa_module_repeat =
+{
+ .name = "repeat",
+
+ .init_module = _dfa_init_module_repeat,
+ .init_syntax = _dfa_init_syntax_repeat,
+
+ .fini_module = _dfa_fini_module_repeat,
+};
+
return SCF_LEX_WORD_RB == w->type;
}
+static inline int scf_dfa_is_range(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_RANGE == w->type;
+}
+
static inline int scf_dfa_is_comma(scf_dfa_t* dfa, void* word)
{
scf_lex_word_t* w = word;
return SCF_LEX_WORD_SEMICOLON == w->type;
}
+static inline int scf_dfa_is_end_struct(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_END_STRUCT == w->type;
+}
+
+static inline int scf_dfa_is_colon(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_COLON == w->type;
+}
+
static inline int scf_dfa_is_star(scf_dfa_t* dfa, void* word)
{
scf_lex_word_t* w = word;
return SCF_LEX_WORD_STAR == w->type;
}
+static inline int scf_dfa_is_assign(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_ASSIGN == w->type;
+}
+
+static inline int scf_dfa_is_array(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_ARRAY == w->type;
+}
+
+static inline int scf_dfa_is_of(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_OF == w->type;
+}
+
static inline int scf_dfa_is_identity(scf_dfa_t* dfa, void* word)
{
scf_lex_word_t* w = word;
return SCF_LEX_WORD_CONST_STRING == w->type;
}
+static inline int scf_dfa_is_if(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_IF == w->type;
+}
+
+static inline int scf_dfa_is_else(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_ELSE == w->type;
+}
+
+static inline int scf_dfa_is_then(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_THEN == w->type;
+}
+
+static inline int scf_dfa_is_elsif(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_ELSIF == w->type;
+}
+
+static inline int scf_dfa_is_end_if(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_END_IF == w->type;
+}
+
+static inline int scf_dfa_is_while(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_WHILE == w->type;
+}
+
+static inline int scf_dfa_is_do(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_DO == w->type;
+}
+
+static inline int scf_dfa_is_to(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_TO == w->type;
+}
+
+static inline int scf_dfa_is_by(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_BY == w->type;
+}
+
+static inline int scf_dfa_is_end_while(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_END_WHILE == w->type;
+}
+
+static inline int scf_dfa_is_for(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_FOR == w->type;
+}
+
+static inline int scf_dfa_is_end_for(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_END_FOR == w->type;
+}
+
+static inline int scf_dfa_is_case(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_CASE == w->type;
+}
+
+static inline int scf_dfa_is_end_case(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_END_CASE == w->type;
+}
+
+static inline int scf_dfa_is_repeat(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_REPEAT == w->type;
+}
+
+static inline int scf_dfa_is_until(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_UNTIL == w->type;
+}
+
+static inline int scf_dfa_is_end_repeat(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_END_REPEAT == w->type;
+}
+
+static inline int scf_dfa_is_function(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_FUNCTION == w->type;
+}
+
+static inline int scf_dfa_is_end_function(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_END_FUNCTION == w->type;
+}
+
+static inline int scf_dfa_is_var(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_VAR == w->type;
+}
+
+static inline int scf_dfa_is_var_input(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_VAR_INPUT == w->type;
+}
+
+static inline int scf_dfa_is_var_output(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_VAR_OUTPUT == w->type;
+}
+
+static inline int scf_dfa_is_var_in_out(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_VAR_IN_OUT == w->type;
+}
+
+static inline int scf_dfa_is_var_temp(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_VAR_TEMP == w->type;
+}
+
+static inline int scf_dfa_is_var_const(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_VAR_CONSTANT == w->type;
+}
+
+static inline int scf_dfa_is_var_global(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_VAR_GLOBAL == w->type;
+}
+
+static inline int scf_dfa_is_var_external(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_VAR_EXTERNAL == w->type;
+}
+
+static inline int scf_dfa_is_end_var(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_KEY_END_VAR == w->type;
+}
+
#endif
return 0;
}
+static int _scf_op_const_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ assert(2 == nb_nodes);
+
+ scf_handler_data_t* d = data;
+ scf_variable_t* r = NULL;
+ scf_expr_t* e = nodes[1];
+
+ assert(SCF_OP_EXPR == e->type);
+
+ if (_scf_op_const_node(ast, nodes[1], d) < 0)
+ return -1;
+
+ if (_scf_expr_calculate_internal(ast, e, &r) < 0)
+ return -1;
+
+ return 0;
+}
+
static int _scf_op_const_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(2 == nb_nodes || 1 == nb_nodes);
{{NULL, NULL}, SCF_LABEL, -1, -1, -1, _scf_op_const_label},
{{NULL, NULL}, SCF_OP_ERROR, -1, -1, -1, _scf_op_const_error},
- {{NULL, NULL}, SCF_OP_IF, -1, -1, -1, _scf_op_const_if},
- {{NULL, NULL}, SCF_OP_WHILE, -1, -1, -1, _scf_op_const_while},
+ {{NULL, NULL}, SCF_OP_IF, -1, -1, -1, _scf_op_const_if},
+ {{NULL, NULL}, SCF_OP_WHILE, -1, -1, -1, _scf_op_const_while},
+ {{NULL, NULL}, SCF_OP_REPEAT, -1, -1, -1, _scf_op_const_repeat},
{{NULL, NULL}, SCF_OP_FOR, -1, -1, -1, _scf_op_const_for},
};
return 0;
}
+static int _scf_op_semantic_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ assert(2 == nb_nodes);
+
+ scf_handler_data_t* d = data;
+ scf_variable_t* r = NULL;
+ scf_node_t* node = nodes[0];
+ scf_expr_t* e = nodes[1];
+ scf_operator_t* op = node->op;
+
+ assert(SCF_OP_EXPR == e->type);
+
+ if (!op) {
+ op = scf_find_base_operator_by_type(node->type);
+ if (!op) {
+ scf_loge("\n");
+ return -1;
+ }
+ }
+
+ scf_variable_t** pret = d->pret;
+
+ scf_operator_handler_t* h = scf_find_semantic_operator_handler(op->type, -1, -1, -1);
+ if (!h) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ d->pret = &node->result;
+ int ret = h->func(ast, node->nodes, node->nb_nodes, d);
+ d->pret = pret;
+
+ if (ret < 0) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ if (_scf_expr_calculate(ast, e, &r) < 0) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ if (!r || !scf_variable_interger(r)) {
+ scf_loge("\n");
+ return -1;
+ }
+
+ scf_variable_free(r);
+ r = NULL;
+
+ return 0;
+}
+
static int _scf_op_semantic_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(2 == nb_nodes || 1 == nb_nodes);
scf_handler_data_t* d = data;
+ scf_variable_t* r = NULL;
+ scf_expr_t* e = nodes[0];
- scf_expr_t* e = nodes[0];
assert(SCF_OP_EXPR == e->type);
- scf_block_t* b = (scf_block_t*)(e->parent);
-
- scf_variable_t* r = NULL;
if (_scf_expr_calculate(ast, e, &r) < 0) {
scf_loge("\n");
return -1;
{{NULL, NULL}, SCF_LABEL, -1, -1, -1, _scf_op_semantic_label},
{{NULL, NULL}, SCF_OP_ERROR, -1, -1, -1, _scf_op_semantic_error},
- {{NULL, NULL}, SCF_OP_IF, -1, -1, -1, _scf_op_semantic_if},
- {{NULL, NULL}, SCF_OP_WHILE, -1, -1, -1, _scf_op_semantic_while},
+ {{NULL, NULL}, SCF_OP_IF, -1, -1, -1, _scf_op_semantic_if},
+ {{NULL, NULL}, SCF_OP_WHILE, -1, -1, -1, _scf_op_semantic_while},
+ {{NULL, NULL}, SCF_OP_REPEAT, -1, -1, -1, _scf_op_semantic_repeat},
{{NULL, NULL}, SCF_OP_FOR, -1, -1, -1, _scf_op_semantic_for},
};
{SCF_FUNCTION_PTR, "funcptr", sizeof(void*)},
};
-extern scf_dfa_module_t dfa_module_include;
-
-extern scf_dfa_module_t dfa_module_identity;
-
-extern scf_dfa_module_t dfa_module_expr;
-extern scf_dfa_module_t dfa_module_create;
-extern scf_dfa_module_t dfa_module_call;
-extern scf_dfa_module_t dfa_module_sizeof;
-extern scf_dfa_module_t dfa_module_container;
-extern scf_dfa_module_t dfa_module_init_data;
-extern scf_dfa_module_t dfa_module_va_arg;
-
-extern scf_dfa_module_t dfa_module_union;
-extern scf_dfa_module_t dfa_module_class;
-
-extern scf_dfa_module_t dfa_module_type;
-
-extern scf_dfa_module_t dfa_module_var;
-
-extern scf_dfa_module_t dfa_module_function;
-extern scf_dfa_module_t dfa_module_operator;
-
-extern scf_dfa_module_t dfa_module_if;
-extern scf_dfa_module_t dfa_module_while;
-extern scf_dfa_module_t dfa_module_for;
-
-#if 1
-extern scf_dfa_module_t dfa_module_break;
-extern scf_dfa_module_t dfa_module_continue;
-extern scf_dfa_module_t dfa_module_return;
-extern scf_dfa_module_t dfa_module_goto;
-extern scf_dfa_module_t dfa_module_label;
-extern scf_dfa_module_t dfa_module_error;
-extern scf_dfa_module_t dfa_module_async;
-#endif
-extern scf_dfa_module_t dfa_module_block;
-
-scf_dfa_module_t* dfa_modules[] =
-{
- &dfa_module_include,
-
- &dfa_module_identity,
-
- &dfa_module_expr,
- &dfa_module_create,
- &dfa_module_call,
- &dfa_module_sizeof,
- &dfa_module_container,
- &dfa_module_init_data,
- &dfa_module_va_arg,
-
- &dfa_module_union,
- &dfa_module_class,
-
- &dfa_module_type,
-
- &dfa_module_var,
-
- &dfa_module_function,
- &dfa_module_operator,
-
- &dfa_module_if,
- &dfa_module_while,
- &dfa_module_for,
-
-#if 1
- &dfa_module_break,
- &dfa_module_continue,
- &dfa_module_goto,
- &dfa_module_return,
- &dfa_module_label,
- &dfa_module_error,
- &dfa_module_async,
-#endif
- &dfa_module_block,
-};
-
-#define SCF_CHECK_LEX_POP_WORD(w) \
- do {\
- int ret = scf_lex_pop_word(parse->lex, &w);\
- if (ret < 0) {\
- printf("%s(),%d, error: \n", __func__, __LINE__);\
- return -1;\
- }\
- } while (0)
-
-
-int scf_parse_dfa_init(scf_parse_t* parse)
-{
- if (scf_dfa_open(&parse->dfa, "parse", parse) < 0) {
- scf_loge("\n");
- return -1;
- }
-
- int nb_modules = sizeof(dfa_modules) / sizeof(dfa_modules[0]);
-
- parse->dfa_data = calloc(1, sizeof(dfa_parse_data_t));
- if (!parse->dfa_data) {
- scf_loge("\n");
- return -1;
- }
-
- parse->dfa_data->module_datas = calloc(nb_modules, sizeof(void*));
- if (!parse->dfa_data->module_datas) {
- scf_loge("\n");
- return -1;
- }
-
- parse->dfa_data->current_identities = scf_stack_alloc();
- if (!parse->dfa_data->current_identities) {
- scf_loge("\n");
- return -1;
- }
-
- int i;
- for (i = 0; i < nb_modules; i++) {
-
- scf_dfa_module_t* m = dfa_modules[i];
-
- if (!m)
- continue;
-
- m->index = i;
-
- if (!m->init_module)
- continue;
-
- if (m->init_module(parse->dfa) < 0) {
- scf_loge("init module: %s\n", m->name);
- return -1;
- }
- }
-
- for (i = 0; i < nb_modules; i++) {
-
- scf_dfa_module_t* m = dfa_modules[i];
-
- if (!m || !m->init_syntax)
- continue;
-
- if (m->init_syntax(parse->dfa) < 0) {
- scf_loge("init syntax: %s\n", m->name);
- return -1;
- }
- }
-
- return 0;
-}
-
int scf_parse_open(scf_parse_t** pparse)
{
assert(pparse);
return 0;
}
-static int _find_function(scf_node_t* node, void* arg, scf_vector_t* vec)
-{
- if (SCF_FUNCTION == node->type) {
-
- scf_function_t* f = (scf_function_t*)node;
-
- return scf_vector_add(vec, f);
- }
-
- return 0;
-}
-
-static int _find_global_var(scf_node_t* node, void* arg, scf_vector_t* vec)
-{
- if (SCF_OP_BLOCK == node->type
- || (node->type >= SCF_STRUCT && node->class_flag)) {
-
- scf_block_t* b = (scf_block_t*)node;
-
- if (!b->scope || !b->scope->vars)
- return 0;
-
- int i;
- for (i = 0; i < b->scope->vars->size; i++) {
-
- scf_variable_t* v = b->scope->vars->data[i];
-
- if (v->global_flag || v->static_flag) {
-
- int ret = scf_vector_add(vec, v);
- if (ret < 0)
- return ret;
- }
- }
- }
-
- return 0;
-}
-
static int _scf_parse_add_rela(scf_vector_t* relas, scf_parse_t* parse, scf_rela_t* r, const char* name, uint16_t st_shndx)
{
scf_elf_rela_t* rela;
scf_lex_word_t* type_w;
scf_type_t* type;
+ int number;
int nb_pointers;
scf_function_t* func_ptr;
int nb_rps;
};
+int scf_parse_dfa_init(scf_parse_t* parse);
+
int scf_parse_open(scf_parse_t** pparse);
int scf_parse_close(scf_parse_t* parse);
int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch);
+int _find_global_var(scf_node_t* node, void* arg, scf_vector_t* vec);
+int _find_function (scf_node_t* node, void* arg, scf_vector_t* vec);
+
#endif
#include"scf_parse.h"
+int _find_function(scf_node_t* node, void* arg, scf_vector_t* vec)
+{
+ if (SCF_FUNCTION == node->type) {
+
+ scf_function_t* f = (scf_function_t*)node;
+
+ return scf_vector_add(vec, f);
+ }
+
+ return 0;
+}
+
+int _find_global_var(scf_node_t* node, void* arg, scf_vector_t* vec)
+{
+ if (SCF_OP_BLOCK == node->type
+ || (node->type >= SCF_STRUCT && node->class_flag)) {
+
+ scf_block_t* b = (scf_block_t*)node;
+
+ if (!b->scope || !b->scope->vars)
+ return 0;
+
+ int i;
+ for (i = 0; i < b->scope->vars->size; i++) {
+
+ scf_variable_t* v = b->scope->vars->data[i];
+
+ if (v->global_flag || v->static_flag) {
+
+ int ret = scf_vector_add(vec, v);
+ if (ret < 0)
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}