Commit graph

66 commits

Author SHA1 Message Date
Leonardo de Moura
e58949e938 chore(library/init/control/id): rename id monad to Id 2019-03-29 16:45:52 -07:00
Leonardo de Moura
b29fb57fcf refactor(library/init/data/string/basic): String.Pos as Nat
@kha: I initially planned to use the UTF8 API only in very special
cases, but I found them to be super useful. They allow us to implement
an efficient String library mostly in Lean.
However, the there was a problem: `abbrev String.Pos := USize`.
This definition is fine for a low level API, but this is not the case
anymore. By having `String.Pos := USize`, we will not be able to
prove natural theorems for the `String` API. For example,
`String.map id s = s` did not hold. We would have to include the
artificial antecedent `s.length <= usizeMax` (or something like this).
I suspect it would be very painful.
So, this commit defines `String.Pos` as `Nat`. The performance
overhead seems to be very small.
2019-03-26 15:35:52 -07:00
Leonardo de Moura
60f8d17942 refactor(library/init/data/string/basic): simplify String.Iterator
The `offset` field is problematic because it prevents us from having an
efficient way of moving back and forth between `String.Pos` and `String.Iterator`.

@kha I temporarily added `String.OldIterator` for making sure the
parser doesn't break. This is a temporary fix that will be eliminated
after we replace `parsec`.
2019-03-25 07:57:12 -07:00
Leonardo de Moura
5b08bf18c5 feat(library/init/lean): improving options
@kha It will be awesome to automate the following idiom with a macro :)
```
def defIndent  := 4
def getIndent (o : Options) : Nat   := o.get `format.indent defIndent
@[init] def indentOption : IO Unit :=
registerOption `format.indent { defValue := defIndent, group := "format", descr := "indentation" }
```
2019-03-24 09:30:20 -07:00
Leonardo de Moura
4a08d6715a chore(library/init/data/array): add HasEmptyc instance 2019-03-21 17:06:56 -07:00
Leonardo de Moura
91204a52d6 chore(library/init/data/dlist): Dlist => DList 2019-03-21 17:03:22 -07:00
Leonardo de Moura
3befc219c9 chore(library/init): Empty => empty when it is a function 2019-03-21 17:03:15 -07:00
Leonardo de Moura
2be87ecd92 chore(library/init): Bool.tt => Bool.true and Bool.ff => Bool.false 2019-03-21 15:06:44 -07:00
Leonardo de Moura
f8113a01eb chore(library): unit => Unit 2019-03-21 15:06:44 -07:00
Leonardo de Moura
04e20623e6 chore(*): use lowercase dir names 2019-03-21 15:06:44 -07:00
Leonardo de Moura
67fb78bb47 chore(*): renaming files 2019-03-21 15:06:44 -07:00
Sebastian Ullrich
beda5f5f43 chore(library): capitalize types and namespaces 2019-03-21 15:06:43 -07:00
Sebastian Ullrich
b939162168 chore(library): switch from snake_case to camelCase 2019-03-21 15:06:43 -07:00
Leonardo de Moura
ecdb9d6df0 feat(library/init, frontends/lean): add abbreviation for abbreviation 2019-03-15 16:01:25 -07:00
Sebastian Ullrich
81615fc856 refactor(library/init/lean/parser/module): replace coroutines with explicit snapshot state 2019-03-07 10:32:28 -08:00
Sebastian Ullrich
cfce916438 perf(library/init/lean/parser/module): make sure commands_aux is tail-recursive 2019-03-06 13:58:26 +01:00
Sebastian Ullrich
0911d16bc3 feat(library/init/lean): compute and show error positions 2018-12-20 14:28:18 +01:00
Sebastian Ullrich
5b44a6f93d feat(library/init/lean/parser/parsec): structured doc_comment syntax nodes 2018-12-19 14:42:33 +01:00
Leonardo de Moura
7937f1e010 chore(library/init/util): remove util.lean
At least initially, we will not support these primitives in the new compiler.
2018-11-15 16:27:52 -08:00
Leonardo de Moura
0dfeb8a79c perf(library/init/lean/parser/parsec): optimize str and raw_str
Both `str` amd `raw_str` are used with string literals. This commit
makes sure we don't need to recompute the nested term
`dlist.singleton (repr s)`. This modification saves .2 secs when
parsing `core.lean` on my MacBook.

