From: yu.dongliang <18588496441@163.com> Date: Sat, 4 Jul 2026 04:15:06 +0000 (+0800) Subject: support trinary operator '?:', mov code for 'macro #if' to dir lex/ X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=8b6d11a5e87ff818704ea0685f36cb597ed03ca1;p=scf.git support trinary operator '?:', mov code for 'macro #if' to dir lex/ --- diff --git a/core/scf_core_types.h b/core/scf_core_types.h index 960b494..a7e225e 100644 --- a/core/scf_core_types.h +++ b/core/scf_core_types.h @@ -96,6 +96,9 @@ enum scf_core_types SCF_OP_DEREFERENCE, // * pointer dereference SCF_OP_ARRAY_INDEX, // [] array index + SCF_OP_Q_MASK, // ? + SCF_OP_COLON, // : + SCF_OP_POINTER, // -> struct member SCF_OP_DOT, // . dot diff --git a/core/scf_dag.c b/core/scf_dag.c index 422c74c..967facf 100644 --- a/core/scf_dag.c +++ b/core/scf_dag.c @@ -335,7 +335,7 @@ scf_dag_node_t* scf_dag_node_alloc(int type, scf_variable_t* var, const scf_node dn->node = (scf_node_t*)node; #if 0 - if (SCF_OP_CALL == type) { + if (SCF_OP_Q_MASK == type) { scf_logw("dn: %#lx, dn->type: %d", 0xffff & (uintptr_t)dn, dn->type); if (var) { printf(", var: %#lx, var->type: %d", 0xffff & (uintptr_t)var, var->type); @@ -570,14 +570,15 @@ int scf_dag_node_same(scf_dag_node_t* dn, const scf_node_t* node) if (SCF_OP_LOGIC_AND == node->type || SCF_OP_LOGIC_OR == node->type + || SCF_OP_Q_MASK == node->type || SCF_OP_INC == node->type || SCF_OP_DEC == node->type || SCF_OP_INC_POST == node->type || SCF_OP_DEC_POST == node->type || SCF_OP_ADDRESS_OF == node->type) { + if (dn->var == _scf_operand_get(node)) return 1; - return 0; } diff --git a/core/scf_expr.c b/core/scf_expr.c index 2cff71c..78764d9 100644 --- a/core/scf_expr.c +++ b/core/scf_expr.c @@ -111,6 +111,24 @@ static int __expr_node_add_node(scf_node_t** pparent, scf_node_t* child) return scf_node_add_child(parent, child); assert(parent->nb_nodes >= 1); + + if (SCF_OP_COLON == child->type && parent->nb_nodes > 1) { + if (SCF_OP_Q_MASK != parent->type) + return -EINVAL; + + scf_node_t* right = parent->nodes[1]; + + if (SCF_OP_Q_MASK == right->type + && right->nb_nodes > 1 + && SCF_OP_COLON == right->nodes[1]->type) { + + parent->nodes[1] = child; + child->parent = parent; + + return scf_node_add_child(child, right); + } + } + return __expr_node_add_node(&(parent->nodes[parent->nb_nodes - 1]), child); } diff --git a/core/scf_operator.c b/core/scf_operator.c index 270bde4..4219d0c 100644 --- a/core/scf_operator.c +++ b/core/scf_operator.c @@ -55,16 +55,19 @@ static scf_operator_t base_operators[] = {"&&", NULL, SCF_OP_LOGIC_AND, 9, 2, SCF_OP_ASSOCIATIVITY_LEFT}, {"||", NULL, SCF_OP_LOGIC_OR, 9, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {"=", "a", SCF_OP_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {"+=", "add_", SCF_OP_ADD_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {"-=", "sub_", SCF_OP_SUB_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {"*=", "mul_", SCF_OP_MUL_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {"/=", "div_", SCF_OP_DIV_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {"%=", "mod_", SCF_OP_MOD_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {"<<=", NULL, SCF_OP_SHL_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"?", NULL, SCF_OP_Q_MASK, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {":", NULL, SCF_OP_COLON, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + + {"=", "a", SCF_OP_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"+=", "add_", SCF_OP_ADD_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"-=", "sub_", SCF_OP_SUB_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"*=", "mul_", SCF_OP_MUL_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"/=", "div_", SCF_OP_DIV_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"%=", "mod_", SCF_OP_MOD_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"<<=", NULL, SCF_OP_SHL_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, {">>=", NULL, SCF_OP_SHR_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {"&=", "and_", SCF_OP_AND_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {"|=", "or_", SCF_OP_OR_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"&=", "and_", SCF_OP_AND_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"|=", "or_", SCF_OP_OR_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, {"{}", NULL, SCF_OP_BLOCK, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, {"return", NULL, SCF_OP_RETURN, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, diff --git a/core/scf_operator_handler_3ac.c b/core/scf_operator_handler_3ac.c index cb81514..ac81c08 100644 --- a/core/scf_operator_handler_3ac.c +++ b/core/scf_operator_handler_3ac.c @@ -688,12 +688,17 @@ static int _scf_op_cond(scf_ast_t* ast, scf_expr_t* e, scf_handler_data_t* d) static int _scf_op_node(scf_ast_t* ast, scf_node_t* node, scf_handler_data_t* d) { + if (0 == node->nb_nodes) { + if (scf_type_is_var(node->type) || node->split_flag) + return 0; + } + scf_operator_t* op = node->op; if (!op) { op = scf_find_base_operator_by_type(node->type); if (!op) { - scf_loge("\n"); + scf_loge("node->type: %d\n", node->type); return -1; } } @@ -711,6 +716,89 @@ static int _scf_op_node(scf_ast_t* ast, scf_node_t* node, scf_handler_data_t* d) return 0; } +static int _scf_op_colon(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + return 0; +} + +static int _scf_op_q_mask(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* v0 = _scf_operand_get(nodes[0]); + scf_expr_t* e = nodes[0]; + scf_node_t* colon = nodes[1]; + scf_node_t* parent = e->parent; + + int ret = scf_node_add_child(parent, colon->nodes[1]); + if (ret < 0) + return ret; + + parent->nodes[1] = colon->nodes[0]; + colon->nodes[0]->parent = parent; + colon->nodes[0] = NULL; + colon->nodes[1] = NULL; + + scf_node_free(colon); + colon = NULL; + + _scf_operand_get(parent)->tmp_flag = 1; + + int jmp_op = _scf_op_cond(ast, e, d); + if (jmp_op < 0) { + scf_loge("\n"); + return -1; + } + + scf_3ac_operand_t* dst; + scf_3ac_code_t* jmp_else = scf_3ac_jmp_code(jmp_op, NULL); + scf_3ac_code_t* jmp_endif = NULL; + scf_list_t* l; + + scf_list_add_tail(d->_3ac_list_head, &jmp_else->list); + + int i; + for (i = 1; i < 3; i++) { + scf_node_t* node = nodes[i]; + + if (_scf_op_node(ast, node, d) < 0) { + scf_loge("\n"); + return -1; + } + + ret = _scf_3ac_code_2(d->_3ac_list_head, SCF_OP_ASSIGN, parent, node); + if (ret < 0) + return ret; + + if (1 == i) { + jmp_endif = scf_3ac_jmp_code(SCF_OP_GOTO, NULL); + scf_list_add_tail(d->_3ac_list_head, &jmp_endif->list); + + l = scf_list_tail(d->_3ac_list_head); + dst = jmp_else->dsts->data[0]; + dst->code = scf_list_data(l, scf_3ac_code_t, list); + } + } + + ret = scf_vector_add(d->branch_ops->_breaks, jmp_else); + if (ret < 0) + return ret; + + if (jmp_endif) { + l = scf_list_tail(d->_3ac_list_head); + dst = jmp_endif->dsts->data[0]; + dst->code = scf_list_data(l, scf_3ac_code_t, list); + + ret = scf_vector_add(d->branch_ops->_breaks, jmp_endif); + if (ret < 0) + return ret; + } + + return 0; +} + static int _scf_op_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { if (2 != nb_nodes && 3 != nb_nodes) { @@ -2453,6 +2541,9 @@ scf_operator_handler_pt __operator_handlers[SCF_N_3AC_OPS] = [SCF_OP_LOGIC_AND] = _scf_op_logic_and, [SCF_OP_LOGIC_OR ] = _scf_op_logic_or, + [SCF_OP_Q_MASK ] = _scf_op_q_mask, + [SCF_OP_COLON ] = _scf_op_colon, + [SCF_OP_ASSIGN ] = _scf_op_assign, [SCF_OP_ADD_ASSIGN] = _scf_op_add_assign, [SCF_OP_SUB_ASSIGN] = _scf_op_sub_assign, diff --git a/examples/trinary_op.c b/examples/trinary_op.c new file mode 100644 index 0000000..3efb8cc --- /dev/null +++ b/examples/trinary_op.c @@ -0,0 +1,9 @@ +int printf(const char* fmt, ...); + +int main(int argc, char* argv[]) +{ + int i = argc > 1 ? 1 : 0; + + printf("argv[%d]: %s\n", i, argv[i]); + return 0; +} diff --git a/lex/scf_lex.c b/lex/scf_lex.c index 068b6c6..998adfb 100644 --- a/lex/scf_lex.c +++ b/lex/scf_lex.c @@ -991,16 +991,21 @@ int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) switch (w1->type) { case SCF_LEX_WORD_KEY_INCLUDE: - case SCF_LEX_WORD_KEY_IF: - case SCF_LEX_WORD_KEY_ELIF: - case SCF_LEX_WORD_KEY_ELSE: case SCF_LEX_WORD_KEY_ENDIF: - scf_lex_push_word(lex, w1); *pword = w; return 0; break; + case SCF_LEX_WORD_KEY_IF: + case SCF_LEX_WORD_KEY_ELIF: + ret = __parse_macro_if(lex); + break; + + case SCF_LEX_WORD_KEY_ELSE: + ret = __parse_macro_else(lex); + break; + case SCF_LEX_WORD_KEY_IFNDEF: ret = __parse_macro_ifdef(lex, 0); break; diff --git a/lex/scf_lex.h b/lex/scf_lex.h index 1e8a672..a5c15f9 100644 --- a/lex/scf_lex.h +++ b/lex/scf_lex.h @@ -74,6 +74,8 @@ int __macro_drop_to_LF(scf_lex_t* lex); int __parse_macro_define(scf_lex_t* lex, int def_flag); int __parse_macro_ifdef (scf_lex_t* lex, int def_flag); +int __parse_macro_if (scf_lex_t* lex); +int __parse_macro_else (scf_lex_t* lex); int _lex_number_base_16(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s); int _lex_number_base_10(scf_lex_t* lex, scf_lex_word_t** pword, scf_string_t* s); diff --git a/lex/scf_macro.c b/lex/scf_macro.c index dff36f5..ee3b80e 100644 --- a/lex/scf_macro.c +++ b/lex/scf_macro.c @@ -333,38 +333,14 @@ int __parse_macro_define(scf_lex_t* lex, int def_flag) return 0; } -int __parse_macro_ifdef(scf_lex_t* lex, int def_flag) +static int __do_macro_if(scf_lex_t* lex, int flag) { - scf_lex_word_t** pp; - scf_lex_word_t* w = NULL; - scf_macro_t* m; - - int ret = __lex_pop_word(lex, &w); - if (ret < 0) - return ret; - - if (!scf_lex_is_identity(w)) { - scf_loge("macro '%s' should be an identity, file: %s, line: %d\n", w->text->data, w->file->data, w->line); - scf_lex_word_free(w); - return -EINVAL; - } - - ret = __macro_drop_to_LF(lex); - if (ret < 0) - return ret; - - int found = 0; - if (lex->macros && __find_macro(lex, w)) - found = 1; - - scf_logw("macro '%s', found: %d, def_flag: %d, file: %s, line: %d\n", - w->text->data, found, def_flag, w->file->data, w->line); - scf_lex_word_t* h = NULL; scf_lex_word_t* w1 = NULL; scf_lex_word_t* w2 = NULL; + int ret; - if (found != def_flag) { + if (!flag) { ret = __macro_drop_to(lex, &w1, &w2); if (ret < 0) return ret; @@ -426,6 +402,53 @@ int __parse_macro_ifdef(scf_lex_t* lex, int def_flag) return 0; } +int __parse_macro_if(scf_lex_t* lex) +{ + int ret = __macro_if_expr(lex); + if (ret < 0) + return ret; + + return __do_macro_if(lex, ret); +} + +int __parse_macro_else(scf_lex_t* lex) +{ + int ret = __macro_drop_to_LF(lex); + if (ret < 0) + return ret; + + return __do_macro_if(lex, 1); +} + +int __parse_macro_ifdef(scf_lex_t* lex, int def_flag) +{ + scf_lex_word_t* w = NULL; + scf_macro_t* m; + + int ret = __lex_pop_word(lex, &w); + if (ret < 0) + return ret; + + if (!scf_lex_is_identity(w)) { + scf_loge("macro '%s' should be an identity, file: %s, line: %d\n", w->text->data, w->file->data, w->line); + scf_lex_word_free(w); + return -EINVAL; + } + + ret = __macro_drop_to_LF(lex); + if (ret < 0) + return ret; + + int found = 0; + if (lex->macros && __find_macro(lex, w)) + found = 1; + + scf_logw("macro '%s', found: %d, def_flag: %d, file: %s, line: %d\n", + w->text->data, found, def_flag, w->file->data, w->line); + + return __do_macro_if(lex, found == def_flag); +} + static int __fill_macro_argv(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use, scf_vector_t* argv) { scf_lex_word_t** pp; diff --git a/lex/scf_macro_expr.c b/lex/scf_macro_expr.c index cb1e217..a1a3aa1 100644 --- a/lex/scf_macro_expr.c +++ b/lex/scf_macro_expr.c @@ -522,7 +522,7 @@ int __macro_if_expr(scf_lex_t* lex) goto error; if (SCF_LEX_WORD_LF == w->type) { - scf_lex_push_word(lex, w); + scf_lex_word_free(w); w = NULL; break; } diff --git a/parse/Makefile b/parse/Makefile index 5374945..01bfcca 100644 --- a/parse/Makefile +++ b/parse/Makefile @@ -131,7 +131,6 @@ CFILES += ../core/scf_calculate.c CFILES += scf_dfa.c CFILES += scf_dfa_parse.c -CFILES += scf_dfa_macro.c CFILES += scf_dfa_include.c CFILES += scf_dfa_call.c diff --git a/parse/scf_dfa_block.c b/parse/scf_dfa_block.c index 2afd08a..8291263 100644 --- a/parse/scf_dfa_block.c +++ b/parse/scf_dfa_block.c @@ -142,8 +142,6 @@ static int _dfa_init_module_block(scf_dfa_t* dfa) SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr); SCF_DFA_GET_MODULE_NODE(dfa, type, entry, type); - SCF_DFA_GET_MODULE_NODE(dfa, macro, hash, macro); - SCF_DFA_GET_MODULE_NODE(dfa, if, _if, _if); SCF_DFA_GET_MODULE_NODE(dfa, while, _while, _while); SCF_DFA_GET_MODULE_NODE(dfa, do, _do, _do); @@ -172,8 +170,6 @@ static int _dfa_init_module_block(scf_dfa_t* dfa) scf_dfa_node_add_child(entry, expr); scf_dfa_node_add_child(entry, type); - scf_dfa_node_add_child(entry, macro); - scf_dfa_node_add_child(entry, _if); scf_dfa_node_add_child(entry, _while); scf_dfa_node_add_child(entry, _do); @@ -223,15 +219,16 @@ static int _dfa_fini_module_block(scf_dfa_t* dfa) static int _dfa_init_syntax_block(scf_dfa_t* dfa) { - SCF_DFA_GET_MODULE_NODE(dfa, block, entry, entry); - SCF_DFA_GET_MODULE_NODE(dfa, block, end, end); + SCF_DFA_GET_MODULE_NODE(dfa, block, entry, entry); + SCF_DFA_GET_MODULE_NODE(dfa, block, end, end); + SCF_DFA_GET_MODULE_NODE(dfa, expr, number, number); scf_dfa_node_add_child(entry, end); scf_dfa_node_add_child(end, entry); int i; - for (i = 0; i < entry->childs->size; i++) { - scf_dfa_node_t* n = entry->childs->data[i]; + for (i = 0; i < number->childs->size; i++) { + scf_dfa_node_t* n = number->childs->data[i]; scf_logd("n->name: %s\n", n->name); } diff --git a/parse/scf_dfa_expr.c b/parse/scf_dfa_expr.c index 8b7c8af..78f6d38 100644 --- a/parse/scf_dfa_expr.c +++ b/parse/scf_dfa_expr.c @@ -317,24 +317,26 @@ static int _expr_action_binary_op(scf_dfa_t* dfa, scf_vector_t* words, void* dat dfa_identity_t* id = scf_stack_top(d->current_identities); scf_variable_t* v; - if (SCF_LEX_WORD_STAR == w->type) { + if (id && id->identity) { + + switch (w->type) { + case SCF_LEX_WORD_STAR: + case SCF_LEX_WORD_COLON: - if (id && id->identity) { + v = scf_block_find_variable(parse->ast->current_block, id->identity->text->data); + if (!v) { + scf_logw("'%s' not var\n", id->identity->text->data); - v = scf_block_find_variable(parse->ast->current_block, id->identity->text->data); - if (!v) { - scf_logw("'%s' not var\n", id->identity->text->data); + if (d->expr) { + scf_expr_free(d->expr); + d->expr = NULL; + } - if (d->expr) { - scf_expr_free(d->expr); - d->expr = NULL; + return SCF_DFA_NEXT_SYNTAX; } - return SCF_DFA_NEXT_SYNTAX; - } - } - } + break; + }; - if (id && id->identity) { if (_expr_add_var(parse, d) < 0) return SCF_DFA_ERROR; } diff --git a/parse/scf_dfa_include.c b/parse/scf_dfa_include.c index d16dad9..5acebc7 100644 --- a/parse/scf_dfa_include.c +++ b/parse/scf_dfa_include.c @@ -82,6 +82,7 @@ static int _include_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) static int _dfa_init_module_include(scf_dfa_t* dfa) { + SCF_DFA_MODULE_NODE(dfa, include, hash, scf_dfa_is_hash, scf_dfa_action_next); SCF_DFA_MODULE_NODE(dfa, include, include, scf_dfa_is_include, _include_action_include); SCF_DFA_MODULE_NODE(dfa, include, path, scf_dfa_is_const_string, _include_action_path); SCF_DFA_MODULE_NODE(dfa, include, LF, scf_dfa_is_LF, _include_action_LF); @@ -91,11 +92,12 @@ static int _dfa_init_module_include(scf_dfa_t* dfa) static int _dfa_init_syntax_include(scf_dfa_t* dfa) { + SCF_DFA_GET_MODULE_NODE(dfa, include, hash, hash); SCF_DFA_GET_MODULE_NODE(dfa, include, include, include); SCF_DFA_GET_MODULE_NODE(dfa, include, path, path); SCF_DFA_GET_MODULE_NODE(dfa, include, LF, LF); - SCF_DFA_GET_MODULE_NODE(dfa, macro, hash, hash); + scf_vector_add(dfa->syntaxes, hash); scf_dfa_node_add_child(hash, include); scf_dfa_node_add_child(include, path); diff --git a/parse/scf_dfa_macro.c b/parse/scf_dfa_macro.c deleted file mode 100644 index 61e5cd2..0000000 --- a/parse/scf_dfa_macro.c +++ /dev/null @@ -1,133 +0,0 @@ -#include"scf_dfa.h" -#include"scf_dfa_util.h" -#include"scf_parse.h" - -extern scf_dfa_module_t dfa_module_macro; - - -static int __macro_do_if_else(scf_lex_t* lex, scf_lex_word_t* w, int flag) -{ - scf_lex_word_t* h = NULL; - scf_lex_word_t* w1 = NULL; - scf_lex_word_t* w2 = NULL; - - int ret = __macro_drop_to_LF(lex); - if (ret < 0) { - scf_loge("'#endif' NOT found for '#%s' in file: %s, line: %d\n", w->text->data, w->file->data, w->line); - return ret; - } - - if (!flag) { - ret = __macro_drop_to(lex, &w1, &w2); - if (ret < 0) - return ret; - - if (SCF_LEX_WORD_KEY_ENDIF == w2->type) { - scf_lex_word_free(w2); - scf_lex_word_free(w1); - - return __macro_drop_to_LF(lex); - } - - scf_lex_push_word(lex, w2); - scf_lex_push_word(lex, w1); - return SCF_DFA_OK; - } - - ret = __macro_pop_to(lex, &h, &w1, &w2); - if (ret < 0) { - scf_slist_clear(h, scf_lex_word_t, next, scf_lex_word_free); - return ret; - } - - int type = w2->type; - - scf_lex_word_free(w2); - scf_lex_word_free(w1); - w1 = NULL; - w2 = NULL; - - while (SCF_LEX_WORD_KEY_ENDIF != type) { - - ret = __macro_drop_to(lex, &w1, &w2); - if (ret < 0) { - scf_slist_clear(h, scf_lex_word_t, next, scf_lex_word_free); - return ret; - } - - type = w2->type; - - scf_lex_word_free(w2); - scf_lex_word_free(w1); - w1 = NULL; - w2 = NULL; - } - - ret = __macro_drop_to_LF(lex); - if (ret < 0) { - scf_slist_clear(h, scf_lex_word_t, next, scf_lex_word_free); - return ret; - } - - while (h) { - w1 = h; - h = h->next; - - scf_lex_push_word(lex, w1); - } - - return SCF_DFA_OK; -} - -static int _macro_action_if(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_parse_t* parse = dfa->priv; - dfa_data_t* d = data; - scf_lex_word_t* w = words->data[words->size - 1]; - - int flag = __macro_if_expr(parse->lex); - if (flag < 0) - return flag; - - return __macro_do_if_else(parse->lex, w, flag); -} - -static int _macro_action_else(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_parse_t* parse = dfa->priv; - scf_lex_word_t* w = words->data[words->size - 1]; - - return __macro_do_if_else(parse->lex, w, 1); -} - -static int _dfa_init_module_macro(scf_dfa_t* dfa) -{ - SCF_DFA_MODULE_NODE(dfa, macro, hash, scf_dfa_is_hash, scf_dfa_action_next); - SCF_DFA_MODULE_NODE(dfa, macro, _if, scf_dfa_is_if, _macro_action_if); - SCF_DFA_MODULE_NODE(dfa, macro, _elif, scf_dfa_is_elif, _macro_action_if); - SCF_DFA_MODULE_NODE(dfa, macro, _else, scf_dfa_is_else, _macro_action_else); - - return SCF_DFA_OK; -} - -static int _dfa_init_syntax_macro(scf_dfa_t* dfa) -{ - SCF_DFA_GET_MODULE_NODE(dfa, macro, hash, hash); - SCF_DFA_GET_MODULE_NODE(dfa, macro, _if, _if); - SCF_DFA_GET_MODULE_NODE(dfa, macro, _elif, _elif); - SCF_DFA_GET_MODULE_NODE(dfa, macro, _else, _else); - - scf_vector_add(dfa->syntaxes, hash); - - scf_dfa_node_add_child(hash, _if); - scf_dfa_node_add_child(hash, _elif); - scf_dfa_node_add_child(hash, _else); - return 0; -} - -scf_dfa_module_t dfa_module_macro = -{ - .name = "macro", - .init_module = _dfa_init_module_macro, - .init_syntax = _dfa_init_syntax_macro, -}; diff --git a/parse/scf_dfa_parse.c b/parse/scf_dfa_parse.c index cd8b1ba..232e93a 100644 --- a/parse/scf_dfa_parse.c +++ b/parse/scf_dfa_parse.c @@ -1,7 +1,6 @@ #include"scf_dfa.h" #include"scf_parse.h" -extern scf_dfa_module_t dfa_module_macro; extern scf_dfa_module_t dfa_module_include; extern scf_dfa_module_t dfa_module_identity; @@ -42,7 +41,6 @@ extern scf_dfa_module_t dfa_module_block; scf_dfa_module_t* dfa_modules[] = { - &dfa_module_macro, &dfa_module_include, &dfa_module_identity, diff --git a/parse/scf_operator_handler_const.c b/parse/scf_operator_handler_const.c index 35ebbae..41ff57b 100644 --- a/parse/scf_operator_handler_const.c +++ b/parse/scf_operator_handler_const.c @@ -882,6 +882,45 @@ static int _scf_op_const_bit_or(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes return _scf_op_const_binary(ast, nodes, nb_nodes, data); } +static int _scf_op_const_q_mask(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(2 == nb_nodes); + + scf_variable_t* v0 = _scf_operand_get(nodes[0]); + scf_node_t* colon = nodes[1]; + scf_node_t* q_mask = colon ->parent; + scf_node_t* parent = q_mask->parent; + + assert(v0); + + if (scf_variable_const_integer(v0)) { + int i; + int j; + + for (i = 0; i < parent->nb_nodes; i++) { + if (q_mask == parent->nodes[i]) + break; + } + assert(i < parent->nb_nodes); + + j = !!scf_zero_extend(v0->data.u64, v0->size); + + colon ->nodes[j]->parent = parent; + parent->nodes[i] = colon->nodes[j]; + colon ->nodes[j] = NULL; + + scf_node_free(q_mask); + q_mask = NULL; + } + + return 0; +} + +static int _scf_op_const_colon(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + return 0; +} + static int _scf_op_const_va_start(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { return 0; @@ -949,6 +988,9 @@ scf_operator_handler_pt const_operator_handlers[SCF_N_OPS] = [SCF_OP_LOGIC_AND ] = _scf_op_const_logic_and, [SCF_OP_LOGIC_OR ] = _scf_op_const_logic_or, + [SCF_OP_Q_MASK ] = _scf_op_const_q_mask, + [SCF_OP_COLON ] = _scf_op_const_colon, + [SCF_OP_ASSIGN ] = _scf_op_const_assign, [SCF_OP_ADD_ASSIGN ] = _scf_op_const_add_assign, [SCF_OP_SUB_ASSIGN ] = _scf_op_const_sub_assign, diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index 7769eb9..dcb7c5a 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -2813,13 +2813,12 @@ static int _scf_op_semantic_binary_interger_assign(scf_ast_t* ast, scf_node_t** { scf_handler_data_t* d = data; - scf_variable_t* v0 = _scf_operand_get(nodes[0]); - scf_variable_t* v1 = _scf_operand_get(nodes[1]); - scf_node_t* parent = nodes[0]->parent; - scf_lex_word_t* w = parent->w; - - scf_type_t* t; - scf_variable_t* r; + scf_node_t* parent = nodes[0]->parent; + scf_variable_t* v0 = _scf_operand_get(nodes[0]); + scf_variable_t* v1 = _scf_operand_get(nodes[1]); + scf_lex_word_t* w = parent->w; + scf_variable_t* r; + scf_type_t* t; assert(v0); assert(v1); @@ -3021,12 +3020,75 @@ static int _scf_op_semantic_logic_or(scf_ast_t* ast, scf_node_t** nodes, int nb_ return _scf_op_semantic_binary_interger(ast, nodes, nb_nodes, data); } +static int _scf_op_semantic_q_mask(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(2 == nb_nodes); + + scf_handler_data_t* d = data; + + scf_type_t* t = NULL; + scf_variable_t* v0 = _scf_operand_get(nodes[0]); + scf_variable_t* v1 = _scf_operand_get(nodes[1]); + + if (!scf_variable_integer(v0)) { + scf_loge("\n"); + return -EINVAL; + } + + int ret = scf_ast_find_type_type(&t, ast, v1->type); + if (ret < 0) + return ret; + + scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(nodes[0]->parent->w, t, v1->const_flag, v1->nb_pointers, v1->func_ptr); + if (!r) + return -ENOMEM; + + *d->pret = r; + return 0; +} + +static int _scf_op_semantic_colon(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(2 == nb_nodes); + + scf_handler_data_t* d = data; + + scf_node_t* parent = nodes[0]->parent; + scf_variable_t* v0 = _scf_operand_get(nodes[0]); + scf_variable_t* v1 = _scf_operand_get(nodes[1]); + scf_lex_word_t* w = parent->w; + scf_type_t* t = NULL; + + if (!scf_variable_same_type(v0, v1)) { + + int ret = _semantic_do_type_cast(ast, nodes, nb_nodes, data); + if (ret < 0) { + scf_loge("semantic do type cast failed, line: %d\n", parent->w->line); + return ret; + } + } + + v0 = _scf_operand_get(nodes[0]); + + int ret = scf_ast_find_type_type(&t, ast, v0->type); + if (ret < 0) + return ret; + + scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, v0->nb_pointers, v0->func_ptr); + if (!r) + return -ENOMEM; + + *d->pret = r; + return 0; +} + static int _scf_op_semantic_va_start(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { if (2 != nb_nodes) { scf_loge("\n"); return -1; } + return 0; } @@ -3121,6 +3183,9 @@ scf_operator_handler_pt semantic_operator_handlers[SCF_N_OPS] = [SCF_OP_LOGIC_AND ] = _scf_op_semantic_logic_and, [SCF_OP_LOGIC_OR ] = _scf_op_semantic_logic_or, + [SCF_OP_Q_MASK ] = _scf_op_semantic_q_mask, + [SCF_OP_COLON ] = _scf_op_semantic_colon, + [SCF_OP_ASSIGN ] = _scf_op_semantic_assign, [SCF_OP_ADD_ASSIGN ] = _scf_op_semantic_add_assign, [SCF_OP_SUB_ASSIGN ] = _scf_op_semantic_sub_assign,