| Gt of ast * ast
| Geq of ast * ast
| If of ast * ast * ast
+ | Let of (string*ast) list * ast
+ | Var of string
+let find name table =
+ let rec sub i = function
+ [] ->
+ failwith @@ "no name: " ^ name
+ | x::xs ->
+ try
+ i,List.assoc name x
+ with Not_found ->
+ sub (i+1) xs in
+ sub 0 table
-let rec generate_expr ast =
+let scope_depth = function
+ [] -> 0
+ | (_,(scope,_))::_ -> scope
+
+let rec generate_expr ast table =
let expr ast =
- right (generate_expr ast) in
+ right (generate_expr ast table) in
let binary_op op l r =
Right ((expr l)@(expr r)@[op]) in
match ast with
exceptions=[];
traits=[];
instructions=inst}]
+ | Var name ->
+ let scope,slot =
+ List.assoc name table in
+ Right [GetScopeObject scope;
+ GetSlot slot]
+ | Let (vars,body) ->
+ let depth =
+ scope_depth table + 1 in
+ let table' =
+ (ExtList.List.mapi (fun i (name,_) -> name,(depth,i+1)) vars)@table in
+ let inits =
+ concatMap (fun (name,init)->
+ let scope,slot =
+ List.assoc name table' in
+ List.concat [ expr init;
+ [GetScopeObject scope;Swap;SetSlot slot]]) vars in
+ Right (List.concat [[NewObject 0; PushScope];
+ inits;
+ right @@ generate_expr body table'])
| Call (name,args) ->
let mname =
Cpool.QName ((Cpool.Namespace ""),name) in
let generate_method program =
- left @@ generate_expr program
+ left @@ generate_expr program []
let generate program =
let m =
function
String s -> Ast.String s
| Int n -> Ast.Int n
+ | Symbol name -> Ast.Var name
| List xs ->
begin match xs with
[Symbol "+";l;r] ->
Ast.Leq (make_ast l,make_ast r)
| [Symbol "if";t;c;a] ->
Ast.If (make_ast t,make_ast c,make_ast a)
+ | [(Symbol "let");List vars;body] ->
+ Ast.Let (List.map (fun (List [Symbol n;init]) -> (n,make_ast init)) vars,make_ast body)
| ((Symbol name)::args) ->
Ast.Call (name,List.map make_ast args)
| _ ->
SetLocal_3: op=0xD7; stack=1
SetLocal of int: op=0x63; stack=1; args=const [u30 arg0]
GetGlobalScope:op=0x64; stack=1
-GetScopeObject:op=0x65; stack=1
+GetScopeObject of int:op=0x65; stack=1; args=const[u8 arg0]
GetSlot of int:op=0x6c; args=const [u30 arg0]
SetSlot of int:op=0x6d; stack= ~2; args=const [u30 arg0]
GetGlobalSlot of int:op=0x6e; stack=1; args=const [u30 arg0]
CallPropLex of Cpool.multiname * int: op=0x4c; stack= ~-arg1; args=fun cmap->[multiname_get arg0 cmap;Bytes.u30 arg1]
Pop: op=0x29; stack= ~-1
Swap:op=0x2b
+
+NewObject of int:op=0x55; args=const [u30 arg0]
\ No newline at end of file