commit 8e8b8808f6394841caff3c6fd14f924980825289
parent 56f52b2c4841ff07db198cf96cbc5006d6ed08f8
Author: thing1 <thing1@seacrossedlovers.xyz>
Date: Tue, 31 Mar 2026 20:00:46 +0100
added better error handling, and got started on collections
Diffstat:
| A | collect.c | | | 47 | +++++++++++++++++++++++++++++++++++++++++++++++ |
| M | comp.h | | | 4 | ++++ |
| M | comp.y | | | 43 | ++++++++++++++++++++++++++++++++++--------- |
| M | lex.c | | | 28 | +++++++++++++++++++++------- |
4 files changed, 106 insertions(+), 16 deletions(-)
diff --git a/collect.c b/collect.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "comp.h"
+
+typedef struct Collect_func {
+ Name *name;
+ Type *ret;
+} Collect_func;
+
+typedef struct Collect_scope {
+ struct Collect_scope *prev;
+ struct {
+ Name *name;
+ Type *type;
+ } *values;
+ int valuec;
+} Collect_scope;
+
+List *funcs;
+List *scopes;
+
+
+Collect_func *collect_func(Func *f) {
+ Collect_func *new = malloc(sizeof(Collect_func));
+ new->name = f->name;
+ new->ret = f->type;
+
+ return new;
+}
+
+Collect_scope *collect_exprs(Expr *body, int exprc) {
+ for (int i = 0; i < exprc; i++) {
+ if (body[i].expr == ASSIGN) {
+ body[i].assign.name
+ }
+ }
+}
+
+void collect_funcs(List *fns) {
+ for (int i = 0; i < fns->count; i++) {
+ Collect_func *f = collect_func(&((Func *)fns->data)[i]);
+ APPEND(funcs, f);
+ collect_exprs(&((Func *)fns->data)[i].body, &((Func *)fns->data)[i].exprc);
+ }
+}
+
diff --git a/comp.h b/comp.h
@@ -112,3 +112,7 @@ typedef struct Arg {
Name *name;
Type *type;
} Arg;
+
+#define APPEND(l, v) l->count++; \
+ l->data = (l->data) ? realloc(l->data, l->size * l->count) : malloc(l->size); \
+ memcpy(l->data + l->size * (l->count - 1), v, l->size);
diff --git a/comp.y b/comp.y
@@ -9,13 +9,11 @@ extern int yylex();
void yyerror(const char *msg);
+List *prog;
-Func magic = {0};
+int nerror = 0;
#define NEW(x, v) x = malloc(sizeof(*x)); memcpy(x, &v, sizeof(v))
-#define APPEND(l, v) l->count++; \
- l->data = (l->data) ? realloc(l->data, l->size * l->count) : malloc(l->size); \
- memcpy(l->data + l->size * (l->count - 1), v, l->size);
#define STR(v, t) v = calloc(1, t->dataend - t->data + 1); memcpy(v, t->data, t->dataend - t->data)
%}
@@ -39,6 +37,7 @@ Func magic = {0};
%token INT
%token FLOAT
+%type <list> prog
%type <func> func
%type <type> type
%type <rhs> rhs
@@ -58,14 +57,23 @@ Func magic = {0};
%left '+' '-'
%%
-prog : func
- | prog func
+prog : func {
+ NEW($$, ((List){.size = sizeof(Func), .count = 0, .data = NULL}));
+ APPEND($$, $1);
+ prog = $$;
+ }
+ | prog func {
+ APPEND($1, $2);
+ $$ = $1;
+ prog = $$;
+ }
+ | prog error { yyerrok; yyclearin; }
;
func : FUNC name '(' args ')' type
'{' exprs '}' { NEW($$, ((Func){.type = $6, .args = (Arg *)$4->data, .argc = $4->count, .name = $2, .body = (Expr *)$8->data, .exprc = $8->count})); }
| FUNC name '(' ')' type
- '{' exprs '}' { NEW($$, ((Func){.type = $5, .name = $2, .body = (Expr *)$7->data, .exprc = $7->count})); magic = *$$;}
+ '{' exprs '}' { NEW($$, ((Func){.type = $5, .name = $2, .body = (Expr *)$7->data, .exprc = $7->count})); }
;
name : NAME {
@@ -82,18 +90,25 @@ args : arg {
APPEND($1, $3);
$$ = $1;
}
+ | args ',' error { yyerrok; yyclearin; }
;
arg : name type { NEW($$, ((Arg){.name = $1, .type = $2})); }
+ ;
type : name {
+ if (!strlen($1->name))
+ goto invalid_type;
+
enum Types ty = 0;
switch (((char *)$1->name)[0]) {
case 'i': break;
case 'u': ty |= 16; break;
case 'f': ty |= 32; break;
case 'v': ty = 64; goto void_type;
- default: yyerror("Invalid type");
+ default:
+ yyerror("Invalid type");
+ goto invalid_type;
}
switch (((char *)$1->name)[1]) {
@@ -101,11 +116,15 @@ type : name {
case '1': ty = 2; break;
case '3': ty = 4; break;
case '6': ty = 8; break;
- default: yyerror("Invalid type size");
+ default:
+ yyerror("Invalid type size");
+ goto invalid_type;
}
void_type:
NEW($$, ((Type){.type = ty}));
+ invalid_type:
+
}
;
@@ -114,6 +133,7 @@ exprs : expr ';' {
APPEND($$, $1);
}
| exprs expr ';' { APPEND($1, $2); }
+ | exprs error ';' { yyerrok; }
;
expr : name '(' params ')' { NEW($$, ((Expr){.expr = FCALL_EXPR, .fcall.name = $1, .fcall.args = (Rhs *)$3->data, .fcall.argc = $3->count})); }
@@ -128,6 +148,7 @@ params : rhs {
APPEND($1, $3);
$$ = $1;
}
+ | params ',' error { yyerrok; yyclearin; }
;
rhs : value { NEW($$, ((Rhs){.rhs = VALUE, .value = $1})); }
@@ -151,5 +172,9 @@ char *getpos(struct Pos p) {
}
void yyerror(const char *msg) {
+ if (nerror++ > 20) {
+ fprintf(stderr, "To many errors, giving up\n");
+ exit(1);
+ }
fprintf(stderr, "%s: %s\n", getpos(lasttok.pos), msg);
}
diff --git a/lex.c b/lex.c
@@ -172,12 +172,16 @@ struct Token lex_obrace() {
struct Token lex_int() {
struct Pos start = lex.pos;
+ int size = 0;
if (!isdigit(lex.input[0]))
llerror("Expected number!");
- struct Token t = {start, INT, lex.input, lex.input + 1};
- move(1);
+ while (isdigit(lex.input[size]))
+ size++;
+
+ struct Token t = {start, INT, lex.input, lex.input + size};
+ move(size);
switch (peek()) {
case ')': lex.f = &lex_cbrace; break;
@@ -208,7 +212,12 @@ struct Token lex_ocbrace() {
struct Token lex_ccbrace() {
struct Token t = lex_char('}');
- lex.f = &lex_name;
+ switch (peek()) {
+ case 'f':
+ if (memcmp(lex.input, "func", 4) == 0) lex.f = &lex_func;
+ break;
+ default: lex.f = &lex_name;
+ }
LEXRET(t);
}
@@ -298,10 +307,15 @@ extern Func magic;
int main() {
lex = (struct Lexer){(struct Pos){0, 0},
- "func foo() i32 { \n\
- var a i8 = 4; \n\
- g((1 + 5) * 2); \n\
- h(3, 5); \n\
+ "func foo() i32 { \n\
+ var a i8 = 5; \n\
+ g((1 + 50) * 2); \n\
+ h(3, 5); \n\
+ } \n\
+ func main() i32 { \n\
+ var a i8 = 4; \n\
+ g((1 + ) * 2); \n\
+ h(3, 5); \n\
}",
&lex_func};
yyparse();