-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinfixing.sml
78 lines (76 loc) · 2.57 KB
/
infixing.sml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
structure Infixing : INFIXING = struct
(* exception that arises when unbound variable occur *)
exception UnboundVar of string
local
open Infixer
open ConcreteSyntax
in
fun reduceBinOp op1 (e1, e2) =
Syntax.APP (Syntax.VAR op1, Syntax.TUPLE [e1, e2])
fun infixing env (CONST c) = Syntax.CONST c
| infixing env (VAR x) = Syntax.VAR x
| infixing env (OP x) = Syntax.VAR x
| infixing env (IF (m, n1, n2)) =
let
val m' = infixing env m
val n1' = infixing env n1
val n2' = infixing env n2
in
Syntax.IF (m', n1', n2')
end
| infixing env (ABS (x, m)) =
Syntax.ABS (x, infixing env m)
| infixing env (LET (dec, m)) =
infixingLet [] env dec m
| infixing env (SEQ ms) =
let
fun lookahead (VAR x :: _) =
(case StringMap.find (env, x) of
SOME desc =>
Token.BINOP desc
| NONE =>
Token.EXP (Syntax.VAR x))
| lookahead (m :: _) =
Token.EXP (infixing env m)
| lookahead [] = Token.EOI
in
parseExp
{getToken = tl,
lookahead = lookahead,
reduceApp = Syntax.APP} ms
end
| infixing env (PAREN m) = infixing env m
| infixing env (TUPLE ms) =
Syntax.TUPLE (map (infixing env) ms)
| infixing env (CASE (m, xs, n)) =
let
val m' = infixing env m
val n' = infixing env n
in
Syntax.CASE (m', xs, n')
end
and infixingLet dec' env [] body =
Syntax.LET (rev dec', infixing env body)
| infixingLet dec' env (VAL (x, m) :: dec) body =
infixingLet (Syntax.VAL (x, infixing env m) :: dec') env dec body
| infixingLet dec' env (VALREC (f, m) :: dec) body =
infixingLet (Syntax.VALREC (f, infixing env m) :: dec') env dec body
| infixingLet dec' env (INFIX (assoc, d, vids) :: dec) body =
let
val env' =
foldl StringMap.insert' env
(map (fn vid =>
(vid, (reduceBinOp vid, d, assoc))) vids)
in
infixingLet dec' env' dec body
end
| infixingLet dec' env (NONFIX vids :: dec) body =
let
val env' =
foldl (fn (vid, env) =>
#1 (StringMap.remove (env, vid))) env vids
in
infixingLet dec' env' dec body
end
end
end