commit cc2a1dcea09d79cd11950843ecc02456266adbdf
parent 1671be35a24f26108bd967f439caa2c7654adec5
Author: thing1 <thing1@seacrossedlovers.xyz>
Date: Sat, 6 Dec 2025 22:36:15 +0000
changes from a while back
Diffstat:
| M | Makefile | | | 4 | ++-- |
| M | lexer.c | | | 7 | +++++-- |
| M | lexer.h | | | 2 | ++ |
| M | spl.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);