| Safe Haskell | Safe |
|---|---|
| Language | Haskell2010 |
ReWire.Eidos.Parse
Description
Parser for the Eidos concrete syntax (.eir; doc/eidos.md, section 9).
ReWire.Eidos.Pretty is the other half of the round-trip contract:
parse . pretty is the identity on programs modulo annotations, and
pretty . parse . pretty == pretty is a tested fixpoint.
The concrete syntax does not carry a type for every binder occurrence, so (as in ReWire.Hyle.Parse) parsing is followed by an elaboration pass that reconstructs what the format leaves implicit:
- variable occurrences print bare (
x#12) and receive their binder'sId(unique, occurrence text, and signature) from a scope map; an occurrence whose unique is not in scope is an error; - the case binder prints bare and receives the scrutinee's synthesized type;
- join point labels print with no signature; a label's signature is reconstructed as arrows from its parameter types to its body's synthesized type (doc/eidos.md section 4.2).
Join point scoping, on the other hand, is resolved during parsing
proper: a scope map of join binders (keyed by unique) is threaded
through the expression grammar, Jump sites take their JoinId
(in particular its arity) from the binding, and a jump to an unbound
label is a parse-time error — labels are lexically scoped and never
escape (section 3.4), so no forward references exist. Join points are
not recursive: a label is not in scope in its own body.
Two lexical devices keep the grammar newline-insensitive:
- a name in expression-atom position followed by
::is not an atom (it starts the next definition's signature line) — the expression grammar itself has no bare::; - a
occ#uniqtoken in type-atom position is a type variable only if its unique is bound by the enclosing signature'sforall, so the equation name following a signature line never extends the signature's type. (Both rely on global binder uniqueness; a program that reuses a signature's type-variable unique as a term binder unique — ill-formed per section 2 — may misparse.)
The machine level's process declarations parse in ReWire.Synolon.Parse, which reuses this grammar and elaboration for the expressions, definitions, and datatypes a Synolon program embeds.
Synopsis
- parseEir :: (MonadError AstError m, MonadIO m) => FilePath -> m Program
- parseEirText :: MonadError AstError m => Text -> FilePath -> m Program
- data Scope = Scope {}
- type TVScope = HashMap Uniq TyVar
- type JScope = HashMap Uniq JoinId
- pendingSig :: Sig
- kindP :: Parser Kind
- tyP :: TVScope -> Parser Ty
- sigP :: TVScope -> Parser (Sig, TVScope)
- param :: TVScope -> Parser Id
- expP :: Scope -> Parser Exp
- atomP :: Scope -> Parser Exp
- defnP :: Parser Defn
- dataDefnP :: Parser DataDefn
- data Env = Env {}
- insertVar :: Id -> Env -> Env
- elabExp :: MonadError AstError m => Env -> Exp -> m Exp
- elabDefn :: MonadError AstError m => Env -> Defn -> m Defn
- synthTy :: MonadError AstError m => Exp -> m Ty
Documentation
parseEirText :: MonadError AstError m => Text -> FilePath -> m Program Source #
The grammar and elaboration, for reuse by other parsers
type TVScope = HashMap Uniq TyVar Source #
Type variables bound by the enclosing signature's forall, by unique.
pendingSig :: Sig Source #
A placeholder signature for binders whose types the concrete syntax does not carry (variable occurrences, case binders, join labels); every one of them is replaced by elaboration.
tyP :: TVScope -> Parser Ty Source #
Type, at top (arrow) level: arrows are right-associative and bind loosest.
sigP :: TVScope -> Parser (Sig, TVScope) Source #
A signature: forall (a#1 :: kind) ... . ty, or a bare type. Returns
the scope extended with the quantified variables, for the types that
follow (a definition's parameters and body, a constructor's fields).
A definition: the signature line, then the equation line. The
signature's forall binders scope over the equation's parameter and
body types; the equation's name must repeat the signature line's.
dataDefnP :: Parser DataDefn Source #
data T kind { C1 :: sig1; ... } (the constructor list may be empty;
each constructor signature quantifies its own type variables).
synthTy :: MonadError AstError m => Exp -> m Ty Source #
Synthesize the type of an (already elaborated) expression: the located,
monadic twin of typeOf, used where the concrete
syntax omits a type that the abstract syntax carries. Fails (rather
than errors) on ill-formed spines, so grossly ill-typed input is
rejected with a diagnostic here; everything subtler is the linter's
job.