commit 8638dd399594573cf2ef8fb00fec751d9e06b44d
parent 2534cc1edbb10f19ce49f8286cf68f5962b9bfb3
Author: thing1 <thing1@seacrossedlovers.xyz>
Date: Tue, 9 Dec 2025 22:27:16 +0000
started work on type system
Diffstat:
7 files changed, 103 insertions(+), 37 deletions(-)
diff --git a/.parse.h.swp b/.parse.h.swp
Binary files differ.
diff --git a/cback.c b/cback.c
@@ -3,6 +3,8 @@
#include "lexer.h"
#include "parse.h"
+#define SAME(s1, s2) (strcmp(s1, s2) == 0)
+
int vid = 0;
int indent = 0;
@@ -14,12 +16,39 @@ putindent(FILE *f) {
fputc('\t', f);
}
+char *
+toctype(char *type) {
+ static char ret[16];
+ if (SAME(type, "i8"))
+ strcpy(ret, "int8_t");
+ else if (SAME(type, "i16"))
+ strcpy(ret, "int16_t");
+ else if (SAME(type, "i32"))
+ strcpy(ret, "int32_t");
+ else if (SAME(type, "i64"))
+ strcpy(ret, "int64_t");
+ else if (SAME(type, "f32"))
+ strcpy(ret, "float");
+ else if (SAME(type, "f64"))
+ strcpy(ret, "double");
+ return ret;
+}
+
+void
+compiletype_C(type *t, FILE *f) {
+ switch (t->type) {
+ case BASIC:
+ fprintf(f, "%s", toctype(t->name));
+ break;
+ }
+}
+
int
compilerexpr_C(rexpr *r, FILE *f) {
int left, right;
if (r->op == INT) {
putindent(f);
- fprintf(f, "int v%d = %d;\n", vid++, r->n);
+ fprintf(f, "int v%d = %ld;\n", vid++, r->n);
return vid - 1;
}
putindent(f);
@@ -33,9 +62,12 @@ compilerexpr_C(rexpr *r, FILE *f) {
void
compilefunc_C(lexpr *l, FILE *f) {
- fprintf(f, "%s %s(", l->rtype->name, l->fname);
- for (int i = 0; i < l->argc; i++)
- fprintf(f, "%s %s%s", l->args[i].type->name, l->args[i].name, (i == l->argc - 1) ? "" : ", ");
+ compiletype_C(l->rtype, f);
+ fprintf(f, " %s(", l->fname);
+ for (int i = 0; i < l->argc; i++) {
+ compiletype_C(l->args[i].type, f);
+ fprintf(f, " %s%s", l->args[i].name, (i == l->argc - 1) ? "" : ", ");
+ }
fprintf(f, ") {\n");
indent++;
@@ -54,12 +86,25 @@ compileassign_C(lexpr *l, FILE *f) {
if (l->rexpr)
id = compilerexpr_C(l->rexpr, f);
putindent(f);
- fprintf(f, "%s %s", l->type->name, l->name);
+ compiletype_C(l->type, f);
+ fprintf(f, " %s", l->name);
if (l->rexpr)
fprintf(f, " = v%d;\n", id);
}
void
+compilereassign_C(lexpr *l, FILE *f) {
+ int id;
+ if (l->rexpr)
+ id = compilerexpr_C(l->rexpr, f);
+ putindent(f);
+ fprintf(f, "%s", l->name);
+ if (l->rexpr)
+ fprintf(f, " = v%d;\n", id);
+}
+
+
+void
compilelexpr_C(lexpr *l, FILE *f) {
switch (l->op) {
case LEXPR_FUNC:
@@ -68,5 +113,8 @@ compilelexpr_C(lexpr *l, FILE *f) {
case LEXPR_ASSIGN:
compileassign_C(l, f);
break;
+ case LEXPR_REASSIGN:
+ compilereassign_C(l, f);
+ break;
}
}
diff --git a/lexer.c b/lexer.c
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
#include "lexer.h"
@@ -11,11 +12,11 @@ lexErr(lex *l) {
exit(1);
}
-int
+uint64_t
lexNum(lex *l) {
- int n = atoi(l->ptr);
- while (isdigit(*l->ptr))
- l->ptr++;
+ char *end = NULL;
+ uint64_t n = strtoll(l->ptr, &end, 0);
+ l->ptr = end;
return n;
}
@@ -87,7 +88,7 @@ void
printTok(tok *t) {
switch (t->op) {
case INT:
- printf("INT: %d\n", t->n);
+ printf("INT: %ld\n", t->n);
break;
case LEOF:
printf("$\n");
diff --git a/lexer.h b/lexer.h
@@ -1,5 +1,6 @@
#ifndef __LEXER_H_
#define __LEXER_H_
+#include <stdint.h>
#include <string.h>
#define SAVE(lexer) lex __SAVE_LEX = *lexer;
@@ -29,7 +30,7 @@ enum lex_ops {
typedef struct tok {
enum lex_ops op;
union {
- int n;
+ int64_t n;
char *name;
};
} tok;
diff --git a/parse.c b/parse.c
@@ -153,26 +153,6 @@ parserexpr(tok *start, tok *end, mctx *ctx) {
return e;
}
-int
-eval(rexpr *e) {
- switch (e->op) {
- case INT:
- return e->n;
- case OBRACE:
- return eval(e->e);
- case NEGATE:
- return -eval(e->e);
- case ADD:
- return eval(e->expr[0]) + eval(e->expr[1]);
- case SUB:
- return eval(e->expr[0]) - eval(e->expr[1]);
- case MUL:
- return eval(e->expr[0]) * eval(e->expr[1]);
- case DIV:
- return eval(e->expr[0]) / eval(e->expr[1]);
- }
-}
-
type *
parsetype(lex *l, mctx *ctx) {
SAVE(l);
@@ -326,13 +306,48 @@ fullbody:
}
lexpr *
+parsereassign(lex *l, tok t, mctx *ctx) {
+ SAVE(l);
+ lexpr *le;
+ rexpr *r;
+ tok *args = NULL, tk;
+ int argc = 0;
+
+ if (next(l).op != ASSIGN) {
+ RESTORE(l);
+ return NULL;
+ }
+
+ for (tk = next(l); !isterm(tk); tk = next(l)) {
+ args = realloczctx(ctx, args, sizeof(tok) * (argc + 1));
+ args[argc++] = tk;
+ }
+ if (argc == 0) {
+ RESTORE(l);
+ return NULL;
+ }
+ if (!(r = parserexpr(&args[0], &args[argc - 1], ctx))) {
+ RESTORE(l);
+ return NULL;
+ }
+
+ le = alloczctx(ctx, sizeof(lexpr));
+ le->op = LEXPR_REASSIGN;
+ le->name = t.name;
+ le->rexpr = r;
+ return le;
+}
+
+lexpr *
parselexpr(lex *l, mctx *ctx) {
SAVE(l);
lexpr *le;
tok t = next(l);
switch (t.op) {
case NAME:
- le = parseassign(l, t, ctx);
+ if (!(le = parseassign(l, t, ctx))) {
+ le = parsereassign(l, t, ctx);
+ }
break;
case FUNC:
le = parsefunc(l, ctx); /* we can drop the FUNC token, as it doesnt hold any info */
diff --git a/parse.h b/parse.h
@@ -1,11 +1,13 @@
#ifndef __PARSE_H_
#define __PARSE_H_
+#include <stdint.h>
#include "lexer.h"
#include "util.h"
enum lexpr_ops {
LEXPR_ASSIGN,
LEXPR_FUNC,
+ LEXPR_REASSIGN,
};
enum type_types {
@@ -22,7 +24,7 @@ typedef struct rexpr {
struct rexpr *expr[2];
};
struct { /* litterals */
- int n;
+ uint64_t n;
};
};
} rexpr;
@@ -63,7 +65,6 @@ tok *findlowest(tok *start, tok *end);
rexpr *parsesimple(tok *start, tok *end, tok *lowest, mctx *ctx);
rexpr *parsebin(tok *start, tok *end, tok *lowest, mctx *ctx);
rexpr *parserexpr(tok *start, tok *end, mctx *ctx);
-int eval(rexpr *e);
type *parsetype(lex *l, mctx *ctx);
int isterm(tok t);
lexpr *parseassign(lex *l, tok name, mctx *ctx);
diff --git a/test.spl b/test.spl
@@ -1,4 +1,4 @@
-func main(arg1 int, arg2 int) int {
- a int = 0;
- a int = 1;
+func main(arg1 i32) i32 {
+ a i64 = 21474836470;
+ a = 1;
}