1, js: support 'switch-case', master
authoryu.dongliang <18588496441@163.com>
Sat, 13 Dec 2025 08:11:40 +0000 (16:11 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 13 Dec 2025 08:11:42 +0000 (16:11 +0800)
2, scf: mov source code of _semantic_find_proper_function2() to scf_ast_find_proper_function().

examples/js.html
js/core/scf_ast.c
js/core/scf_ast.h
js/core/scf_operator_handler_3ac.c
js/core/scf_scope.c
js/core/scf_scope.h
js/core/scf_type_cast.h
js/doc.c
js/parse/scf_dfa_switch.c
js/parse/scf_operator_handler_semantic.c
js/parse/scf_parse.c

index 234458c1bf9ea6ed342140eecba865da66845972..08e8a76018d51c0b8bd3874b1a90f5eb9274fa14 100644 (file)
@@ -8,14 +8,16 @@
 
 <script>
 
 
 <script>
 
-var obj = {
-       a: 1,
-};
+var a = 0;
 
 
-for (var x in obj) {
-       document.write(x);
-       document.write(obj[x]);
-}
+switch (a) {
+       case 1:
+               document.write(1);
+               break;
+       default:
+               document.write("default");
+               break;
+};
 
 </script>
 
 
 </script>
 
index 0b79c910dc4c9db3d549cff5b31f1297abd02b4b..aa22dff14d60c402ca19b02eda8c4723efe7f002 100644 (file)
@@ -1,4 +1,5 @@
 #include"scf_ast.h"
 #include"scf_ast.h"
+#include"scf_type_cast.h"
 
 int    scf_ast_open(scf_ast_t** past)
 {
 
 int    scf_ast_open(scf_ast_t** past)
 {
@@ -577,3 +578,65 @@ error:
        scf_string_free(s);
        return -1;
 }
        scf_string_free(s);
        return -1;
 }
+
+int scf_ast_find_proper_function(scf_function_t** pf, scf_ast_t* ast, scf_vector_t* fvec, scf_vector_t* argv)
+{
+       scf_function_t* f;
+       scf_variable_t* v0;
+       scf_variable_t* v1;
+
+       int i;
+       int j;
+
+       for (i = 0; i < fvec->size; ) {
+               f  =        fvec->data[i];
+
+               f->score = 0;
+
+               for (j = 0; j < argv->size; j++) {
+                       v0 =     f->argv->data[j];
+                       v1 =        argv->data[j];
+
+                       if (scf_variable_is_struct_pointer(v0))
+                               continue;
+
+                       if (scf_type_cast_check(ast, v0, v1) < 0)
+                               break;
+
+                       int type = scf_find_updated_type(ast, v0, v1);
+                       if (type < 0)
+                               break;
+
+                       if (scf_variable_nb_pointers(v0) == scf_variable_nb_pointers(v1)) {
+                               if (v0->type == v1->type)
+                                       f->score += 10000;
+                               else if (type == v0->type) {
+                                       f->score += 1;
+
+                                       if (type == v1->type)
+                                               f->score += 100;
+                               }
+                       }
+               }
+
+               if (j < argv->size)
+                       assert(0 == scf_vector_del(fvec, f)); // drop invalid function
+               else
+                       i++;
+       }
+
+       if (fvec->size <= 0)
+               return -404;
+
+       int max = INT_MIN;
+       for (i = 0; i < fvec->size; i++) {
+               f  =        fvec->data[i];
+
+               if (max < f->score) {
+                       max = f->score;
+                       *pf = f;
+               }
+       }
+
+       return 0;
+}
index dbd9169bb77ea0ed2fd1dc941c39d7b7d1275472..0cc4cc024c93bff5f59b120f100741830b204aeb 100644 (file)
@@ -82,6 +82,7 @@ static inline scf_scope_t* scf_ast_current_scope(scf_ast_t* ast)
        return ast->current_block->scope;
 }
 
        return ast->current_block->scope;
 }
 
