Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete rewrite of the parser #84

Open
wants to merge 120 commits into
base: scala-2.13
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
a399596
Add HoleType, which indicates the type of values expected by a hole
redelmann Jul 31, 2018
fb2cb3a
Add an interpolator implemented with macros
redelmann Jul 31, 2018
b4a4941
Add implicit store argument to getDefinitions
redelmann Jul 31, 2018
992bc06
Add HoleValues class
redelmann Jul 31, 2018
38d9a9f
Parse holes in function application position to identifier by default
redelmann Jul 31, 2018
5207dd8
Add replaceHoles functions
redelmann Jul 31, 2018
70c693b
Fix macros implementations
redelmann Jul 31, 2018
267926f
Use replaceHoles to feed parameters of quasiquotes
redelmann Jul 31, 2018
0dd8c2d
Code quality and comment
redelmann Jul 31, 2018
bc2e3be
Add macro extractor for types
redelmann Jul 31, 2018
304b999
Refactoring
redelmann Aug 2, 2018
b04eb26
Use MacroInterpolator as the default interpolator
redelmann Aug 2, 2018
7ba44a7
Handle implicit symbols
redelmann Aug 2, 2018
66b60de
Comment out the warning for using default
redelmann Aug 2, 2018
972da12
Remove useless import
redelmann Aug 2, 2018
6861e4b
Rename interpolator-related classes and fix their hierarchy
redelmann Aug 2, 2018
ba8a399
Add unapply for expressions
redelmann Aug 2, 2018
4ad9907
Refactor
redelmann Aug 2, 2018
d318c59
Add s to MacroInterpolator
redelmann Aug 2, 2018
dd8aef7
Add definition interpolators to the macro interpolator
redelmann Aug 2, 2018
e3a0955
Add the concept of a Binding to the IRs
redelmann Aug 2, 2018
dede1ca
Add different constructors for bindings
redelmann Aug 2, 2018
96866dc
Some fixes
redelmann Aug 2, 2018
8e55f16
First draft
redelmann Aug 3, 2018
9d3fa24
More work
redelmann Aug 3, 2018
4503a96
Simplify constrained.
redelmann Aug 3, 2018
46ae7c2
Refactor harder, structure looks better now
redelmann Aug 4, 2018
834e118
Yet more refactoring
redelmann Aug 4, 2018
a53fb38
Refactor harder
redelmann Aug 6, 2018
944d23b
Greatly simplify the types IR, use Store to resolve all names, even p…
redelmann Aug 6, 2018
344d7e8
More work on Expr, refactor HSeq
redelmann Aug 6, 2018
13cc34a
Remove context for elaborators, add result for matchings
redelmann Aug 6, 2018
9e127bc
Also split binding extractor in two
redelmann Aug 6, 2018
7d3f7dd
Yet in the middle of refactoring
redelmann Aug 6, 2018
f8cea27
More work on extractor and elaborator
redelmann Aug 7, 2018
cdc3807
Add a size specification parameter to the Bits typeclass, to support …
redelmann Aug 7, 2018
1792417
Done with extractors
redelmann Aug 7, 2018
dc1f710
Finish expression elaborator
redelmann Aug 7, 2018
43ad977
Add bidirectional conversions between simple types and inox types
redelmann Aug 7, 2018
e5aa08e
Implement constraint solver
redelmann Aug 8, 2018
4d84f96
Work towards elaboration of function definitions
redelmann Aug 9, 2018
d182bc9
Add function extractor
redelmann Aug 9, 2018
93b5696
Add simple adts and fully implement store
redelmann Aug 9, 2018
fd8f6ba
Add ADT elaborator and extractor
redelmann Aug 10, 2018
ee6c027
Add lexer and parsers, fix some bugs
redelmann Aug 15, 2018
8d4894a
Separate the namespaces of types and expressions
redelmann Aug 15, 2018
c8986a4
Add Liftable instances for the various IRs
redelmann Aug 15, 2018
3e6ea5f
Add macro interpolator for types
redelmann Aug 15, 2018
ecad27c
Add macro interpolators for expressions
redelmann Aug 16, 2018
cb44839
Add function definition macros interpolators
redelmann Aug 16, 2018
08c000f
Fix bugs in parser and hseq extractor
redelmann Aug 16, 2018
d75951c
Add explicit type argument to HSeq call in macro
redelmann Aug 16, 2018
2918334
Accept syntactic sugar for refinement types, fix bugs
redelmann Aug 16, 2018
84cb940
Add macro interpolator for value definitions and type definitions
redelmann Aug 16, 2018
12578f4
Package all internal values in companion object of Interpolator
redelmann Aug 16, 2018
052aa44
Fix bug in elaboration of IsConstructor
redelmann Aug 16, 2018
e5936b4
Add interpolator for programs
redelmann Aug 16, 2018
94319e0
Handle invocations made to variables
redelmann Aug 17, 2018
4ca54ba
Fix bug in macro
redelmann Aug 17, 2018
49de17b
Attach positions to IRs
redelmann Aug 17, 2018
77686ef
Begin working on providing good error messages
redelmann Aug 17, 2018
8def752
Continue work on error messages
redelmann Aug 17, 2018
3e54005
More work on error messages
redelmann Aug 17, 2018
4d5e9a9
Better error messages, add constructors for sets, maps and bags
redelmann Oct 26, 2018
bb42f19
Remove old parser, fix bugs, update doc
redelmann Oct 29, 2018
0b0f176
Fix last merge errors
redelmann Oct 29, 2018
7cf875c
Use a Macros implementation for interpolators by default in inox.ast.…
redelmann Oct 30, 2018
ad1019d
Overridable macro interpolators
samarion Oct 30, 2018
65a7d31
Fix bugs, add tests
redelmann Oct 31, 2018
6db8245
Remove warning about implicit conversions
redelmann Nov 1, 2018
d984ee2
Add test
redelmann Nov 1, 2018
2f0b213
Remove debug print
redelmann Nov 1, 2018
614b5db
Fix priority in parser
redelmann Nov 1, 2018
619945a
Add tests for elaboration of function definitions
redelmann Nov 1, 2018
2c6fc13
Make the annotated types of macro-generated terms shorter
redelmann Nov 1, 2018
62ff2a7
Fix bug with hole in return type of function definition
redelmann Nov 5, 2018
22e418a
Add some tests for function definition parsing
redelmann Nov 5, 2018
32691f1
Fix error message in case of wrong number of arguments
redelmann Nov 5, 2018
0950745
Make sure the definitions appear in the same order as they are defined
redelmann Nov 5, 2018
89067fc
Tests for program parser
redelmann Nov 5, 2018
ee608ca
Switch from objects to class/val instead, so that it is easier to ove…
redelmann Nov 5, 2018
8b09b46
Made Lexer and operators overridable
redelmann Nov 6, 2018
e8a844b
Unseal all IRs
redelmann Nov 6, 2018
ca065f4
Add widening and narrowing casts to the parser
redelmann Nov 6, 2018
f2cdd47
Unseal HoleType
redelmann Nov 7, 2018
f950d85
Add unsigned bit vectors to the parser
redelmann Nov 8, 2018
9fab8e4
Simplify complement computation
redelmann Nov 8, 2018
71a1910
New syntax for sigma and pi types, as well as let expressions
redelmann Nov 21, 2018
8207d12
Add more tests for lets
redelmann Nov 22, 2018
84baa99
Add block syntax
redelmann Nov 22, 2018
040d038
Change syntax for lambda, forall and choose expressions
redelmann Nov 22, 2018
a135c5b
Fix syntax in tests with quantifiers
redelmann Nov 23, 2018
50acc5b
Fix documentation
redelmann Nov 23, 2018
55cc979
Add test for if-expressions
redelmann Nov 23, 2018
2637294
Add syntax for assume
redelmann Nov 23, 2018
afb59c0
Accept single argument without type to omit parentheses in lambda, fo…
redelmann Nov 23, 2018
4d358f3
Work on a new pretty printer
redelmann Nov 23, 2018
2e9cfd8
Add check that the fields have unique names in an ADT
redelmann Nov 28, 2018
019c677
Fix broken test
redelmann Nov 28, 2018
80b1ca3
Add literal trait for IR expressions
redelmann Nov 28, 2018
8c7e0b7
Make it possible to refer to earlier identifiers in sequences of bind…
redelmann Dec 3, 2018
f92eed2
Added OneOf to inox solver
Dec 13, 2018
2e5b958
Added store changes which are prerequisite for the overloading
Dec 13, 2018
68f28af
Added overloading, all previous tests pass
Dec 14, 2018
7b2a68e
Overloading before extensive testing
Dec 14, 2018
9261ddb
Function overloading
Jan 2, 2019
e442a40
Added comments for function name overloading
Jan 2, 2019
d0f01cd
Comments for solver
Jan 2, 2019
1e6df5b
Before adding examples to report
Jan 6, 2019
d3a5d4d
Solved the problem with OneOf
Jan 6, 2019
f99ecbc
Overloading should be done
Jan 7, 2019
9ab927a
Fixed the OneOf
Jan 7, 2019
a7f26ee
Fixed another bug
Jan 7, 2019
03cc038
Another change to solver
Jan 7, 2019
c57f7ab
Added more tests
Jan 21, 2019
987dc1d
Fixed more bugs
Jan 21, 2019
0f22471
One bug fixed
Jan 22, 2019
e8fbc4e
Final for presentation
Jan 23, 2019
da2c7b5
More general unification for pairs, coding style fixes
Jan 24, 2019
8441ed7
Merge pull request #90 from OStevan/overloading
redelmann Feb 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 82 additions & 83 deletions doc/interpolations.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Inox String Interpolation

