fix: some analysis stage problems
This commit is contained in:
@@ -32,6 +32,8 @@ typedef struct fzl_an_ctx
|
|||||||
struct fzl_an_ctx *parent;
|
struct fzl_an_ctx *parent;
|
||||||
|
|
||||||
fzl_an_ctx_type_t type;
|
fzl_an_ctx_type_t type;
|
||||||
|
fzl_symtable_t *symbols;
|
||||||
|
size_t symbols_level;
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -106,9 +106,9 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
|||||||
.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
|
.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
|
||||||
}
|
}
|
||||||
|
|
||||||
fzl_an_res_t callee_res = analyze_common(analyzer, callee);
|
// fzl_an_res_t callee_res = analyze_common(analyzer, callee);
|
||||||
if (callee_res.error)
|
// if (callee_res.error)
|
||||||
return (fzl_an_res_t){.error = true};
|
// return (fzl_an_res_t){.error = true};
|
||||||
|
|
||||||
fzl_sym_t sym;
|
fzl_sym_t sym;
|
||||||
bool sym_found = false;
|
bool sym_found = false;
|
||||||
@@ -148,11 +148,12 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
|||||||
return (fzl_an_res_t){.error = true};
|
return (fzl_an_res_t){.error = true};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym.node->fn.args_count != call_node->call.args_count)
|
size_t start_i = is_method ? 1 : 0;
|
||||||
|
if ((sym.node->fn.args_count - start_i) != call_node->call.args_count)
|
||||||
{
|
{
|
||||||
snprintf(call_problem, sizeof(call_problem),
|
snprintf(call_problem, sizeof(call_problem),
|
||||||
"expected %zu argument(s) while %zu is specified",
|
"expected %zu argument(s) while %zu is specified",
|
||||||
sym.node->fn.args_count, call_node->call.args_count);
|
sym.node->fn.args_count, call_node->call.args_count - start_i);
|
||||||
an_push_error(analyzer, call_node->token, call_problem);
|
an_push_error(analyzer, call_node->token, call_problem);
|
||||||
|
|
||||||
if (tmp_method_name != NULL)
|
if (tmp_method_name != NULL)
|
||||||
@@ -164,7 +165,6 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
|||||||
return (fzl_an_res_t){.error = true};
|
return (fzl_an_res_t){.error = true};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t start_i = is_method ? 1 : 0;
|
|
||||||
for (size_t i = start_i; i < sym.node->fn.args_count; i++)
|
for (size_t i = start_i; i < sym.node->fn.args_count; i++)
|
||||||
{
|
{
|
||||||
fzl_node_t *arg = sym.node->fn.args[i];
|
fzl_node_t *arg = sym.node->fn.args[i];
|
||||||
@@ -173,7 +173,8 @@ fzl_an_res_t analyze_call(fzl_analyzer_t *analyzer, fzl_node_t *call_node)
|
|||||||
if (req_type == FZL_TYPE_OBJECT)
|
if (req_type == FZL_TYPE_OBJECT)
|
||||||
req_classname = arg->var.type->value;
|
req_classname = arg->var.type->value;
|
||||||
|
|
||||||
fzl_an_res_t got = analyze_common(analyzer, call_node->call.args[i]);
|
fzl_an_res_t got =
|
||||||
|
analyze_common(analyzer, call_node->call.args[i - start_i]);
|
||||||
if (got.error)
|
if (got.error)
|
||||||
{
|
{
|
||||||
if (tmp_method_name != NULL)
|
if (tmp_method_name != NULL)
|
||||||
|
|||||||
@@ -20,9 +20,15 @@ fzl_an_res_t analyze_conditional(fzl_analyzer_t *analyzer, fzl_node_t *cond)
|
|||||||
|
|
||||||
fzl_an_res_t cond_res = analyze_common(analyzer, cond->cond.condition);
|
fzl_an_res_t cond_res = analyze_common(analyzer, cond->cond.condition);
|
||||||
fzl_an_res_t true_res = analyze_common(analyzer, cond->cond.true_block);
|
fzl_an_res_t true_res = analyze_common(analyzer, cond->cond.true_block);
|
||||||
fzl_an_res_t else_res = analyze_common(analyzer, cond->cond.else_block);
|
|
||||||
|
|
||||||
if (cond_res.error || true_res.error || else_res.error)
|
if (cond->cond.else_block)
|
||||||
|
{
|
||||||
|
fzl_an_res_t else_res = analyze_common(analyzer, cond->cond.else_block);
|
||||||
|
if (else_res.error)
|
||||||
|
return (fzl_an_res_t){.error = true};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond_res.error || true_res.error)
|
||||||
return (fzl_an_res_t){.error = true};
|
return (fzl_an_res_t){.error = true};
|
||||||
|
|
||||||
if (cond_res.type != FZL_TYPE_BOOL)
|
if (cond_res.type != FZL_TYPE_BOOL)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ extern fzl_type_t an_toktotype(fzl_token_t *tok);
|
|||||||
// Analyze field access
|
// Analyze field access
|
||||||
fzl_an_res_t analyze_field(fzl_analyzer_t *analyzer, fzl_node_t *field)
|
fzl_an_res_t analyze_field(fzl_analyzer_t *analyzer, fzl_node_t *field)
|
||||||
{
|
{
|
||||||
if (analyzer)
|
if (!analyzer)
|
||||||
return (fzl_an_res_t){.error = true};
|
return (fzl_an_res_t){.error = true};
|
||||||
|
|
||||||
if (!field || field->type != FZL_NODETYPE_FIELD)
|
if (!field || field->type != FZL_NODETYPE_FIELD)
|
||||||
@@ -46,7 +46,7 @@ fzl_an_res_t analyze_field(fzl_analyzer_t *analyzer, fzl_node_t *field)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym_found)
|
if (!sym_found)
|
||||||
{
|
{
|
||||||
snprintf(field_problem, sizeof(field_problem), "class '%s' not found",
|
snprintf(field_problem, sizeof(field_problem), "class '%s' not found",
|
||||||
parent.classname);
|
parent.classname);
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ fzl_an_res_t analyze_function(fzl_analyzer_t *analyzer, fzl_node_t *fn_node)
|
|||||||
analyzer->alloc_names[analyzer->alloc_names_top++] = methodname;
|
analyzer->alloc_names[analyzer->alloc_names_top++] = methodname;
|
||||||
|
|
||||||
fzl_symtable_res_t putres =
|
fzl_symtable_res_t putres =
|
||||||
fzl_symt_put(analyzer->symbols[analyzer->symbols_top - 2], fn_node,
|
fzl_symt_put(analyzer->symbols[ctx->symbols_level - 1], fn_node,
|
||||||
methodname, rettype, 0);
|
methodname, rettype, 0);
|
||||||
if (putres != FZL_SYMTABLE_RESULT_OK)
|
if (putres != FZL_SYMTABLE_RESULT_OK)
|
||||||
{
|
{
|
||||||
@@ -99,13 +99,13 @@ fzl_an_res_t analyze_function(fzl_analyzer_t *analyzer, fzl_node_t *fn_node)
|
|||||||
an_fin_ctx(analyzer);
|
an_fin_ctx(analyzer);
|
||||||
return (fzl_an_res_t){.error = true};
|
return (fzl_an_res_t){.error = true};
|
||||||
}
|
}
|
||||||
fzl_symt_setobjclass(analyzer->symbols[analyzer->symbols_top - 1],
|
fzl_symt_setobjclass(analyzer->symbols[ctx->symbols_level - 1], methodname,
|
||||||
methodname, classname);
|
classname);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fzl_symtable_res_t putres =
|
fzl_symtable_res_t putres =
|
||||||
fzl_symt_put(analyzer->symbols[analyzer->symbols_top - 1], fn_node,
|
fzl_symt_put(analyzer->symbols[analyzer->symbols_top - 2], fn_node,
|
||||||
(char *)fn_node->fn.name->value, rettype, 0);
|
(char *)fn_node->fn.name->value, rettype, 0);
|
||||||
if (putres != FZL_SYMTABLE_RESULT_OK)
|
if (putres != FZL_SYMTABLE_RESULT_OK)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ fzl_an_ctx_t *an_nest_ctx(fzl_analyzer_t *analyzer, fzl_an_ctx_type_t type)
|
|||||||
else
|
else
|
||||||
ctx->parent = NULL;
|
ctx->parent = NULL;
|
||||||
|
|
||||||
|
ctx->symbols = fzl_mksymt();
|
||||||
|
ctx->symbols_level = analyzer->symbols_top;
|
||||||
analyzer->ctx = ctx;
|
analyzer->ctx = ctx;
|
||||||
analyzer->symbols[analyzer->symbols_top++] = fzl_mksymt();
|
analyzer->symbols[analyzer->symbols_top++] = ctx->symbols;
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ bool an_push_error(fzl_analyzer_t *analyzer, fzl_token_t *tok, char *error)
|
|||||||
|
|
||||||
size_t ei = aerrors_top++;
|
size_t ei = aerrors_top++;
|
||||||
if (tok != NULL)
|
if (tok != NULL)
|
||||||
snprintf(aerrors[ei], sizeof(aerrors[ei]), "'%s'(%zu:%zu) => %s",
|
snprintf(aerrors[ei], sizeof(aerrors[ei]), "'%s':%zu:%zu => %s",
|
||||||
tok->filename, tok->ln, tok->cn, error);
|
tok->filename, tok->ln, tok->cn, error);
|
||||||
else
|
else
|
||||||
snprintf(aerrors[ei], sizeof(aerrors[ei]), "<unknown location> => %s",
|
snprintf(aerrors[ei], sizeof(aerrors[ei]), "<unknown location> => %s",
|
||||||
@@ -64,7 +64,7 @@ bool an_push_warning(fzl_analyzer_t *analyzer, fzl_token_t *tok, char *warning)
|
|||||||
|
|
||||||
size_t wi = awarnings_top++;
|
size_t wi = awarnings_top++;
|
||||||
if (tok != NULL)
|
if (tok != NULL)
|
||||||
snprintf(awarnings[wi], sizeof(awarnings[wi]), "'%s'(%zu:%zu) => %s",
|
snprintf(awarnings[wi], sizeof(awarnings[wi]), "'%s':%zu:%zu => %s",
|
||||||
tok->filename, tok->ln, tok->cn, warning);
|
tok->filename, tok->ln, tok->cn, warning);
|
||||||
else
|
else
|
||||||
snprintf(awarnings[wi], sizeof(awarnings[wi]), "<unknown location> => %s",
|
snprintf(awarnings[wi], sizeof(awarnings[wi]), "<unknown location> => %s",
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
fn choose(bool flag) int
|
||||||
|
{
|
||||||
|
if (flag)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int invalid = "not an integer";
|
||||||
|
exit(1);
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
fn doSomeWork()
|
||||||
|
{
|
||||||
|
printline("Some work");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sum(int a, int b) int
|
||||||
|
{
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = sum(5, 6);
|
||||||
|
printline(result);
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class Node
|
||||||
|
{
|
||||||
|
Node next;
|
||||||
|
|
||||||
|
fn ping()
|
||||||
|
{
|
||||||
|
printline("ping");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pingNext()
|
||||||
|
{
|
||||||
|
this.next.ping();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Node head = new Node;
|
||||||
|
Node tail = new Node;
|
||||||
|
head.next = tail;
|
||||||
|
head.pingNext();
|
||||||
Reference in New Issue
Block a user