diff options
| author | 2022-08-22 13:07:20 +0200 | |
|---|---|---|
| committer | 2022-08-22 13:07:20 +0200 | |
| commit | c9bcf39a2ad78c7bc9cbfaab43e03771899cfa44 (patch) | |
| tree | bd3c305a3d6b558fde1f04e9683d0f97bb4f8620 | |
| parent | 135e66c64adf0ef5d2723c243d2f2f6a059ae753 (diff) | |
ir
| -rw-r--r-- | bootstrap/parse.c | 2 | ||||
| -rw-r--r-- | src/ir.hff | 4 | ||||
| -rw-r--r-- | src/irdump.cff | 7 | ||||
| -rw-r--r-- | src/irgen.cff | 73 | ||||
| -rw-r--r-- | src/parse.cff | 4 |
5 files changed, 86 insertions, 4 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c index 91c7567..99d317a 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -1809,7 +1809,7 @@ pexlog(struct parser *P) { struct expr rhs = pexcmp(P); if (tokt == '?\?') { const struct type *ty = typeof2(ex.ty, rhs.ty); - if (ex.ty->t != TYptr || rhs.ty->t != TYptr || !ty) + if (!(ex.ty->t == TYptr || rhs.ty->t == TYptr) || !ty) fatal(P, tok.span, "invalid operands %t and %t to binary operator %k", ex.ty, rhs.ty, tok.t); @@ -54,6 +54,10 @@ enum IRInstT { neq, lt, lteq, + ftrunc, + itof, + getelem, + pgetelem, copy, setvar, load, diff --git a/src/irdump.cff b/src/irdump.cff index ee68f91..9d31935 100644 --- a/src/irdump.cff +++ b/src/irdump.cff @@ -138,8 +138,13 @@ extern fn irdump(inst *IRInst) void { dump("\n"); continue #'dump; } + exprinst(:ftrunc, "ftrunc", 2); + exprinst(:itof, "itof", 2); + exprinst(:getelem, "getelem", 4); + exprinst(:pgetelem, "pgetelem", 4); + stmtinst(:nop, "nop", 0); - exprinst(:copy, "copy", 2) + exprinst(:copy, "copy", 2); if inst.t == :setvar { dump("set %a, %a\n", inst.args[0], inst.args[1]); continue #'dump; diff --git a/src/irgen.cff b/src/irgen.cff index 9d32bfd..e157406 100644 --- a/src/irgen.cff +++ b/src/irgen.cff @@ -54,6 +54,15 @@ struct InstStream { return inst; } + fn mkinst4(S *InstStream, inst0 IRInst, a IRArg, b IRArg, c IRArg, d IRArg) *IRInst { + let inst = S->mkinst(inst0, 4); + inst.args[0] = a; + inst.args[1] = b; + inst.args[2] = c; + inst.args[3] = d; + return inst; + } + fn pushnop(S *InstStream) *IRInst { S->push(S->mkinst({:nop}, 0)); return S.tail; @@ -190,6 +199,70 @@ fn genexpr(S *InstStream, ex *Expr) IRValue { } } + case Cast src; + let src = genexpr(S, src); + let ret = IRValue{ex.ty, .u: :Tmp(tmpid++)}; + switch { + case ex.ty->is(:Int) and src.ty->is(:Flo); + S->push(S->mkinst2({:ftrunc}, :Val(ret), :Val(src))); + + case ex.ty->is(:Flo) and src.ty->is(:Int); + S->push(S->mkinst2({:itof}, :Val(ret), :Val(src))); + + case ex.ty->is(:Int) and src.ty->is(:Int); + S->push(S->mkinst2({:copy}, :Val(ret), :Val(src))); + + case ex.ty->is(:Int) and src.ty->is(:Bool); + S->push(S->mkinst2({:copy}, :Val(ret), :Val(src))); + + case ex.ty->is(:Bool) and src.ty->is(:Int); + S->push(S->mkinst2({:copy}, :Val(ret), :Val(src))); + + case ex.ty->is(:Ptr) and src.ty->is(:Int); + S->push(S->mkinst2({:copy}, :Val(ret), :Val(src))); + + case ex.ty->is(:Int) and src.ty->is(:Ptr); + S->push(S->mkinst2({:copy}, :Val(ret), :Val(src))); + + case else + assert(#f, "bad cast"); + } + return ret; + + case Dot dot; + let lhs = genexpr(S, dot.lhs); + let res = IRValue{ex.ty, .u: :Tmp(tmpid++)}; + let inst = S->mkinst4({lhs.ty->is(:Ptr) ? :pgetelem : :getelem}, + :Val(res), :Val(lhs), :Val{ty_usize,:IImm(dot.fld.off)}, :Ty(ex.ty)); + S->push(inst); + return res; + + case SLen lhs; + let lhs = genexpr(S, lhs); + let res = IRValue{ex.ty, .u: :Tmp(tmpid++)}; + let inst = S->mkinst4({lhs.ty->is(:Ptr) ? :pgetelem : :getelem}, + :Val(res), :Val(lhs), :Val{ty_usize,:IImm(g_targ.ptrsize)}, + :Ty(ex.ty)); + S->push(inst); + return res; + + case SPtr lhs; + let lhs = genexpr(S, lhs); + let res = IRValue{ex.ty, .u: :Tmp(tmpid++)}; + let inst = S->mkinst4({lhs.ty->is(:Ptr) ? :pgetelem : :getelem}, + :Val(res), :Val(lhs), :Val{ty_usize,:IImm(0)}, :Ty(ex.ty)); + S->push(inst); + return res; + + case EUTag lhs; + let lhs = genexpr(S, lhs); + let res = IRValue{ex.ty, .u: :Tmp(tmpid++)}; + let inst = S->mkinst4({lhs.ty->is(:Ptr) ? :pgetelem : :getelem}, + :Val(res), :Val(lhs), :Val{ty_usize,:IImm(0)}, :Ty(ex.ty)); + S->push(inst); + return res; + + case Index idx; let i = genexpr(S, idx.lhs); let off = genexpr(S, idx.rhs); diff --git a/src/parse.cff b/src/parse.cff index 11c17cc..a1f0dd0 100644 --- a/src/parse.cff +++ b/src/parse.cff @@ -1609,8 +1609,8 @@ fn pexpostfix(P *Parser) Expr { ty = ty.u.Ptr; } switch ty.u { - case Slice; - ex = { tok.loc, ty_usize, :SPtr(exprdup(P.alloc, ex)) }; + case Slice sl; + ex = { tok.loc, mkptrtype(sl), :SPtr(exprdup(P.alloc, ex)) }; case else; fatal(P, ex.loc, "invalid operand to `#len' (%t)", ex.ty); } |