yukigo-haskell-parser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mocharc.json +4 -0
- package/CHANGELOG.md +19 -0
- package/README.md +10 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/grammar.d.ts +28 -0
- package/dist/parser/grammar.js +404 -0
- package/dist/parser/grammar.js.map +1 -0
- package/dist/parser/layoutPreprocessor.d.ts +1 -0
- package/dist/parser/layoutPreprocessor.js +22 -0
- package/dist/parser/layoutPreprocessor.js.map +1 -0
- package/dist/parser/lexer.d.ts +42 -0
- package/dist/parser/lexer.js +75 -0
- package/dist/parser/lexer.js.map +1 -0
- package/dist/parser/preprocessor.d.ts +28 -0
- package/dist/parser/preprocessor.js +453 -0
- package/dist/parser/preprocessor.js.map +1 -0
- package/dist/prelude.d.ts +1 -0
- package/dist/prelude.js +205 -0
- package/dist/prelude.js.map +1 -0
- package/dist/typechecker/DeclarationCollector.d.ts +15 -0
- package/dist/typechecker/DeclarationCollector.js +80 -0
- package/dist/typechecker/DeclarationCollector.js.map +1 -0
- package/dist/typechecker/TypeBuilder.d.ts +12 -0
- package/dist/typechecker/TypeBuilder.js +113 -0
- package/dist/typechecker/TypeBuilder.js.map +1 -0
- package/dist/typechecker/checker.d.ts +80 -0
- package/dist/typechecker/checker.js +269 -0
- package/dist/typechecker/checker.js.map +1 -0
- package/dist/typechecker/core.d.ts +14 -0
- package/dist/typechecker/core.js +142 -0
- package/dist/typechecker/core.js.map +1 -0
- package/dist/typechecker/inference.d.ts +69 -0
- package/dist/typechecker/inference.js +984 -0
- package/dist/typechecker/inference.js.map +1 -0
- package/dist/utils/helpers.d.ts +2 -0
- package/dist/utils/helpers.js +25 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/types.d.ts +6 -0
- package/dist/utils/types.js +53 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +36 -0
- package/src/index.ts +55 -0
- package/src/parser/grammar.ne +463 -0
- package/src/parser/grammar.ts +512 -0
- package/src/parser/layoutPreprocessor.ts +21 -0
- package/src/parser/lexer.ts +77 -0
- package/src/parser/preprocessor.ne +375 -0
- package/src/parser/preprocessor.ts +502 -0
- package/src/prelude.ts +206 -0
- package/src/typechecker/DeclarationCollector.ts +104 -0
- package/src/typechecker/TypeBuilder.ts +148 -0
- package/src/typechecker/checker.ts +395 -0
- package/src/typechecker/core.ts +162 -0
- package/src/typechecker/inference.ts +1327 -0
- package/src/utils/helpers.ts +29 -0
- package/src/utils/types.ts +56 -0
- package/tests/parser.spec.ts +823 -0
- package/tests/prelude.spec.ts +22 -0
- package/tests/preprocessor.spec.ts +69 -0
- package/tests/typechecker.spec.ts +310 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import moo, { Lexer } from "moo";
|
|
2
|
+
import { keywords } from "../utils/types.js";
|
|
3
|
+
import { makeLexer } from "moo-ignore";
|
|
4
|
+
import IndentationLexer from "moo-indentation-lexer";
|
|
5
|
+
|
|
6
|
+
export const HaskellLexerConfig = {
|
|
7
|
+
NL: { match: /\r?\n/, lineBreaks: true },
|
|
8
|
+
anonymousVariable: "_",
|
|
9
|
+
WS: / |\t/,
|
|
10
|
+
comment: /--.*?$|{-[\s\S]*?-}/,
|
|
11
|
+
number:
|
|
12
|
+
/0[xX][0-9a-fA-F]+|0[bB][01]+|0[oO][0-7]+|(?:\d*\.\d+|\d+)(?:[eE][+-]?\d+)?/,
|
|
13
|
+
char: /'(?:\\['\\bfnrtv0]|\\u[0-9a-fA-F]{4}|[^'\\\n\r])?'/,
|
|
14
|
+
string: /"(?:\\["\\bfnrtv0]|\\u[0-9a-fA-F]{4}|[^"\\\n\r])*"/,
|
|
15
|
+
//template: /`(?:\\[\s\S]|[^\\`])*`/,
|
|
16
|
+
backtick: "`",
|
|
17
|
+
lparen: "(",
|
|
18
|
+
rparen: ")",
|
|
19
|
+
lbracket: "{",
|
|
20
|
+
rbracket: "}",
|
|
21
|
+
lsquare: "[",
|
|
22
|
+
rsquare: "]",
|
|
23
|
+
rangeOperator: "..",
|
|
24
|
+
semicolon: ";",
|
|
25
|
+
typeArrow: "->",
|
|
26
|
+
leftArrow: "<-",
|
|
27
|
+
typeEquals: "::",
|
|
28
|
+
question: "?",
|
|
29
|
+
arrow: "=>",
|
|
30
|
+
bool: {
|
|
31
|
+
match: ["True", "False"],
|
|
32
|
+
},
|
|
33
|
+
op: /,|>>=|>>|\\\\|\\|\.|\+\+|\+|\-|\*\*|\*|===|!==|==|\/=|<=|>=|<|>|&&|\/|\|\||\.\.|\$|\^\^|\^|#|@|~|!!|!|%|\?|:|&|\||`/,
|
|
34
|
+
assign: "=",
|
|
35
|
+
constructor: {
|
|
36
|
+
match: /[A-Z][a-zA-Z0-9']*/,
|
|
37
|
+
type: moo.keywords({
|
|
38
|
+
typeClass: [
|
|
39
|
+
"Foldable",
|
|
40
|
+
"Bounded",
|
|
41
|
+
"Enum",
|
|
42
|
+
"Eq",
|
|
43
|
+
"Floating",
|
|
44
|
+
"Fractional",
|
|
45
|
+
"Functor",
|
|
46
|
+
"Integral",
|
|
47
|
+
"Ix",
|
|
48
|
+
"Monad",
|
|
49
|
+
"MonadPlus",
|
|
50
|
+
"Num",
|
|
51
|
+
"Ord",
|
|
52
|
+
"Random",
|
|
53
|
+
"RandomGen",
|
|
54
|
+
"Read",
|
|
55
|
+
"Real",
|
|
56
|
+
"RealFloat",
|
|
57
|
+
"RealFrac",
|
|
58
|
+
"Show",
|
|
59
|
+
],
|
|
60
|
+
}),
|
|
61
|
+
},
|
|
62
|
+
variable: {
|
|
63
|
+
match: /[a-z_][a-zA-Z0-9_']*/,
|
|
64
|
+
type: moo.keywords({
|
|
65
|
+
otherwise: "otherwise",
|
|
66
|
+
error: "error",
|
|
67
|
+
keyword: keywords,
|
|
68
|
+
}),
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const HSLexer: Lexer = makeLexer(HaskellLexerConfig, []);
|
|
73
|
+
export const PreprocessorLexer: Lexer = new IndentationLexer({
|
|
74
|
+
lexer: moo.compile(HaskellLexerConfig),
|
|
75
|
+
indentationType: "WS",
|
|
76
|
+
newlineType: 'NL',
|
|
77
|
+
});
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
@{%
|
|
2
|
+
import { HSLexer } from "./lexer.js"
|
|
3
|
+
|
|
4
|
+
const filter = d => {
|
|
5
|
+
return d.filter((token) => token !== null);
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
%}
|
|
9
|
+
@preprocessor typescript
|
|
10
|
+
@lexer HSLexer
|
|
11
|
+
|
|
12
|
+
program ->
|
|
13
|
+
declaration:* {% (d) => d[0].filter(x => x !== null).join("\n") %}
|
|
14
|
+
| apply_operator {% id %}
|
|
15
|
+
|
|
16
|
+
declaration -> (function_declaration
|
|
17
|
+
| function_signature
|
|
18
|
+
| type_declaration
|
|
19
|
+
| data_declaration
|
|
20
|
+
| comment
|
|
21
|
+
| empty_line) {% (d) => d[0][0] %}
|
|
22
|
+
|
|
23
|
+
comment -> %comment {% d => null %}
|
|
24
|
+
|
|
25
|
+
empty_line -> _ %NL {% d => null %}
|
|
26
|
+
|
|
27
|
+
expression ->
|
|
28
|
+
(type_cast
|
|
29
|
+
| letin_expression
|
|
30
|
+
| if_expression
|
|
31
|
+
| case_expression) {% (d) => `${d[0][0]}` %}
|
|
32
|
+
|
|
33
|
+
type_cast -> apply_operator _ "::" _ type {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
34
|
+
| apply_operator {% (d) => d[0] %}
|
|
35
|
+
|
|
36
|
+
# Operation rules
|
|
37
|
+
|
|
38
|
+
apply_operator ->
|
|
39
|
+
logical_expression _ "$" _ apply_operator {% (d) => `${d[0]} $ ${d[4]}` %}
|
|
40
|
+
| logical_expression {% (d) => d[0] %}
|
|
41
|
+
|
|
42
|
+
logical_expression ->
|
|
43
|
+
comparison _ "&&" _ logical_expression {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
44
|
+
| comparison _ "||" _ logical_expression {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
45
|
+
| comparison {% (d) => d[0] %}
|
|
46
|
+
|
|
47
|
+
comparison ->
|
|
48
|
+
cons_expression _ comparison_operator _ cons_expression {% (d) => `${d[0]} ${d[2]} ${d[4]}` %}
|
|
49
|
+
| cons_expression {% (d) => d[0] %}
|
|
50
|
+
|
|
51
|
+
cons_expression ->
|
|
52
|
+
concatenation _ ":" _ cons_expression {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
53
|
+
| concatenation {% (d) => d[0] %}
|
|
54
|
+
|
|
55
|
+
concatenation ->
|
|
56
|
+
addition _ "++" _ concatenation {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
57
|
+
| addition {% (d) => d[0] %}
|
|
58
|
+
|
|
59
|
+
addition ->
|
|
60
|
+
addition _ "+" _ multiplication {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
61
|
+
| addition _ "-" _ multiplication {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
62
|
+
| multiplication {% (d) => d[0] %}
|
|
63
|
+
|
|
64
|
+
multiplication ->
|
|
65
|
+
multiplication _ "*" _ power {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
66
|
+
| multiplication _ "/" _ power {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
67
|
+
| power {% (d) => d[0] %}
|
|
68
|
+
|
|
69
|
+
power ->
|
|
70
|
+
unary_negation _ "**" _ power {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
71
|
+
| unary_negation _ "^" _ power {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
72
|
+
| unary_negation _ "^^" _ power {% (d) => `${d[0]} ${d[2].value} ${d[4]}` %}
|
|
73
|
+
| unary_negation {% (d) => d[0] %}
|
|
74
|
+
|
|
75
|
+
unary_negation ->
|
|
76
|
+
"-" _ unary_negation {% (d) => `-${d[2]}` %}
|
|
77
|
+
| index_access {% (d) => d[0] %}
|
|
78
|
+
|
|
79
|
+
index_access ->
|
|
80
|
+
index_access _ "!!" _ composition_expression {% (d) => `${d[0]} !! ${d[4]}` %}
|
|
81
|
+
| composition_expression {% d => d[0] %}
|
|
82
|
+
|
|
83
|
+
composition_expression ->
|
|
84
|
+
composition_expression _ "." _ infix_operator_expression {% (d) => `${d[0]} . ${d[4]}` %}
|
|
85
|
+
| infix_operator_expression {% d => d[0] %}
|
|
86
|
+
|
|
87
|
+
infix_operator_expression ->
|
|
88
|
+
infix_operator_expression _ "`" _ variable _ "`" _ application {% (d) => `${d[0]} \`${d[4]}\` ${d[8]}` %}
|
|
89
|
+
| application {% d => d[0] %}
|
|
90
|
+
|
|
91
|
+
application ->
|
|
92
|
+
"error" __ primary {% d => `error ${d[2]}` %}
|
|
93
|
+
| primary ((__ | _ %NL __) primary):* {% (d) => {
|
|
94
|
+
if (d[1].length === 0) return d[0];
|
|
95
|
+
return [d[0], ...d[1].map(x => x[1])].join(" ");
|
|
96
|
+
} %}
|
|
97
|
+
|
|
98
|
+
operator ->
|
|
99
|
+
("=="
|
|
100
|
+
| "/="
|
|
101
|
+
| "<"
|
|
102
|
+
| ">"
|
|
103
|
+
| "<="
|
|
104
|
+
| ">="
|
|
105
|
+
| "++"
|
|
106
|
+
| "+"
|
|
107
|
+
| ","
|
|
108
|
+
| "*"
|
|
109
|
+
| "/"
|
|
110
|
+
| ":") {% (d) => d[0][0].value %}
|
|
111
|
+
|
|
112
|
+
left_section -> "(" _ expression _ operator _ ")" {% (d) => `(${d[2]} ${d[4]})`%}
|
|
113
|
+
|
|
114
|
+
right_section -> "(" _ operator _ expression _ ")" {% (d) => `(${d[2]} ${d[4]})`%}
|
|
115
|
+
|
|
116
|
+
operator_section -> "(" _ operator _ ")" {% (d) => `(${d[2]})` %}
|
|
117
|
+
|
|
118
|
+
primary ->
|
|
119
|
+
primitive {% (d) => d[0] %}
|
|
120
|
+
#| primitive_operator {% (d) => d[0] %}
|
|
121
|
+
| variable {% (d) => d[0] %}
|
|
122
|
+
| constr {% (d) => d[0] %}
|
|
123
|
+
| tuple_expression {% (d) => d[0] %}
|
|
124
|
+
| left_section {% (d) => d[0] %}
|
|
125
|
+
| right_section {% (d) => d[0] %}
|
|
126
|
+
| operator_section {% (d) => d[0] %}
|
|
127
|
+
| "(" _ expression _ ")" {% (d) => `(${d[2]})` %}
|
|
128
|
+
| "[" _ range_expression _ "]" {% (d) => `[${d[2]}]` %}
|
|
129
|
+
| list_literal {% (d) => d[0] %}
|
|
130
|
+
| lambda_expression {% (d) => d[0] %}
|
|
131
|
+
| data_expression {% d => d[0] %}
|
|
132
|
+
| list_comprehension {% (d) => d[0] %}
|
|
133
|
+
|
|
134
|
+
# Expression rules
|
|
135
|
+
|
|
136
|
+
# List comprehension rules
|
|
137
|
+
list_comprehension ->
|
|
138
|
+
"[" _ expression _ "|" _ comprehension_clause_list _ "]" {% (d) => `[${d[2]} | ${d[6]}]` %}
|
|
139
|
+
|
|
140
|
+
comprehension_clause_list ->
|
|
141
|
+
comprehension_clause (_ "," _ comprehension_clause):* {% (d) => [d[0], ...d[1].map((x) => x[3])].join(`, `) %}
|
|
142
|
+
|
|
143
|
+
comprehension_clause ->
|
|
144
|
+
variable _ "<-" _ expression {% (d) => `${d[0]} <- ${d[4]}` %}
|
|
145
|
+
| expression {% (d) => d[0] %}
|
|
146
|
+
|
|
147
|
+
lambda_expression ->
|
|
148
|
+
"(" _ "\\" _ parameter_list _ "->" (_ | _ %NL __) expression (_ | _ %NL __) ")" {% (d) => `(\\${d[4]} -> ${d[8]})` %}
|
|
149
|
+
|
|
150
|
+
tuple_expression -> "(" _ tuple_value (_ "," _ tuple_value):+ _ ")" {% (d) => `(` + [d[2], ...d[3].map(x => `,${x[3]}`)].join(``) + `)` %}
|
|
151
|
+
tuple_value -> expression {% d => d[0] %}
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
data_expression -> constr _ %lbracket _ fields_expressions _ %rbracket {%
|
|
155
|
+
(d) => d[0] + ` { ` + d[4] + ` }`
|
|
156
|
+
%}
|
|
157
|
+
|
|
158
|
+
fields_expressions -> field_exp (_ "," _ field_exp):* {% (d) => [d[0], ...d[1].map(x => x[3])].join(", ") %}
|
|
159
|
+
|
|
160
|
+
field_exp -> variable _ "=" _ expression {% (d) => d[0] + ` = ` + d[4] %}
|
|
161
|
+
|
|
162
|
+
if_expression ->
|
|
163
|
+
"if" (__ | (_ %NL _)) expression (__ | (_ %NL _)) "then" (__ | (_ %NL __)) expression (__ | (_ %NL _)) "else" (__ | (_ %NL __)) expression {%
|
|
164
|
+
(d) => `if ` + d[2] + ` then ` + d[6] + ` else ` + d[10]
|
|
165
|
+
%}
|
|
166
|
+
|
|
167
|
+
letin_expression -> "let" (_ | (_ "{" _) | (_ %NL __)) bindings_list:? (_ | (_ "}" _) | (_ %NL __)) "in" ((_ %NL __) | _) expression {% (d) => `let { ${(d[2] ?? ``)} }` + ` in ` + d[6] %}
|
|
168
|
+
|
|
169
|
+
case_expression ->
|
|
170
|
+
"case" ((_ %NL __) | _) expression ((_ %NL __) | _) "of" (_ | (_ "{" _) | (_ %NL __)) case_arms (_ "}" _):? {% (d) => `case ${d[2]} of { ${d[6]} }` %}
|
|
171
|
+
|
|
172
|
+
case_arms ->
|
|
173
|
+
case_arm (((_ %NL __) | (_ ";" _)) case_arm):* {% (d) => [d[0], ...d[1].map(x => x[1])].join("; ") %}
|
|
174
|
+
|
|
175
|
+
case_arm ->
|
|
176
|
+
pattern ((_ %NL __) | _) "->" ((_ %NL __) | _) expression {% (d) => d[0] + ` -> ` + d[4] %}
|
|
177
|
+
|
|
178
|
+
# Data rules
|
|
179
|
+
|
|
180
|
+
data_declaration -> "data" __ constr (__ type_variable):* _ "=" _ constructor_def (_ "|" _ constructor_def):* deriving_clause:? {%
|
|
181
|
+
(d) => `data ` + d[2] + (d[3] ? ` ` + d[3].map(x => x[1]).join(" ") : ``) + ` = ` + [d[7], ...d[8].map(x => `| ${x[3]}`)].join(" ") + (d[9] ?? ``)
|
|
182
|
+
%}
|
|
183
|
+
|
|
184
|
+
deriving_clause ->
|
|
185
|
+
__ "deriving" _ deriving_spec {% (d) => ` deriving ` + d[3] %}
|
|
186
|
+
|
|
187
|
+
deriving_spec ->
|
|
188
|
+
"(" _ deriving_classes _ ")" {% (d) => `(${d[2]})` %}
|
|
189
|
+
| constr {% (d) => d[0] %}
|
|
190
|
+
|
|
191
|
+
deriving_classes ->
|
|
192
|
+
%typeClass (_ "," _ %typeClass):* {% (d) => [d[0].value, ...d[1].map(x => x[3].value)].join(", ") %}
|
|
193
|
+
|
|
194
|
+
constructor_def ->
|
|
195
|
+
constr _ (%NL __):? %lbracket _ (%NL _):? field_list _ (%NL _):? %rbracket {% (d) => d[0] + ` { ` + d[6] + ` }` %}
|
|
196
|
+
| constr (__ simple_type):* {% (d) => [d[0], ...d[1].map(x => x[1])].join(" ") %}
|
|
197
|
+
|
|
198
|
+
field_list -> field (_ "," _ (%NL _):? field):* {% (d) => [d[0], ...d[1].map(x => x[4])].join(", ") %}
|
|
199
|
+
|
|
200
|
+
field -> variable _ %typeEquals _ type {% (d) => d[0] + ` :: ` + d[4] %}
|
|
201
|
+
|
|
202
|
+
# Function rules
|
|
203
|
+
|
|
204
|
+
binding_name ->
|
|
205
|
+
"(" _ %op _ ")" {% d => `(${d[2].value})` %}
|
|
206
|
+
| variable {% d => d[0] %}
|
|
207
|
+
|
|
208
|
+
function_signature ->
|
|
209
|
+
binding_name (_ "," _ binding_name):* _ %typeEquals (_ | (_ %NL __)) type {% (d) => [`${d[0]} :: ${d[5]}`, ...d[1].map(x => `${x[3]} :: ${d[5]}`)].join("\n") %}
|
|
210
|
+
|
|
211
|
+
function_declaration ->
|
|
212
|
+
variable equation {% (d) => d[0] + d[1] %}
|
|
213
|
+
| "(" _ %op _ ")" equation {% (d) => `(${d[2]})` + d[5] %}
|
|
214
|
+
|
|
215
|
+
return_expression -> expression {% d => d[0] %}
|
|
216
|
+
|
|
217
|
+
where_clause -> "where" (_ | (_ "{" _) | (_ %NL __)) bindings_list (_ | (_ "}" _)) {% d => `where { ${d[2]} }` %}
|
|
218
|
+
|
|
219
|
+
bindings_list -> function_declaration (((_ ";" _) | (_ %NL __)) function_declaration):* {% d => [d[0], ...d[1].map(x => x[1])].join('; ') %}
|
|
220
|
+
|
|
221
|
+
equation ->
|
|
222
|
+
params (%NL __):? guarded_rhs (((_ %NL __) | _) where_clause):? {% (d) => {
|
|
223
|
+
const body = d[2];
|
|
224
|
+
const whereClause = d[3] ? ` ` + d[3][1] : ``;
|
|
225
|
+
return d[0] + ` ` + body + whereClause;
|
|
226
|
+
} %}
|
|
227
|
+
| params %assign ((_ %NL __) | _) return_expression (((_ %NL __) | _) where_clause):? {% d => d[0] + ` = ` + d[3] + (d[4] ? ` ` + d[4][1] : ``) %}
|
|
228
|
+
|
|
229
|
+
params ->
|
|
230
|
+
__ parameter_list _ {% d => ` ${d[1]}` %}
|
|
231
|
+
| _ {% d => `` %}
|
|
232
|
+
|
|
233
|
+
guarded_rhs ->
|
|
234
|
+
guarded_branch ((_ %NL __) | _) guarded_rhs {% (d) => `${d[0]} ${d[2]}` %}
|
|
235
|
+
| guarded_branch {% (d) => d[0] %}
|
|
236
|
+
|
|
237
|
+
guarded_branch ->
|
|
238
|
+
"|" ((_ %NL __) | _) condition ((_ %NL __) | _) "=" ((_ %NL __) | _) expression {% (d) => `| ${d[2]} = ${d[6]}` %}
|
|
239
|
+
|
|
240
|
+
condition ->
|
|
241
|
+
"otherwise" {% d => `otherwise` %}
|
|
242
|
+
| expression {% d => d[0] %}
|
|
243
|
+
|
|
244
|
+
parameter_list -> pattern (__ pattern):* {% (d) => [d[0], ...d[1].map(x => x[1])].join(" ") %}
|
|
245
|
+
|
|
246
|
+
# Patterns
|
|
247
|
+
|
|
248
|
+
pattern -> ("~" _):? cons_pattern {% (d) => d[1] %}
|
|
249
|
+
|
|
250
|
+
cons_pattern ->
|
|
251
|
+
"(" _ cons_pattern (_ ":" _ cons_pattern):+ _ ")" {% (d) => `(${[d[2], ...d[3].map(x => x[3])].join(":")})` %}
|
|
252
|
+
| simple_pattern {% (d) => d[0] %}
|
|
253
|
+
|
|
254
|
+
simple_pattern ->
|
|
255
|
+
(as_pattern
|
|
256
|
+
| constructor_pattern
|
|
257
|
+
| list_pattern
|
|
258
|
+
| tuple_pattern
|
|
259
|
+
#| record_pattern
|
|
260
|
+
| literal_pattern
|
|
261
|
+
| variable_pattern
|
|
262
|
+
| wildcard_pattern
|
|
263
|
+
| paren_pattern) {% (d) => d[0][0] %}
|
|
264
|
+
|
|
265
|
+
wildcard_pattern -> %anonymousVariable {% (d) => `_` %}
|
|
266
|
+
|
|
267
|
+
paren_pattern -> "(" _ pattern _ ")" {% (d) => `(${d[2]})` %}
|
|
268
|
+
|
|
269
|
+
variable_pattern -> variable {% (d) => d[0] %}
|
|
270
|
+
|
|
271
|
+
literal_pattern -> primitive {% (d) => d[0] %}
|
|
272
|
+
|
|
273
|
+
as_pattern -> (variable_pattern | wildcard_pattern) "@" pattern {% (d) => d[0][0] + `@` + d[2] %}
|
|
274
|
+
|
|
275
|
+
constructor_pattern ->
|
|
276
|
+
"(" _ constr (__ pattern):+ _ ")" {% (d) => `(${[d[2], ...d[3].map(x => x[1])].join(" ")})` %}
|
|
277
|
+
| constr {% (d) => `${d[0]}` %}
|
|
278
|
+
|
|
279
|
+
# record_pattern ->
|
|
280
|
+
# constr:? _ %lbracket _ field_pattern_list _ %rbracket {% (d) => ({
|
|
281
|
+
# type: "RecordPattern",
|
|
282
|
+
# constructor: d[0] ? d[0].value : null,
|
|
283
|
+
# fields: d[4]
|
|
284
|
+
# }) %}
|
|
285
|
+
|
|
286
|
+
field_pattern_list -> field_pattern (_ "," _ field_pattern):* {% (d) => [d[0], ...d[1].map(x => x[3])].join(`, `) %}
|
|
287
|
+
|
|
288
|
+
field_pattern -> variable _ "=" _ pattern {% (d) => d[0] + ` = ` + d[4] %}
|
|
289
|
+
|
|
290
|
+
list_pattern -> "[" _ pattern_list:? _ "]" {% (d) => `[${d[2] ?? ``}]` %}
|
|
291
|
+
|
|
292
|
+
pattern_list -> pattern (_ "," _ pattern):* {% (d) => [d[0], ...d[1].map(x => x[3])].join(`, `) %}
|
|
293
|
+
|
|
294
|
+
tuple_pattern -> "(" _ pattern (_ "," _ pattern):+ _ ")" {% (d) => `(${[d[2], ...d[3].map(x => x[3])].join(`, `)})` %}
|
|
295
|
+
|
|
296
|
+
# Type rules
|
|
297
|
+
|
|
298
|
+
type_declaration -> "type" __ constr (__ variable_list):? _ "=" _ type {% (d) => {
|
|
299
|
+
const varList = d[3] ? ` ` + d[3][1] : ``
|
|
300
|
+
|
|
301
|
+
return `type ${d[2]}` + varList + ` = ${d[7]}`
|
|
302
|
+
} %}
|
|
303
|
+
|
|
304
|
+
variable_list -> variable (__ variable):* {% (d) => [d[0], ...d[1].map(x => x[1])].join(" ") %}
|
|
305
|
+
|
|
306
|
+
type -> function_type {% d => d[0] %}
|
|
307
|
+
|
|
308
|
+
constrained_type -> constraint_list _ %arrow _ type {% (d) => d[0] + ` -> ` + d[4] %}
|
|
309
|
+
|
|
310
|
+
context ->
|
|
311
|
+
constraint {% (d) => d[0] %}
|
|
312
|
+
| "(" _ constraint_list _ ")" {% (d) => `(${d[2]})` %}
|
|
313
|
+
|
|
314
|
+
constraint_list ->
|
|
315
|
+
constraint (_ "," _ constraint):* {% (d) =>
|
|
316
|
+
[d[0], ...d[1].map(x => x[3])].join(", ")
|
|
317
|
+
%}
|
|
318
|
+
|
|
319
|
+
constraint -> %typeClass (_ application_type):+ {% (d) => [d[0].value, ...d[1].map(x => x[1])].join(" ") %}
|
|
320
|
+
|
|
321
|
+
function_type ->
|
|
322
|
+
(context _ %arrow _):? (application_type (_ | (_ %NL __)) %typeArrow (_ | (_ %NL __))):* application_type {% (d) => {
|
|
323
|
+
const constraints = d[0] ? `${d[0][0]} => ` : ``;
|
|
324
|
+
const inputs = [...d[1].map(x => x[0]), d[2]].join(" -> ")
|
|
325
|
+
return constraints + inputs
|
|
326
|
+
}
|
|
327
|
+
%}
|
|
328
|
+
|
|
329
|
+
application_type ->
|
|
330
|
+
simple_type (_ simple_type):+ {% (d) => [d[0], ...d[1].map(x => x[1])].join(" ") %}
|
|
331
|
+
| simple_type {% (d) => d[0] %}
|
|
332
|
+
|
|
333
|
+
simple_type ->
|
|
334
|
+
(type_variable | type_constructor) {% (d) => d[0][0] %}
|
|
335
|
+
| "[" _ type _ "]" {% (d) => `[${d[2]}]` %}
|
|
336
|
+
| "(" _ type (_ "," _ type):+ _ ")" {% (d) => `(${[d[2], ...d[3].map(x => x[3])].join(`, `)})` %}
|
|
337
|
+
| "(" _ type _ ")" {% (d) => `(${d[2]})` %}
|
|
338
|
+
|
|
339
|
+
type_variable -> variable {% (d) => d[0] %}
|
|
340
|
+
type_constructor -> constr {% (d) => d[0] %}
|
|
341
|
+
|
|
342
|
+
# Misc rules
|
|
343
|
+
|
|
344
|
+
constr -> %constructor {% (d) => `${d[0].value}` %}
|
|
345
|
+
variable -> %variable {% (d) => `${d[0].value}` %}
|
|
346
|
+
|
|
347
|
+
list_literal ->
|
|
348
|
+
"[" _ "]" {% (d) => `[]` %}
|
|
349
|
+
| "[" _ expression_list _ "]" {% (d) => `[${d[2]}]` %}
|
|
350
|
+
|
|
351
|
+
range_expression ->
|
|
352
|
+
expression _ ".." {% (d) => d[0] + ".." %} # [start ..]
|
|
353
|
+
| expression _ ".." _ expression {% (d) => d[0] + ".." + d[4] %} # [start .. end]
|
|
354
|
+
| expression _ "," _ expression _ ".." {% (d) => d[0] + ", " + d[4] + ".." %} # [start, second ..]
|
|
355
|
+
| expression _ "," _ expression _ ".." _ expression {% (d) => d[0] + ", " + d[4] + ".." + d[6] %} # [start, second .. end]
|
|
356
|
+
|
|
357
|
+
expression_list -> expression (_ "," _ expression):* {% (d) => [d[0], ...d[1].map(x => x[3])].join(`, `) %}
|
|
358
|
+
|
|
359
|
+
comparison_operator ->
|
|
360
|
+
("=="
|
|
361
|
+
| "/="
|
|
362
|
+
| "<"
|
|
363
|
+
| ">"
|
|
364
|
+
| "<="
|
|
365
|
+
| ">=") {% (d) => d[0][0].value %}
|
|
366
|
+
|
|
367
|
+
primitive ->
|
|
368
|
+
(%number
|
|
369
|
+
| %char
|
|
370
|
+
| %string
|
|
371
|
+
| %bool) {% (d) => `${d[0][0].value}` %}
|
|
372
|
+
|
|
373
|
+
_ -> %WS:*
|
|
374
|
+
|
|
375
|
+
__ -> %WS:+
|