Impl analyzer #5

Merged
samsonium merged 11 commits from impl-analyzer into v1.1 2026-10-27 12:43:08 +00:00
Owner
  • Feat: new analyzer step before parsing and after reading (lexing) step
  • Fix: VM protection for zero-field object
- Feat: new analyzer step before parsing and after reading (lexing) step - Fix: VM protection for zero-field object
samsonium added 9 commits 2026-10-27 11:13:18 +00:00
- Feat: now symbols table store node on PUT
- Feat: call analyzer with callee resolving and arguments validate
- Feat: identifier analyzer
- Feat: analyzer utils (types compat, tok-to-type, type-to-string)
- Feat: add `nest_ctx` and `fin_ctx` fns for working with context and
environment
- Feat: add block analyzer
- Feat: add conditional statement analyzer
- Feat: implement return analyzer
- Fix: add block return check if inside function
- 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
- Feat: add assigns analysis
- Fix: change node check condition in binary math analysis
- Feat: add unary and binary conditions analysis
- Fix: add type passtrough in declaration analysis
- Feat: add unary math analysis
samsonium left a comment
Author
Owner

part 1 :P

part 1 :P
@@ -0,0 +93,4 @@
fzl_an_res_t analyze_unarymath(fzl_analyzer_t *analyzer, fzl_node_t *unary);
fzl_an_res_t analyze_condition(fzl_analyzer_t *analyzer, fzl_node_t *cond_node);
fzl_an_res_t analyze_unarycond(fzl_analyzer_t *analyzer, fzl_node_t *unary);
fzl_an_res_t analyze_assign(fzl_analyzer_t *analyzer, fzl_node_t *assign_node);
Author
Owner

Move these functions to another header

Move these functions to another header
samsonium marked this conversation as resolved
@@ -0,0 +3,4 @@
#include <compiler/fzl_parser.h>
#include <stdio.h>
char asn_problem[256];
Author
Owner

Make a common 2nd level string buffer for errors in analyze_* functions

Make a common 2nd level string buffer for errors in `analyze_*` functions
@@ -0,0 +6,4 @@
char asn_problem[256];
// defined in `compiler/analyzer/utility.c`
extern bool an_is_compatible(fzl_type_t a, fzl_type_t b, char *ac, char *bc);
Author
Owner

Move these externs to the same header as analyze_* function

Move these `extern`s to the same header as `analyze_*` function
@@ -0,0 +17,4 @@
if (!assign_node || assign_node->type != FZL_NODETYPE_ASSIGN)
{
an_push_error(analyzer, NULL, "node is not typeof ASSIGN");
Author
Owner

"... is not assignment"

"... is not assignment"
@@ -0,0 +35,4 @@
left->type != FZL_NODETYPE_IDENTIFIER && left->type != FZL_NODETYPE_FIELD)
{
an_push_error(analyzer, left->token,
"this type of assignment left is not supported");
Author
Owner

need more understandable message

need more understandable message
@@ -0,0 +3,4 @@
#include <compiler/fzl_parser.h>
// defined in `compiler/analyzer/utility.c`
extern bool an_is_compatible(fzl_type_t a, fzl_type_t b, char *ac, char *bc);
Author
Owner

Also look for another extern functions in an_*.c files

Also look for another `extern` functions in `an_*.c` files
@@ -0,0 +33,4 @@
if (left.type < FZL_TYPE_INT8)
{
an_push_error(analyzer, bin_node->binary_op.left->token,
"left side is not an integer type");
Author
Owner

"expected integer type, got M"

"expected integer type, got M"
@@ -0,0 +40,4 @@
if (right.type < FZL_TYPE_INT8)
{
an_push_error(analyzer, bin_node->binary_op.right->token,
"right side is not an integer type");
Author
Owner

"expected integer type, got N"

"expected integer type, got N"
@@ -0,0 +5,4 @@
#include <stddef.h>
#include <stdio.h>
char block_problem[256];
Author
Owner

Also replace this "per-analyzer-buffers" with single one in other "an_*.c" files

Also replace this "per-analyzer-buffers" with single one in other "an_*.c" files
@@ -0,0 +19,4 @@
if (!block_node || block_node->type != FZL_NODETYPE_BLOCK)
{
snprintf(block_problem, sizeof(block_problem), "node is not typeof BLOCK");
Author
Owner

"... is not a block"

"... is not a block"
@@ -0,0 +32,4 @@
{
if (has_return)
an_push_warning(analyzer, block_node->list.entries[i]->token,
"this node will never execute");
Author
Owner

"statement", not "node"

"statement", not "node"
@@ -0,0 +66,4 @@
if (!has_return || block_node->list.entry_count < 1)
{
snprintf(block_problem, sizeof(block_problem),
"expected 'return <%s>' in function because return type is %s",
Author
Owner

"expect 'return <%s>' inside function with non-null return type"

"expect 'return <%s>' inside function with non-null return type"
@@ -0,0 +76,4 @@
block_node->list.entries[block_node->list.entry_count - 1];
if (last_node->type != FZL_NODETYPE_RETURN)
{
snprintf(block_problem, sizeof(block_problem),
Author
Owner

Replace with ghost walker to check if all branches returning a value

Replace with ghost walker to check if all branches returning a value
@@ -0,0 +10,4 @@
if (!break_node || break_node->type != FZL_NODETYPE_BREAK)
{
an_push_error(analyzer, NULL, "node is not typeof BREAK");
Author
Owner

"... is not break statement"

"... is not break statement"
@@ -0,0 +21,4 @@
return (char *)callee->token->value;
if (callee->type != FZL_NODETYPE_FIELD)
return NULL;
Author
Owner

add an error for unknown callee type

add an error for unknown callee type
@@ -0,0 +78,4 @@
return (fzl_an_res_t){.error = true};
}
if (strcmp(callee_name, "printline") == 0 || strcmp(callee_name, "exit") == 0)
Author
Owner

Move builtins outside (f.e. compiler/analyzer/builtins.c)

Move builtins outside (f.e. `compiler/analyzer/builtins.c`)
@@ -0,0 +106,4 @@
.error = false, .type = FZL_TYPE_NULL, .classname = NULL};
}
// fzl_an_res_t callee_res = analyze_common(analyzer, callee);
Author
Owner

remove

remove
@@ -0,0 +148,4 @@
return (fzl_an_res_t){.error = true};
}
size_t start_i = is_method ? 1 : 0;
Author
Owner

rename variable to offset

rename variable to `offset`
@@ -0,0 +152,4 @@
if ((sym.node->fn.args_count - start_i) != call_node->call.args_count)
{
snprintf(call_problem, sizeof(call_problem),
"expected %zu argument(s) while %zu is specified",
Author
Owner

function '%s' requires %zu argument(s), got %zu (or method, if is_method == true)

`function '%s' requires %zu argument(s), got %zu` (or `method`, if `is_method == true`)
@@ -0,0 +188,4 @@
if (!an_is_compatible(req_type, got.type, req_classname, got.classname))
{
snprintf(call_problem, sizeof(call_problem),
"expect argument %zu to be %s, got '%s'", i + 1,
Author
Owner

function '%s' is expecting argument %zu to be '%s', got '%s'

`function '%s' is expecting argument %zu to be '%s', got '%s'`
samsonium added 1 commit 2026-10-27 12:40:29 +00:00
samsonium added 1 commit 2026-10-27 12:42:10 +00:00
samsonium merged commit b24cefee96 into v1.1 2026-10-27 12:43:08 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: samsonium/fz-lang#5