1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-24 07:57:58 +03:00
Commit Graph

994 Commits

Author SHA1 Message Date
janmasrovira
d4b355315a
Use Ape to format patterns (#1870)
This pr implements pretty printing of patterns using the Ape interface. 
This means that we will have pretty chains of infix constructors and `,`
will be printed as expected (in a pattern), i.e. `(a, b)` instead of `(a
, b)`

---------

Co-authored-by: Paul Cadman <git@paulcadman.dev>
2023-03-01 09:13:04 +00:00
Jonathan Cubides
0ef464668d
Fix Core-To-Geb translation (#1863)
This PR adds support for all recent changes in GEB introduced by:
- https://github.com/anoma/geb/pull/70
- Closes #1814

Summary:

- [x] Add LeftInj, RightIng, and Absurd types in GEB language
- [x] Fix FromCore translation for the new data types and minor code
styling issues.
  - [x] Fix GEB-STLC type inference and checking
- [X] Add support for evaluating typed morphism "(typed ...)" in the Geb
repl and .geb files.
- [x] Simplify a bit the Geb parser
- [x] Fix `dev geb check` command
- [x] Type check files in `tests/Geb/positive`

After this PR, we should include interval location for Geb terms to
facility debugging type-checking errors.
2023-02-28 18:49:44 +01:00
Łukasz Czajka
027954b1d8
Fix bugs in the Case translation in Core-to-Geb (#1858) 2023-02-23 17:16:53 +01:00
janmasrovira
e0b2d202ed
Add _caseTypeWholeExpression to Internal (#1860) 2023-02-23 14:50:20 +01:00
janmasrovira
23f34403f5
Move substEnv to its own module (#1861)
The pretty printer for `Core` depends on `substEnv`, so it is convenient
to have it isolated so that it is possible to use ``ppTrace`` when
debugging functions in `Core.Utils` (or anything depending on it).
2023-02-22 19:21:41 +01:00
Jonathan Cubides
1ca7030993 Update README.md Closes #1855 2023-02-22 18:00:51 +01:00
Jonathan Cubides
9a4da4cab8
Add Geb Backend Evaluator with some extra subcommands (#1808)
This PR introduces an evaluator for the Geb STLC interface/fragment and
other related commands, including a REPL to interact with his backend.

-
https://github.com/anoma/geb/blob/mariari/binaries/src/specs/lambda.lisp

We have included a REPL and support for commands such as read and eval
here. Check out:

```
juvix dev geb --help
```

- [x] Add Geb evaluator with the two basic eval strategies.
- [x] Add quasi quoter: return morphisms from typed geb values.
- [x] Add type/object inference for morphisms.
- [x] All combined: morphisms-eval-to-morphisms
- [x] Parse and pretty printer Geb values (without quoting them)
- [x] Parse files containing Geb terms:
- [x] Saved in a .lisp file according to anoma/geb example (typed
object).
  - [x] Store in a .geb file simple as simple lisp expression.
- [x] Add related commands to the CLI for `dev geb`:
  - [x] Subcommand: eval
  - [x] Subcommand: read
  - [x] Subcommand: infer
  - [x] Subcommand: repl
  - [x] Subcommand: check 
- [x] Minor changes `hom` by `!->` in the Geb prettyprinter
- [x] Add tests for:
   - [x] New subcommand (smoke tests)
   - [x] Eval

Issues to solve after merging this PR: 

- Add location to Geb ast for proper error location.
- Add tests for all related subcommands, e.g. check, and infer.
- Check compilation from Core to Geb: (run inferObject with the type
provided by the core node).
- [x] Update the vs code-plugin to load Geb repl and eval.
(31994c8684)
2023-02-22 15:27:40 +01:00
Jonathan Cubides
f4591be3bd
remove old minihaskell files (#1859) 2023-02-22 13:47:20 +01:00
janmasrovira
098c256da8
Allow shadowing local variables with let function definitions (#1847)
Co-authored-by: Paul Cadman <git@paulcadman.dev>
2023-02-22 10:26:54 +01:00
janmasrovira
d24ad5821a
Format examples (#1856) 2023-02-21 20:40:09 +01:00
Paul Cadman
791666fbaf
Use APE mechanism to format Function expressions (#1852)
I paired with @janmasrovira on this work.

Before this change - long type signatures were formatted to contain line
breaks within applications:

```
  exampleFunction : {A : Type} -> List A -> List A -> List
        A -> List A -> List A -> List A -> List A -> Nat;
```

After this change we treat `->` and an infix operator and format like
other infix applications:

```
  exampleFunction :
    {A : Type}
      -> List A
      -> List A
      -> List A
      -> List A
      -> List A
      -> List A
      -> List A
      -> Nat;
```

* Fixes #1850
Co-authored-by: @janmasrovira
2023-02-21 17:59:34 +01:00
Łukasz Czajka
26424b1338
Sort the identifiers topologically in the Core-to-GEB translation (#1854) 2023-02-20 14:51:06 +01:00
Łukasz Czajka
5d2dacf3bd
Add type info to the mid-square hashing function (#1853) 2023-02-20 12:55:36 +01:00
Paul Cadman
848b6d66f5
Preserve single wildcards pretty printing function parameters (#1851) 2023-02-17 13:00:47 +00:00
janmasrovira
ca4926527e
Add type annotation to case expression (#1849) 2023-02-16 12:54:53 +01:00
janmasrovira
dd8457d097
Remove module parameters (#1848) 2023-02-16 12:05:49 +01:00
Paul Cadman
c93013229a
Add compilation of complex pattern matching to case (#1824)
This PR adds the `match-to-case` Core transformation. This transforms
pattern matching nodes to a sequence of case and let nodes.

## High level description

Each branch of the match is compiled to a lambda. In the combined match 

Each branch of the match is compiled to a lambda. These lambdas are
combined in nested lets and each lambda is called in turn as each branch
gets checked. The lambda corresponding to the first branch gets called
first, if the pattern match in the branch fails, the lambda
corresponding to the next branch is called and so on. If no branches
match then a lambda is called which returns a fail node.

Conceptually:

<table>
<tr>
<td>
Core
</td>
<td>
Transformed
</td>
</tr>
<tr>
<td>

```

match v1 .. vn {
  b1
  b2
  ...
  bk
}

```

</td>
<td>

```
λ
  let c0 := λ FAIL in
    let ck := λ {...} in
      ...
      let c1 := λ {...} in
  c1 v1 ... vn

```

</td>
</tr>
</table>

The patterns on each branch are compiled to either let bindings (pattern
binders) or case expressions (constructor patterns).

Auxillary bindings are added in the case of nested constructor patterns.

The default branch in each case expression has a call to the lambda
corresponding to the next branch of the match. This is because the
default
branch is reached if the pattern match fails.

<table>

<tr>
<td>
Pattern match
</td>
<td>
Transformed
</td>
</tr>
<tr>
<td>

```
suc (suc n) ↦ n
```

</td>
<td>

```
  case ?$0 of {
    suc arg_8 := case ?$0 of {
      suc n := let n := ?$0 in n$0;
      _ := ?$2 ?$1
    };
    _ := ?$1 ?$0
  }

```

</td>
</tr>
</table>

The body of each branch is wrapped in let bindings so that the indicies
of bound
variables in the body point to the correct variables in the compiled
expression.
This is necessary because the auxiliary bindings added for nested
constructor
patterns will cause the original indicies to be offset.

Finally, the free variables in the match branch body need to be shifted
by all the bindings we've added as part of the compilation.

## Examples

### Single wildcard

<table>
<tr>
<td> Juvix </td> <td> Core </td> <td> Transformed Core </td>
</tr>
<tr>
<td>

```
f : Nat -> Nat;
f _ := 1;
```

</td>
<td>

```
λ? match ?$0 with {
  _ω309 ↦ ? 1
}
```

</td>
<td>

```
λ? let ? := λ? fail "Non-exhaustive patterns" in
   let ? := λ? let _ω309 := ?$0 in
               let _ω309 := ?$0 in 1 in
   ?$0 ?$2
```

</td>
</tr>
</table>

### Single binder

<table>
<tr>
<td> Juvix </td> <td> Core </td> <td> Transformed Core </td>
</tr>
<tr>
<td>

```
f : Nat -> Nat;
f n := n;
```

</td>
<td>

```
λ? match ?$0 with {
  n ↦ n$0
}
```

</td>
<td>

```
λ? let ? := λ? fail "Non-exhaustive patterns" in
   let ? := λ? let n := ?$0 in
               let n := ?$0 in n$0 in
   ?$0 ?$2
```

</td>
</tr>
</table>

### Single Constructor

<table>
<tr>
<td> Juvix </td> <td> Core </td> <td> Transformed Core </td>
</tr>
<tr>
<td>

```
f : Nat -> Nat;
f (suc n) := n;
```

</td>
<td>

```
λ? match ?$0 with {
  suc n ↦ n$0
}
```

</td>
<td>

```
λ? let ? := λ? fail "Non-exhaustive patterns" in let ? := λ? case ?$0 of {
  suc n := let n := ?$0 in let n := ?$0 in n$0;
  _ := ?$1 ?$0
} in ?$0 ?$2
```

</td>
</tr>
</table>

### Nested Constructor

<table>
<tr>
<td> Juvix </td> <td> Core </td> <td> Transformed Core </td>
</tr>
<tr>
<td>

```
f : Nat -> Nat;
f (suc (suc n)) := n;
```

</td>
<td>

```
λ? match ?$0 with {
  suc (suc n) ↦ n$0
}
```

</td>
<td>

```
λ? let ? := λ? fail "Non-exhaustive patterns" in let ? := λ? case ?$0 of {
  suc arg_8 := case ?$0 of {
    suc n := let n := ?$0 in let n := ?$0 in n$0;
    _ := ?$2 ?$1
  };
  _ := ?$1 ?$0
} in ?$0 ?$2
```

</td>
</tr>
</table>

### Multiple Branches

<table>
<tr>
<td> Juvix </td> <td> Core </td> <td> Transformed Core </td>
</tr>
<tr>
<td>

```
f : Nat -> Nat;
f (suc n) := n;
f zero := 0;
```

</td>
<td>

```
λ? match ?$0 with {
  suc n ↦ n$0;
  zero ↦ ? 0
}
```

</td>
<td>

```
λ? let ? := λ? fail "Non-exhaustive patterns" in let ? := λ? case ?$0 of {
  zero := ? 0;
  _ := ?$1 ?$0
} in let ? := λ? case ?$0 of {
  suc n := let n := ?$0 in let n := ?$0 in n$0;
  _ := ?$1 ?$0
} in ?$0 ?$3
```

</td>
</tr>
</table>

### Nested case with captured variable

<table>
<tr>
<td> Juvix </td> <td> Core </td> <td> Transformed Core </td>
</tr>
<tr>
<td>

```
f : Nat -> Nat -> Nat;
f n m := case m
  | suc k := n + k;
```

</td>
<td>

```
f = λ? λ? match ?$1, ?$0 with {
  n, m ↦ match m$0 with {
    suc k ↦ + n$2 k$0
  }
}
```

</td>
<td>

```
λ? λ?
  let ? := λ? λ? fail "Non-exhaustive patterns" in
  let ? := λ? λ? let n := ?$1 in let m := ?$1 in let n := ?$1 in let m := ?$1 in
      let ? := λ? fail "Non-exhaustive patterns" in let ? := λ? case ?$0 of {
            suc k := let k := ?$0 in let k := ?$0 in + n$6 k$0;
            _ := ?$1 ?$0
} in ?$0 m$2 in ?$0 ?$3 ?$2
```

</td>
</tr>
</table>

## Testing

The `tests/Compilation/positive` tests are run up to the Core evaluator
with `match-to-case` and `nat-to-int` transformations on Core turned on.

---------

Co-authored-by: Lukasz Czajka <lukasz@heliax.dev>
2023-02-15 11:30:12 +01:00
janmasrovira
764c6faa80
Improve comma formatting (#1842)
- Closes #1837
2023-02-14 15:27:11 +00:00
janmasrovira
b47bb8305a
Improve formatter (#1840)
- Closes #1793.

Now, if the body of a function clause does not fit in a line, the body
will start indented in the next line.

The example presented in the linked issue is now formatted thus:
```
  go n s :=
    if
      (s < n)
      (go (sub n 1) s)
      (go n (sub s n) + go (sub n 1) s);
```
2023-02-14 14:39:12 +00:00
janmasrovira
9ae0a41577
Add lambda type info (#1845)
This pr adds the `_lambdaType :: Maybe Expression` to `Internal.Lambda`.
This field will be `Nothing` before typechecking and `Just _` after it.

The type is printed if present. For example if the input of `juvix dev
internal typecheck M.juvix --print-result` is the following:
```
id : {A : Type} → A → A
id := λ { a := a}
```
Then the output is as follows:
```
id : {A : Type} → A → A
id {_ω209} := λ : _ω209 → _ω209 {| a := a}
```
2023-02-14 13:49:53 +01:00
Łukasz Czajka
c1d85c451e
Give proper errors for incorrect application of lazy builtins (#1830)
* Closes #1828
2023-02-10 19:21:46 +01:00
janmasrovira
f897fc2cc0
Fix juvix init (#1835) 2023-02-10 17:53:23 +01:00
Łukasz Czajka
d15a5695fc
Documentation: update language reference (#1829)
* Closes #1627
2023-02-10 17:25:40 +01:00
janmasrovira
d2eb020f1f
Respect lambda Ascii/Unicode (#1838)
- Closes #1836
2023-02-10 16:57:47 +01:00
janmasrovira
33a0675c99
Respect the juvix dev highlight --format flag when outputting errors (#1820)
Currently errors were always being highlighted using the emacs backend.
Now they properly depend on the `--format` flag.
2023-02-10 13:43:13 +01:00
janmasrovira
207b1594f8
Add dev core from-concrete command (#1833) 2023-02-10 12:37:28 +01:00
janmasrovira
1876883445
The formatter respects the ascii function arrow (#1834)
- Closes #1827
2023-02-10 10:01:49 +00:00
Łukasz Czajka
92042fa10c
Emacs mode and VSCode extension tutorials (#1815)
* Depends on PR #1813 
* Closes #1630
2023-02-09 14:25:36 +01:00
Łukasz Czajka
0ee8bdf8ef
Make '>>' lazy (#1812)
* Closes #1773 
* Closes #1817
2023-02-09 11:03:12 +01:00
Paul Cadman
10c3478875
Apply CI ghcup workaround to docs build (#1823)
We also need to apply the workaround from
https://github.com/anoma/juvix/pull/1821 to the linux docs build
2023-02-08 18:14:56 +00:00
Łukasz Czajka
41ea59e96f
Update the Juvix tutorial for 0.3 (#1822)
* Closes #1758
2023-02-08 18:18:01 +01:00
Paul Cadman
e0337c18e4
Add internal core-eval option to evaluate named function identifier (#1819) 2023-02-08 17:23:11 +01:00
Paul Cadman
e0b5ac9c4a
Workaround ghcup issue on CI runner (#1821)
ghcup is currently broken after a CI runner update. See
https://github.com/actions/runner-images/issues/7061

This workaround is temporary while the underlying issue is fixed
upstream.
2023-02-08 15:57:57 +00:00
Łukasz Czajka
a288ae3a09
Comments about the usage of the JuvixCore recursors (#1818) 2023-02-08 12:49:06 +01:00
Łukasz Czajka
151bba5113
Output proper GEB Lisp programs (#1810)
* Closes #1807
2023-02-08 10:36:22 +01:00
Łukasz Czajka
58a0f196da
Documentation: how to compile Juvix programs (#1813) 2023-02-07 19:12:44 +01:00
Łukasz Czajka
45aa415b71
Short syntax for sequences of function and datatype parameters (#1809) 2023-02-06 19:01:54 +01:00
janmasrovira
929a8658ac
Special syntax for case (#1800)
- Closes #1716

---------

Co-authored-by: Paul Cadman <git@paulcadman.dev>
2023-02-06 14:53:35 +01:00
Łukasz Czajka
e5a9853998
Remove the usage annotation syntax (#1805) 2023-02-03 19:16:06 +01:00
Łukasz Czajka
14d1e5d614
Mid-square hashing implemented in JuvixCore (#1804)
- Can be compiled to GEB after merging #1778.
2023-02-03 13:09:41 +01:00
Łukasz Czajka
5e06441f48
Support integers in the GEB backend (#1778)
* Depends on PR #1748 
* Closes #1753
2023-02-03 12:45:57 +01:00
janmasrovira
50aca6f74c
Autocompletion for dev core compilation --target (#1803) 2023-02-02 18:09:22 +01:00
janmasrovira
fab40c6c99
Support letrec lifting without lambda lifting (#1794)
- Closes #1756
2023-02-02 11:10:12 +01:00
janmasrovira
3c33916034
Remove braces from let expressions (#1790) 2023-02-01 19:22:43 +01:00
Łukasz Czajka
5ec80641cb
Adapt benchmarks to the new pipeline (#1795)
Closes #1742
2023-02-01 15:44:09 +01:00
Paul Cadman
672e400a2a
Add REPL option to apply Core transformations (#1796)
Core transformations apply to the whole InfoTable, the REPL needs to
apply Core transformations to the single node that it compiles from the
user input string.

The solution in this commit is to:

1. Compile the input string as before to obtain a Core Node.
2. Add this Node to a copy of the Core InfoTable for the loaded file.
3. Apply the (CLI specified) Core transformations to this InfoTable.
4. Extract the (now transformed) Node from the InfoTable.

We can think of a way to improve this, maybe when we tackle allowing the
user to make new definitions in the REPL.

As soon as compilation of pattern matching is complete we should enable
some (all?) Core transformations by default.

Example:

At the moment we get the following result in the REPL:

```
juvix repl
...
Stdlib.Prelude> 1 + 1
suc (suc zero)
```

After this commit we can turn on `nat-to-int` transformation:

```
juvix repl -t nat-to-int
Stdlib.Prelude> 1 + 1
2
```

* Part of https://github.com/anoma/juvix/issues/1531
2023-02-01 13:00:06 +00:00
janmasrovira
f0e493f86f
Use the reader effect in the Core to GEB translation (#1791) 2023-02-01 12:53:57 +01:00
Łukasz Czajka
a5d19c5881
Basic Geb integration (#1748)
This PR:

- Closes #1647 

It gives compilation errors for language features that require more
substantial support (recursion, polymorphism). The additional features
are to be implemented in future separate PRs.
* Adds a new target `geb` to the CLI command `juvix dev core compile`,
which produces a `*.geb` output file in the `.juvix-build` directory.
* Adds a few tests. These are not yet checked automatically because
there is no GEB evaluator; checking the `*.geb` output would be too
brittle.
2023-02-01 12:04:05 +01:00
Jonathan Cubides
a5623c54ae
Use restore/save github action to speed up the CI testing (#1783)
This PR addresses a caching issue in our CI by streamlining each
operating system's build and test processes, reducing CI time. 🤞 Also,
our caching strategy has been updated with the new restore/save actions.
For example, we aim to cache the .stack folder, and if the stack build
is successful, the .stack-build. The building documentation job
continues depending on the Linux build. Upon merging this PR, we get
back to the point where the CI maintain a cache for each OS to be shared
among all PRs, significantly reducing CI testing time. The expected
scenario is as follows. The CI can take, on average, 35' in Linux to
build and test everything. Using caching, that time is reduced to less
than 10'. macOS is a different story. It can easily take one hour, and
even more, the first time to build and test the project. After that, it
might take an average of 20'.

- Caching strategies
[descriptions](https://github.com/actions/cache/blob/main/caching-strategies.md#saving-cache-even-if-the-build-fails)
- Closes #1776
2023-01-31 19:34:05 +01:00
Łukasz Czajka
4be4d58d30
String builtins (#1784)
- Progress for #1742 
* Adds builtin primitives for operations on strings and removes the
corresponding foreign & compile blocks.
2023-01-31 18:31:04 +01:00