spl

a Simple Programming Language
Log | Files | Refs

commit 8638dd399594573cf2ef8fb00fec751d9e06b44d
parent 2534cc1edbb10f19ce49f8286cf68f5962b9bfb3
Author: thing1 <thing1@seacrossedlovers.xyz>
Date:   Tue,  9 Dec 2025 22:27:16 +0000

started work on type system

Diffstat:
A.parse.h.swp | 0
Mcback.c | 58+++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mlexer.c | 11++++++-----
Mlexer.h | 3++-
Mparse.c | 57++++++++++++++++++++++++++++++++++++---------------------
Mparse.h | 5+++--
Mtest.spl | 6+++---
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; }