diff options
Diffstat (limited to 'src/scTypes.ml')
-rw-r--r--[-rwxr-xr-x] | src/scTypes.ml | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/src/scTypes.ml b/src/scTypes.ml index 31dc799..e85b2f1 100755..100644 --- a/src/scTypes.ml +++ b/src/scTypes.ml @@ -167,19 +167,32 @@ module Expr = struct module T = Type.Eval(E.T) module R = Refs.Eval(E.R) - let eval e t = begin - - let rec eval_expr : t -> E.repr = function - | Ref r -> E.ref (R.eval_ref r) t - | Value v -> E.value (T.eval_type v) t - | Call0 ident -> E.call0 ident t - | Call1 (ident, p1) -> E.call1 ident (eval_expr p1) t - | Call2 (ident, p1, p2) -> E.call2 ident (eval_expr p1) (eval_expr p2) t - | Call3 (ident, p1, p2, p3) -> E.call3 ident (eval_expr p1) (eval_expr p2) (eval_expr p3) t - | CallN (ident, exprs) -> E.callN ident (List.map (fun x -> eval_expr x) exprs) t - | Expression e -> E.expression (eval_expr e) t - in - E.observe (eval_expr e) + let eval e t = begin + + let rec _eval v k = begin match v with + | Ref r -> k @@ E.ref (R.eval_ref r) t + | Value v -> k @@ E.value (T.eval_type v) t + | Call0 ident -> k @@ E.call0 ident t + | Call1 (ident, p1) -> + _eval p1 (fun v1 -> + k @@ E.call1 ident v1 t) + | Call2 (ident, p1, p2) -> + _eval p1 (fun v1 -> + _eval p2 (fun v2 -> + k @@ E.call2 ident v1 v2 t)) + | Call3 (ident, p1, p2, p3) -> + (_eval[@tailcall]) p1 (fun v1 -> + (_eval[@tailcall]) p2 (fun v2 -> + (_eval[@tailcall]) p3 (fun v3 -> + k @@ E.call3 ident v1 v2 v3 t))) + | CallN (ident, exprs) -> + let mapped = List.map (fun x -> _eval x (fun x -> x)) exprs in + k @@ E.callN ident mapped t + | Expression e -> + (_eval[@tailcall]) e (fun v1 -> k @@ E.expression v1 t) + end in + + E.observe (_eval e (fun x -> x)) end end |