tamer: Introduce NIR (accepting only)
This introduces NIR, but only as an accepting grammar; it doesn't yet emit
the NIR IR, beyond TODOs.
This modifies `tamec` to, while copying XIR, also attempt to lower NIR to
produce parser errors, if any. It does not yet fail compilation, as I just
want to be cautious and observe that everything's working properly for a
little while as people use it, before I potentially break builds.
This is the culmination of months of supporting effort. The NIR grammar is
derived from our existing TAME sources internally, which I use for now as a
test case until I introduce test cases directly into TAMER later on (I'd do
it now, if I hadn't spent so much time on this; I'll start introducing tests
as I begin emitting NIR tokens). This is capable of fully parsing our
largest system with >900 packages, as well as `core`.
`tamec`'s lowering is a mess; that'll be cleaned up in future commits. The
same can be said about `tameld`.
NIR's grammar has some initial documentation, but this will improve over
time as well.
The generated docs still need some improvement, too, especially with
generated identifiers; I just want to get this out here for testing.
DEV-7145
2022-08-29 15:28:03 -04:00
|
|
|
// Normalized source IR
|
|
|
|
//
|
|
|
|
// Copyright (C) 2014-2022 Ryan Specialty Group, LLC.
|
|
|
|
//
|
|
|
|
// This file is part of TAME.
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2022-09-16 09:59:38 -04:00
|
|
|
//! An IR that is "near" the source code.
|
tamer: Introduce NIR (accepting only)
This introduces NIR, but only as an accepting grammar; it doesn't yet emit
the NIR IR, beyond TODOs.
This modifies `tamec` to, while copying XIR, also attempt to lower NIR to
produce parser errors, if any. It does not yet fail compilation, as I just
want to be cautious and observe that everything's working properly for a
little while as people use it, before I potentially break builds.
This is the culmination of months of supporting effort. The NIR grammar is
derived from our existing TAME sources internally, which I use for now as a
test case until I introduce test cases directly into TAMER later on (I'd do
it now, if I hadn't spent so much time on this; I'll start introducing tests
as I begin emitting NIR tokens). This is capable of fully parsing our
largest system with >900 packages, as well as `core`.
`tamec`'s lowering is a mess; that'll be cleaned up in future commits. The
same can be said about `tameld`.
NIR's grammar has some initial documentation, but this will improve over
time as well.
The generated docs still need some improvement, too, especially with
generated identifiers; I just want to get this out here for testing.
DEV-7145
2022-08-29 15:28:03 -04:00
|
|
|
//!
|
|
|
|
//! This IR is "near" the source code written by the user,
|
2022-09-16 09:59:38 -04:00
|
|
|
//! performing only basic normalization tasks like desugaring.
|
|
|
|
//! It takes a verbose input language and translates it into a much more
|
|
|
|
//! concise internal representation.
|
|
|
|
//! The hope is that most desugaring will be done by templates in the future.
|
|
|
|
//!
|
|
|
|
//! NIR cannot completely normalize the source input because it does not
|
|
|
|
//! have enough information to do so---the
|
|
|
|
//! template system requires a compile-time interpreter that is beyond
|
|
|
|
//! the capabilities of NIR,
|
|
|
|
//! and so a final normalization pass must be done later on in the
|
|
|
|
//! lowering pipeline.
|
tamer: Introduce NIR (accepting only)
This introduces NIR, but only as an accepting grammar; it doesn't yet emit
the NIR IR, beyond TODOs.
This modifies `tamec` to, while copying XIR, also attempt to lower NIR to
produce parser errors, if any. It does not yet fail compilation, as I just
want to be cautious and observe that everything's working properly for a
little while as people use it, before I potentially break builds.
This is the culmination of months of supporting effort. The NIR grammar is
derived from our existing TAME sources internally, which I use for now as a
test case until I introduce test cases directly into TAMER later on (I'd do
it now, if I hadn't spent so much time on this; I'll start introducing tests
as I begin emitting NIR tokens). This is capable of fully parsing our
largest system with >900 packages, as well as `core`.
`tamec`'s lowering is a mess; that'll be cleaned up in future commits. The
same can be said about `tameld`.
NIR's grammar has some initial documentation, but this will improve over
time as well.
The generated docs still need some improvement, too, especially with
generated identifiers; I just want to get this out here for testing.
DEV-7145
2022-08-29 15:28:03 -04:00
|
|
|
//!
|
|
|
|
//! This is a streaming IR,
|
|
|
|
//! meaning that the equivalent AST is not explicitly represented as a
|
|
|
|
//! tree structure in memory.
|
|
|
|
//!
|
2022-09-16 09:59:38 -04:00
|
|
|
//! NIR is lossy and does not retain enough information for code
|
tamer: Introduce NIR (accepting only)
This introduces NIR, but only as an accepting grammar; it doesn't yet emit
the NIR IR, beyond TODOs.
This modifies `tamec` to, while copying XIR, also attempt to lower NIR to
produce parser errors, if any. It does not yet fail compilation, as I just
want to be cautious and observe that everything's working properly for a
little while as people use it, before I potentially break builds.
This is the culmination of months of supporting effort. The NIR grammar is
derived from our existing TAME sources internally, which I use for now as a
test case until I introduce test cases directly into TAMER later on (I'd do
it now, if I hadn't spent so much time on this; I'll start introducing tests
as I begin emitting NIR tokens). This is capable of fully parsing our
largest system with >900 packages, as well as `core`.
`tamec`'s lowering is a mess; that'll be cleaned up in future commits. The
same can be said about `tameld`.
NIR's grammar has some initial documentation, but this will improve over
time as well.
The generated docs still need some improvement, too, especially with
generated identifiers; I just want to get this out here for testing.
DEV-7145
2022-08-29 15:28:03 -04:00
|
|
|
//! formatting---that
|
|
|
|
//! type of operation will require a mapping between
|
|
|
|
//! XIRF and NIR,
|
|
|
|
//! where the latter is used to gather enough context for formatting
|
|
|
|
//! and the former is used as a concrete representation of what the user
|
|
|
|
//! actually typed.
|
2022-09-19 09:22:07 -04:00
|
|
|
//!
|
|
|
|
//! For more information on the parser,
|
|
|
|
//! see [`parse`].
|
|
|
|
//! The entry point for NIR in the lowering pipeline is exported as
|
|
|
|
//! [`XirfToNir`].
|
tamer: Introduce NIR (accepting only)
This introduces NIR, but only as an accepting grammar; it doesn't yet emit
the NIR IR, beyond TODOs.
This modifies `tamec` to, while copying XIR, also attempt to lower NIR to
produce parser errors, if any. It does not yet fail compilation, as I just
want to be cautious and observe that everything's working properly for a
little while as people use it, before I potentially break builds.
This is the culmination of months of supporting effort. The NIR grammar is
derived from our existing TAME sources internally, which I use for now as a
test case until I introduce test cases directly into TAMER later on (I'd do
it now, if I hadn't spent so much time on this; I'll start introducing tests
as I begin emitting NIR tokens). This is capable of fully parsing our
largest system with >900 packages, as well as `core`.
`tamec`'s lowering is a mess; that'll be cleaned up in future commits. The
same can be said about `tameld`.
NIR's grammar has some initial documentation, but this will improve over
time as well.
The generated docs still need some improvement, too, especially with
generated identifiers; I just want to get this out here for testing.
DEV-7145
2022-08-29 15:28:03 -04:00
|
|
|
|
|
|
|
mod parse;
|
|
|
|
|
|
|
|
use std::{convert::Infallible, error::Error, fmt::Display};
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
diagnose::{Annotate, Diagnostic},
|
|
|
|
fmt::{DisplayWrapper, TtQuote},
|
|
|
|
parse::{Object, Token},
|
|
|
|
span::Span,
|
|
|
|
sym::SymbolId,
|
|
|
|
xir::{attr::Attr, fmt::TtXmlAttr, QName},
|
|
|
|
};
|
|
|
|
|
|
|
|
pub use parse::{
|
|
|
|
NirParseState as XirfToNir, NirParseStateError_ as XirfToNirError,
|
|
|
|
};
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub enum Nir {
|
|
|
|
Todo,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Token for Nir {
|
|
|
|
fn ir_name() -> &'static str {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn span(&self) -> crate::span::Span {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Object for Nir {}
|
|
|
|
|
|
|
|
impl Display for Nir {
|
|
|
|
fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
todo!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
type PkgPath = SymbolId;
|
|
|
|
type PkgTitle = SymbolId;
|
|
|
|
type Title = SymbolId;
|
|
|
|
type ParamName = SymbolId;
|
|
|
|
type ParamType = SymbolId;
|
|
|
|
type Dim = SymbolId;
|
|
|
|
type NumLiteral = SymbolId;
|
|
|
|
type DescLiteral = SymbolId;
|
|
|
|
type ParamDefault = SymbolId;
|
|
|
|
type ParamIdent = SymbolId;
|
|
|
|
type ClassIdent = SymbolId;
|
|
|
|
type ClassIdentList = SymbolId;
|
|
|
|
type BooleanLiteral = SymbolId;
|
|
|
|
type CalcIdent = SymbolId;
|
|
|
|
type ValueIdent = SymbolId;
|
|
|
|
type TplName = SymbolId;
|
|
|
|
type TplParamIdent = SymbolId;
|
|
|
|
type TplMetaIdent = SymbolId;
|
|
|
|
type TypeIdent = SymbolId;
|
|
|
|
type ConstIdent = SymbolId;
|
|
|
|
type TexMathLiteral = SymbolId;
|
|
|
|
type FuncIdent = SymbolId;
|
|
|
|
type ShortDimNumLiteral = SymbolId;
|
|
|
|
type StringLiteral = SymbolId;
|
|
|
|
type IdentType = SymbolId;
|
|
|
|
type AnyIdent = SymbolId;
|
|
|
|
type SymbolTableKey = SymbolId;
|
|
|
|
type IdentDtype = SymbolId;
|
|
|
|
type DynNodeLiteral = SymbolId;
|
|
|
|
type MapTransformLiteral = SymbolId;
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub enum PkgType {
|
|
|
|
/// Package is intended to produce an executable program.
|
|
|
|
///
|
|
|
|
/// This is specified by the `rater` root node.
|
|
|
|
Prog,
|
|
|
|
/// Package is intended to be imported as a component of a larger
|
|
|
|
/// program.
|
|
|
|
Mod,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Attr> for SymbolId {
|
|
|
|
fn from(attr: Attr) -> Self {
|
|
|
|
match attr {
|
|
|
|
Attr(_, value, _) => value,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub struct Literal<const S: SymbolId>;
|
|
|
|
|
|
|
|
impl<const S: SymbolId> TryFrom<Attr> for Literal<S> {
|
|
|
|
type Error = NirAttrParseError;
|
|
|
|
|
|
|
|
fn try_from(attr: Attr) -> Result<Self, Self::Error> {
|
|
|
|
match attr {
|
|
|
|
Attr(_, val, _) if val == S => Ok(Literal),
|
|
|
|
Attr(name, _, aspan) => Err(NirAttrParseError::LiteralMismatch(
|
|
|
|
name,
|
|
|
|
aspan.value_span(),
|
|
|
|
S,
|
|
|
|
)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Infallible> for NirAttrParseError {
|
|
|
|
fn from(x: Infallible) -> Self {
|
|
|
|
match x {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type ExpectedSymbolId = SymbolId;
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub enum NirAttrParseError {
|
|
|
|
LiteralMismatch(QName, Span, ExpectedSymbolId),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Error for NirAttrParseError {
|
|
|
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for NirAttrParseError {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
match self {
|
|
|
|
Self::LiteralMismatch(name, _, _) => {
|
|
|
|
write!(f, "unexpected value for {}", TtXmlAttr::wrap(name),)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Diagnostic for NirAttrParseError {
|
|
|
|
fn describe(&self) -> Vec<crate::diagnose::AnnotatedSpan> {
|
|
|
|
match self {
|
|
|
|
Self::LiteralMismatch(_, span, expected) => span
|
|
|
|
.error(format!("expecting {}", TtQuote::wrap(expected)))
|
|
|
|
.into(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|