+int scf_ast_find_proper_function (scf_function_t** pf, scf_ast_t* ast, scf_vector_t* fvec, scf_vector_t* argv);
 int scf_ast_find_global_function (scf_function_t** pf, scf_ast_t* ast, char* name);
 int scf_ast_find_global_variable (scf_variable_t** pv, scf_ast_t* ast, char* name);
 int scf_ast_find_global_type     (scf_type_t**     pt, scf_ast_t* ast, char* name);
 int scf_ast_find_global_function (scf_function_t** pf, scf_ast_t* ast, char* name);
 int scf_ast_find_global_variable (scf_variable_t** pv, scf_ast_t* ast, char* name);
 int scf_ast_find_global_type     (scf_type_t**     pt, scf_ast_t* ast, char* name);
@@ -92,8 +93,6 @@ int scf_ast_find_variable (scf_variable_t** pv, scf_ast_t* ast, char* name);
 int scf_ast_find_type     (scf_type_t**     pt, scf_ast_t* ast, char* name);
 int scf_ast_find_type_type(scf_type_t**     pt, scf_ast_t* ast, int   type);
 
 int scf_ast_find_type     (scf_type_t**     pt, scf_ast_t* ast, char* name);
 int scf_ast_find_type_type(scf_type_t**     pt, scf_ast_t* ast, int   type);
 
-int scf_operator_function_call(scf_ast_t* ast, scf_function_t* f, const int argc, const scf_variable_t** argv, scf_variable_t** pret, scf_list_t* _3ac_list_head);
-
 int    scf_ast_open(scf_ast_t** past);
 int scf_ast_close(scf_ast_t* ast);
 
 int    scf_ast_open(scf_ast_t** past);
 int scf_ast_close(scf_ast_t* ast);
 
index 3d31a07f70c08584a4b29dfe689a14f7b0292752..02b34adf2f6eefb99a2adc2e371067fe71166420 100644 (file)
@@ -1211,12 +1211,20 @@ static int _scf_op_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void
 
                                scf_node_t* srcs[2] = {e, e2};
 
 
                                scf_node_t* srcs[2] = {e, e2};
 
-                               if (SCF_OP_CALL != e2->type)
-                                       cmp = scf_3ac_code_NN(SCF_OP_3AC_CMP, NULL, 0, srcs, 2);
-                               else
+                               if (SCF_OP_CALL == e2->type) {
                                        cmp = scf_3ac_code_NN(SCF_OP_3AC_TEQ, NULL, 0, &e2, 1);
 
                                        cmp = scf_3ac_code_NN(SCF_OP_3AC_TEQ, NULL, 0, &e2, 1);
 
-                               jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL, NULL);
+                                       scf_variable_t* v = _scf_operand_get(e2->nodes[0]);
+                                       scf_function_t* f = v->func_ptr;
+
+                                       if (SCF_OP_EQ == f->op_type)
+                                               jnot = scf_3ac_jmp_code(SCF_OP_3AC_JZ, NULL, NULL);
+                                       else
+                                               jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL, NULL);
+                               } else {
+                                       cmp  = scf_3ac_code_NN (SCF_OP_3AC_CMP, NULL, 0, srcs, 2);
+                                       jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL, NULL);
+                               }
 
                                scf_list_add_tail(d->_3ac_list_head, &cmp->list);
                                scf_list_add_tail(d->_3ac_list_head, &jnot->list);
 
                                scf_list_add_tail(d->_3ac_list_head, &cmp->list);
                                scf_list_add_tail(d->_3ac_list_head, &jnot->list);
index 9e7612f612725941d933cf88236878e0204e69d3..424fb0f5b1a0e9e77be8cbb805fdfa3320ccb734 100644 (file)
@@ -181,23 +181,6 @@ scf_function_t*    scf_scope_find_same_function(scf_scope_t* scope, scf_function_t*
        return NULL;
 }
 
        return NULL;
 }
 
