diff options
| author | hachem <im@hachem.wtf> | 2026-08-30 23:14:01 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-08-30 23:14:01 +0200 |
| commit | 8eac30c13cfa4f47a8a0aa0772b96f0813fe33a5 (patch) | |
| tree | 8ddf6be2ffd623e3c8bd931ba1f43699f10a447a /src/sema/sema.c | |
| parent | 81799f3e41ad9cab305930b7743a752003ff16ec (diff) | |
feat: add sematic analysis
Diffstat (limited to 'src/sema/sema.c')
| -rw-r--r-- | src/sema/sema.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/sema/sema.c b/src/sema/sema.c new file mode 100644 index 0000000..99ec4f1 --- /dev/null +++ b/src/sema/sema.c @@ -0,0 +1,73 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "sema/sema.h" + +static bool names_equal(struct Token a, struct Token b) +{ + return a.length == b.length && memcmp(a.start, b.start, a.length) == 0; +} + +static bool check_duplicate_names(struct Program* program) +{ + size_t count = program->const_count + program->data_count + program->proc_count; + if (count == 0) + return true; + + struct Token* names = malloc(count * sizeof(struct Token)); + size_t n = 0; + for (size_t i = 0; i < program->const_count; i += 1) + { + names[n] = program->consts[i].name; + n += 1; + } + for (size_t i = 0; i < program->data_count; i += 1) + { + names[n] = program->data_decls[i].name; + n += 1; + } + for (size_t i = 0; i < program->proc_count; i += 1) + { + names[n] = program->procs[i].name; + n += 1; + } + + bool ok = true; + for (size_t i = 0; i < count; i += 1) + for (size_t j = 0; j < i; j += 1) + if (names_equal(names[i], names[j])) + { + fprintf(stderr, "error: line %u: '%.*s' is already defined\n", + names[i].line, (int)names[i].length, names[i].start); + ok = false; + } + + free(names); + return ok; +} + +static bool check_entry_point(struct Program* program) +{ + for (size_t i = 0; i < program->proc_count; i += 1) + { + struct Token name = program->procs[i].name; + if (name.length == 4 && memcmp(name.start, "main", 4) == 0) + return true; + } + + fprintf(stderr, "error: no 'main' procedure defined\n"); + return false; +} + +bool analyze_program(struct Program* program) +{ + bool ok = true; + + if (!check_duplicate_names(program)) + ok = false; + if (!check_entry_point(program)) + ok = false; + + return ok; +} |
