From: yu.dongliang <18588496441@163.com> Date: Fri, 14 Nov 2025 14:56:54 +0000 (+0800) Subject: support ++, -- for float & double X-Git-Url: http://baseworks.info/?a=commitdiff_plain;ds=inline;p=scf.git support ++, -- for float & double --- diff --git a/examples/float_cmp.c b/examples/float_cmp.c new file mode 100644 index 0000000..0040933 --- /dev/null +++ b/examples/float_cmp.c @@ -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 index 0000000..c22fe88 --- /dev/null +++ b/examples/float_inc.c @@ -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; +} + diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index 9854380..c98b96f 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -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); diff --git a/parse/scf_dfa_for.c b/parse/scf_dfa_for.c index fa243ed..543c116 100644 --- a/parse/scf_dfa_for.c +++ b/parse/scf_dfa_for.c @@ -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; diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index a80a216..7dbdabe 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -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);