commit 63c43210f409875968beaa5e20d19c2b1f406287
parent 5246c1bc8bb53fff55dffeeca75702bbda811f85
Author: thing1 <thing1@seacrossedlovers.xyz>
Date: Mon, 15 Dec 2025 11:03:46 +0000
started work on function calls, which will be used for casts
Diffstat:
| M | lexer.h | | | 5 | ++++- |
| M | parse.c | | | 92 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ |
| M | parse.h | | | 5 | +++++ |
| M | test.spl | | | 3 | +-- |
4 files changed, 95 insertions(+), 10 deletions(-)
diff --git a/lexer.h b/lexer.h
@@ -21,11 +21,14 @@ enum lex_ops {
SEMI = ';',
COMMA = ',',
FUNC = 256,
- NEGATE,
INT,
FLOAT,
NAME,
WALRUS,
+
+ /* used by the parser, wont be assigned by the lexer */
+ FUNCALL,
+ NEGATE,
};
typedef struct tok {
diff --git a/parse.c b/parse.c
@@ -1,10 +1,12 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
#include "lexer.h"
#include "parse.h"
#include "util.h"
+#include "check.h"
int funcargs = 0;
@@ -104,30 +106,87 @@ mkbasictype(char *name, mctx *ctx) {
return t;
}
+/* checks if t2 can be losslessly casted to t1 */
+int
+isequaltype(type *t1, type *t2) {
+ if (t1->type == BASIC && t2->type == BASIC) {
+ if (t1->name[0] == t2->name[0]) {
+ if (atoi(t1->name + 1) >= atoi(t2->name + 1))
+ return 1;
+ }
+ }
+ return 0;
+}
+
rexpr *
-parsesimple(tok *start, tok *end, tok *lowest, mctx *ctx) {
+parsefcall(tok *start, tok *end, mctx *ctx) {
rexpr *e = alloczctx(ctx, sizeof(rexpr));
+ tok *exprend;
+ e->op = FUNCALL;
+
+ /* TODO lookup the return type of the function and put it into e->type*/
+ if (start[1].op != '(')
+ return NULL;
+ start = &start[2];
+ exprend = start;
+
+another:
+ while (!isterm(*exprend)) {
+ if (exprend->op == ')')
+ break;
+ exprend = &exprend[1];
+ }
+ e->argc++;
+ e->args = realloczctx(ctx, e->args, sizeof(rexpr) * e->argc);
+ e->args[e->argc - 1] = *parserexpr(start, &exprend[-1], ctx);
+ start = &exprend[1];
+ if (exprend->op != ')')
+ goto another;
+
+noargs:
+ return e;
+}
+
+rexpr *
+parsesimple(tok *start, tok *end, tok *lowest, mctx *ctx) {
+ rexpr *e;
+ var *v;
+
switch (lowest->op) {
+ case NAME:
+ if (lowest[1].op == '(') {
+ e = parsefcall(lowest, end, ctx);
+ return e;
+ }
case INT:
case FLOAT:
- case NAME:
if (start != end) {
parserErr("Trailing expression");
return NULL;
}
+ e = alloczctx(ctx, sizeof(rexpr));
e->op = lowest->op;
- e->n = lowest->n; /* this is okay as n is 64 bits so any pointer types fit here */
+ e->n = lowest->n; /* this is okay as n is 64 bits so any pointer type fits here */
switch (e->op) {
case INT:
- /* TODO make this use smol ints when possible */
- e->type = mkbasictype("i64", ctx);
+ if (e->n > INT32_MAX)
+ e->type = mkbasictype("i64", ctx);
+ else if (e->n > INT16_MAX)
+ e->type = mkbasictype("i32", ctx);
+ else if (e->n > INT8_MAX)
+ e->type = mkbasictype("i16", ctx);
+ else
+ e->type = mkbasictype("i8", ctx);
break;
case FLOAT:
e->type = mkbasictype("f64", ctx);
break;
case NAME:
- /* TODO make this lookup the var and assign the type*/
- e->type = mkbasictype("i64", ctx);
+ if (!(v = (var *)lookupmap(vars, lowest->name))) {
+ parserErr("var is not declared");
+ return NULL;
+ }
+ e->type = v->type;
break;
}
break;
@@ -211,6 +270,7 @@ parseassign(lex *l, tok name, mctx *ctx) {
type *ty;
rexpr *r = NULL;
tok *arr, t;
+ var *v;
int count = 1;
if (!(ty = parsetype(l, ctx))) {
@@ -241,12 +301,30 @@ parseassign(lex *l, tok name, mctx *ctx) {
}
shortdec:
+ if (lookupmap(vars, name.name)) {
+ parserErr("redeclaration of var");
+ RESTORE(l);
+ return NULL;
+ }
+
le = alloczctx(ctx, sizeof(lexpr));
le->name = alloczctx(ctx, strlen(name.name) + 1);
strcpy(le->name, name.name);
le->op = LEXPR_ASSIGN;
le->type = ty;
le->rexpr = r;
+
+ if (!isequaltype(ty, r->type)) {
+ parserErr("type missmatch");
+ RESTORE(l);
+ return NULL;
+ }
+
+ v = alloczctx(ctx, sizeof(var));
+ v->name = le->name;
+ v->type = le->type;
+ vars = addmap(vars, v, le->name, ctx);
+
return le;
}
diff --git a/parse.h b/parse.h
@@ -33,6 +33,11 @@ typedef struct rexpr {
struct { /* operators */
struct rexpr *expr[2];
};
+ struct { /* fun call */
+ char *fname;
+ struct rexpr *args;
+ int argc;
+ };
/* litterals */
uint64_t n;
double f;
diff --git a/test.spl b/test.spl
@@ -1,4 +1,3 @@
func main() i32 {
- a i64 = 42342342;
- b i8 = a;
+ a f32 = f32(30);
}