summaryrefslogtreecommitdiffstats
path: root/parser.sml
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2024-05-18 13:08:31 -0700
committerRose Hogenson <rosehogenson@posteo.net>2024-05-18 13:08:31 -0700
commit2581ac99323ead839964e9b5f2a799cf61fd5bdc (patch)
treea733c96894f4e8fb37dffb964f57fd39d9996d08 /parser.sml
parentFix case on datatype. (diff)
downloadsml-2581ac99323ead839964e9b5f2a799cf61fd5bdc.tar.zst
Allow pattern matching in function definitions.
Diffstat (limited to 'parser.sml')
-rw-r--r--parser.sml23
1 files changed, 14 insertions, 9 deletions
diff --git a/parser.sml b/parser.sml
index 8057873..08cb992 100644
--- a/parser.sml
+++ b/parser.sml
@@ -489,15 +489,20 @@ struct
then Syntax.DValRec (p, e)
else Syntax.DVal (p, e))))))
<|> (reserved "fun" >>
- bind identifier (fn name =>
- bind (many1 atpat) (fn args =>
- reserved "=" >>
- bind expr (fn body =>
- const
- (Syntax.DValRec
- ( Syntax.PVar name
- , foldr Syntax.ELambda body args
- ))))))) st
+ bind
+ (sepBy1
+ (bind identifier (fn name =>
+ bind (many1 atpat) (fn args =>
+ reserved "=" >>
+ bind expr (fn body =>
+ const (name, args, body)))))
+ (reserved "|")) (fn cases =>
+ let val (name, _, _) = hd cases
+ in
+ if not (List.all (fn (n, _, _) => n = name) cases)
+ then raise Fail "clauses do not all have same function name"
+ else const (Syntax.DFun (name, map (fn (_, x, y) => (x, y)) cases))
+ end))) st
val program : Syntax.expr parser = (fn decs => Syntax.ELet (decs, Syntax.EInt 0)) <$> many dec
fun parse (f : string) : (string, Syntax.expr) Result.either = runParser program f