-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathtoBytecode.wyv
69 lines (56 loc) · 2.71 KB
/
toBytecode.wyv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
module def toBytecode(javascript:JavaScript, js:Dyn)
import selfhost.types
import selfhost.bytecode
import wyvern.collections.llist
import selfhost.error
type List = llist.LinkedList
val b = bytecode(javascript, js)
def toBytecode(e:types.Statement):b.SeqExpr
b.SeqExpr(toBytecodeStmt(e))
def toBytecodeStmt(e:types.Statement):List[b.SeqStmt] = match e:
d:types.DeclStatement =>
val declBytecode = b.DeclStmt(toBytecodeDecl(d.decl))
val stmtBytecode = toBytecodeStmt(d.stmt)
llist.Cons[b.SeqStmt](declBytecode, stmtBytecode)
e:types.ExprStatement =>
llist.Singleton[b.SeqStmt](b.ExpStmt(toBytecodeExpr(e.exp)))
def toBytecodeDecl(e:types.Decl):b.Decl = match e:
v:types.Val => b.ValDecl(v.binding.name, toBytecodeExpr(v.exp))
d:types.Def => b.MethodDecl(d.binding.name, d.args.map[String](e => e.name.name), b.SeqExpr(toBytecodeStmt(d.body)))
t:types.TypeDecl => b.ValDecl("_", toBytecodeExpr(types.UnitVal()))
s:types.SubtypeDecl => b.ValDecl("_", toBytecodeExpr(types.UnitVal()))
m:types.TypeEq => b.ValDecl("_", toBytecodeExpr(types.UnitVal()))
default => error.report("not a declaration",error.unknownLocation)
def toBytecodeExpr(e:types.Exp):b.Expr = match e:
v:types.Var => b.VarExpr(v.binding.name)
c:types.Call => b.CallExpr(toBytecodeExpr(c.receiver), c.name, c.args.map[b.Expr](e => toBytecodeExpr(e)), false)
f:types.Field => b.AccessExpr(toBytecodeExpr(f.receiver), f.field)
// no lambda or app case - should have been lowered away
n:types.New => b.NewExpr(n.binding.name, n.body.map[b.Decl](d => toBytecodeDecl(d)))
i:types.Integer => b.IntLit(i.str)
u:types.UnitVal => b.IntLit("0")
def toFileBytecode(e:types.Statement):b.Bytecode
js.log("Converting expression to bytecode...\n")
val expBytecode = toBytecode(e)
//js.log(d.sequenceExpression.statements.get(0).declaration)
js.log("Creating top level bytecode...\n")
b.singletonBytecode(b.toplevel(expBytecode))
// takes the same thing as writeExpToFile
// encodes to protobuf bytes and decodes
// returns the same thing as b.loadBytecode
def encodeAndDecode(e:types.Statement): Dyn
val fileBytecode = toFileBytecode(e)
b.encodeAndDecode(fileBytecode)
def writeExpToFile(e:types.Statement, filename:String):Unit
val fileBytecode = toFileBytecode(e)
js.log("Actually saving...\n")
b.saveBytecode(filename, fileBytecode)
/*
// test code
val expr = b.StrLit("Hello")
b.encodeExpr(expr)
val apply = b.MethodDecl("apply", llist.Singleton[String]("x"), b.VarExpr("x"))
val expr2 = b.NewExpr("this", llist.Singleton[b.Decl](apply))
val callExpr = b.CallExpr(expr2, "apply", llist.Singleton[b.Expr](expr), false)
b.encodeExpr(callExpr)
*/