lean4-htt/library/init/lean/parser/syntax.lean
Sebastian Ullrich 46f734b1b1 refactor(library/init/lean/parser/reader): replace macro with syntax_node_kind
Also make sure that the name inside a node kind is the full name of the
declaration. This way, we cannot have accidentally conflicting node kind names.
2018-08-28 13:13:14 -07:00

128 lines
3.8 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
-/
prelude
import init.lean.name init.lean.parser.parsec
namespace lean
namespace parser
/-- De Bruijn index relative to surrounding 'bind' macros -/
@[reducible] def var_offset :=
@[reducible] def macro_scope_id :=
--TODO(Sebastian): move
structure substring :=
(start : string.iterator)
(stop : string.iterator)
structure source_info :=
(leading : substring)
(pos : parsec.position)
(trailing : substring)
structure resolved :=
-- local or (overloaded) global
(decl : var_offset ⊕ list name)
/- prefix of the reference that corresponds to the decl. All trailing name components
are field accesses. -/
(«prefix» : name)
instance resolved.has_to_format : has_to_format resolved := ⟨λ r, to_fmt (r.decl, r.prefix)⟩
structure syntax_ident :=
(info : option source_info) (name : name) (msc : option macro_scope_id) (res : option resolved)
inductive atomic_val
| string (s : string)
| name (n : name)
structure syntax_atom :=
(info : option source_info) (val : atomic_val)
/-- A simple wrapper that should remind you to use the static declaration instead
of hard-coding the node name. -/
structure syntax_node_kind :=
-- should be equal to the name of the declaration this structure instance was bound to
(name : name)
structure syntax_node (syntax : Type) :=
(kind : option syntax_node_kind) (args : list syntax)
inductive syntax
| ident (val : syntax_ident)
/- any non-ident atom -/
| atom (val : syntax_atom)
| node (val : syntax_node syntax)
| missing
instance : inhabited syntax :=
⟨syntax.missing⟩
instance coe_string_syntax : has_coe string syntax :=
⟨λ s, syntax.atom ⟨none, atomic_val.string s⟩⟩
instance coe_name_syntax : has_coe name syntax :=
⟨λ n, syntax.ident ⟨none, n, none, none⟩⟩
def substring.to_string (s : substring) : string :=
(s.start.extract s.stop).get_or_else ""
namespace syntax
open lean.format
protected mutual def to_format, to_format_lst
with to_format : syntax → format
| (ident id) :=
let n :=
to_fmt id.name ++
(match id.msc with
| some msc := "!" ++ to_fmt msc
| none := "") ++
(match id.res with
| some res :=
":" ++
(match res.decl with
| sum.inl idx := to_fmt idx
| sum.inr [n] := to_fmt n
| sum.inr ns := to_fmt ns)
++ if res.prefix = id.name then
to_fmt ""
else
to_fmt ".(" ++ to_fmt (id.name.replace_prefix res.prefix name.anonymous) ++ ")"
| none := "") in
n
| (atom ⟨_, atomic_val.string s⟩) := to_fmt $ repr s
| (atom ⟨_, atomic_val.name n⟩) := to_fmt "`" ++ to_fmt n
| (node {kind := none, args := args, ..}) :=
sbracket $ join_sep (to_format_lst args) line
| (node {kind := some kind, args := args, ..}) :=
paren $ join_sep (to_fmt kind.name :: to_format_lst args) line
| missing := "<missing>"
with to_format_lst : list syntax → list format
| [] := []
| (s::ss) := to_format s :: to_format_lst ss
def reprint_with_info : option source_info → string → string
| (some info) inner := info.leading.to_string ++ inner ++ info.trailing.to_string
| none inner := inner
mutual def reprint, reprint_lst
with reprint : syntax → string
| (ident id) := reprint_with_info id.info id.name.to_string
| (atom ⟨info, atomic_val.string s⟩) := reprint_with_info info s
| (atom ⟨info, atomic_val.name n⟩) := reprint_with_info info n.to_string
| (node n) := reprint_lst n.args
| missing := ""
with reprint_lst : list syntax → string
| [] := ""
| (s::ss) := reprint s ++ reprint_lst ss
end syntax
instance : has_to_format syntax := ⟨syntax.to_format⟩
instance : has_to_string syntax := ⟨to_string ∘ to_fmt⟩
end parser
end lean