- ***[Introduction](#introduction)***
- [Importing](#importing)
- ***[Syntax](#syntax)***
- ***[Expressions](#expressions)***
- [Literals](#literals)
- [Boolean](#boolean-literals)
- [Numeric](#numeric-literals)
Expand All @@ -20,7 +20,6 @@ Inox String Interpolation
- [Lambda expressions](#lambda-expressions)
- [Quantifiers](#quantifiers)
- [Universal quantifiers](#universal-quantifiers)
- [Existential quantifiers](#existential-quantifiers)
- [Choose](#choose)

- ***[Primitives](#primitives)***
Expand Down Expand Up @@ -51,23 +50,23 @@ Once imported, it is possible to build Inox types and expressions using a friend

```scala
scala> val tpe = t"Boolean"
tpe: inox.trees.interpolator.trees.Type = Boolean
tpe: inox.trees.Type = Boolean

scala> val expr = e"1 + 1 == 2"
expr: inox.trees.interpolator.trees.Expr = 1 + 1 == 2
expr: inox.trees.Expr = 1 + 1 == 2
```

It is also possible to embed types and expressions:

```scala
scala> e"let x: $tpe = $expr in !x"
res1: inox.trees.interpolator.trees.Expr =
val x: Boolean = 1 + 1 == 2
¬x
scala> e"let x: $tpe = $expr; !x"
res1: inox.trees.Expr =
let x: Boolean = 1 + 1 == 2;
!x
```

<a name="syntax"></a>
# Syntax
<a name="expressions"></a>
# Expressions

<a name="literals"></a>
## Literals
Expand All @@ -77,70 +76,70 @@ val x: Boolean = 1 + 1 == 2

```scala
scala> e"true"
res2: inox.trees.interpolator.trees.Expr = true
res2: inox.trees.Expr = true

scala> e"false"
res3: inox.trees.interpolator.trees.Expr = false
res3: inox.trees.Expr = false
```

<a name="numeric-literals"></a>
### Numeric literal

```scala
scala> e"1"
res4: inox.trees.interpolator.trees.Expr = 1
res4: inox.trees.Expr = 1
```

Note that the type of numeric expressions is inferred. In case of ambiguity, `BigInt` is chosen by default.
Note that the type of numeric expressions is inferred. In case of ambiguity, `Integer` is chosen by default.

```scala
scala> val bigIntLit = e"1"
bigIntLit: inox.trees.interpolator.trees.Expr = 1
bigIntLit: inox.trees.Expr = 1

scala> bigIntLit.getType
res5: inox.trees.interpolator.trees.Type = BigInt
res5: inox.trees.Type = Integer
```

It is however possible to annotate the desired type.

```scala
scala> val intLit = e"1 : Int"
intLit: inox.trees.interpolator.trees.Expr = 1
scala> val intLit = e"1 as Int"
intLit: inox.trees.Expr = 1

scala> intLit.getType
res6: inox.trees.interpolator.trees.Type = Int
res6: inox.trees.Type = Int
```

```scala
scala> val realLit = e"1 : Real"
realLit: inox.trees.interpolator.trees.Expr = 1
scala> val realLit = e"1 as Real"
realLit: inox.trees.Expr = 1

scala> realLit.getType
res7: inox.trees.interpolator.trees.Type = Real
res7: inox.trees.Type = Real
```

<a name="real-literals"></a>
#### Real literals

```scala
scala> e"3.75"
res8: inox.trees.interpolator.trees.Expr = 15/4
res8: inox.trees.Expr = 15/4
```

<a name="string-literals"></a>
### String literals

```scala
scala> e"'Hello world!'"
res9: inox.trees.interpolator.trees.Expr = "Hello world!"
res9: inox.trees.Expr = "Hello world!"
```

<a name="character-literals"></a>
### Character literals

```scala
scala> e"`a`"
res10: inox.trees.interpolator.trees.Expr = 'a'
res10: inox.trees.Expr = 'a'
```

<a name="arithmetic"></a>
Expand All @@ -150,15 +149,15 @@ Arithmetic operators are infix and have there usual associativity and priority.

```scala
scala> e"1 + 2 * 5 + 6 - 7 / 17"
res11: inox.trees.interpolator.trees.Expr = ((1 + 2 * 5) + 6) - 7 / 17
res11: inox.trees.Expr = ((1 + 2 * 5) + 6) - 7 / 17
```

<a name="conditionals"></a>
## Conditionals

```scala
scala> e"if (1 == 2) 'foo' else 'bar'"
res12: inox.trees.interpolator.trees.Expr =
res12: inox.trees.Expr =
if (1 == 2) {
"foo"
} else {
Expand All @@ -170,32 +169,39 @@ if (1 == 2) {
## Let bindings

```scala
scala> e"let word: String = 'World!' in concatenate('Hello ', word)"
res13: inox.trees.interpolator.trees.Expr =
val word: String = "World!"
"Hello " + word
scala> e"let word: String = 'World!'; concatenate('Hello ', word)"
res13: inox.trees.Expr =
let word: String = "World!";
concatenate("Hello ", word)
```

<a name="lambda-expressions"></a>
## Lambda expressions

```scala
scala> e"lambda x: BigInt, y: BigInt. x + y"
res14: inox.trees.interpolator.trees.Expr = (x: BigInt, y: BigInt) => x + y
scala> e"lambda (x: Integer, y: Integer) => x + y"
res14: inox.trees.Expr = (x: Integer, y: Integer) => x + y
```

It is also possible to use the Unicode `λ` symbol.

```scala
scala> e"λx: BigInt, y: BigInt. x + y"
res15: inox.trees.interpolator.trees.Expr = (x: BigInt, y: BigInt) => x + y
scala> e"λ(x: Integer, y: Integer) => x + y"
res15: inox.trees.Expr = (x: Integer, y: Integer) => x + y
```

Or even use this syntax:

```scala
scala> e"(x: Integer, y: Integer) => x + y"
res16: inox.trees.Expr = (x: Integer, y: Integer) => x + y
```

Type annotations can be omitted for any of the parameters if their type can be inferred.

```scala
scala> e"lambda x. x * 0.5"
res16: inox.trees.interpolator.trees.Expr = (x: Real) => x * 1/2
scala> e"lambda (x) => x * 0.5"
res17: inox.trees.Expr = (x: Real) => x * 1/2
```

<a name="quantifiers"></a>
Expand All @@ -205,33 +211,22 @@ res16: inox.trees.interpolator.trees.Expr = (x: Real) => x * 1/2
### Universal Quantifier

```scala
scala> e"forall x: Int. x > 0"
res17: inox.trees.interpolator.trees.Expr = ∀x: Int. (x > 0)

scala> e"∀x. x || true"
res18: inox.trees.interpolator.trees.Expr = ∀x: Boolean. (x || true)
```

<a name="existential-quantifiers"></a>
### Existential Quantifier

```scala
scala> e"exists x: BigInt. x < 0"
res19: inox.trees.interpolator.trees.Expr = ¬∀x: BigInt. ¬(x < 0)
scala> e"forall (x: Int) => x > 0"
res18: inox.trees.Expr = ∀ (x: Int) => (x > 0)

scala> e"∃x, y. x + y == 0"
res20: inox.trees.interpolator.trees.Expr = ¬∀x: BigInt, y: BigInt. (x + y ≠ 0)
scala> e"∀(x) => x || true"
res19: inox.trees.Expr = ∀ (x: Boolean) => (x || true)
```

<a name="choose"></a>
## Choose

```scala
scala> e"choose x. x * 3 < 17"
res21: inox.trees.interpolator.trees.Expr = choose((x: BigInt) => x * 3 < 17)
scala> e"choose (x) => x * 3 < 17"
res20: inox.trees.Expr = choose (x: Integer) => x * 3 < 17

scala> e"choose x: String. true"
res22: inox.trees.interpolator.trees.Expr = choose((x: String) => true)
scala> e"choose (x: String) => length(x) == 10"
res21: inox.trees.Expr = choose (x: String) => length(x) == 10
```

<a name="primitives"></a>
Expand All @@ -252,9 +247,9 @@ res22: inox.trees.interpolator.trees.Expr = choose((x: String) => true)

| Function | Type | Description | Inox Constructor |
| -------- | ---- | ----------- | ---------------- |
| `length` | `String => BigInt` | Returns the length of the string. | `StringLength` |
| `length` | `String => Integer` | Returns the length of the string. | `StringLength` |
| `concatenate` | `(String, String) => String` | Returns the concatenation of the two strings. | `StringConcat` |
| `substring` | `(String, BigInt, BigInt) => String` | Returns the substring from the first index inclusive to the second index exclusive. | `SubString ` |
| `substring` | `(String, Integer, Integer) => String` | Returns the substring from the first index inclusive to the second index exclusive. | `SubString ` |

### Operators

Expand All @@ -271,14 +266,6 @@ res22: inox.trees.interpolator.trees.Expr = choose((x: String) => true)
| ----------- | ----------- | ---------------- |
| `Set[A](elements: A*)` | Returns a set containing the given `elements`. | `FiniteSet` |

### Literal Syntax

```
{}
{1, 2, 3}
{'foo', 'bar', 'baz'}
```

### Functions

| Function | Type | Description | Inox Constructor |
Expand Down Expand Up @@ -307,20 +294,13 @@ res22: inox.trees.interpolator.trees.Expr = choose((x: String) => true)

| Constructor | Description | Inox Constructor |
| ----------- | ----------- | ---------------- |
| `Bag[A](bindings: (A -> BigInt)*)` | Returns a bag containing the given `bindings`. | `FiniteBag` |

### Literal Syntax

```
{1 -> 2, 2 -> 4, 3 -> 6}
{'foo' -> 5, 'bar' -> 2, 'baz' -> 2}
```
| `Bag[A](bindings: (A -> Integer)*)` | Returns a bag containing the given `bindings`. | `FiniteBag` |

### Functions

| Function | Type | Description | Inox Constructor |
| -------- | ---- | ----------- | ---------------- |
| `multiplicity[A]` | `(Bag[A], A) => BigInt` | Returns the number of occurrences in the given bag of the given value. | `MultiplicityInBag` |
| `multiplicity[A]` | `(Bag[A], A) => Integer` | Returns the number of occurrences in the given bag of the given value. | `MultiplicityInBag` |
| `bagAdd[A]` | `(Bag[A], A) => Bag[A]` | Returns the bag with an element added. | `BagAdd` |
| `bagUnion[A]` | `(Bag[A], Bag[A]) => Bag[A]` | Returns the unions of the two bags. | `BagUnion` |
| `bagIntersection[A]` | `(Bag[A], Bag[A]) => Bag[A]` | Returns the intersection of the two bags. | `BagIntersection` |
Expand All @@ -333,18 +313,37 @@ res22: inox.trees.interpolator.trees.Expr = choose((x: String) => true)

| Constructor | Description | Inox Constructor |
| ----------- | ----------- | ---------------- |
| `Map[A](default: A, bindings: (A -> BigInt)*)` | Returns a map with default value `default` containing the given `bindings`. | `FiniteMap` |

### Literal syntax

```
{*: Int -> 42}
{* -> '???', 'hello' -> 'HELLO', 'world' -> 'WORLD'}
```
| `Map[A](default: A, bindings: (A -> Integer)*)` | Returns a map with default value `default` containing the given `bindings`. | `FiniteMap` |

### Functions

| Function | Type | Description | Inox Constructor |
| -------- | ---- | ----------- | ---------------- |
| `apply[K, V]` | `(Map[K, V], K) => V` | Returns the value associated to the given key. | `MapApply` |
| `updated[K, V]` | `(Map[K, V], K, V) => Map[K, V]` | Returns the map with a bidding from the key to the value added. | `MapUpdated` |

<a name="type-definitions"></a>
# Type Definitions

```scala
scala> td"type List[A] = Cons(head: A, tail: List[A]) | Nil()"
res22: inox.trees.ADTSort = type List[A] = Cons(head: A, tail: List[A]) | Nil()
```

```scala
scala> td"type Option[A] = Some(value: A) | None()"
res23: inox.trees.ADTSort = type Option[A] = Some(value: A) | None()
```

<a name="type-definitions"></a>
# Function Definitions

```scala
scala> fd"def id[A](x: A): A = x"
res24: inox.trees.FunDef = def id[A](x: A): A = x
```

```scala
scala> fd"def twice[A](f: A => A): A => A = (x: A) => f(f(x))"
res25: inox.trees.FunDef = def twice[A](f: (A) => A): (A) => A = (x: A) => f(f(x))
```
Loading