-scf_function_t*        scf_scope_find_proper_function(scf_scope_t* scope, const char* name, scf_vector_t* argv)
-{
-       scf_function_t* f;
-       scf_list_t*     l;
-
-       for (l = scf_list_head(&scope->function_list_head); l != scf_list_sentinel(&scope->function_list_head); l = scf_list_next(l)) {
-               f  = scf_list_data(l, scf_function_t, list);
-
-               if (strcmp(f->node.w->text->data, name))
-                       continue;
-
-               if (scf_function_same_argv(f->argv, argv))
-                       return f;
-       }
-       return NULL;
-}
-
 int scf_scope_find_like_functions(scf_vector_t** pfunctions, scf_scope_t* scope, const char* name, scf_vector_t* argv)
 {
        scf_function_t* f;
 int scf_scope_find_like_functions(scf_vector_t** pfunctions, scf_scope_t* scope, const char* name, scf_vector_t* argv)
 {
        scf_function_t* f;
index 119077df82de68e236928e110b06349d256060d0..53ef96ad5a3902223a572ca87c2c6f6d874f0fb6 100644 (file)
@@ -40,8 +40,6 @@ scf_function_t* scf_scope_find_function(scf_scope_t* scope, const char* name);
 
 scf_function_t*        scf_scope_find_same_function(scf_scope_t* scope, scf_function_t* f0);
 
 
 scf_function_t*        scf_scope_find_same_function(scf_scope_t* scope, scf_function_t* f0);
 
-scf_function_t*        scf_scope_find_proper_function(scf_scope_t* scope, const char* name, scf_vector_t* argv);
-
 int             scf_scope_find_overloaded_functions(scf_vector_t** pfunctions, scf_scope_t* scope, const int op_type, scf_vector_t* argv);
 
 int             scf_scope_find_like_functions(scf_vector_t** pfunctions, scf_scope_t* scope, const char* name, scf_vector_t* argv);
 int             scf_scope_find_overloaded_functions(scf_vector_t** pfunctions, scf_scope_t* scope, const int op_type, scf_vector_t* argv);
 
 int             scf_scope_find_like_functions(scf_vector_t** pfunctions, scf_scope_t* scope, const char* name, scf_vector_t* argv);
index 4ea173bc4779eb3fb51389a5e373fb5b664cd3f8..1e8977877134ef20e47171d7dafdb99d528667d1 100644 (file)
@@ -36,4 +36,3 @@ int scf_cast_to_float(scf_ast_t* ast, scf_variable_t** pret, scf_variable_t* src
 int scf_cast_to_double(scf_ast_t* ast, scf_variable_t** pret, scf_variable_t* src);
 
 #endif
 int scf_cast_to_double(scf_ast_t* ast, scf_variable_t** pret, scf_variable_t* src);
 
 #endif
-
index 6de9ccf719aff2dd0d60a8f3bd8f1f5b04b4fc22..ceeda44e1fe16478a6f4e70389b8736ed06a34f8 100644 (file)
--- a/js/doc.c
+++ b/js/doc.c
@@ -412,6 +412,24 @@ struct Object
                return res;
        }
 
                return res;
        }
 
+       bool operator==(Object* this, double d)
+       {
+               printf("this->d: %lg, d: %lg\n", this->d, d);
+               if (JS_Number == this->type)
+                       return this->d == d;
+
+               if (JS_Boolean == this->type)
+                       return this->i64 == d;
+               return 0;
+       }
+
+       bool operator==(Object* this, const char* s)
+       {
+               if (JS_String == this->type)
+                       return !strcmp(this->str, s);
+               return 0;
+       }
+
        bool operator==(Object* this, Object* that)
        {
                if (JS_Number == this->type && JS_Number == that->type)
        bool operator==(Object* this, Object* that)
        {
                if (JS_Number == this->type && JS_Number == that->type)
index 331236ae727e3d755456d5164f7f3eb80108250e..084a883c2faaba17239fb1f2d348e182c9da3249 100644 (file)
@@ -269,6 +269,9 @@ static int _dfa_init_syntax_switch(scf_dfa_t* dfa)
        SCF_DFA_GET_MODULE_NODE(dfa, expr,  entry,     expr);
        SCF_DFA_GET_MODULE_NODE(dfa, block, entry,     block);
 
        SCF_DFA_GET_MODULE_NODE(dfa, expr,  entry,     expr);
        SCF_DFA_GET_MODULE_NODE(dfa, block, entry,     block);
 
+       // switch start
+       scf_vector_add(dfa->syntaxes,  _switch);
+
        scf_dfa_node_add_child(_switch,  lp);
        scf_dfa_node_add_child(lp,       expr);
        scf_dfa_node_add_child(expr,     rp);
        scf_dfa_node_add_child(_switch,  lp);
        scf_dfa_node_add_child(lp,       expr);
        scf_dfa_node_add_child(expr,     rp);
index 22bb5fe2ac838ef80cdd79c710931d0f45913410..f3eacb679501fec7054547cd31008af24c4266a7 100644 (file)
@@ -284,75 +284,15 @@ static int _semantic_add_call(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes,
        return _semantic_add_call_rets(ast, parent, d, f);
 }
 
        return _semantic_add_call_rets(ast, parent, d, f);
 }
 
-static int _semantic_find_proper_function2(scf_ast_t* ast, scf_vector_t* fvec, scf_vector_t* argv, scf_function_t** pf)
-{
-       scf_function_t* f;
-       scf_variable_t* v0;
-       scf_variable_t* v1;
-
-       int i;
-       int j;
-
-       for (i = 0; i < fvec->size; ) {
-               f  =        fvec->data[i];
-
-               f->score = 0;
-
-               for (j = 0; j < argv->size; j++) {
-                       v0 =     f->argv->data[j];
-                       v1 =        argv->data[j];
-
-                       if (scf_variable_is_struct_pointer(v0))
-                               continue;
-
-                       if (scf_type_cast_check(ast, v0, v1) < 0)
-                               break;
-
-                       int type = scf_find_updated_type(ast, v0, v1);
-                       if (type < 0)
-                               break;
-
-                       if (scf_variable_nb_pointers(v0) == scf_variable_nb_pointers(v1)) {
-                               if (type == v0->type) {
-                                       f->score += 1;
-
-                                       if (type == v1->type)
-                                               f->score += 1000;
-                               }
-                       }
-               }
-
-               if (j < argv->size)
-                       assert(0 == scf_vector_del(fvec, f)); // drop invalid function
-               else
-                       i++;
-       }
-
-       if (fvec->size <= 0)
-               return -404;
-
-       int max = INT_MIN;
-       for (i = 0; i < fvec->size; i++) {
-               f  =        fvec->data[i];
-
-               if (max < f->score) {
-                       max = f->score;
-                       *pf = f;
-               }
-       }
-
-       return 0;
-}
-
 static int _semantic_find_proper_function(scf_ast_t* ast, scf_type_t* t, const char* fname, scf_vector_t* argv, scf_function_t** pf)
 {
        scf_vector_t* fvec = NULL;
 
 static int _semantic_find_proper_function(scf_ast_t* ast, scf_type_t* t, const char* fname, scf_vector_t* argv, scf_function_t** pf)
 {
        scf_vector_t* fvec = NULL;
 
-       int ret  = scf_scope_find_like_functions(&fvec, t->scope, fname, argv);
+       int ret = scf_scope_find_like_functions(&fvec, t->scope, fname, argv);
        if (ret < 0)
                return ret;
 
        if (ret < 0)
                return ret;
 
-       ret = _semantic_find_proper_function2(ast, fvec, argv, pf);
+       ret = scf_ast_find_proper_function(pf, ast, fvec, argv);
 
        scf_vector_free(fvec);
        return ret;
 
        scf_vector_free(fvec);
        return ret;
@@ -427,7 +367,7 @@ static int _semantic_do_overloaded(scf_ast_t* ast, scf_node_t** nodes, int nb_no
                return ret;
        }
 
                return ret;
        }
 
-       ret = _semantic_find_proper_function2(ast, fvec, argv, &f);
+       ret = scf_ast_find_proper_function(&f, ast, fvec, argv);
        if (ret < 0)
                scf_loge("\n");
        else
        if (ret < 0)
                scf_loge("\n");
        else
@@ -488,7 +428,7 @@ static int _semantic_do_overloaded_assign(scf_ast_t* ast, scf_node_t** nodes, in
                return ret;
        }
 
                return ret;
        }
 
-       ret = _semantic_find_proper_function2(ast, fvec, argv, &f);
+       ret = scf_ast_find_proper_function(&f, ast, fvec, argv);
        if (ret < 0)
                scf_loge("\n");
        else
        if (ret < 0)
                scf_loge("\n");
        else
@@ -1327,6 +1267,117 @@ static int _scf_op_semantic_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nod
        return 0;
 }
 
        return 0;
 }
 
