wip: working on analyzer
- Feat: add binary math analysis - Fix: check for function context in block analysis - Feat: add 'break' analysis - Fix: few fixes in call analysis - Feat: add class analysis - Feat: add construct analysis - Feat: add declaration analysis - Feat: add field analysis - Feat: add function analysis - Feat: add loop analysis - Ref: updated utilities and context functions
This commit is contained in:
@@ -32,7 +32,7 @@ char *resolve_callee(fzl_analyzer_t *analyzer, fzl_node_t *callee, bool *method)
|
||||
size_t classname_len = strlen(parent_res.classname);
|
||||
size_t methodname_len = strlen(fn_name);
|
||||
tmp_method_name = malloc(classname_len + methodname_len + 2);
|
||||
if (tmp_method_name)
|
||||
if (!tmp_method_name)
|
||||
{
|
||||
an_push_error(analyzer, callee->token,
|
||||
"failed to allocate space for method name");
|
||||
@@ -61,10 +61,7 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
||||
return (fzl_an_res_t){.error = true};
|
||||
}
|
||||
|
||||
fzl_node_t *callee = call_node->call.callee;
|
||||
fzl_an_res_t callee_res = analyze_common(analyzer, callee);
|
||||
if (callee_res.error)
|
||||
return (fzl_an_res_t){.error = true};
|
||||
fzl_node_t *callee = call_node->call.callee;
|
||||
|
||||
bool is_method = false;
|
||||
char *callee_name = resolve_callee(analyzer, callee, &is_method);
|
||||
@@ -73,11 +70,46 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
||||
an_push_error(analyzer, callee->token, "expression is not callable");
|
||||
|
||||
if (tmp_method_name != NULL)
|
||||
{
|
||||
free(tmp_method_name);
|
||||
tmp_method_name = NULL;
|
||||
}
|
||||
|
||||
return (fzl_an_res_t){.error = true};
|
||||
}
|
||||
|
||||
if (strcmp(callee_name, "printline") == 0 || strcmp(callee_name, "exit") == 0)
|
||||
{
|
||||
if (call_node->call.args_count != 1)
|
||||
{
|
||||
snprintf(call_problem, sizeof(call_problem),
|
||||
"'%s' builtin should be called with 1 argument instead of %zu",
|
||||
callee_name, call_node->call.args_count);
|
||||
an_push_error(analyzer, call_node->token, call_problem);
|
||||
|
||||
if (tmp_method_name != NULL)
|
||||
{
|
||||
free(tmp_method_name);
|
||||
tmp_method_name = NULL;
|
||||
}
|
||||
|
||||
return (fzl_an_res_t){.error = true};
|
||||
}
|
||||
|
||||
if (tmp_method_name != NULL)
|
||||
{
|
||||
free(tmp_method_name);
|
||||
tmp_method_name = NULL;
|
||||
}
|
||||
|
||||
return (fzl_an_res_t){
|
||||
.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
|
||||
}
|
||||
|
||||
fzl_an_res_t callee_res = analyze_common(analyzer, callee);
|
||||
if (callee_res.error)
|
||||
return (fzl_an_res_t){.error = true};
|
||||
|
||||
fzl_sym_t sym;
|
||||
bool sym_found = false;
|
||||
for (ssize_t i = analyzer->symbols_top - 1; i >= 0; i--)
|
||||
@@ -91,6 +123,13 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
||||
snprintf(call_problem, sizeof(call_problem), "cannot resolve symbol '%s'",
|
||||
callee_name);
|
||||
an_push_error(analyzer, call_node->token, call_problem);
|
||||
|
||||
if (tmp_method_name != NULL)
|
||||
{
|
||||
free(tmp_method_name);
|
||||
tmp_method_name = NULL;
|
||||
}
|
||||
|
||||
return (fzl_an_res_t){.error = true};
|
||||
}
|
||||
|
||||
@@ -99,6 +138,13 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
||||
snprintf(call_problem, sizeof(call_problem), "'%s' is not callable",
|
||||
callee_name);
|
||||
an_push_error(analyzer, call_node->token, call_problem);
|
||||
|
||||
if (tmp_method_name != NULL)
|
||||
{
|
||||
free(tmp_method_name);
|
||||
tmp_method_name = NULL;
|
||||
}
|
||||
|
||||
return (fzl_an_res_t){.error = true};
|
||||
}
|
||||
|
||||
@@ -108,6 +154,13 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
||||
"expected %zu argument(s) while %zu is specified",
|
||||
sym.node->fn.args_count, call_node->call.args_count);
|
||||
an_push_error(analyzer, call_node->token, call_problem);
|
||||
|
||||
if (tmp_method_name != NULL)
|
||||
{
|
||||
free(tmp_method_name);
|
||||
tmp_method_name = NULL;
|
||||
}
|
||||
|
||||
return (fzl_an_res_t){.error = true};
|
||||
}
|
||||
|
||||
@@ -122,6 +175,13 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
||||
an_typetostr(req.type, req.classname),
|
||||
an_typetostr(got.type, got.classname));
|
||||
an_push_error(analyzer, call_node->token, call_problem);
|
||||
|
||||
if (tmp_method_name != NULL)
|
||||
{
|
||||
free(tmp_method_name);
|
||||
tmp_method_name = NULL;
|
||||
}
|
||||
|
||||
return (fzl_an_res_t){.error = true};
|
||||
}
|
||||
}
|
||||
@@ -129,5 +189,11 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
||||
fzl_type_t type = an_toktotype(sym.node->fn.type);
|
||||
char *classname = sym.classname;
|
||||
|
||||
if (tmp_method_name != NULL)
|
||||
{
|
||||
free(tmp_method_name);
|
||||
tmp_method_name = NULL;
|
||||
}
|
||||
|
||||
return (fzl_an_res_t){.error = false, .type = type, .classname = classname};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user