|  | 
|  | 1 | +open Base | 
|  | 2 | + | 
|  | 3 | +let pos x = Expr.Raw.Symbol ("+" ^ x) | 
|  | 4 | + | 
|  | 5 | +let neg x = Expr.Raw.Symbol ("-" ^ x) | 
|  | 6 | + | 
|  | 7 | +let out x = x ^ "_out" | 
|  | 8 | + | 
|  | 9 | +let func es = Expr.Raw.List es | 
|  | 10 | + | 
|  | 11 | +let var x = Expr.Raw.Var x | 
|  | 12 | + | 
|  | 13 | +let star es = Expr.Raw.Cons es | 
|  | 14 | + | 
|  | 15 | +let interact e = Expr.Raw.List [ Expr.Raw.Symbol "interact"; e ] | 
|  | 16 | + | 
|  | 17 | +let group es = Expr.Raw.Group es | 
|  | 18 | + | 
|  | 19 | +let def x t = Expr.Raw.List [ Expr.Raw.Symbol ":="; Expr.Raw.Symbol x; t ] | 
|  | 20 | + | 
|  | 21 | +let show x = Expr.Raw.List [ Expr.Raw.Symbol "show"; x ] | 
|  | 22 | + | 
|  | 23 | +let id x = Expr.Raw.Call (Expr.Raw.Symbol x) | 
|  | 24 | + | 
|  | 25 | +let add s = function | 
|  | 26 | +  | Expr.Raw.Cons es -> Expr.Raw.Cons (Expr.Raw.Symbol s :: es) | 
|  | 27 | +  | e -> Expr.Raw.Cons [ Expr.Raw.Symbol s; e ] | 
|  | 28 | + | 
|  | 29 | +let inject_lr = function | 
|  | 30 | +  | Expr.Raw.Cons [ Expr.Raw.List [ h1; a1 ]; Expr.Raw.List [ h2; a2 ] ] -> | 
|  | 31 | +    Expr.Raw.Cons | 
|  | 32 | +      [ Expr.Raw.List [ h1; add "l" a1 ]; Expr.Raw.List [ h2; add "r" a2 ] ] | 
|  | 33 | +  | _ -> failwith "Compiler error: could not apply inject_lr" | 
|  | 34 | + | 
|  | 35 | +(* FIXME *) | 
|  | 36 | +let rec compile_expr e = | 
|  | 37 | +  if not @@ Lambda.is_linear e then | 
|  | 38 | +    failwith | 
|  | 39 | +      (Printf.sprintf "Compiler error: term '%s' is not linear." | 
|  | 40 | +         (Lambda.to_string e) ); | 
|  | 41 | +  match e.content with | 
|  | 42 | +  | Lambda.Var _ -> | 
|  | 43 | +    [ star [ func [ pos e.loc; var "X" ]; func [ pos (out e.loc); var "X" ] ] ] | 
|  | 44 | +  | Lambda.Fun (_x, _t) -> | 
|  | 45 | +    [ star [ func [ pos e.loc; var "X" ]; func [ pos (out e.loc); var "X" ] ] | 
|  | 46 | +      |> inject_lr | 
|  | 47 | +    ] | 
|  | 48 | +  | Lambda.App (t1, t2) -> | 
|  | 49 | +    let cuts = | 
|  | 50 | +      star | 
|  | 51 | +        [ func [ neg (t1.loc ^ "_out"); var "X" ] | 
|  | 52 | +        ; func [ neg (t2.loc ^ "_out"); var "X" ] | 
|  | 53 | +        ] | 
|  | 54 | +    in | 
|  | 55 | +    let out = star [ func [ pos (e.loc ^ "_out"); var "X" ] ] in | 
|  | 56 | +    [ cuts; out ] @ compile_expr t1 @ compile_expr t2 | 
|  | 57 | + | 
|  | 58 | +let compile_decl = function | 
|  | 59 | +  | Lambda.Let (x, t) -> [ def x (group (compile_expr t)) ] | 
|  | 60 | +  | Lambda.Print x -> [ show (interact (id x)) ] | 
|  | 61 | + | 
|  | 62 | +let compile : Lambda.program -> Expr.Raw.t list = | 
|  | 63 | + fun e -> List.map ~f:compile_decl e |> List.concat | 
0 commit comments