comp

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

commit 699d5e217911710d2a6f9989c62bc0115e535790
parent 119b3d86b933c4ad97d529501e089eab788b1c13
Author: thing1 <thing1@seacrossedlovers.xyz>
Date:   Sun, 22 Mar 2026 19:37:25 +0000

started constructing the tree

Diffstat:
MMakefile | 2+-
Mcomp.h | 26++++++++++++++++----------
Mcomp.y | 103+++++++++++++++++++++++++++++++++++++------------------------------------------
Mlex.c | 46+++++++++++++++++++++++++++++++++++-----------
4 files changed, 100 insertions(+), 77 deletions(-)

diff --git a/Makefile b/Makefile @@ -3,7 +3,7 @@ CFLAGS=-ggdb all: lex y.tab.c: comp.y - yacc -ytd comp.y + yacc -td comp.y comp.o: y.tab.c cc -DYYDEBUG y.tab.c -c -o comp.o ${CFLAGS} diff --git a/comp.h b/comp.h @@ -15,18 +15,20 @@ typedef struct Func { } Func; enum Types { - I8, - I16, - I32, - I64, + I8 = 1, + I16 = 2, + I32 = 4, + I64 = 8, - U8, - U16, - U32, - U64, + U8 = I8 | 16, + U16 = I16 | 16, + U32 = I32 | 16, + U64 = I64 | 16, - F32, - F64, + F32 = I32 | 32, + F64 = I64 | 32, + + VOID = 64, COMPLEX, }; @@ -92,3 +94,7 @@ typedef struct Value { long long int lval; double dval; } Value; + +typedef struct Name { + char *name; +} Name; diff --git a/comp.y b/comp.y @@ -8,6 +8,8 @@ extern int yylex(); void yyerror(const char *msg); +#define NEW(x, v) x = malloc(sizeof(*x)); memcpy(x, &v, sizeof(v)) + %} %union { @@ -16,19 +18,26 @@ void yyerror(const char *msg); Rhs *rhs; Expr *expr; Value *value; + Name *name; + + struct Token *tok; } %token FUNC +%token VAR %token NAME %token INT %token FLOAT %type <func> func %type <type> type -%type <rhs> name %type <rhs> rhs %type <expr> expr %type <value> value +%type <name> name +%type <tok> INT +%type <tok> FLOAT +%type <tok> NAME %left '(' ')' %left '*' '/' @@ -39,81 +48,65 @@ prog : func | prog func ; -func : FUNC name '(' args ')' type '{' exprs '}' - | FUNC name '(' ')' type '{' exprs '}' +func : FUNC name '(' args ')' type + '{' exprs '}' + | FUNC name '(' ')' type + '{' exprs '}' ; -name : NAME +name : NAME { NEW($$, ((Name){.name = $1->data})); } ; args : name | args ',' name ; -type : NAME +type : NAME { + enum Types ty = 0; + switch (((char *)$1->data)[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"); + } + + switch (((char *)$1->data)[1]) { + case '8': ty = 1; break; + case '1': ty = 2; break; + case '3': ty = 4; break; + case '6': ty = 8; break; + default: yyerror("Invalid type size"); + } + + void_type: + NEW($$, ((Type){.type = ty})); + } ; exprs : expr ';' | exprs expr ';' ; -expr : name '(' params ')' - | type name '=' rhs +expr : name '(' params ')' { NEW($$, ((Expr){.expr = FCALL_EXPR, .fcall.name = $1->name})); } + | VAR name type '=' rhs { NEW($$, ((Expr){.expr = ASSIGN, .assign.type = $3, .assign.name = $2->name, .assign.rhs = $5})); } ; params : rhs - | params ',' rhs + | params ',' rhs ; -rhs : value - | name '(' params ')' { - $$ = malloc(sizeof(Rhs)); - $$->rhs = FCALL_RHS; - $$->fcall.name = $1; - } - | rhs '+' rhs { - $$ = malloc(sizeof(Rhs)); - $$->rhs = MATH; - $$->math.op = ADD; - $$->math.lhs = $1 - $$->math.rhs = $3; - } - | rhs '-' rhs { - $$ = malloc(sizeof(Rhs)); - $$->rhs = MATH; - $$->math.op = SUB; - $$->math.lhs = $1 - $$->math.rhs = $3; - } - | rhs '*' rhs { - $$ = malloc(sizeof(Rhs)); - $$->rhs = MATH; - $$->math.op = MUL; - $$->math.lhs = $1 - $$->math.rhs = $3; - } - | rhs '/' rhs { - $$ = malloc(sizeof(Rhs)); - $$->rhs = MATH; - $$->math.op = DIV; - $$->math.lhs = $1 - $$->math.rhs = $3; - } - | '(' rhs ')' { - $$ = malloc(sizeof(Rhs)); - $$->rhs = BRACE; - $$->brace = $2; - } +rhs : value { NEW($$, ((Rhs){.rhs = VALUE, .value = $1})); } + | name '(' params ')' { NEW($$, ((Rhs){.rhs = FCALL_RHS, .fcall.name = $1->name})); } + | rhs '+' rhs { NEW($$, ((Rhs){.rhs = MATH, .math.op = ADD, .math.lhs = $1, .math.rhs = $3}));} + | rhs '-' rhs { NEW($$, ((Rhs){.rhs = MATH, .math.op = SUB, .math.lhs = $1, .math.rhs = $3}));} + | rhs '*' rhs { NEW($$, ((Rhs){.rhs = MATH, .math.op = MUL, .math.lhs = $1, .math.rhs = $3}));} + | rhs '/' rhs { NEW($$, ((Rhs){.rhs = MATH, .math.op = DIV, .math.lhs = $1, .math.rhs = $3}));} + | '(' rhs ')' { NEW($$, ((Rhs){.rhs = BRACE, .brace = $2})); } ; -value : INT { - $$ = malloc(sizeof(Value)); - memcpy($$, &(Value){atoll(lasttok.data), 0}, sizeof(Value)); - } - | FLOAT { - $$ = malloc(sizeof(Value)); - memcpy($$, &(Value){0, atof(lasttok.data)}, sizeof(Value)); - } +value : INT { NEW($$, ((Value){.lval = atoll($1->data)})); } + | FLOAT { NEW($$, ((Value){.dval = atof($1->data)})); } ; %% diff --git a/lex.c b/lex.c @@ -5,7 +5,7 @@ #include "comp.h" #include "y.tab.h" -#define LEXRET(t) lasttok = (t); return (t); +#define LEXRET(t) memcpy(&Gtoken, &(t), sizeof((t))); yylval.tok = &Gtoken; lasttok = (t); return (t); extern void yyerror(const char *msg); @@ -26,6 +26,8 @@ struct Lexer { struct Token (*f)(); }; +struct Token Gtoken; + struct Token lex_func(); struct Token lex_name(); struct Token lex_obrace(); @@ -44,6 +46,28 @@ struct Lexer lex = {0}; struct Token lasttok = {0}; +void llerror(const char *msg) { + char *terms = ",{};"; + char *first = NULL, *new; + do { + new = strchr(lex.input, *terms); + if (!first) first = new; + if (new && new < first) + first = new; + } while (*(terms++) && new); + + yyerror(msg); + if (!first) exit(1); + lex.input = first; + + switch (lex.input[0]) { + case '{': lex.f = lex_ocbrace; break; + case '}': lex.f = lex_ccbrace; break; + case ',': lex.f = lex_comma; break; + case ';': lex.f = lex_semi; break; + } +} + void move(int off) { lex.input += off; lex.pos.col += off; @@ -69,7 +93,7 @@ struct Token lex_char(char c) { struct Pos start = lex.pos; if (lex.input[0] != c) - yyerror("Expected different char"); + llerror("Expected different char"); move(1); skip(); @@ -80,7 +104,7 @@ struct Token lex_func() { struct Pos start = lex.pos; if (memcmp(lex.input, "func", 4) != 0) - yyerror("Expected func!"); + llerror("Expected func!"); move(4); lex.f = &lex_name; @@ -91,7 +115,7 @@ struct Token lex_name() { struct Pos start = lex.pos; if (!isalpha(lex.input[0])) - yyerror("Expected name!"); + llerror("Expected name!"); struct Token t = {start, NAME, lex.input, lex.input + 1}; move(1); @@ -104,7 +128,7 @@ struct Token lex_name() { case '*': lex.f = &lex_mul; break; case '/': lex.f = &lex_div; break; case ',': lex.f = &lex_comma; break; - default: yyerror("Unexpected token!"); + default: llerror("Unexpected token!"); } LEXRET(t); @@ -118,7 +142,7 @@ struct Token lex_obrace() { case '(': lex.f = &lex_obrace; break; default: if (isdigit(peek())) lex.f = &lex_int; - else yyerror("Unexpected token!"); + else llerror("Unexpected token!"); } LEXRET(t); @@ -128,7 +152,7 @@ struct Token lex_int() { struct Pos start = lex.pos; if (!isdigit(lex.input[0])) - yyerror("Expected number!"); + llerror("Expected number!"); struct Token t = {start, INT, lex.input, lex.input + 1}; move(1); @@ -140,7 +164,7 @@ struct Token lex_int() { case '*': lex.f = &lex_mul; break; case '/': lex.f = &lex_div; break; case ',': lex.f = &lex_comma; break; - default: yyerror("Unexpected token!"); + default: llerror("Unexpected token!"); } LEXRET(t); @@ -198,7 +222,7 @@ struct Token lex_comma() { lex.f = &lex_name; else switch (peek()) { case '(': lex.f = &lex_obrace; break; - default: yyerror("Unexpeced token!"); + default: llerror("Unexpeced token!"); } LEXRET(t); @@ -212,7 +236,7 @@ struct Token lex_comma() { lex.f = &lex_int; \ else if (isalpha(peek())) \ lex.f = &lex_name; \ - else yyerror("Unexpeced token!"); \ + else llerror("Unexpeced token!"); \ LEXRET(t); \ } @@ -228,6 +252,6 @@ int yylex() { } int main() { - lex = (struct Lexer){(struct Pos){0, 0}, "func f() v {\n\tg((1 + 5) * 2);\nh(3, 5);\n}", &lex_func}; + lex = (struct Lexer){(struct Pos){0, 0}, "func f() i32 {\n\tg((1 + 5) * 2);\nh(3, 5);\n}", &lex_func}; yyparse(); }