comp

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

commit 3e00dac04bacb2dabe36a9e6b7aa7bba493c8c3d
parent 699d5e217911710d2a6f9989c62bc0115e535790
Author: thing1 <thing1@seacrossedlovers.xyz>
Date:   Mon, 23 Mar 2026 15:12:12 +0000

got basic language down

next step is to do var checking

Diffstat:
MMakefile | 5++++-
Mcomp.h | 21+++++++++++++++++----
Mcomp.y | 52+++++++++++++++++++++++++++++++++++++++++-----------
Mlex.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++------
4 files changed, 115 insertions(+), 22 deletions(-)

diff --git a/Makefile b/Makefile @@ -6,7 +6,10 @@ y.tab.c: comp.y yacc -td comp.y comp.o: y.tab.c - cc -DYYDEBUG y.tab.c -c -o comp.o ${CFLAGS} + cc -DYYALLOC -DYYDEBUG y.tab.c -c -o comp.o ${CFLAGS} lex: lex.c comp.o cc lex.c comp.o -o lex ${CFLAGS} + +clean: + rm -rf ./lex y.tab.h y.tab.c *.o diff --git a/comp.h b/comp.h @@ -1,16 +1,19 @@ +#include <stdio.h> +#include <stdlib.h> + typedef struct Type Type; typedef struct Func Func; typedef struct Rhs Rhs; typedef struct Expr Expr; typedef struct Value Value; +typedef struct Arg Arg; typedef struct Func { Type *type; char *name; - Type **argtypes; - char **argnames; + Arg *args; int argc; - Expr **body; + Expr *body; int exprc; } Func; @@ -52,7 +55,7 @@ typedef struct Expr { } assign; struct { char *name; - Rhs **args; + Rhs *args; int argc; } fcall; }; @@ -98,3 +101,13 @@ typedef struct Value { typedef struct Name { char *name; } Name; + +typedef struct List { + int count, size; + void *data; +} List; + +typedef struct Arg { + char *name; + Type *type; +} Arg; diff --git a/comp.y b/comp.y @@ -1,5 +1,6 @@ %{ #include <stdio.h> +#include <stdlib.h> #include "lex.h" #include "comp.h" @@ -8,8 +9,13 @@ extern int yylex(); void yyerror(const char *msg); -#define NEW(x, v) x = malloc(sizeof(*x)); memcpy(x, &v, sizeof(v)) +Func magic = {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); %} %union { @@ -19,8 +25,11 @@ void yyerror(const char *msg); Expr *expr; Value *value; Name *name; + Arg *arg; struct Token *tok; + + struct List *list; } %token FUNC @@ -33,6 +42,10 @@ void yyerror(const char *msg); %type <type> type %type <rhs> rhs %type <expr> expr +%type <list> exprs +%type <list> params +%type <list> args +%type <arg> arg %type <value> value %type <name> name %type <tok> INT @@ -49,18 +62,26 @@ prog : func ; func : FUNC name '(' args ')' type - '{' exprs '}' - | FUNC name '(' ')' type - '{' exprs '}' + '{' exprs '}' { NEW($$, ((Func){.type = $6, .args = (Arg *)$4->data, .argc = $4->count, .name = $2->name, .body = (Expr *)$8->data, .exprc = $8->count})); } + | FUNC name '(' ')' type + '{' exprs '}' { NEW($$, ((Func){.type = $5, .name = $2->name, .body = (Expr *)$7->data, .exprc = $7->count})); magic = *$$;} ; name : NAME { NEW($$, ((Name){.name = $1->data})); } ; -args : name - | args ',' name +args : arg { + NEW($$, ((List){.size = sizeof(Arg), .count = 0, .data = NULL})); + APPEND($$, $1); + } + | args ',' arg { + APPEND($1, $3); + $$ = $1; + } ; +arg : name type { NEW($$, ((Arg){.name = $1->name, .type = $2})); } + type : NAME { enum Types ty = 0; switch (((char *)$1->data)[0]) { @@ -84,16 +105,25 @@ type : NAME { } ; -exprs : expr ';' - | exprs expr ';' +exprs : expr ';' { + NEW($$, ((List){.size = sizeof(Expr), .count = 0, .data = NULL})); + APPEND($$, $1); + } + | exprs expr ';' { APPEND($1, $2); } ; -expr : name '(' params ')' { NEW($$, ((Expr){.expr = FCALL_EXPR, .fcall.name = $1->name})); } +expr : name '(' params ')' { NEW($$, ((Expr){.expr = FCALL_EXPR, .fcall.name = $1->name, .fcall.args = (Rhs *)$3->data, .fcall.argc = $3->count})); } | VAR name type '=' rhs { NEW($$, ((Expr){.expr = ASSIGN, .assign.type = $3, .assign.name = $2->name, .assign.rhs = $5})); } ; -params : rhs - | params ',' rhs +params : rhs { + NEW($$, ((List){.size = sizeof(Rhs), .count = 0, .data = NULL})); + APPEND($$, $1); + } + | params ',' rhs { + APPEND($1, $3); + $$ = $1; + } ; rhs : value { NEW($$, ((Rhs){.rhs = VALUE, .value = $1})); } diff --git a/lex.c b/lex.c @@ -29,12 +29,14 @@ struct Lexer { struct Token Gtoken; struct Token lex_func(); +struct Token lex_var(); struct Token lex_name(); struct Token lex_obrace(); struct Token lex_cbrace(); struct Token lex_ocbrace(); struct Token lex_ccbrace(); struct Token lex_semi(); +struct Token lex_assign(); struct Token lex_int(); struct Token lex_add(); struct Token lex_sub(); @@ -103,14 +105,25 @@ struct Token lex_char(char c) { struct Token lex_func() { struct Pos start = lex.pos; - if (memcmp(lex.input, "func", 4) != 0) - llerror("Expected func!"); - move(4); + if (memcmp(lex.input, "func ", 5) != 0) + llerror("Expected 'func'!"); + move(5); lex.f = &lex_name; LEXRET(((struct Token){start, FUNC, NULL, NULL})); } +struct Token lex_var() { + struct Pos start = lex.pos; + + if (memcmp(lex.input, "var ", 4) != 0) + llerror("Expected 'var'!"); + move(4); + + lex.f = &lex_name; + LEXRET(((struct Token){start, VAR, NULL, NULL})); +} + struct Token lex_name() { struct Pos start = lex.pos; @@ -128,7 +141,12 @@ struct Token lex_name() { case '*': lex.f = &lex_mul; break; case '/': lex.f = &lex_div; break; case ',': lex.f = &lex_comma; break; - default: llerror("Unexpected token!"); + case '=': lex.f = &lex_assign; break; + default: + if (lasttok.type == VAR) + lex.f = &lex_name; + else + llerror("Unexpected token!"); } LEXRET(t); @@ -164,6 +182,7 @@ struct Token lex_int() { case '*': lex.f = &lex_mul; break; case '/': lex.f = &lex_div; break; case ',': lex.f = &lex_comma; break; + case ';': lex.f = &lex_semi; break; default: llerror("Unexpected token!"); } @@ -173,7 +192,12 @@ struct Token lex_int() { struct Token lex_ocbrace() { struct Token t = lex_char('{'); switch (peek()) { - default: lex.f = &lex_name; break; + default: + if (memcmp(lex.input, "var ", 4) == 0) + lex.f = &lex_var; + else + lex.f = &lex_name; + break; } LEXRET(t); } @@ -213,6 +237,21 @@ struct Token lex_semi() { LEXRET(t); } +struct Token lex_assign() { + struct Token t = lex_char('='); + + switch (peek()) { + case '(': lex.f = &lex_obrace; break; + default: + lex.f = (isdigit(peek())) ? &lex_int : &lex_name; + break; + } + + LEXRET(t); +} + + + struct Token lex_comma() { struct Token t = lex_char(','); @@ -251,7 +290,15 @@ int yylex() { return lex.f().type; } +extern Func magic; + int main() { - lex = (struct Lexer){(struct Pos){0, 0}, "func f() i32 {\n\tg((1 + 5) * 2);\nh(3, 5);\n}", &lex_func}; + lex = (struct Lexer){(struct Pos){0, 0}, + "func f() v { \n\ + var a v = 4; \n\ + g((1 + 5) * 2); \n\ + h(3, 5); \n\ + }", + &lex_func}; yyparse(); }