spl

a Simple Programming Language
Log | Files | Refs

commit cc2a1dcea09d79cd11950843ecc02456266adbdf
parent 1671be35a24f26108bd967f439caa2c7654adec5
Author: thing1 <thing1@seacrossedlovers.xyz>
Date:   Sat,  6 Dec 2025 22:36:15 +0000

changes from a while back

Diffstat:
MMakefile | 4++--
Mlexer.c | 7+++++--
Mlexer.h | 2++
Mspl.c | 92++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,6 +1,6 @@ -CFLAGS = -ggdb -pedantic +CFLAGS = -ggdb -pedantic #-fsanitize=address CPPFLAGS = -D_POSIX_C_SOURCE -D_XOPEN_SOURCE=500 -LDFLAGS = +LDFLAGS = #-fsanitize=address SRC = spl.c lexer.c util.c OBJ = ${SRC:.c=.o} diff --git a/lexer.c b/lexer.c @@ -52,13 +52,16 @@ next(lex *l) { case CBRACE: case ASSIGN: case SEMI: + case COMMA: t.op = *l->ptr++; return t; } - - if (isdigit(*l->ptr)) { + if (memcmp(l->ptr, "func", 4) == 0) { + l->ptr += 4; + t.op = FUNC; + } else if (isdigit(*l->ptr)) { t.op = INT; t.n = lexNum(l); } else if (isalpha(*l->ptr)) { diff --git a/lexer.h b/lexer.h @@ -17,6 +17,8 @@ enum lex_ops { LEOF = '$', ASSIGN = '=', SEMI = ';', + COMMA = ',', + FUNC, NEGATE, NAME, }; diff --git a/spl.c b/spl.c @@ -7,6 +7,7 @@ enum lexpr_ops { LEXPR_ASSIGN, + LEXPR_FUNC, }; enum type_types { @@ -45,6 +46,12 @@ typedef struct lexpr { char *name; rexpr *rexpr; }; + struct { /* function decs */ + type *rtype; + char *fname; + struct lexpr *args; /* must be of type assign */ + int argc; + }; }; } lexpr; @@ -232,6 +239,11 @@ parsetype(lex *l, mctx *ctx) { return ty; } +int +isterm(tok t) { + return (t.op == SEMI || t.op == COMMA || t.op == CBRACE); +} + lexpr * parseassign(lex *l, tok name, mctx *ctx) { SAVE(l); @@ -246,13 +258,17 @@ parseassign(lex *l, tok name, mctx *ctx) { return NULL; } if ((t = next(l)).op != ASSIGN) { - if (t.op == SEMI) goto shortdec; + if (isterm(t)) { + if (t.op != SEMI) + l->ptr--; + goto shortdec; + } RESTORE(l); return NULL; } arr = alloczctx(ctx, sizeof(tok)); - while ((t = next(l)).op != LEOF && t.op != SEMI) { /* TODO switch this check out for some kind is termiating thing */ + while ((t = next(l)).op != LEOF && !isterm(t)) { arr[count++ - 1] = t; arr = realloczctx(ctx, arr, sizeof(tok) * count); } @@ -274,6 +290,69 @@ shortdec: } lexpr * +parsefunc(lex *l, mctx *ctx) { + SAVE(l); + tok name, t; + lexpr *args, *arg, *func; + type *ty; + int argc = 1; + + if ((name = next(l)).op != NAME) { + parserErr("function has no name"); + RESTORE(l); + return NULL; + } + if (next(l).op != OBRACE) { + parserErr("expected '('"); + RESTORE(l); + return NULL; + } + args = alloczctx(ctx, sizeof(lexpr)); + + for (;;) { + t = next(l); + switch (t.op) { + case NAME: + if (!(arg = parseassign(l, t, ctx))) { + parserErr("malformed function arg"); + RESTORE(l); + return NULL; + } + args[argc++ - 1] = *arg; + args = realloczctx(ctx, args, sizeof(lexpr) * argc); + case COMMA: + continue; + case CBRACE: + goto done; + default: + parserErr("unexpected token"); + RESTORE(l); + return NULL; + } + } +done: + argc--; + if (argc ==0) { + argc = 0; + args = NULL; + } + + if (!(ty = parsetype(l, ctx))) { + parserErr("function has no type"); + RESTORE(l); + return NULL; + } + + func = alloczctx(ctx, sizeof(lexpr)); + func->op = LEXPR_FUNC; + func->rtype = ty; + func->name = name.name; + func->args = args; + func->argc = argc; + return func; +} + +lexpr * parselexpr(lex *l, mctx *ctx) { SAVE(l); lexpr *le; @@ -282,6 +361,9 @@ parselexpr(lex *l, mctx *ctx) { case NAME: le = parseassign(l, t, ctx); break; + case FUNC: + le = parsefunc(l, ctx); /* we can drop the FUNC token, as it doesnt hold any info */ + break; default: parserErr("unexpected tok type"); } @@ -293,9 +375,11 @@ parselexpr(lex *l, mctx *ctx) { return le; } + + int main() { - lex l = mklexer("a int;"); + lex l = mklexer("func foo(n int, m int) int"); mctx *ctx = newctx(); lexpr *e = parselexpr(&l, ctx); @@ -303,8 +387,6 @@ main() { parserErr("failed to parse lexpr"); goto cleanup; } - if (e->rexpr) printf("%s is of type %s = %d\n", e->name, e->type->name, eval(e->rexpr)); - else printf("%s is of type %s\n", e->name, e->type->name); cleanup: freectx(ctx);