comp

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
Acollect.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Mcomp.h | 4++++
Mcomp.y | 43++++++++++++++++++++++++++++++++++---------
Mlex.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();