support trinary operator '?:', mov code for 'macro #if' to dir lex/
authoryu.dongliang <18588496441@163.com>
Sat, 4 Jul 2026 04:15:06 +0000 (12:15 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 4 Jul 2026 04:15:06 +0000 (12:15 +0800)
18 files changed:
core/scf_core_types.h
core/scf_dag.c
core/scf_expr.c
core/scf_operator.c
core/scf_operator_handler_3ac.c
examples/trinary_op.c [new file with mode: 0644]
lex/scf_lex.c
lex/scf_lex.h
lex/scf_macro.c
lex/scf_macro_expr.c
parse/Makefile
parse/scf_dfa_block.c
parse/scf_dfa_expr.c
parse/scf_dfa_include.c
parse/scf_dfa_macro.c [deleted file]
parse/scf_dfa_parse.c
parse/scf_operator_handler_const.c
parse/scf_operator_handler_semantic.c

index 960b494f2d071a20466d76175d73ad485f10dc91..a7e225e79ceac59d4f4b123b7cbc11c70331ae66 100644 (file)
@@ -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
 
index 422c74c42dc11725b801bfd20a39b4b42dc5224e..967facf282730b31db119e23c3ecf20738a7abe6 100644 (file)
@@ -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;
        }
 
index 2cff71cc4aa5cfa1fefeb3f2e1cb0a318068f097..78764d9cc3d109682b02af4b2ab2d5e78d242a7d 100644 (file)
@@ -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);
 }
 
index 270bde422236914ce3390988881f9d17abd697f1..4219d0c8fcaa26af12432d851c861b2db4750bc3 100644 (file)
@@ -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},
index cb81514cb7ae58069722a04842f02dac1fd1ebea..ac81c08288fe9b94c38cb7a3f00bf3f5a066ead5 100644 (file)
@@ -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 (file)
index 0000000..3efb8cc
--- /dev/null
@@ -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;
+}
index 068b6c6f7dbfa50ea231b4d559cc8443e5991175..998adfb9a6dd5dcb22dad5e7633baec060a99ebe 100644 (file)
@@ -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;
index 1e8a67255163f9c95ffbd37273c135afe3bd39b6..a5c15f91b2c177908ce5241bafc48828ed5493e7 100644 (file)
@@ -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);
index dff36f52cee6fa6b0602dbc36d3afa56105ad2e0..ee3b80e0ada4271fe730268648dbd6696d702f05 100644 (file)
@@ -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;
index cb1e21781c05a541c60c8a98e19cde7f143fde5f..a1a3aa16d454e7b67efb2832323e029ed039e7d9 100644 (file)
@@ -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;
                }
index 5374945457beed611c430e756633451010e18f47..01bfcca8ab96bcb98054d1de4cb16b74b2b292a4 100644 (file)
@@ -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
index 2afd08a2a670bf37a4c0890e6daa3bbfdf4f9457..8291263c14918d49860788aad24dda774085a549 100644 (file)
@@ -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);
        }
index 8b7c8af754c3a123e7fc8472a827df1caaa64552..78f6d3804cab187b3f5dd96b87c2c2b2d229ea21 100644 (file)
@@ -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;
        }
index d16dad94a1fe8999a1a595b715940e38ceb12c08..5acebc701cc6ac37b720b2f427db9942a4eacb33 100644 (file)
@@ -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 (file)
index 61e5cd2..0000000
+++ /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,
-};
index cd8b1bacb78b3489579d9a2682ade306782db41b..232e93aa620891eb6d453c5e716297f37bb67882 100644 (file)
@@ -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,
index 35ebbaeacb52ef7acd1deeacefe7980af6dd0507..41ff57beacbcd486e780cb2fd3f92b622a5783ef 100644 (file)
@@ -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,
index 7769eb9e394caf18180cdcd6db62a169ceb5c184..dcb7c5a45e71db7cac2219fec4a913966da89200 100644 (file)
@@ -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,