185 lines
4.8 KiB
Rust
185 lines
4.8 KiB
Rust
|
// 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/>.
|
||
|
|
||
|
//! Normalized source IR.
|
||
|
//!
|
||
|
//! This IR is "near" the source code written by the user,
|
||
|
//! performing only normalization tasks like desugaring.
|
||
|
//! The hope is that all desugaring will be done by templates in the future.
|
||
|
//!
|
||
|
//! This is a streaming IR,
|
||
|
//! meaning that the equivalent AST is not explicitly represented as a
|
||
|
//! tree structure in memory.
|
||
|
//!
|
||
|
//! This IR is lossy and does not retain enough information for code
|
||
|
//! 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.
|
||
|
|
||
|
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(),
|
||
|
}
|
||
|
}
|
||
|
}
|