commit cd52eda689ea5f02b61f126fd0ffc456a35391da
parent da26e040551f989e0a85f9c617625d833f7fc41c
Author: thing1 <thing1@seacrossedlovers.xyz>
Date: Sat, 17 Jan 2026 18:32:50 +0000
update
Diffstat:
7 files changed, 103 insertions(+), 18 deletions(-)
diff --git a/cback.c b/cback.c
@@ -55,6 +55,9 @@ compiletype_C(type *t, FILE *f) {
compiletype_C(t->nested, f);
fprintf(f, "*");
break;
+ case ARR:
+ fprintf(f, "array*");
+ break;
}
}
@@ -95,6 +98,10 @@ compilerexpr_C(rexpr *r, FILE *f) {
compiletype_C(r->type, f);
fprintf(f, " v%d = %s;\n", vid++, r->name);
return vid - 1;
+ case DQUOTE:
+ compiletype_C(r->type, f);
+ fprintf(f, " v%d;\n", vid++);
+ return vid - 1;
case FUNCALL:
right = compilefcall_C(r, f);
compiletype_C(r->type, f);
@@ -157,11 +164,23 @@ compilefunc_C(lexpr *l, FILE *f) {
void
compileassign_C(lexpr *l, FILE *f) {
- int id;
+ int id, sizeid;
if (l->rexpr)
id = compilerexpr_C(l->rexpr, f);
+ if (l->type->type == ARR && l->type->size)
+ sizeid = compilerexpr_C(l->type->size, f);
+
compiletype_C(l->type, f);
fprintf(f, " %s", l->name);
+
+ if (l->type->type == ARR) {
+ fprintf(f, " = newarray(");
+ if (l->type->size) fprintf(f, "v%d, sizeof(", sizeid);
+ else fprintf(f, "0, sizeof(");
+
+ compiletype_C(l->type->nested, f);
+ fprintf(f, "))");
+ }
if (l->rexpr)
fprintf(f, " = v%d;\n", id);
else
diff --git a/lexer.c b/lexer.c
@@ -69,6 +69,8 @@ next(lex *l) {
l->prev = l->ptr;
tok t = {0};
t.l = *l;
+ char *estring;
+
switch (*l->ptr) {
case 0:
t.op = LEOF;
@@ -81,6 +83,13 @@ next(lex *l) {
l->ptr++;
return next(l);
+ case DQUOTE:
+ t.op = DQUOTE;
+ *(estring = strchr(++l->ptr, '\"')) = 0;
+ t.name = strdup(l->ptr);
+ l->ptr = estring + 1;
+ return t;
+
case ADD:
case SUB:
case MUL:
@@ -89,6 +98,8 @@ next(lex *l) {
case CBRACE:
case OCBRACE:
case CCBRACE:
+ case OSBRACE:
+ case CSBRACE:
case ASSIGN:
case SEMI:
case COMMA:
diff --git a/lexer.h b/lexer.h
@@ -16,6 +16,9 @@ enum lex_ops {
CBRACE = ')',
OCBRACE = '{',
CCBRACE = '}',
+ OSBRACE = '[',
+ CSBRACE = ']',
+ DQUOTE = '\"',
LEOF = '$',
ASSIGN = '=',
SEMI = ';',
diff --git a/parse.c b/parse.c
@@ -56,6 +56,22 @@ isbasictype(char *t) {
return 0;
}
+type *
+mkbasictype(char *name, mctx *ctx) {
+ type *t = alloczctx(ctx, sizeof(type));
+ t->type = BASIC;
+ t->name = strdup(name);
+ return t;
+}
+
+type *
+mkarrtype(type *nested, mctx *ctx) {
+ type *t = alloczctx(ctx, sizeof(type));
+ t->type = ARR;
+ t->nested = nested;
+ return t;
+}
+
int
getpres(tok t) {
switch (t.op) {
@@ -142,13 +158,6 @@ findlowest(tok *start, tok *end) {
return lowest;
}
-type *
-mkbasictype(char *name, mctx *ctx) {
- type *t = alloczctx(ctx, sizeof(type));
- t->type = BASIC;
- t->name = strdup(name);
- return t;
-}
/* checks if t2 can be losslessly casted to t1 */
int
@@ -160,6 +169,8 @@ isequaltype(type *t1, type *t2) {
}
} else if (t1->type == PTR && t2->type == PTR)
return isequaltype(t1->nested, t2->nested);
+ else if (t1->type == ARR && t2->type == ARR)
+ return isequaltype(t1->nested, t2->nested);
return 0;
}
@@ -243,9 +254,18 @@ mkptrtype(type *t, mctx *ctx) {
}
rexpr *
+mklitteral(uint64_t n, type *t, mctx *ctx) {
+ rexpr *e = alloczctx(ctx, sizeof(rexpr));
+ e->type = t;
+ e->n = n;
+ return e;
+}
+
+rexpr *
parsesimple(tok *start, tok *end, tok *lowest, mctx *ctx) {
rexpr *e;
var *v;
+ tok *current;
switch (lowest->op) {
case NAME:
@@ -285,6 +305,15 @@ parsesimple(tok *start, tok *end, tok *lowest, mctx *ctx) {
break;
}
break;
+ case DQUOTE:
+ e = alloczctx(ctx, sizeof(rexpr));
+ e->op = DQUOTE;
+ for (e->elementc = 0; e->elementc < strlen(lowest->name); e->elementc++) {
+ e->elements = realloczctx(ctx, e->elements, (1 + e->elementc) * sizeof(rexpr));
+ e->elements[e->elementc] = *mklitteral(lowest->name[e->elementc], mkbasictype("i8", ctx), ctx);
+ }
+ e->type = mkarrtype(mkbasictype("i8", ctx), ctx);
+ break;
case OBRACE:
e = alloczctx(ctx, sizeof(rexpr));
e->op = OBRACE;
@@ -361,12 +390,30 @@ type *
parsetype(lex *l, mctx *ctx) {
SAVE(l);
type *ty;
- tok t = next(l);
+ tok t = next(l), *ts = NULL;
+ int tcount = 0;
ty = alloczctx(ctx, sizeof(type));
+
if (t.op == MUL) {
ty->type = PTR;
ty->nested = parsetype(l, ctx);
return ty;
+ } else if (t.op == OSBRACE) {
+ if ((t = next(l)).op != CSBRACE) {
+ do {
+ ts = realloczctx(ctx, ts, ++tcount * sizeof(tok));
+ ts[tcount - 1] = t;
+ } while ((t = next(l)).op != CSBRACE);
+ ty->size = parserexpr(ts, &ts[tcount - 1], ctx);
+ if (!isequaltype(mkbasictype("i64", ctx), ty->size->type)) {
+ parserErr("can not use non int type as array size", *l);
+ RESTORE(l);
+ return NULL;
+ }
+ }
+ ty->type = ARR;
+ ty->nested = parsetype(l, ctx);
+ return ty;
} else if (t.op != NAME) {
RESTORE(l);
return NULL;
diff --git a/parse.h b/parse.h
@@ -14,13 +14,19 @@ enum lexpr_ops {
enum type_types {
BASIC,
PTR,
+ ARR,
};
+typedef struct rexpr rexpr;
+
typedef struct type {
enum type_types type;
union {
char *name; /* basic types */
- struct type *nested; /* ptr types */
+ struct {
+ struct type *nested; /* ptr types */
+ rexpr *size;
+ };
};
} type;
@@ -44,6 +50,10 @@ typedef struct rexpr {
uint64_t n;
double f;
char *name;
+ struct { /* array litterals */
+ rexpr *elements;
+ int elementc;
+ };
};
} rexpr;
diff --git a/rt/array.c b/rt/array.c
@@ -9,8 +9,8 @@ array *
newarray(int cap, int size) {
cap = (!cap) ? 1 : cap;
array *a = malloc(sizeof(array));
- a->arr = malloc(cap);
- a->cap = cap;
+ a->arr = malloc(cap * size);
+ a->cap = cap * size;
a->len = 0;
a->size = size;
return a;
diff --git a/test.spl b/test.spl
@@ -1,8 +1,3 @@
-func foo() i32 {
- a i32 = 21;
- return a;
-}
-
func main() i32 {
- a i32 = i16(400);
+ arr []i8 = "hello world";
}