+static int __switch_for_Object(scf_ast_t* ast, scf_type_t* Object, scf_node_t* parent, scf_node_t* child, scf_expr_t* e, scf_expr_t* e1, scf_handler_data_t* d,
+               scf_variable_t* v,
+               scf_variable_t* v1)
+{
+       scf_function_t* f    = NULL;
+       scf_vector_t*   fvec = NULL;
+       scf_vector_t*   argv;
+       scf_expr_t*     e2;
+       scf_expr_t*     e3;
+       scf_expr_t*     e4;
+
+       argv = scf_vector_alloc();
+       if (!argv)
+               return -ENOMEM;
+
+       int ret = scf_vector_add(argv, v);
+       if (ret < 0) {
+               scf_vector_free(argv);
+               return ret;
+       }
+
+       ret = scf_vector_add(argv, v1);
+       if (ret < 0) {
+               scf_vector_free(argv);
+               return ret;
+       }
+
+       ret = scf_scope_find_overloaded_functions(&fvec, Object->scope, SCF_OP_EQ, argv);
+       if (ret < 0) {
+               scf_loge("\n");
+               return ret;
+       }
+
+       ret = scf_ast_find_proper_function(&f, ast, fvec, argv);
+       if (ret < 0) {
+               scf_loge("can't find overloaded operator '==' for compare Object, file: %s, line: %d\n",
+                               parent->w->file->data, parent->w->line);
+               return -1;
+       }
+
+       scf_vector_free(argv);
+       scf_vector_free(fvec);
+       argv = NULL;
+       fvec = NULL;
+
+       assert(2 == f->argv->size);
+
+       if (!scf_variable_same_type(f->argv->data[1], v1)) {
+               e2 = e1;
+               while (SCF_OP_EXPR == e2->type)
+                       e2 = e2->nodes[0];
+
+               ret = _semantic_add_type_cast(ast, &(e2->parent->nodes[0]), f->argv->data[1], e2);
+               if (ret < 0)
+                       return ret;
+       }
+
+       e2 = scf_expr_clone(e);
+       if (!e1)
+               return -ENOMEM;
+
+       v = NULL;
+       if (_scf_expr_calculate(ast, e2, &v) < 0) {
+               scf_expr_free(e2);
+               return -1;
+       }
+       scf_variable_free(v);
+       v = NULL;
+
+       e3 = scf_expr_alloc();
+       if (!e3) {
+               scf_expr_free(e2);
+               return -ENOMEM;
+       }
+
+       ret = scf_node_add_child(e3, e2);
+       if (ret < 0) {
+               scf_expr_free(e2);
+               scf_expr_free(e3);
+               return ret;
+       }
+       e2 = NULL;
+
+       ret = scf_node_add_child(e3, e1);
+       if (ret < 0) {
+               scf_expr_free(e3);
+               return ret;
+       }
+       child->nodes[0] = NULL;
+
+       e4 = scf_expr_alloc();
+       if (!e4) {
+               scf_expr_free(e3);
+               return -ENOMEM;
+       }
+
+       ret = scf_node_add_child(e4, e3);
+       if (ret < 0) {
+               scf_expr_free(e3);
+               scf_expr_free(e4);
+               return ret;
+       }
+
+       child->nodes[0] = e4;
+       e4->parent      = child;
+
+       d->pret = &e3->result;
+
+       return _semantic_add_call(ast, e3->nodes, e3->nb_nodes, d, f);
+}
+
 static int __switch_for_string(scf_ast_t* ast, scf_node_t* parent, scf_node_t* child, scf_expr_t* e, scf_expr_t* e1, scf_handler_data_t* d)
 {
        scf_function_t* f = NULL;
 static int __switch_for_string(scf_ast_t* ast, scf_node_t* parent, scf_node_t* child, scf_expr_t* e, scf_expr_t* e1, scf_handler_data_t* d)
 {
        scf_function_t* f = NULL;
@@ -1407,6 +1458,7 @@ static int _scf_op_semantic_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_no
        scf_variable_t*     v0     = NULL;
        scf_variable_t*     v1     = NULL;
        scf_block_t*        tmp    = ast->current_block;
        scf_variable_t*     v0     = NULL;
        scf_variable_t*     v1     = NULL;
        scf_block_t*        tmp    = ast->current_block;
+       scf_type_t*         Object = NULL;
        scf_expr_t*         e      = nodes[0];
        scf_node_t*         b      = nodes[1];
        scf_node_t*         parent = nodes[0]->parent;
        scf_expr_t*         e      = nodes[0];
        scf_node_t*         b      = nodes[1];
        scf_node_t*         parent = nodes[0]->parent;
@@ -1416,6 +1468,9 @@ static int _scf_op_semantic_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_no
        assert(SCF_OP_EXPR  == e->type);
        assert(SCF_OP_BLOCK == b->type);
 
        assert(SCF_OP_EXPR  == e->type);
        assert(SCF_OP_BLOCK == b->type);
 
+       if (scf_ast_find_type(&Object, ast, "Object") < 0)
+               return -1;
+
        if (_scf_expr_calculate(ast, e, &v0) < 0)
                return -1;
 
        if (_scf_expr_calculate(ast, e, &v0) < 0)
                return -1;
 
@@ -1452,24 +1507,29 @@ static int _scf_op_semantic_switch(scf_ast_t* ast, scf_node_t** nodes, int nb_no
                                goto error;
                        }
 
                                goto error;
                        }
 
-                       if (!scf_variable_type_like(v0, v1)) {
-
-                               if (scf_type_cast_check(ast, v0, v1) < 0) {
-                                       ret = -1;
-                                       scf_loge("type of switch's expr is NOT same to the case's, file: %s, line: %d\n", child->w->file->data, child->w->line);
-                                       goto error;
-                               }
-
-                               ret = _semantic_add_type_cast(ast, &(e1->nodes[0]), v0, e1->nodes[0]);
+                       if (v0->type == Object->type) {
+                               ret = __switch_for_Object(ast, Object, parent, child, e, e1, d, v0, v1);
                                if (ret < 0)
                                        goto error;
                                if (ret < 0)
                                        goto error;
-                       }
 
 
-                       if (scf_variable_const_string(v1)) {
+                       } else {
+                               if (!scf_variable_type_like(v0, v1)) {
+                                       if (scf_type_cast_check(ast, v0, v1) < 0) {
+                                               ret = -1;
+                                               scf_loge("type of switch's expr is NOT same to the case's, file: %s, line: %d\n", child->w->file->data, child->w->line);
+                                               goto error;
+                                       }
 
 
-                               ret = __switch_for_string(ast, parent, child, e, e1, d);
-                               if (ret < 0)
-                                       goto error;
+                                       ret = _semantic_add_type_cast(ast, &(e1->nodes[0]), v0, e1->nodes[0]);
+                                       if (ret < 0)
+                                               goto error;
+                               }
+
+                               if (scf_variable_const_string(v1)) {
+                                       ret = __switch_for_string(ast, parent, child, e, e1, d);
+                                       if (ret < 0)
+                                               goto error;
+                               }
                        }
 
                        scf_variable_free(v1);
                        }
 
                        scf_variable_free(v1);
index 5d180b8d2d3500e8458b9cc020f713de920cb2af..852afbda05ecb41538ab912b7c81ca522c625b18 100644 (file)
@@ -2334,6 +2334,7 @@ int scf_parse_compile(scf_parse_t* parse, const char* arch)
 
                        switch (e->type) {
                                case SCF_OP_EXPR:
 
                        switch (e->type) {
                                case SCF_OP_EXPR:
+                               case SCF_OP_SWITCH:
                                case SCF_OP_IF:
                                case SCF_OP_FOR:
                                        ret = scf_node_add_child((scf_node_t*)f, e);
                                case SCF_OP_IF:
                                case SCF_OP_FOR:
                                        ret = scf_node_add_child((scf_node_t*)f, e);