aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-24 19:52:42 +0200
committerlemon <lsof@mailbox.org>2022-08-24 19:52:42 +0200
commit4f479ac68028a89c8e545f72335642c42a5c4efe (patch)
treefb07ab4811c58f133edc6bcc7171f71945496d20
parent12e1b45da9b79247f4655332c298c08a2ad5c9b4 (diff)
slice and stuff
-rw-r--r--src/env.cff8
-rw-r--r--src/llvm.cff52
-rw-r--r--src/parse.cff2
-rw-r--r--vgcore.215350bin0 -> 7004160 bytes
4 files changed, 60 insertions, 2 deletions
diff --git a/src/env.cff b/src/env.cff
index 6bc24fe..04dc81d 100644
--- a/src/env.cff
+++ b/src/env.cff
@@ -32,12 +32,20 @@ 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());
+
case old.u.#tag == :Ty and decl.u.#tag == :Ty and old.u.Ty == decl.u.Ty;
+
case old.u.#tag == :Def and decl.u.#tag == :Def
and memcmp(&old.u.Def, &decl.u.Def, sizeof(old.u.Def)) == 0;
+
+ case old.u.#tag == :Static and decl.u.#tag == :Static
+ and memcmp(&old.u.Static, &decl.u.Static, sizeof(old.u.Static)) == 0;
+
case old.u.#tag == :Macro and decl.u.#tag == :Macro
and memcmp(&old.u.Macro, &decl.u.Macro, sizeof(old.u.Macro)) == 0;
+
case decl.u.#tag == :Let;
+
case env != old.myenv;
case else;
diff --git a/src/llvm.cff b/src/llvm.cff
index 5772f76..e64d2e3 100644
--- a/src/llvm.cff
+++ b/src/llvm.cff
@@ -232,16 +232,29 @@ fn genaddr(f *Fn, ex *Expr) Value {
case Dot dot;
let lhs = dot.lhs.ty->is(:Ptr) ? genexpr(f, dot.lhs) : genaddr(f, dot.lhs);
assert(dot.fld.off % dot.fld.ty.align == 0, "field align");
- let idx int = dot.fld - ex.ty.u.Agg.flds.#ptr;
+ let idx int #?;
+ if dot.lhs.ty->is(:Ptr) {
+ idx = dot.fld - dot.lhs.ty.u.Ptr.u.Agg.flds.#ptr;
+ } else {
+ idx = dot.fld - dot.lhs.ty.u.Agg.flds.#ptr;
+ }
let addr = mktmp(mkptrtype(ex.ty));
switch lhs.ty.u.Ptr.u.Agg.kind {
case :Struct;
gen("\t%v = getelementptr %t, %t %v, i32 0, i32 %d\n", addr, lhs.ty.u.Ptr, lhs.ty, lhs, idx);
case :Union;
gen("\t%v = bitcast %t %v to %v", addr, lhs.ty, lhs, addr.ty);
+ case else
+ assert(#f, "nyi eunion access");
}
return addr;
+ case EUTag eex;
+ let lhs = eex.ty->is(:Ptr) ? genexpr(f, eex) : genaddr(f, eex);
+ let addr = mktmp(mkptrtype(ex.ty));
+ gen("\t%v = bitcast %t %v to %v", addr, lhs.ty, lhs, addr);
+ return addr;
+
case AggIni ini;
let tmp = mktmp(mkptrtype(ex.ty));
gen("\t%v = alloca %t\n", tmp, ex.ty);
@@ -642,6 +655,13 @@ fn genexpr(f *Fn, ex *Expr) Value {
gen("\t%v = load %t, %t %v\n", tmp, ex.ty, addr.ty, addr);
return tmp;
+ case EUTag;
+ let tmp = mktmp(ex.ty);
+ let addr = genaddr(f, ex);
+ gen("\t%v = load %t, %t %v\n", tmp, ex.ty, addr.ty, addr);
+ return tmp;
+
+
case Cast it;
return convert(f, ex.ty, it);
@@ -655,6 +675,36 @@ fn genexpr(f *Fn, ex *Expr) Value {
gen("\t%v = load %t, %t %v\n", tmp, ex.ty, addr.ty, addr);
return tmp;
}
+
+ case Slice sl;
+ if sl.lhs.ty.u.#tag == :Arr {
+ assert(#f,"");
+ } else if sl.lhs.ty.u.#tag == :Ptr {
+ let addr = genexpr(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 == :Slice {
+ let slice = genexpr(f, sl.lhs);
+ let begin = convert(f, ty_usize, sl.begin);
+ let end = convert(f, ty_usize, sl.end);
+ let addr = mktmp(mkptrtype(slice.ty.u.Slice));
+ gen("\t%v = extractvalue %t %v, 0", addr, ex.ty, slice);
+ 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;
+ }
+
case Call call;
let lhs = genexpr(f, call.lhs);
let fnty = &(lhs.ty->is(:Ptr) ? lhs.ty.u.Ptr : lhs.ty).u.Fn;
diff --git a/src/parse.cff b/src/parse.cff
index 5a50e96..752165b 100644
--- a/src/parse.cff
+++ b/src/parse.cff
@@ -2794,7 +2794,7 @@ fn parsedecls(P *Parser, loc Loc, yield DeclYielder, yarg *void, toplevel bool)
let path = (tok = lexexpects(P, :str, "import path")).u.str.#ptr;
let decls = doimport(P, tok.loc, path);
foreach(decl, _, decls) {
- let decl = putdecl(P, tok.loc, decl);
+ let decl = putdecl(P, decl.loc, decl);
if yield {
yield(decl, yarg);
}
diff --git a/vgcore.215350 b/vgcore.215350
new file mode 100644
index 0000000..f55e2bf
--- /dev/null
+++ b/vgcore.215350
Binary files differ