spl

a Simple Programming Language
Log | Files | Refs

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:
Mlexer.h | 5++++-
Mparse.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Mparse.h | 5+++++
Mtest.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); }