aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-25 18:08:54 +0200
committerlemon <lsof@mailbox.org>2022-08-25 18:08:54 +0200
commit09c083ea08b7436a9ca39734e5c6b82c6198746e (patch)
tree0c570c3f6e3becdca3989d189f638d71e304143f /src
parent9eeb4f4641481279895a927f97503d7a6938b2e5 (diff)
now test.cff kinda
Diffstat (limited to 'src')
-rw-r--r--src/env.cff1
-rw-r--r--src/llvm.cff74
-rw-r--r--src/parse.cff1
3 files changed, 64 insertions, 12 deletions
diff --git a/src/env.cff b/src/env.cff
index 04dc81d..d45e373 100644
--- a/src/env.cff
+++ b/src/env.cff
@@ -32,6 +32,7 @@ extern fn envput_alloc(env *Env, alloc *Allocator, decl Decl, old **const Decl)
switch {
case old.u.#tag == :Fn and decl.u.#tag == :Fn
and decl.u.Fn.ty == old.u.Fn.ty and (old.u.Fn.body->empty() or decl.u.Fn.body->empty());
+ decl.u.Fn.id = old.u.Fn.id;
case old.u.#tag == :Ty and decl.u.#tag == :Ty and old.u.Ty == decl.u.Ty;
diff --git a/src/llvm.cff b/src/llvm.cff
index ba4b556..3dcebe6 100644
--- a/src/llvm.cff
+++ b/src/llvm.cff
@@ -19,6 +19,7 @@ struct Value {
LocalRef *Var,
GlobalRef *Var,
Fn *Fn,
+ FnRef *Fn,
}
}
@@ -90,7 +91,8 @@ fn gen(fmt *const u8, ...) void {
case Ptr p; gen("ptr");
case Slice p; gen("{ %t, %t }", mkptrtype(p), ty_usize);
case Arr arr;
- gen("[%z x %t]", arr.length, arr.child);
+ assert(arr.length >= 0, "arr length");
+ gen("[%z x %t]", arr.length, arr.child);
case Agg;
genagg(ty);
case Enum enu; pritype(enu.intty);
@@ -138,13 +140,17 @@ fn gen(fmt *const u8, ...) void {
case 'I';
fprintf(outfp, "%lld", as(c_llong)ap->arg(i64));
case 'f';
- fprintf(outfp, "%.17f", ap->arg(f64));
+ let f f64 = as(f32)ap->arg(f64);
+ fprintf(outfp, "%#.16llx", *as(*u64)&f);
+ case 'F';
+ fprintf(outfp, "%e", ap->arg(f64));
case 'z';
fprintf(outfp, "%zu", ap->arg(usize));
case 'v';
- switch ap->arg(Value).u {
+ let val = ap->arg(Value);
+ switch val.u {
case IImm i; gen("%I", i);
- case FImm f; gen("%f", f);
+ case FImm f; gen(val.ty.size == 4 ? "%f" : "%F", f);
case BImm b; gen("%d", as(int)b);
case Null; gen("null");
case ZeroIni; gen("zeroinitializer");
@@ -164,6 +170,13 @@ fn gen(fmt *const u8, ...) void {
} else {
gen("@%s", decl.name);
}
+ case FnRef f;
+ let decl = container_of(f, Decl, u.Fn);
+ if !decl.externp {
+ gen("@%s.%d", decl.name, f.id);
+ } else {
+ gen("@%s", decl.name);
+ }
case StrConstRef id;
gen("@.str.%d", id);
@@ -206,6 +219,7 @@ fn genaddr(f *Fn, ex *Expr) Value {
switch decl.u {
case Let *var; return {mkptrtype(var.ty), :LocalRef(var)};
case Static *var; return {mkptrtype(var.ty), :GlobalRef(var)};
+ case Fn *f; return {mkptrtype(f.ty), :FnRef(f)};
}
case UnOp un;
switch un.op {
@@ -217,12 +231,19 @@ fn genaddr(f *Fn, ex *Expr) Value {
}
case Index idx;
let lhs Value #?;
- if idx.lhs.ty->is(:Arr) {
+ switch idx.lhs.ty.u {
+ case Arr arrty;
let arr = genaddr(f, idx.lhs);
lhs = mktmp(mkptrtype(ex.ty));
- gen("\t%v = getelementptr %t, %t %v, i32 0, i32 0\n", lhs, arr.ty.u.Arr.child, arr.ty, arr);
- } else {
+ gen("\t%v = getelementptr %t, %t %v, i32 0, i32 0\n", lhs, idx.lhs.ty, arr.ty, arr);
+ case Ptr;
lhs = genexpr(f, idx.lhs);
+ case Slice child;
+ let tmp = genexpr(f, idx.lhs);
+ lhs = mktmp(mkptrtype(child));
+ gen("\t%v = extractvalue %t %v, 0\n", lhs, tmp.ty, tmp);
+ case else;
+ assert(#f, "index");
}
let rhs = genexpr(f, idx.rhs),
addr = mktmp(mkptrtype(ex.ty));
@@ -271,7 +292,20 @@ fn genaddr(f *Fn, ex *Expr) Value {
case :Union;
gen("\t%v = bitcast %t %v to %t\n", ptr, tmp.ty, tmp, ptr.ty);
}
- gen("\tstore %t %v, %t %v\n", fex.ty, convert(f, fld.ty, fex), ptr.ty, ptr);
+ gen("\tstore %t %v, %t %v\n", fld.ty, convert(f, fld.ty, fex), ptr.ty, ptr);
+ }
+ return tmp;
+
+ case ArrIni ini;
+ let ty = mkarrtype(ini.maxn, #f, ex.ty.u.Arr.child);
+ let tmp = mktmp(mkptrtype(ty));
+ gen("\t%v = alloca %t\n", tmp, ty);
+ gen("\tstore %t zeroinitializer, %t %v\n", ty, tmp.ty, tmp);
+ foreach(idx, i, ini.idxs) {
+ let fex = &ini.exs[i];
+ let ptr = mktmp(mkptrtype(fex.ty));
+ gen("\t%v = getelementptr %t, %t %v, i32 0, i32 %d\n", ptr, ty, tmp.ty, tmp, idx);
+ gen("\tstore %t %v, %t %v\n", fex.ty, convert(f, ty.u.Arr.child, fex), ptr.ty, ptr);
}
return tmp;
}
@@ -695,7 +729,16 @@ fn genexpr(f *Fn, ex *Expr) Value {
case Slice sl;
if sl.lhs.ty.u.#tag == :Arr {
- assert(#f,"");
+ let addr = genaddr(f, sl.lhs);
+ let begin = convert(f, ty_usize, sl.begin);
+ let end = convert(f, ty_usize, sl.end);
+ let len = mktmp(ty_usize);
+ gen("\t%v = sub %t %v, %v\n", len, ty_usize, end, begin);
+ let tmp = mktmp(ex.ty);
+ gen("\t%v = insertvalue %t undef, %t %v, 0\n", tmp, ex.ty, addr.ty, addr);
+ let res = mktmp(ex.ty);
+ gen("\t%v = insertvalue %t %v, %t %v, 1\n", res, ex.ty, tmp, len.ty, len);
+ return res;
} else if sl.lhs.ty.u.#tag == :Ptr {
let addr = genexpr(f, sl.lhs);
let begin = convert(f, ty_usize, sl.begin);
@@ -755,6 +798,13 @@ fn genexpr(f *Fn, ex *Expr) Value {
gen("\t%v = load %t, %t %v\n", val, ex.ty, tmp.ty, tmp);
return val;
+ case ArrIni ini;
+ let ty = mkarrtype(ini.maxn, #f, ex.ty.u.Arr.child);
+ let tmp = genaddr(f, ex);
+ let val = mktmp(ty);
+ gen("\t%v = load %t, %t %v\n", val, ty, tmp.ty, tmp);
+ return val;
+
case EUnionIni ini;
let t0 = mktmp(mkptrtype(ex.ty));
let vidx = ini.var - ex.ty.u.Agg.flds.#ptr;
@@ -907,8 +957,8 @@ fn genstmt(f *Fn, block *Block, st *Stmt) void {
gen("\tswitch %t %v, label %%ISx%d [", test.ty, test);
foreach (c, i, sw.cs) {
foreach_ptr (ex, _, c.es) {
- let t = convert(f, test.ty, ex);
- gen(" %t %v, label %%IS%d.%d ", t.ty, t, id, i);
+ assert(ex.u.#tag == :IntLit or ex.u.#tag == :EnumIni, "case");
+ gen(" %t %I, label %%IS%d.%d ", test.ty, ex.u.IntLit.i, id, i);
}
}
gen(" ]\n");
@@ -1043,7 +1093,7 @@ struct GloblKeyTraits {
static globls Map<GloblKey, GloblEntry, GloblKeyTraits> = {};
extern fn llvm_addglobl(decl *Decl, staticp bool) void {
- assert(decl.toplevel, "llvm-addfn");
+ assert(decl.toplevel or decl.externp, "llvm-addfn %d", decl.u.#tag);
let slot = globls->get_slot({decl.name, decl.externp});
if slot.t != :Def {
slot.t = :Decl;
diff --git a/src/parse.cff b/src/parse.cff
index 0eb251d..3512c96 100644
--- a/src/parse.cff
+++ b/src/parse.cff
@@ -2584,6 +2584,7 @@ fn parsefn(P *Parser, loc Loc, toplevel bool, externp bool, name *const u8) *Dec
Fn.id = ++id;
// TODO tlalloc necessary for templates. but it leaks some memory
let decl = putdecl_alloc(P, P.tlalloc, loc, decl);
+ let Fn = &decl.u.Fn;
decl.toplevel = toplevel;
if !lexmatch(P, #null, '{') {