feat(library/init/lean/elaborator): initial version of translating syntax trees to preterms
This commit is contained in:
parent
9e8dfbad79
commit
cd287629cb
3 changed files with 69 additions and 3 deletions
|
|
@ -7,6 +7,8 @@ Elaborator for the Lean language: takes commands and produces side effects
|
|||
-/
|
||||
prelude
|
||||
import init.lean.parser.module
|
||||
import init.lean.expander
|
||||
import init.lean.expr
|
||||
|
||||
namespace lean
|
||||
namespace elaborator
|
||||
|
|
@ -62,6 +64,69 @@ do cfg ← read,
|
|||
|
||||
local attribute [instance] name.has_lt_quick
|
||||
|
||||
def mangle_ident (id : syntax_ident) : name :=
|
||||
id.scopes.foldl name.mk_numeral id.val
|
||||
|
||||
def to_level : syntax → elaborator_m level
|
||||
| stx := do
|
||||
some k ← pure stx.kind | error stx $ "unexpected atom: " ++ to_string stx,
|
||||
match k with
|
||||
| level.leading := (match view level.leading stx with
|
||||
| level.leading.view.hole _ := pure $ level.mvar "u" -- TODO(Sebastian): name?
|
||||
| level.leading.view.lit lit := pure $ level.of_nat lit.to_nat
|
||||
| level.leading.view.var id := pure $ level.param $ mangle_ident id
|
||||
| _ := error stx "ill-formed universe level")
|
||||
| _ := error stx $ "unexpected node: " ++ to_string k.name
|
||||
|
||||
def to_pexpr : syntax → elaborator_m expr
|
||||
| stx := do
|
||||
some k ← pure stx.kind | error stx $ "unexpected atom: " ++ to_string stx,
|
||||
match k with
|
||||
| @ident_univs := (match view ident_univs stx with
|
||||
| {id := id, univs := some univs} := expr.const (mangle_ident id) <$> univs.levels.mmap to_level
|
||||
| {id := id, univs := none} := pure $ expr.const (mangle_ident id) [])
|
||||
| @app := let v := view app stx in
|
||||
expr.app <$> to_pexpr v.fn <*> to_pexpr v.arg
|
||||
| @lambda := do
|
||||
({binders := {leading_ids := [],
|
||||
remainder := binders_remainder.view.mixed [mixed_binder.view.bracketed bb]},
|
||||
body := body}) ←
|
||||
pure $ view lambda stx | error stx "ill-formed lambda",
|
||||
(bi, bc) ← match bb with
|
||||
| bracketed_binder.view.explicit {content := bc} :=
|
||||
(match bc with
|
||||
| explicit_binder_content.view.other bc := pure (binder_info.default, bc)
|
||||
| _ := error stx "ill-formed lambda")
|
||||
| bracketed_binder.view.implicit {content := bc} :=
|
||||
pure (binder_info.implicit, bc)
|
||||
| bracketed_binder.view.strict_implicit {content := bc} :=
|
||||
pure (binder_info.strict_implicit, bc)
|
||||
| bracketed_binder.view.inst_implicit {content := bc} :=
|
||||
prod.mk binder_info.inst_implicit <$> (match bc.kind with
|
||||
| some @inst_implicit_anonymous_binder :=
|
||||
pure {ids := ["_inst_"], type := some {type := (view inst_implicit_anonymous_binder bc).type}}
|
||||
| some @inst_implicit_named_binder :=
|
||||
let v := view inst_implicit_named_binder bc in
|
||||
pure {ids := [v.id], type := some {type := v.type}}
|
||||
| _ := error stx "ill-formed lambda")
|
||||
/-| bracketed_binder.view.anonymous_constructor {content := bc} :=-/
|
||||
| _ := error stx "ill-formed lambda",
|
||||
{ids := [binder_ident.view.id id], type := some type} ← pure bc | error stx "ill-formed lambda",
|
||||
expr.lam (mangle_ident id) bi <$> to_pexpr type.type <*> to_pexpr body
|
||||
| @sort := (match view sort stx with
|
||||
| sort.view.Sort _ := pure $ expr.sort level.zero
|
||||
| sort.view.Type _ := pure $ expr.sort $ level.succ level.zero)
|
||||
| _ := error stx $ "unexpected node: " ++ to_string k.name
|
||||
|
||||
def declaration.elaborate : elaborator :=
|
||||
λ stx, do
|
||||
let decl := view «declaration» stx,
|
||||
-- just test `to_pexpr` for now
|
||||
match decl.inner with
|
||||
| declaration.inner.view.def_like {val := decl_val.view.simple val, ..} :=
|
||||
to_pexpr val.body *> pure ()
|
||||
| _ := pure ()
|
||||
|
||||
def prec_to_nat : option precedence.view → nat
|
||||
| (some prec) := prec.term.to_nat
|
||||
| none := 0
|
||||
|
|
@ -284,7 +349,8 @@ def elaborators : rbmap name coelaborator (<) := rbmap.from_list [
|
|||
(notation.name, notation.elaborate),
|
||||
(reserve_notation.name, reserve_notation.elaborate),
|
||||
(section.name, section.elaborate),
|
||||
(namespace.name, namespace.elaborate)
|
||||
(namespace.name, namespace.elaborate),
|
||||
(declaration.name, declaration.elaborate)
|
||||
] _
|
||||
|
||||
protected def max_recursion := 100
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ structure syntax_node_kind :=
|
|||
@[pattern] def no_kind : syntax_node_kind := ⟨`lean.parser.no_kind⟩
|
||||
|
||||
/-- A hygiene marker introduced by a macro expansion. -/
|
||||
@[irreducible, derive decidable_eq has_to_format]
|
||||
@[derive decidable_eq has_to_format]
|
||||
def macro_scope := nat
|
||||
|
||||
/-
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ node! ident_univ_spec [".{", levels: level.parser+, "}"]
|
|||
|
||||
@[derive parser.has_tokens parser.has_view]
|
||||
def ident_univs.parser : term_parser :=
|
||||
node! ident_univs [id: ident.parser, univ: (monad_lift ident_univ_spec.parser)?]
|
||||
node! ident_univs [id: ident.parser, univs: (monad_lift ident_univ_spec.parser)?]
|
||||
|
||||
namespace term
|
||||
/-- Access leading term -/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue