tamer: tamec: Introduce NIR->AIR->ASG lowering

This does not yet yield the produces ASG, but does set up the lowering
pipeline to prepare to produce it.  It's also currently a no-op, with
`NirToAsg` just yielding `Incomplete`.

The goal is to begin to move toward vertical slices for TAMER as I start to
return to the previous approach of a handoff with the old compiler.  Now
that I've gained clarity from my previous failed approach (which I
documented in previous commits), I feel that this is the best way forward
that will allow me to incrementally introduce more fine-grained performance
improvements, at the cost of some throwaway work as this progresses.  But
the cost of delay with these build times is far greater.

DEV-13429
main
Mike Gerwitz 2022-12-13 13:34:52 -05:00
parent f0aa8c7554
commit aa1ca06a0e
5 changed files with 147 additions and 22 deletions

View File

@ -34,10 +34,17 @@ use std::{
path::Path,
};
use tamer::{
asg::{
air::{AirAggregate, AirToken as Air},
AsgError,
},
diagnose::{
AnnotatedSpan, Diagnostic, FsSpanResolver, Reporter, VisualReporter,
},
nir::{InterpError, InterpolateNir, Nir, XirfToNir, XirfToNirError},
nir::{
InterpError, InterpolateNir, Nir, NirToAir, NirToAirError, XirfToNir,
XirfToNirError,
},
parse::{
Lower, ParseError, Parsed, ParsedObject, ParsedResult, UnknownToken,
},
@ -137,12 +144,16 @@ fn compile<R: Reporter>(
>::lower::<_, UnrecoverableError>(src, |toks| {
Lower::<XirToXirf<64, RefinedText>, XirfToNir, _>::lower(toks, |nir| {
Lower::<XirfToNir, InterpolateNir, _>::lower(nir, |nir| {
nir.fold(Ok(()), |x, result| match result {
Ok(_) => x,
Err(e) => {
report_err(&e, reporter, &mut ebuf)?;
x
}
Lower::<InterpolateNir, NirToAir, _>::lower(nir, |air| {
Lower::<NirToAir, AirAggregate, _>::lower(air, |end| {
end.fold(Ok(()), |x, result| match result {
Ok(_) => x,
Err(e) => {
report_err(&e, reporter, &mut ebuf)?;
x
}
})
})
})
})
})
@ -298,6 +309,8 @@ pub enum RecoverableError {
XirfParseError(ParseError<XirToken, XirToXirfError>),
NirParseError(ParseError<XirfToken<RefinedText>, XirfToNirError>),
InterpError(ParseError<Nir, InterpError>),
NirToAirError(ParseError<Nir, NirToAirError>),
AirAggregateError(ParseError<Air, AsgError>),
}
impl From<io::Error> for UnrecoverableError {
@ -344,6 +357,18 @@ impl From<ParseError<Nir, InterpError>> for RecoverableError {
}
}
impl From<ParseError<Nir, NirToAirError>> for RecoverableError {
fn from(e: ParseError<Nir, NirToAirError>) -> Self {
Self::NirToAirError(e)
}
}
impl From<ParseError<Air, AsgError>> for RecoverableError {
fn from(e: ParseError<Air, AsgError>) -> Self {
Self::AirAggregateError(e)
}
}
impl Display for UnrecoverableError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -361,11 +386,15 @@ impl Display for UnrecoverableError {
impl Display for RecoverableError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use RecoverableError::*;
match self {
Self::XirParseError(e) => Display::fmt(e, f),
Self::XirfParseError(e) => Display::fmt(e, f),
Self::NirParseError(e) => Display::fmt(e, f),
Self::InterpError(e) => Display::fmt(e, f),
XirParseError(e) => Display::fmt(e, f),
XirfParseError(e) => Display::fmt(e, f),
NirParseError(e) => Display::fmt(e, f),
InterpError(e) => Display::fmt(e, f),
NirToAirError(e) => Display::fmt(e, f),
AirAggregateError(e) => Display::fmt(e, f),
}
}
}
@ -383,11 +412,15 @@ impl Error for UnrecoverableError {
impl Error for RecoverableError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
use RecoverableError::*;
match self {
Self::XirParseError(e) => Some(e),
Self::XirfParseError(e) => Some(e),
Self::NirParseError(e) => Some(e),
Self::InterpError(e) => Some(e),
XirParseError(e) => Some(e),
XirfParseError(e) => Some(e),
NirParseError(e) => Some(e),
InterpError(e) => Some(e),
NirToAirError(e) => Some(e),
AirAggregateError(e) => Some(e),
}
}
}
@ -403,11 +436,15 @@ impl Diagnostic for UnrecoverableError {
impl Diagnostic for RecoverableError {
fn describe(&self) -> Vec<AnnotatedSpan> {
use RecoverableError::*;
match self {
Self::XirParseError(e) => e.describe(),
Self::XirfParseError(e) => e.describe(),
Self::NirParseError(e) => e.describe(),
Self::InterpError(e) => e.describe(),
XirParseError(e) => e.describe(),
XirfParseError(e) => e.describe(),
NirParseError(e) => e.describe(),
InterpError(e) => e.describe(),
NirToAirError(e) => e.describe(),
AirAggregateError(e) => e.describe(),
}
}
}

View File

@ -49,6 +49,7 @@
//! The entry point for NIR in the lowering pipeline is exported as
//! [`XirfToNir`].
mod air;
mod interp;
mod parse;
@ -70,6 +71,7 @@ use std::{
fmt::{Debug, Display},
};
pub use air::{NirToAir, NirToAirError};
pub use interp::{InterpError, InterpState as InterpolateNir};
pub use parse::{
NirParseState as XirfToNir, NirParseStateError_ as XirfToNirError,

View File

@ -0,0 +1,86 @@
// Lower NIR into AIR
//
// 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/>.
//! Lower [NIR](super) into [AIR](crate::asg::air).
use std::{error::Error, fmt::Display};
use crate::{
asg::air::AirToken as Air, diagnose::Diagnostic, parse::prelude::*,
};
use super::Nir;
#[derive(Debug, PartialEq, Eq, Default)]
pub enum NirToAir {
#[default]
Ready,
}
impl Display for NirToAir {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
use NirToAir::*;
match self {
Ready => write!(f, "ready to lower NIR to AIR"),
}
}
}
impl ParseState for NirToAir {
type Token = Nir;
type Object = Air;
type Error = NirToAirError;
fn parse_token(
self,
_tok: Self::Token,
_: NoContext,
) -> TransitionResult<Self::Super> {
Transition(self).incomplete()
}
fn is_accepting(&self, _: &Self::Context) -> bool {
true
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum NirToAirError {
Todo,
}
impl Display for NirToAirError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
use NirToAirError::*;
match self {
Todo => write!(f, "TODO"),
}
}
}
impl Error for NirToAirError {}
impl Diagnostic for NirToAirError {
fn describe(&self) -> Vec<crate::diagnose::AnnotatedSpan> {
// TODO
vec![]
}
}

View File

@ -116,7 +116,7 @@
//!
//! See [`TplKw`] for template tokens that are accepted anywhere.
use super::{*, Nir::*};
use super::{Nir::*, *};
use crate::{
ele_parse,
xir::st::{prefix::*, qname::*},

View File

@ -50,8 +50,8 @@ use std::{
/// parser.
pub mod prelude {
pub use super::{
ClosedParseState, Context, Object, ParseError, ParseState, ParseStatus,
Parsed, Token, Transition, TransitionResult,
ClosedParseState, Context, NoContext, Object, ParseError, ParseState,
ParseStatus, Parsed, Token, Transition, TransitionResult,
};
}