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);
- 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);
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;
- 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;
- 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;
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
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
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;
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;
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;
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 (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);