Commit graph

244 commits

Author SHA1 Message Date
Sebastian Ullrich
d10ff29bea fix(library/init/lean/parser/term): placeholder binder after bracketed binder 2018-11-19 13:38:45 +01:00
Sebastian Ullrich
cd287629cb feat(library/init/lean/elaborator): initial version of translating syntax trees to preterms 2018-11-19 13:38:45 +01:00
Sebastian Ullrich
9e8dfbad79 perf(library/init/lean/parser): reintroduce separate syntax.ident constructor with much simpler and more efficient encoding 2018-11-18 16:55:04 +01:00
Sebastian Ullrich
68dad5e77c chore(library/init/lean/parser/token): raw: unnecessary try 2018-11-18 16:11:41 +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
Sebastian Ullrich
600b7ceb28 fix(library/init/lean/parser/syntax): make sure macro scopes are not pushed inside of ident nodes 2018-11-14 17:23:32 +01:00
Leonardo de Moura
182812a278 chore(library/init/lean/parser/token): make sure generate code does contain partially applied reader_t.or_else and reader_t.bind
@kha This one was crazy, the compiler created a join point for the
continuation of the match-expression. Each case of the match was
invoking the join point with a different parser. Two of the branches
were the partially applied `reader_t.bind` and `reader_t.orelse`.
This change did not improve the performance much, but it makes sure we
don't waste time trying to figure out why we have these two partial
applications in the call graph.
2018-11-08 17:39:46 -08:00
Leonardo de Moura
6eca6bdb0e perf(library/init/lean/parser/term): avoid eta-expansion issues
cc @kha
2018-11-08 16:21:37 -08:00
Leonardo de Moura
1cb22b6801 perf(library/init/lean/parser/command): move common command parsers to the beginning of the list
@kha This modification saved 150k object allocations on my machine.

BTW, the function
```
def command_parser.run (commands : list command_parser) (p : command_parser)
  : parser_t command_parser_config id syntax :=
λ cfg, (p.run cfg).run_parsec $ λ _, any_of $ commands.map (λ p, p.run cfg)
```
is also affected by the problem I described at Zulip. It is another
example where eager eta-expansion is bad. Every time we call it, we
will create approx. 20 closures and 20 cons memory cells. We have at
least 600 commands in core.lean. So, just the `map` nested there will
generate 24k memory allocations. Moreover, the problem will get worse as we add
more commands.
2018-11-08 14:45:34 -08:00
Leonardo de Moura
ad9aa3bc19 perf(library/init/lean/parser/token): optimize symbol
Same trick used at `str`.

@kha: I also replaced `"token " ++ sym'` with `sym'`. We were creating
thousands of strings of the form "token ...".
2018-11-08 14:05:09 -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
Sebastian Ullrich
eaeb0a40a5 chore(library/init/lean/parser): do not expose the parser cache as monad_state 2018-11-08 16:01:19 +01:00
Sebastian Ullrich
bd70dc1fc9 perf(library/init/lean/parser): move backtrackable state from parser_core_t to module_parser_m 2018-11-08 15:58:41 +01:00
Sebastian Ullrich
41f4a34d4b feat(library/init/lean/parser/token): cache hit statistics 2018-11-08 14:52:54 +01:00
Sebastian Ullrich
d77c6169f4 chore(library/init/lean/parser/combinators): node: small simplification 2018-11-08 10:43:17 +01:00
Sebastian Ullrich
7fdfdb1784 chore(library/init/lean/parser): remove unnecessary class constraints 2018-11-06 21:45:08 +01:00
Sebastian Ullrich
090c4c0ce7 feat(library/init/lean/syntax): add lazily propagated macro scopes to syntax_node 2018-11-06 16:46:50 +01:00
Sebastian Ullrich
fc4dcd19cf refactor(library/init/lean/parser): use ident.view in syntax.to_format 2018-11-05 17:57:00 +01:00
Sebastian Ullrich
8c27f0aac6 refactor(frontends/lean/elaborator,library/init/lean): finish no_kind refactoring 2018-11-04 20:24:40 +01:00
Sebastian Ullrich
93fc1fd1de fix(library/init/lean/parser/combinators): node: do not wrap error in first argument 2018-10-30 17:43:05 +01:00
Sebastian Ullrich
74bd182bc8 perf(library/init/lean/parser/combinators): make node semireducible 2018-10-30 17:43:05 +01:00
Sebastian Ullrich
0d7ea62f9a perf(frontends/lean/elaborator,library/init/lean): put out_params first to benefit from instance pre-filtering 2018-10-30 17:43:05 +01:00
Sebastian Ullrich
2e0d6649be perf(library/init/lean/parser/basic): make basic_parser_m semireducible 2018-10-30 17:43:05 +01:00
Sebastian Ullrich
188ab30a9c fix(library/init/lean/parser/declaration): precedence for attribute arguments 2018-10-30 17:43:05 +01:00
Leonardo de Moura
cc3767e6a5 refactor(library/init/data): avoid indirection at rbmap
Now, the nodes in a `rbmap` contain the key and value, and we avoid
one level of indirection. `rbmap`s are more common than `rbtree`.
We implement `rbtree A` as `rbmap A unit`.
2018-10-26 17:14:09 -07: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
08d8856112 perf(library/init/lean/parser/token): replace longest_match in token with custom implementation 2018-10-22 22:33:58 +02: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
880137f0ed feat(library/init/lean/parser/basic): mark tokens with @[nospecialize] 2018-10-18 15:20:54 -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
Sebastian Ullrich
1d0456adf5 fix(library/init/lean/parser/term): revert refactoring that broke sort_apps of Type 2018-10-17 09:13:52 +02:00
Sebastian Ullrich
f29d886c29 fix(library/init/lean/parser/string_literal): letter escapes 2018-10-16 22:43:30 +02:00
Leonardo de Moura
88de81077c feat(library/compiler/specialize): do not specialize instances unless they are marked with [specialize]
@kha: I changed the specialization candidate selection procedure.
Now, instances are not considered for specializations unless we mark
them with `[specialize]`. The idea is that an instance application is
morally just creating the "dictionary" for invoking a polymorphic
function.
2018-10-15 18:29:29 -07:00
Leonardo de Moura
4cfe44bed0 feat(library/compiler/specialize): add nospecialize attribute
@kha I had to add this attribute because the specializer was generated
many specialization candidates for functions that take `[has_tokens ...]`
as an argument. Moreover, these candidates had a lot of
dependencies. I am trying to workaround this issue by marking the
instances with the new attribute `[nospecialize]`.
I did not mark instances created by `[derive]`. It is quite tedious to
do it.

