Skip to content

Commit 20801ef

Browse files
committed
Fix various type related rules
- variant constructor can have zero arguments (e.g. `Just(int) | Nothing`) - type alias can be quantified with type parameter (e.g. `type List[a]` = ...`) - polymorphic types can have multiple type arguments (e.g. `List[a,b]`) - operator types can have multiple arguments (e.g. `(int, bool) => int`) or no arguments (e.g. `() => int`)
1 parent 0caf7d5 commit 20801ef

File tree

3 files changed

+139
-14
lines changed

3 files changed

+139
-14
lines changed

grammar.js

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,21 +69,39 @@ module.exports = grammar({
6969

7070
// TODO: all types covered?
7171
type: $ => choice(
72-
$.identifier, // basic type
72+
prec('basic_type', $.identifier), // basic type
7373
$.operator_type,
7474
$.function_type,
7575
$.polymorphic_type,
76-
$.sum_type, // QUESTION: are sum types allowed everywhere?
7776
),
7877

78+
// QUESTION: function types always have exaclty one argument?
7979
function_type: $ => prec.right('function_type', seq($.type, '->', $.type)),
8080

81-
operator_type: $ => prec.right('operator_type', seq($.type, '=>', $.type)),
81+
operator_type: $ => prec.right('operator_type', seq(
82+
choice(
83+
$.type, // single argument / no parens, e.g. `int => bool`
84+
withParens(sepBy(',', $.type)), // zero or more arguments, e.g. `(int, int) => int`
85+
),
86+
"=>",
87+
$.type, // result type
88+
)),
8289

83-
polymorphic_type: $ => seq($.identifier, '[', $.type, ']'),
90+
polymorphic_type: $ => seq(
91+
$.identifier,
92+
withBrackets(sepBy1(',', $.type))
93+
),
94+
95+
// TODO: can variant constructors have more than one argument?
96+
variant_constructor: $ => prec('variant_constr', seq(
97+
$.identifier,
98+
optional(withParens($.type))
99+
)),
84100

85-
// TODO: can type constructors have more/less than one argument?
86-
sum_type: $ => sepBy1('|', seq($.identifier, withParens($.type))),
101+
// We say sum types must have at least two variant constructor.
102+
// One variant constructor makes sense, but can't be distingished
103+
// with a basic type like `int`.
104+
sum_type: $ => sepBy1('|', $.variant_constructor),
87105

88106
/////////// Module-level constructs ///////////
89107

@@ -112,7 +130,7 @@ module.exports = grammar({
112130
),
113131

114132
typed_argument_list: $ => withParens(
115-
sepBy1(
133+
sepBy(
116134
',',
117135
seq(
118136
$.identifier,
@@ -150,7 +168,16 @@ module.exports = grammar({
150168
// TODO: https://quint-lang.org/docs/lang#module-instances
151169

152170
// TODO: type alias identifier must be all CAPS
153-
type_alias: $ => seq('type', $.identifier, '=', $.type),
171+
type_alias: $ => seq(
172+
'type',
173+
$.identifier,
174+
optional(withBrackets(sepBy1(',', $.identifier))), // optional type arguments
175+
'=',
176+
choice(
177+
$.type,
178+
$.sum_type,
179+
)
180+
),
154181

155182
/////////// Namespaces and Imports ///////////
156183

@@ -329,6 +356,8 @@ module.exports = grammar({
329356
[
330357
'function_type',
331358
'operator_type',
359+
'variant_constr',
360+
'basic_type',
332361
]
333362
],
334363

queries/helix-highlights.scm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@
9393
(polymorphic_type
9494
(type) @type.parameter)
9595

96+
(variant_constructor) @type.enum.variant
97+
9698
(type) @type
9799
(int_literal) @constant.numeric.integer
98100
(comment) @comment

test/corpus/module-level-constructs.txt

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ var isArmed: bool
8181
Static Constant Value
8282
========================
8383

84-
pure val Nodes: Set[int] = 1 to 10
84+
pure val Nodes: Set[int] = 1.to(10)
8585

8686
---
8787

@@ -93,7 +93,14 @@ pure val Nodes: Set[int] = 1 to 10
9393
(identifier)
9494
(type
9595
(identifier))))
96-
(expr)))
96+
(expr
97+
(binary_expr
98+
(expr
99+
(int_literal))
100+
(operator_application
101+
(identifier)
102+
(expr
103+
(int_literal)))))))
97104

98105

99106
==========================================
@@ -114,6 +121,23 @@ pure val eleven = 11;
114121
Two-Argument Operator
115122
========================
116123

124+
pure def fst(): int = 1
125+
126+
---
127+
128+
(source_file
129+
(operator_definition
130+
(identifier)
131+
(typed_argument_list)
132+
(type
133+
(identifier))
134+
(expr
135+
(int_literal))))
136+
137+
========================
138+
Two-Argument Operator
139+
========================
140+
117141
pure def fst(x: int, y: int): int =
118142
x
119143

@@ -309,18 +333,88 @@ type INT_SET = Set[int]
309333
Sum Type
310334
========================
311335

312-
type Elem = S(str) | I(int)
336+
type Elem = S(str) | I(int) | Nil
313337

314338
---
315339

316340
(source_file
317341
(type_alias
318342
(identifier)
319-
(type
320-
(sum_type
343+
(sum_type
344+
(variant_constructor
321345
(identifier)
322346
(type
323-
(identifier))
347+
(identifier)))
348+
(variant_constructor
324349
(identifier)
350+
(type
351+
(identifier)))
352+
(variant_constructor
353+
(identifier)))))
354+
355+
========================
356+
Operator Type
357+
========================
358+
359+
type _ = int => int
360+
type _ = () => int
361+
type _ = (int) => int
362+
type _ = (int, bool) => int
363+
364+
---
365+
366+
(source_file
367+
(type_alias
368+
(identifier)
369+
(type
370+
(operator_type
371+
(type
372+
(identifier))
373+
(type
374+
(identifier)))))
375+
(type_alias
376+
(identifier)
377+
(type
378+
(operator_type
379+
(type
380+
(identifier)))))
381+
(type_alias
382+
(identifier)
383+
(type
384+
(operator_type
385+
(type
386+
(identifier))
387+
(type
388+
(identifier)))))
389+
(type_alias
390+
(identifier)
391+
(type
392+
(operator_type
393+
(type
394+
(identifier))
395+
(type
396+
(identifier))
325397
(type
326398
(identifier))))))
399+
400+
========================
401+
Function Type
402+
========================
403+
404+
type _ = bool -> int -> int
405+
406+
---
407+
408+
(source_file
409+
(type_alias
410+
(identifier)
411+
(type
412+
(function_type
413+
(type
414+
(identifier))
415+
(type
416+
(function_type
417+
(type
418+
(identifier))
419+
(type
420+
(identifier))))))))

0 commit comments

Comments
 (0)