cc @kha
2018-11-08 11:18:21 -08:00
Leonardo de Moura
96ef30e827 chore(library/init/lean/parser/parsec): remove private
Motivation: allow us to change the attribute in other files
2018-10-25 10:55:32 -07:00
Leonardo de Moura
370f67b27b feat(library/init/lean/parser/parsec): mark *_mk_res functions as [inline_if_reduce] 2018-10-25 10:10:54 -07:00
Sebastian Ullrich
163f996d00 perf(library/init/lean/parser): inline some trivial functions 2018-10-22 22:23:54 +02:00
Leonardo de Moura
19be59065a perf(library/init/lean/parser/parsec): mark bind_mk_res and orelse_mk_res with @[inline]
A few weeks ago, it was not feasible to inline `bind_mk_res` and
`orelse_mk_res` because the compilation time would increase a lot.
Since then I have improved the heuristics for deciding whether to float
`cases_on` or not.
So, I tried today to mark them with `@[inline]` again.
The corelib build time increased only 1.2 secs, but the `parser1.lean` runtime improved:
Before:
```
num. allocated objects:  18025367
num. allocated closures: 2988476
```
After:
```
num. allocated objects:  15774515
num. allocated closures: 2488695
```
I used my desktop to collect the numbers above.
2018-10-22 11:11:21 -07:00
Leonardo de Moura
89afabae29 refactor(library/init/lean/parser/parsec): make sure custom error message doesn't need to be inhabited 2018-10-21 10:57:23 -07:00
Leonardo de Moura
0f7745a3e0 feat(library/init/lean/parser/parsec): mark whitespace and num with [noinline]
We want them to be specialized for a given monad stack, but not
inlined. If we inline them, then every occurrence of `whitespace` and
`num` will specialize the nested `take_while?` application.
This is bad since we don't cache them.
2018-10-18 16:33:10 -07:00
Leonardo de Moura
677864dee5 feat(library/init/lean/parser/parsec): mark some of the parsec functions with @[specialize] 2018-10-18 16:23:47 -07:00
Leonardo de Moura
38bc3beffb fix(library/init): alternative instances
Both `alternative` and `monad` implement `applicative`. However,
their default implementations for `seq_right` and `seq_left` are
different. The `alternative` implementation uses the inefficient default
version for `seq_right` available at `applicative`:
```
(seq_right := λ α β a b, const α id <$> a <*> b)
```
instead of the more efficient
```
(seq_right := λ α β x y, x >>= λ _, y)
```
defined at `monad` using the `bind` operator.

This commit makes sure the `applicative` instances for `reader_t`,
`state_t`, `option` and `parsec_t` use the efficient version.
I found the problem when inspecting the generated code for:
```
def symbol (s : string) : parsec' unit :=
(str s *> whitespace) <?> ("'" ++ s ++ "'")
```
2018-10-17 14:25:50 -07:00
Leonardo de Moura
15a25d5aa9 chore(library/init/lean/parser): add a few comments 2018-10-11 15:54:57 -07:00
Leonardo de Moura
429f844fbe @chore(library/init/lean/parser/parsec): remove @[inline] annotations to reduce compilation time
We will mark them as `@[specialize]` as soon as we implement code specialization
2018-10-01 17:30:13 -07:00
Sebastian Ullrich
ab5460d010 perf(library/init/lean/parser/parsec): more [inline] attributes 2018-10-01 16:32:11 -07:00
Sebastian Ullrich
6a23ecfe9c fix(library/init/lean/parser/parsec): fix lookahead, longest_match 2018-10-01 09:02:39 -07:00
Leonardo de Moura
b3451fb682 perf(library/init/lean/parser/parsec): merge ok and ok_eps 2018-09-27 15:14:37 -07:00
Leonardo de Moura
64b5e05a3e feat(library/init/lean/parser/parsec): try to minimize the amount of inlined code 2018-09-27 14:53:30 -07:00
Leonardo de Moura
dd50cc1785 feat(library/init/lean/parser/parsec): add orelse_cont to improve compilation time 2018-09-27 13:22:18 -07:00
Leonardo de Moura
b4b42ef8b2 feat(library/init/lean/parser/parsec): missing [inline] 2018-09-24 18:57:49 -07:00
Sebastian Ullrich
80e37aa8c5 chore(library/init/lean/parser): improve error messages 2018-09-19 12:36:34 -07:00
Sebastian Ullrich
468ac814a7 perf(library/init/lean/parser/token): move number' out of longest_match call 2018-09-14 16:33:04 -07:00
Sebastian Ullrich
123adc1ae2 fix(library/init/lean/parser/parsec): longest_match: do not consume if no parser consumed 2018-09-14 16:33:04 -07:00
Sebastian Ullrich
384389c84b refactor(library/init/lean/parser/basic): move out rec_t and trie 2018-09-14 16:33:04 -07:00
Sebastian Ullrich
6733d5ab21 feat(library/init/lean/parser/token): comments are not tokens anymore 2018-09-14 16:33:04 -07:00
Sebastian Ullrich
98e09c274f feat(library/init/lean/parser/{pratt,level}): factor out pratt combinator, implement level parsers 2018-09-13 16:38:40 -07:00
Leonardo de Moura
afd54039ab chore(library): remove >>, we should use *> 2018-09-12 17:31:21 -07:00
Leonardo de Moura
9e305a5f26 chore(library): remove return, we should use pure 2018-09-12 16:51:11 -07:00
Sebastian Ullrich
9c96aec3dc perf(library/init/lean/parser/parsec): inline pure, bind, and left_over 2018-09-05 09:58:49 -07:00
Sebastian Ullrich
cec1ee2564 feat(library/init/lean/parser/parsec): reintroduce parsec_t 2018-08-29 16:42:24 -07:00
Leonardo de Moura
261dc999d0 refactor(frontends/lean/elaborator): mark thunk as opaque, and thunk A to A is now a coercion
@kha I was working in the new declaration type and using tasks there.
Since we don't have tasks yet in Lean, I decided to start refactoring
the `thunk` type. I defined it as:

