support ++, -- for float & double
authoryu.dongliang <18588496441@163.com>
Fri, 14 Nov 2025 14:56:54 +0000 (22:56 +0800)
committeryu.dongliang <18588496441@163.com>
Fri, 14 Nov 2025 14:56:54 +0000 (22:56 +0800)
examples/float_cmp.c [new file with mode: 0644]
examples/float_inc.c [new file with mode: 0644]
native/x64/scf_x64_inst.c
parse/scf_dfa_for.c
parse/scf_operator_handler_semantic.c

diff --git a/examples/float_cmp.c b/examples/float_cmp.c
new file mode 100644 (file)
index 0000000..0040933
--- /dev/null
@@ -0,0 +1,12 @@
+int printf(const char* fmt, ...);
+
+int f(double a, double b)
+{
+       return a < b;
+}
+
+int main()
+{
+       printf("%d\n", f(0.0, 1.0));
+       return 0;
+}
diff --git a/examples/float_inc.c b/examples/float_inc.c
new file mode 100644 (file)
index 0000000..c22fe88
--- /dev/null
@@ -0,0 +1,11 @@
+
+int printf(const char* fmt, ...);
+
+int main()
+{
+       double d;
+       for (d = 0.1; d < 10.0; d++)
+               printf("%lg\n", d);
+       return 0;
+}
+
index 985438098bc5046025323f5501642a2cb8c78137..c98b96f2a01abde4599bfb9189f62cb49c827522 100644 (file)
@@ -803,6 +803,59 @@ static int _x64_inst_neg_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        return 0;
 }
 
+static int _x64_inst_inc_float(scf_function_t* f, scf_3ac_code_t* c, int INC)
+{
+       scf_3ac_operand_t*  src = c->srcs->data[0];
+       scf_variable_t*     v   = src->dag_node->var;
+       scf_variable_t*     v1;
+       scf_register_t*     rs  = NULL;
+       scf_x64_OpCode_t*   OpCode;
+       scf_instruction_t*  inst = NULL;
+       scf_rela_t*         rela = NULL;
+
+       v1 = scf_variable_clone(v);
+       if (!v1)
+               return -ENOMEM;
+
+       scf_string_free(v1->w->text);
+       v1->w->text = scf_string_cstr("1.0");
+       if (!v1->w->text) {
+               scf_variable_free(v1);
+               return -ENOMEM;
+       }
+
+       scf_scope_push_var(f->scope, v1);
+
+       v1->const_literal_flag = 1;
+       v1->const_flag  = 1;
+       v1->global_flag = 1;
+       v1->local_flag  = 0;
+       v1->tmp_flag    = 0;
+
+       if (4 == v->size) {
+               if (SCF_X64_INC == INC)
+                       OpCode = x64_find_OpCode(SCF_X64_ADDSS, 4, 4, SCF_X64_E2G);
+               else
+                       OpCode = x64_find_OpCode(SCF_X64_SUBSS, 4, 4, SCF_X64_E2G);
+
+               v1->data.f = 1.0;
+       } else {
+               v1->data.d = 1.0;
+
+               if (SCF_X64_INC == INC)
+                       OpCode = x64_find_OpCode(SCF_X64_ADDSD, 8, 8, SCF_X64_E2G);
+               else
+                       OpCode = x64_find_OpCode(SCF_X64_SUBSD, 8, 8, SCF_X64_E2G);
+       }
+
+       X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
+
+       inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, v1);
+       X64_INST_ADD_CHECK(c->instructions, inst);
+       X64_RELA_ADD_CHECK(f->data_relas, rela, c, v1, NULL);
+       return 0;
+}
+
 static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD)
 {
        if (!c->srcs || c->srcs->size != 1)
@@ -818,11 +871,20 @@ static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD)
        if (0 == src->dag_node->color)
                return -EINVAL;
 
+       if (!c->instructions) {
+               c->instructions = scf_vector_alloc();
+               if (!c->instructions)
+                       return -ENOMEM;
+       }
+
        scf_variable_t*     v    = src->dag_node->var;
        scf_register_t*     rs   = NULL;
        scf_x64_OpCode_t*   OpCode;
        scf_instruction_t*  inst = NULL;
 
+       if (scf_variable_float(v))
+               return _x64_inst_inc_float(f, c, INC);
+
        int imm_size = 1;
        if (v->data_size > 0xff)
                imm_size = 4;
@@ -837,12 +899,6 @@ static int _x64_inst_inc(scf_native_t* ctx, scf_3ac_code_t* c, int INC, int ADD)
                return -EINVAL;
        }
 
