The new folder will contain the new parser, macro expander and compiler. This commit also renames the namespace for the old parser `lean3.parser`
89 lines
2.9 KiB
Text
89 lines
2.9 KiB
Text
/-
|
||
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Sebastian Ullrich
|
||
-/
|
||
prelude
|
||
import init.meta.tactic
|
||
|
||
namespace lean3
|
||
|
||
-- TODO: make inspectable (and pure)
|
||
meta constant parser_state : Type
|
||
meta constant parser_state.env : parser_state → environment
|
||
meta constant parser_state.options : parser_state → options
|
||
meta constant parser_state.cur_pos : parser_state → pos
|
||
|
||
@[reducible] meta def parser := interaction_monad parser_state
|
||
@[reducible] meta def parser_result := interaction_monad.result parser_state
|
||
|
||
open interaction_monad
|
||
open interaction_monad.result
|
||
|
||
namespace parser
|
||
variable {α : Type}
|
||
|
||
meta constant set_env : environment → parser unit
|
||
|
||
/-- Make sure the next token is an identifier, consume it, and
|
||
produce the quoted name `t, where t is the identifier. -/
|
||
meta constant ident : parser name
|
||
/-- Make sure the next token is a small nat, consume it, and produce it -/
|
||
meta constant small_nat : parser nat
|
||
/-- Check that the next token is `tk` and consume it. `tk` must be a registered token. -/
|
||
meta constant tk (tk : string) : parser unit
|
||
/-- Parse an unelaborated expression using the given right-binding power. -/
|
||
protected meta constant pexpr (rbp := std.prec.max) : parser pexpr
|
||
|
||
/-- Do not report info from content parsed by `p`. -/
|
||
meta constant skip_info (p : parser α) : parser α
|
||
/-- Set goal info position of content parsed by `p` to current position. Nested calls take precedence. -/
|
||
meta constant set_goal_info_pos (p : parser α) : parser α
|
||
|
||
/-- Return the current parser position without consuming any input. -/
|
||
meta def cur_pos : parser pos := λ s, success (parser_state.cur_pos s) s
|
||
|
||
/-- Temporarily replace input of the parser state, run `p`, and return remaining input. -/
|
||
meta constant with_input (p : parser α) (input : string) : parser (α × string)
|
||
|
||
/-- Parse a top-level command. -/
|
||
meta constant command_like : parser unit
|
||
|
||
meta def parser_orelse (p₁ p₂ : parser α) : parser α :=
|
||
λ s,
|
||
let pos₁ := parser_state.cur_pos s in
|
||
result.cases_on (p₁ s)
|
||
success
|
||
(λ e₁ ref₁ s',
|
||
let pos₂ := parser_state.cur_pos s' in
|
||
if pos₁ ≠ pos₂ then
|
||
exception e₁ ref₁ s'
|
||
else result.cases_on (p₂ s)
|
||
success
|
||
exception)
|
||
|
||
meta instance : alternative parser :=
|
||
{ failure := @interaction_monad.failed _,
|
||
orelse := @parser_orelse,
|
||
..interaction_monad.monad }
|
||
|
||
|
||
-- TODO: move
|
||
meta def {u v} many {f : Type u → Type v} [monad f] [alternative f] {a : Type u} : f a → f (list a)
|
||
| x := (do y ← x,
|
||
ys ← many x,
|
||
return $ y::ys) <|> pure list.nil
|
||
|
||
local postfix `?`:100 := optional
|
||
local postfix `*`:100 := many
|
||
|
||
meta def sep_by : parser unit → parser α → parser (list α)
|
||
| s p := (list.cons <$> p <*> (s *> p)*) <|> return []
|
||
|
||
meta constant of_tactic : tactic α → parser α
|
||
|
||
meta instance : has_coe (tactic α) (parser α) :=
|
||
⟨of_tactic⟩
|
||
|
||
end parser
|
||
end lean3
|