```
-- TODO(Leo): mark as opaque, it is implemented by the new runtime
structure thunk (α : Type u) : Type u :=
(fn : unit → α)

def thunk.pure {α : Type u} (a : α) : thunk α :=
⟨λ _, a⟩

def thunk.get {α : Type u} (t : thunk α) : α :=
t.fn ()
```

The idea is to use the runtime primitives to implement them.
Then, I realized the support for `thunk`s in the elaborator are quite
hacky. Given `f x`, if `f`'s domain has type `thunk A`, we elaborate
`f x` as `f (fun _, x)` even if `x` has type `thunk A`.
This is quite bad, for example, suppose we have
```
def f (x : thunk A) := ...
```
Then, the following definition is type incorrect.
```
def g (x : thunk A) := f x
```
and we are forced to write
```
def g (x : thunk A) := f (x ())
```
The term `f (x ())` will be elaborated as `f (fun _, x ())` and an
unnecessary closure is created at runtime.

This mechanism inherited from Lean 3 is also incompatible with the
new thunk definition. Given `x : thunk A`, I want to write `x.get`
to retrieve the value instead of `x ()` as in Lean 3.
However, `x.get` expands into the nonsensical `(fun _, x).get`.

So, I decided to view the mapping `A` to `thunk A` as a "coercion".
I used double quotes, because it is a macro instead of a function.
If it were a coercion, then we would be using `thunk.pure` to coerce
values but this is not we want most of the time.
For example, given `f : thunk A -> B` and a term `t : A`, when we write
`f t`, we want it to be converted into `f (fun _, t)` instead of
`f (thunk.pure t)` which would eagerly compute `t`. The transformation
`t` into `fun _, t` is syntactic.
We cannot implement it using type classes. I implemented it as
a hard-coded extra case like the one from `Prop` to `bool`.
We can also add a coercion from `thunk A` to `A` to avoid the `.get`.

That being said, I had a few breakages in the code base since we only
use coercions when the given and expected type do not contain
metavariables.
2018-08-21 15:27:51 -07:00
Sebastian Ullrich
6b55e24ab7 feat(library/init/{io,control/except}): use lift_t to automatically upcast io and other errors 2018-08-21 08:43:09 -07:00
Sebastian Ullrich
f52395140a feat(library/init/lean/parser/parsec): add dbg helper combinator 2018-08-02 13:32:42 -07:00
Sebastian Ullrich
87dc8adbe6 fix(library/init/lean/parser/parsec): monad_except.catch should not reset position, consumed flag 2018-07-30 17:50:37 -07:00