feat(library/init/lean/compiler/ir/emitcpp): add some missing cases

This commit is contained in:
Leonardo de Moura 2019-05-21 10:21:52 -07:00
parent 510de7a3a9
commit cc4c26e8ab

View file

@ -247,12 +247,6 @@ emitLns [
"#pragma GCC diagnostic ignored \"-Wunused-but-set-variable\"",
"#endif"]
def isIf (alts : Array Alt) : Option (Nat × FnBody × FnBody) :=
if alts.size != 2 then none
else match alts.get 0 with
| Alt.ctor c b := some (c.cidx, b, (alts.get 1).body)
| _ := none
def throwUnknownVar {α : Type} (x : VarId) : M α :=
throw ("unknown variable '" ++ toString x ++ "'")
@ -279,20 +273,32 @@ partial def declareVars : FnBody → Bool → M Bool
| (FnBody.jdecl j xs _ b) d := declareParams xs *> declareVars b (d || xs.size > 0)
| e d := if e.isTerminal then pure d else declareVars e.body d
partial def emitCase (emitBody : FnBody → M Unit) (x : VarId) (alts : Array Alt) : M Unit :=
def emitTag (x : VarId) : M Unit :=
do
xIsObj ← isObj x,
if xIsObj then do
emit "lean::obj_tag(", emitVar x, emit ")"
else
emitVar x
def isIf (alts : Array Alt) : Option (Nat × FnBody × FnBody) :=
if alts.size != 2 then none
else match alts.get 0 with
| Alt.ctor c b := some (c.cidx, b, (alts.get 1).body)
| _ := none
def emitIf (emitBody : FnBody → M Unit) (x : VarId) (tag : Nat) (t : FnBody) (e : FnBody) : M Unit :=
do
emit "if (", emitTag x, emit " == ", emit tag, emitLn ")",
emitBody t,
emitLn "else",
emitBody e
def emitCase (emitBody : FnBody → M Unit) (x : VarId) (alts : Array Alt) : M Unit :=
match isIf alts with
| some (tag, t, e) := do
emit "if (", emitVar x, emit " == ", emit tag, emitLn ")",
emitBody t,
emitLn "else",
emitBody e
| some (tag, t, e) := emitIf emitBody x tag t e
| _ := do
xIsObj ← isObj x,
if xIsObj then do {
emit "switch (lean::obj_tag(", emitVar x, emitLn ")) {"
} else do {
emit "switch (", emitVar x, emitLn ") {"
},
emit "switch (", emitTag x, emitLn ") {",
alts.mfor $ λ alt, match alt with
| Alt.ctor c b := emit "case " *> emit c.cidx *> emitLn ":" *> emitBody b
| Alt.default b := emitLn "default: " *> emitBody b,
@ -342,12 +348,100 @@ do
},
emit "goto ", emitLabel j, emitLn ";"
def emitVDecl (x : VarId) (v : Expr) : M Unit :=
def emitLhs (z : VarId) : M Unit :=
do emitVar z, emit " = "
def emitCtor (z : VarId) (c : CtorInfo) (ys : Array Arg) : M Unit :=
pure () -- TODO
def emitReset (z : VarId) (x : VarId) : M Unit :=
pure () -- TODO
def emitReuse (z : VarId) (x : VarId) (c : CtorInfo) (updtHeader : Bool) (ys : Array Arg) : M Unit :=
pure () -- TODO
def emitProj (z : VarId) (i : Nat) (x : VarId) : M Unit :=
do emitLhs z, emit "lean::cnstr_get(", emitVar x, emit ", ", emit i, emitLn ");"
def emitUProj (z : VarId) (i : Nat) (x : VarId) : M Unit :=
pure () -- TODO
def emitSProj (z : VarId) (t : IRType) (n offset : Nat) (x : VarId) : M Unit :=
pure () -- TODO
def emitFullApp (z : VarId) (f : FunId) (ys : Array Arg) : M Unit :=
pure () -- TODO
def emitPartialApp (z : VarId) (f : FunId) (ys : Array Arg) : M Unit :=
pure () -- TODO
def emitApp (z : VarId) (f : VarId) (ys : Array Arg) : M Unit :=
pure () -- TODO
def emitBox (z : VarId) (t : IRType) (x : VarId) : M Unit :=
pure () -- TODO
def emitUnbox (z : VarId) (x : VarId) : M Unit :=
pure () -- TODO
def emitIsShared (z : VarId) (x : VarId) : M Unit :=
do emitLhs z, emit "!lean::is_exclusive(", emitVar x, emitLn ");"
def emitIsTaggedPtr (z : VarId) (x : VarId) : M Unit :=
do emitLhs z, emit "!lean::is_scalar(", emitVar x, emitLn ");"
def toHexDigit (c : Nat) : String :=
String.singleton c.digitChar
def quoteString (s : String) : String :=
let q := "\"" in
let q := s.foldl
(λ q c, q ++
if c == '\n' then "\\n"
else if c == '\n' then "\\t"
else if c == '\\' then "\\\\"
else if c == '\"' then "\\\""
else if c.toNat <= 31 || c.toNat >= 0x7f then
"\\x" ++ toHexDigit (c.toNat / 16) ++ toHexDigit (c.toNat % 16)
else String.singleton c )
q in
q ++ "\""
def emitNumLit (t : IRType) (v : Nat) : M Unit :=
if t.isObj then do
emit "lean::mk_nat_obj(",
if v < uint32Sz then emit v
else emit "lean::mpz(\"" *> emit v *> emit "\"",
emit ")"
else
emit v
def emitLit (z : VarId) (t : IRType) (v : LitVal) : M Unit :=
emitLhs z *>
match v with
| LitVal.num v := emitNumLit t v *> emitLn ";"
| LitVal.str v := do emit "lean::mk_string(", emit (quoteString v), emitLn ");"
def emitVDecl (z : VarId) (t : IRType) (v : Expr) : M Unit :=
match v with
| Expr.ctor c ys := emitCtor z c ys
| Expr.reset x := emitReset z x
| Expr.reuse x c u ys := emitReuse z x c u ys
| Expr.proj i x := emitProj z i x
| Expr.uproj i x := emitUProj z i x
| Expr.sproj n o x := emitSProj z t n o x
| Expr.fap c ys := emitFullApp z c ys
| Expr.pap c ys := emitPartialApp z c ys
| Expr.ap x ys := emitApp z x ys
| Expr.box t x := emitBox z t x
| Expr.unbox x := emitUnbox z x
| Expr.isShared x := emitIsShared z x
| Expr.isTaggedPtr x := emitIsTaggedPtr z x
| Expr.lit v := emitLit z t v
partial def emitBlock (emitBody : FnBody → M Unit) : FnBody → M Unit
| (FnBody.jdecl j xs v b) := emitBlock b
| (FnBody.vdecl x _ v b) := emitVDecl x v *> emitBlock b
| (FnBody.vdecl x t v b) := emitVDecl x t v *> emitBlock b
| (FnBody.inc x n c b) := emitInc x n c *> emitBlock b
| (FnBody.dec x n c b) := emitDec x n c *> emitBlock b
| (FnBody.release x i b) := emitRelease x i *> emitBlock b