-       if (!c->instructions) {
-               c->instructions = scf_vector_alloc();
-               if (!c->instructions)
-                       return -ENOMEM;
-       }
-
        if (v->nb_pointers > 0) {
                if (src->dag_node->color > 0) {
                        X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
index fa243edf038607f558f554edc30267e7a184e556..543c1169499454feb1467c2a656d438a2754baae 100644 (file)
@@ -103,27 +103,36 @@ static int _for_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                return SCF_DFA_ERROR;
        }
 
-       if (0 == fd->nb_semicolons) {
-               if (!fd->init_exprs)
-                       fd->init_exprs = scf_vector_alloc();
-
-               scf_vector_add(fd->init_exprs, d->expr);
-               d->expr = NULL;
-
-       } else if (1 == fd->nb_semicolons) {
-               fd->cond_expr = d->expr;
-               d->expr = NULL;
-
-       } else if (2 == fd->nb_semicolons) {
-               if (!fd->update_exprs)
-                       fd->update_exprs = scf_vector_alloc();
-
-               scf_vector_add(fd->update_exprs, d->expr);
-               d->expr = NULL;
-       } else {
-               scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
-               return SCF_DFA_ERROR;
-       }
+       switch (fd->nb_semicolons) {
+               case 0:
+                       if (d->expr) {
+                               if (!fd->init_exprs)
+                                       fd->init_exprs = scf_vector_alloc();
+
+                               scf_vector_add(fd->init_exprs, d->expr);
+                               d->expr = NULL;
+                       }
+                       break;
+
+               case 1:
+                       fd->cond_expr = d->expr;
+                       d->expr = NULL;
+                       break;
+
+               case 2:
+                       if (d->expr) {
+                               if (!fd->update_exprs)
+                                       fd->update_exprs = scf_vector_alloc();
+
+                               scf_vector_add(fd->update_exprs, d->expr);
+                               d->expr = NULL;
+                       }
+                       break;
+               default:
+                       scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
+                       return SCF_DFA_ERROR;
+                       break;
+       };
 
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_comma"),   SCF_DFA_HOOK_POST);
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_lp_stat"), SCF_DFA_HOOK_POST);
@@ -142,22 +151,25 @@ static int _for_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data
        scf_stack_t*     s     = d->module_datas[dfa_module_for.index];
        dfa_for_data_t*  fd    = scf_stack_top(s);
 
-       if (0 == fd->nb_semicolons) {
-               if (d->expr) {
-                       if (!fd->init_exprs)
-                               fd->init_exprs = scf_vector_alloc();
+       switch (fd->nb_semicolons) {
+               case 0:
+                       if (d->expr) {
+                               if (!fd->init_exprs)
+                                       fd->init_exprs = scf_vector_alloc();
 
-                       scf_vector_add(fd->init_exprs, d->expr);
-                       d->expr = NULL;
-               }
-       } else if (1 == fd->nb_semicolons) {
-               if (d->expr) {
+                               scf_vector_add(fd->init_exprs, d->expr);
+                               d->expr = NULL;
+                       }
+                       break;
+
+               case 1:
                        fd->cond_expr = d->expr;
                        d->expr = NULL;
-               }
-       } else {
-               scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
-               return SCF_DFA_ERROR;
+                       break;
+               default:
+                       scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
+                       return SCF_DFA_ERROR;
+                       break;
        }
 
        fd->nb_semicolons++;
@@ -184,21 +196,17 @@ static int _for_add_expr_vector(dfa_for_data_t* fd, scf_vector_t* vec)
                return SCF_DFA_OK;
        }
 
-       scf_node_t* parent = fd->_for;
-       if (vec->size > 1) {
-
-               scf_block_t* b = scf_block_alloc_cstr("for");
-
-               scf_node_add_child(fd->_for, (scf_node_t*)b);
-               parent = (scf_node_t*)b;
-       }
+       scf_block_t* b = scf_block_alloc_cstr("for");
+       if (!b)
+               return -ENOMEM;
+       scf_node_add_child(fd->_for, (scf_node_t*)b);
 
        int i;
        for (i = 0; i < vec->size; i++) {
 
                scf_expr_t* e = vec->data[i];
 
-               scf_node_add_child(parent, e);
+               scf_node_add_child((scf_node_t*)b, e);
        }
 
        scf_vector_free(vec);
@@ -241,11 +249,13 @@ static int _for_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        }
 
        if (2 == fd->nb_semicolons) {
-               if (!fd->update_exprs)
-                       fd->update_exprs = scf_vector_alloc();
+               if (d->expr) {
+                       if (!fd->update_exprs)
+                               fd->update_exprs = scf_vector_alloc();
 
-               scf_vector_add(fd->update_exprs, d->expr);
-               d->expr = NULL;
+                       scf_vector_add(fd->update_exprs, d->expr);
+                       d->expr = NULL;
+               }
        } else {
                scf_loge("too many ';' in for, file: %s, line: %d\n", w->file->data, w->line);
                return SCF_DFA_ERROR;
index a80a21663be22a0b5832ebfadd960f8befe66f22..7dbdabe700430fae484975203dd45c57dbf8f05b 100644 (file)
@@ -1738,7 +1738,7 @@ static int _scf_op_semantic_inc(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes
                }
        }
 
-       if (scf_variable_integer(v0)) {
+       if (scf_variable_integer(v0) || scf_variable_float(v0)) {
 
                scf_type_t*     t = NULL;
                int ret = scf_ast_find_type_type(&t, ast, v0->type);