diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2024-02-07 21:08:35 -0800 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2024-02-19 14:24:27 -0800 |
| commit | bc2fef3a2ab81270af207568706647ced919bbe6 (patch) | |
| tree | bbb63738ec94757ff65554bcc8bc6a4ab2cfdef9 /elab.sml | |
| parent | Fix some bugs in the bytecode interpreter. (diff) | |
| download | sml-bc2fef3a2ab81270af207568706647ced919bbe6.tar.zst | |
Support function arguments.
Diffstat (limited to 'elab.sml')
| -rw-r--r-- | elab.sml | 36 |
1 files changed, 26 insertions, 10 deletions
@@ -1,31 +1,47 @@ structure Elab = struct + structure StringMap = Map(type k = string val cmp = String.compare); + fun primop (s : string) : Syntax.primop = case s of "exit" => Syntax.PExit | _ => raise Fail ("invalid op: " ^ s) - fun elaborate (p : Syntax.expr) : Syntax.lexp = + fun elab (env : int StringMap.map) (p : Syntax.expr) : Syntax.lexp = case p of - Syntax.EIdent [i] => raise Fail "only primitive operations for now, no variables" + Syntax.EIdent [i] => (case StringMap.lookup i env of + NONE => raise Fail ("unbound identifier " ^ i) + | SOME x => Syntax.LVar x) | Syntax.EIdent _ => raise Fail "long identifiers are not supported" | Syntax.EBuiltin builtin => Syntax.LPrim (primop builtin) | Syntax.EInt i => Syntax.LInt i | Syntax.EStr s => Syntax.LString s - | Syntax.ETuple exprs => Syntax.LRecord (map elaborate exprs) + | Syntax.ETuple exprs => Syntax.LRecord (map (elab env) exprs) | Syntax.EList exprs => foldr (fn (x, acc) => - Syntax.LRecord [elaborate x, acc]) + Syntax.LRecord [elab env x, acc]) (Syntax.LInt 0) exprs - | Syntax.EApp (f, x) => Syntax.LApp (elaborate f, elaborate x) - | Syntax.ETyped (e, _) => elaborate e + | Syntax.EApp (f, x) => Syntax.LApp (elab env f, elab env x) + | Syntax.ETyped (e, _) => elab env e | Syntax.EAndAlso (_, _) => raise Fail "unimplemented" | Syntax.EOrElse (_, _) => raise Fail "unimplemented" | Syntax.ELet (decls, body) => - Syntax.LRecord - (map elaborate - (map (fn (Syntax.DVal e) => e) decls @ [body])) - | Syntax.ELambda e => Syntax.LFn (Gensym.new (), elaborate e) + foldr + (fn (Syntax.DVal v, acc) => + Syntax.LApp (Syntax.LFn (Gensym.new (), acc), elab env v)) + (elab env body) + decls + | Syntax.ELambda (var, body) => + let + val v = Gensym.new () + val env' = + case var of + Syntax.PWild => env + | Syntax.PVar name => StringMap.insert name v env + in Syntax.LFn (v, elab env' body) + end + + fun elaborate (p : Syntax.expr) : Syntax.lexp = elab StringMap.empty p end |
