summaryrefslogtreecommitdiffstats
path: root/elab.sml
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2024-02-07 21:08:35 -0800
committerRose Hogenson <rosehogenson@posteo.net>2024-02-19 14:24:27 -0800
commitbc2fef3a2ab81270af207568706647ced919bbe6 (patch)
treebbb63738ec94757ff65554bcc8bc6a4ab2cfdef9 /elab.sml
parentFix some bugs in the bytecode interpreter. (diff)
downloadsml-bc2fef3a2ab81270af207568706647ced919bbe6.tar.zst
Support function arguments.
Diffstat (limited to 'elab.sml')
-rw-r--r--elab.sml36
1 files changed, 26 insertions, 10 deletions
diff --git a/elab.sml b/elab.sml
index 6a80715..032d1d7 100644
--- a/elab.sml
+++ b/elab.sml
@@ -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