BTW, when I was investigating the problem I stumbled at `node.view`.
Its type is:
```
node.view :
  Π {α : Type} {m : Type → Type} [_inst_1 : monad m] [_inst_2 : monad_except (parsec.message syntax) m]
  [_inst_3 : monad_parsec syntax m] [_inst_4 : alternative m] (k : syntax_node_kind) (rs : list (m syntax))
  [i : @has_view syntax_node_kind k α], @has_view (m syntax) (@node m _inst_1 _inst_2 _inst_3 _inst_4 k rs) α
```
This looks wrong: the view depends on `[monad_parsec syntax m]`

We should also make sure definitions do not have unnecessary type
class instances. Otherwise, we will put additional stress on the code
specializer. One option is to change the frontend and filter unused
instances.
2018-10-15 17:44:26 -07:00
Sebastian Ullrich
a820b9955f perf(library/init/lean/parser/term): index term parsers by leading token
66% speedup on core.lean
2018-10-15 10:21:08 +02:00
Sebastian Ullrich
2df885d9a3 fix(library/init/lean/parser/token): broken end of comment 2018-10-13 12:01:48 -07:00
Sebastian Ullrich
8a88d4d5e2 feat(library/init/lean/parser/token): string literals
hard-coded for now because we do not have general support for variable-length
tokens yet
2018-10-13 08:11:36 -07:00
Sebastian Ullrich
758d258210 fix(library/init/lean/parser/term): rename term.ident to ident_univs to remove confusion with ident
`protected` didn't do anything here
2018-10-13 08:11:36 -07:00
Leonardo de Moura
c0b76704a0 chore(library/init/lean/parser/level): typo 2018-10-12 11:56:34 -07:00
Leonardo de Moura
15a25d5aa9 chore(library/init/lean/parser): add a few comments 2018-10-11 15:54:57 -07:00
Sebastian Ullrich
8e0778e54a fix(library/init/lean/parser/token): parse whitespace after raw_ident 2018-10-08 09:30:48 -07:00
Sebastian Ullrich
4e3f9b46c2 refactor(library/init/lean/parser/token): remove weird with_source higher-order function 2018-10-05 08:52:04 -07:00
Sebastian Ullrich
ebeec844af perf(library/init/lean/parser): minor performance tweaks 2018-10-05 08:52:04 -07:00
Sebastian Ullrich
22714b9b10 perf(library/init/lean/parser/combinators): node: no need to fill up with syntax.missing anymore
Views now do iterated pattern matches instead of a single one
2018-10-04 14:27:24 -07:00
Sebastian Ullrich
959948b901 feat(library/init/lean): even more core.lean progress 2018-10-03 16:00:08 -07:00