-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgrammar.scala
More file actions
108 lines (76 loc) · 2.84 KB
/
Copy pathgrammar.scala
File metadata and controls
108 lines (76 loc) · 2.84 KB
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package ulang.expr
import java.io._
import scala.language.postfixOps
import arse._
import arse.implicits._
import sourcecode.Name
object operators extends Syntax[Id] {
def is_mixfix_op(id: Id): Boolean = {
contains(id) || is_bind_op(id)
}
def is_bind_op(id: Id) = {
bind_ops contains id
}
var data: Set[Id] = Set()
var prefix_ops: Map[Id, Int] = Map()
var postfix_ops: Map[Id, Int] = Map()
var infix_ops: Map[Id, (Assoc, Int)] = Map(
builtin.eq.op -> (Non, 6))
var bind_ops: Set[Id] = Set()
}
object scanner {
// val string = scan("""\' ([^\']|\\\')* \' | \" ([^\"]|\\\")* \"""")
}
object grammar {
val keywords = Set(",", ";", "(", ")", "{", "}", "[", "]", "->", "`", "|", "\\", "_",
"as", "if", "then", "else", "let", "in", "match", "with", "end")
val name = S("""[^ \r\n\t\f()\[\],;\'\"`]+""") filterNot keywords
val names = name.*
val wildcard = Wildcard("_")
val anyatom = Id(name)
val atom = anyatom filterNot operators.is_mixfix_op
val bindatom = anyatom filter operators.is_bind_op
val pat: Mixfix[Id, Pat] = M(inner_pat, anyatom, UnApps, operators)
val pats = pat ~+ ","
val patarg: Parser[Pat] = P(("(" ~ patopen ~ ")") | patlist | wildcard | atom) ~ ("as" ~ atom).? map {
case pat ~ None => pat
case pat ~ Some(x: Var) => Named(pat, x)
case _ => ???
}
val patargs = patarg.+
val expr: Mixfix[Id, Expr] = M(inner_expr, anyatom, Apps, operators)
val exprs = expr ~+ ","
val arg: Parser[Expr] = P(("(" ~ open ~ ")") | lambda | binder | ite | /* matches | */ let | quote | any | list | atom)
val args = arg +
val abs = patargs ~ "->" ~ expr
val lambda = Lambda("\\" ~ abs)
val binder = App(bindatom ~ Lambda(abs))
val ite = ("if" ~ expr ~ "then" ~ expr ~ "else" ~ expr) map {
case test ~ left ~ right => builtin.IfThenElse(test, left, right)
}
// val matches = MatchWith("match" ~ args ~ "with" ~ bindings)
val eq = patarg ~ "=" ~ expr // TODO: pat_high instead of patarg
val eqs = eq ~+ ","
val let = LetIn("let" ~ eqs ~ "in" ~ expr)
val any = (string | char) map { Lit(_) }
val tuple = exprs map reify.tuple
val pattuple = pats map reify.tuple
val open = tuple | anyatom | ret(builtin.Tuple(): Expr)
val patopen = pattuple | anyatom | ret(builtin.Tuple(): Pat)
val inner_pat = (patarg +) map {
case Nil => ???
case fun :: args => UnApps(fun, args)
}
val inner_expr = args map {
case Nil => ???
case fun :: args => Apps(fun, args)
}
val quote = "`" ~ expr map reify.reify
val nil = ret(builtin.Nil)
val tail = (";" ~ expr) | nil
val cons = exprs ~ tail map { case (exprs, tail) => reify.list_with_tail(exprs, tail) }
val list = "[" ~ (cons | nil) ~ "]"
val pattail = (";" ~ pat) | nil
val uncons = pats ~ pattail map { case (pats, tail) => reify.list_with_tail(pats, tail) }
val patlist = "[" ~ (uncons | nil) ~ "]"
}