lean4-htt/library/init/lean/expander.lean
2018-09-24 09:53:28 -07:00

69 lines
2.5 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2018 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Sebastian Ullrich
Macro expander for the Lean language
-/
prelude
import init.lean.parser.module
namespace lean
namespace expander
open parser
open parser.term
open parser.command
open parser.command.notation_spec
@[derive monad]
def transform_m := option_t $ except message
abbreviation transformer := syntax → transform_m syntax
section
local attribute [reducible] transform_m
instance coe_option_transform_m {α : Type} : has_coe (option α) (transform_m α) :=
⟨λ o, match o with some a := pure a | none := failure⟩
end
def mixfix.transform (stx : tysyntax mixfix.view) : transform_m (tysyntax notation.view) :=
do v ← view stx,
-- TODO: reserved token case
notation_symbol.view.quoted quoted ← view v.symbol,
quoted ← view quoted,
prec ← view quoted.prec,
-- `notation` allows more syntax after `:` than mixfix commands, so we have to do a small conversion
let prec_to_action : precedence.view → action.view :=
λ prec, {action := review $ action_kind.view.prec prec.prec, ..prec},
k ← view v.kind,
let (spec, term) := match k : _ → (notation_spec.view × syntax) with
| mixfix.kind.view.prefix _ :=
let b : tysyntax parser.ident.view := review {part := review $ ident_part.view.default "b"} in
(notation_spec.view.rules $ review {
rules := review [review {
symbol := v.symbol,
transition := review $ some $ review $ transition.view.arg $ review {
id := b,
action := review $ do prec ← prec, prec ← view prec, pure $ review $ prec_to_action prec}}]},
review {lambda.view . op := review lambda_op.view.«λ», binders := review [review $
binder.view.unbracketed $ review {
ids := review [review $ binder_id.view.id $ review {id := b}]}
],
body := review_as app.view {fn := v.term, arg := b}})
| _ := sorry,
pure $ review {spec := review spec, term := term}
local attribute [instance] name.has_lt_quick
-- TODO(Sebastian): replace with attribute
def transformers : rbmap name transformer (<) := rbmap.from_list [
(mixfix.name, mixfix.transform)
] _
def expand (stx : syntax) : except message syntax :=
--TODO(Sebastian): recursion, hygiene, error messages
do syntax.node {kind := some k, ..} ← pure stx | pure stx,
some t ← pure $ transformers.find k.name | pure stx,
flip option.get_or_else stx <$> t stx
end expander
end lean