Skip to content

Commit

Permalink
Add parsing of sum type declarations (#1088)
Browse files Browse the repository at this point in the history
* Add syntax for sum type declarations

* Add parser generator updates

* Adapt flattening and graphics for sum types

* Add unit test for sum type declaration parsing

* Update the super spec

Not sure why this updating. Tests succeed whether this file is updated
or not. But, well, it's up to date now :)

* Add test for IRPrinting
  • Loading branch information
Shon Feder authored and shonfeder committed Aug 4, 2023
1 parent e7a7b23 commit f3a3cee
Show file tree
Hide file tree
Showing 17 changed files with 1,497 additions and 1,104 deletions.
24 changes: 23 additions & 1 deletion quint/src/IRprinting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/

import { OpQualifier, QuintDef, QuintEx, QuintModule, isAnnotatedDef } from './quintIr'
import { EmptyRow, QuintType, Row, VarRow } from './quintTypes'
import { EmptyRow, QuintSumType, QuintType, Row, RowField, VarRow, isTheUnit } from './quintTypes'
import { TypeScheme } from './types/base'
import { typeSchemeToString } from './types/printing'

Expand Down Expand Up @@ -160,6 +160,9 @@ export function typeToString(type: QuintType): string {
case 'rec': {
return rowToString(type.fields)
}
case 'sum': {
return sumToString(type)
}
case 'union': {
const records = type.records.map(rec => {
return `| { ${type.tag}: "${rec.tagValue}", ${rowFieldsToString(rec.fields)} }`
Expand All @@ -181,6 +184,25 @@ export function rowToString(r: Row): string {
return fields === '' ? '{}' : `{ ${fields} }`
}

/**
* Pretty prints a sum type. Standard sum printing used in error reporting
*
* @param r the sum type to be formatted
*
* @returns a string with the pretty printed sum
*/
export function sumToString(s: QuintSumType): string {
return s.fields.fields
.map((f: RowField) => {
if (isTheUnit(f.fieldType)) {
return `| ${f.fieldName}`
} else {
return `| ${f.fieldName}(${typeToString(f.fieldType)})`
}
})
.join('\n')
}

/**
* Pretty prints an operator qualifier.
*
Expand Down
20 changes: 19 additions & 1 deletion quint/src/flattening.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
isFlat,
} from './quintIr'
import { definitionToString } from './IRprinting'
import { QuintType, Row } from './quintTypes'
import { ConcreteFixedRow, QuintType, Row } from './quintTypes'
import { Loc, parsePhase3importAndNameResolution } from './parsing/quintParserFrontend'
import { compact, uniqBy } from 'lodash'
import { AnalysisOutput } from './quintAnalyzer'
Expand Down Expand Up @@ -398,6 +398,12 @@ class Flatenner {
fields: this.addNamespaceToRow(name, type.fields),
id,
}
case 'sum':
return {
...type,
fields: this.addNamespaceToSumRow(name, type.fields),
id,
}
case 'union':
return {
...type,
Expand Down Expand Up @@ -428,6 +434,18 @@ class Flatenner {
}
}

private addNamespaceToSumRow(name: string | undefined, row: ConcreteFixedRow): ConcreteFixedRow {
return {
...row,
fields: row.fields.map(field => {
return {
...field,
fieldType: this.addNamespaceToType(name, field.fieldType),
}
}),
}
}

private namespacedName(namespace: string | undefined, name: string): string {
return namespace ? `${namespace}::${name}` : name
}
Expand Down
10 changes: 8 additions & 2 deletions quint/src/generated/Quint.g4
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,16 @@ operDef : qualifier normalCallName
;

typeDef
: 'type' qualId # typeAbstractDef
| 'type' qualId '=' type # typeAliasDef
: 'type' qualId # typeAbstractDef
| 'type' qualId '=' type # typeAliasDef
| 'type' typeName=qualId '=' '|'? typeSumVariant ('|' typeSumVariant)* # typeSumDef
;

// A single variant case in a sum type definition.
//
// E.g., `A(t)` or `A`.
typeSumVariant : sumLabel=simpleId["variant label"] ('(' type ')')? ;

nondetOperDef : 'nondet' qualId (':' type)? '=' expr ';'?;

qualifier : 'val'
Expand Down
5 changes: 3 additions & 2 deletions quint/src/generated/Quint.interp

Large diffs are not rendered by default.

40 changes: 20 additions & 20 deletions quint/src/generated/Quint.tokens

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions quint/src/generated/QuintLexer.interp

Large diffs are not rendered by default.

40 changes: 20 additions & 20 deletions quint/src/generated/QuintLexer.tokens

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 53 additions & 53 deletions quint/src/generated/QuintLexer.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions quint/src/generated/QuintListener.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f3a3cee

Please sign in to comment.