From e3d53b0517965ac61c2bd60ac1d8036bcef580e5 Mon Sep 17 00:00:00 2001 From: Tom Anderson Date: Thu, 22 Aug 2024 22:47:29 +1000 Subject: [PATCH] create `AstMetadata` trait to reduce generics --- src/repr/ast/base/expression/assign.rs | 12 ++- src/repr/ast/base/expression/block.rs | 10 +- src/repr/ast/base/expression/boolean.rs | 8 +- src/repr/ast/base/expression/call.rs | 12 ++- src/repr/ast/base/expression/ident.rs | 19 ++-- src/repr/ast/base/expression/if_else.rs | 14 +-- src/repr/ast/base/expression/infix.rs | 12 ++- src/repr/ast/base/expression/integer.rs | 8 +- src/repr/ast/base/expression/loop_block.rs | 10 +- src/repr/ast/base/expression/mod.rs | 77 ++++++--------- src/repr/ast/base/function.rs | 13 +-- src/repr/ast/base/macros.rs | 108 +++++++++++++++++---- src/repr/ast/base/mod.rs | 9 ++ src/repr/ast/base/program.rs | 11 ++- src/repr/ast/base/statement.rs | 90 ++++++++--------- src/repr/ast/typed.rs | 20 +++- src/repr/ast/untyped.rs | 17 +++- src/stage/lower_ir/lowering/mod.rs | 2 +- src/stage/parse/block.rs | 2 +- src/stage/parse/expression/e_boolean.rs | 4 +- src/stage/parse/expression/e_ident.rs | 6 +- src/stage/parse/expression/e_if.rs | 1 + src/stage/parse/expression/e_integer.rs | 2 +- src/stage/parse/expression/mod.rs | 102 ++++++++++--------- src/stage/parse/statement.rs | 12 ++- src/stage/type_check/expression/block.rs | 3 + src/stage/type_check/expression/boolean.rs | 4 +- src/stage/type_check/expression/ident.rs | 8 +- src/stage/type_check/expression/infix.rs | 2 + src/stage/type_check/expression/integer.rs | 4 +- src/stage/type_check/mod.rs | 7 +- src/stage/type_check/statement.rs | 4 +- 32 files changed, 369 insertions(+), 244 deletions(-) diff --git a/src/repr/ast/base/expression/assign.rs b/src/repr/ast/base/expression/assign.rs index e6cab3b..8770573 100644 --- a/src/repr/ast/base/expression/assign.rs +++ b/src/repr/ast/base/expression/assign.rs @@ -1,9 +1,11 @@ use super::*; -use crate::ast_node; +use crate::ast_node2; -ast_node! { - typed struct Assign { - binding: IdentIdentifier, - value: Box>, +ast_node2! { + Assign { + binding: M::IdentIdentifier, + value: Box>, + span, + ty_info, } } diff --git a/src/repr/ast/base/expression/block.rs b/src/repr/ast/base/expression/block.rs index fba37db..4bc19af 100644 --- a/src/repr/ast/base/expression/block.rs +++ b/src/repr/ast/base/expression/block.rs @@ -1,8 +1,10 @@ use super::*; -use crate::ast_node; +use crate::ast_node2; -ast_node! { - typed struct Block { - statements: Vec>, +ast_node2! { + Block { + statements: Vec>, + span, + ty_info, } } diff --git a/src/repr/ast/base/expression/boolean.rs b/src/repr/ast/base/expression/boolean.rs index 57ead4c..0afe4a1 100644 --- a/src/repr/ast/base/expression/boolean.rs +++ b/src/repr/ast/base/expression/boolean.rs @@ -1,7 +1,9 @@ -use crate::ast_node; +use crate::ast_node2; -ast_node! { - typed struct Boolean { +ast_node2! { + Boolean { value: bool, + span, + ty_info, } } diff --git a/src/repr/ast/base/expression/call.rs b/src/repr/ast/base/expression/call.rs index c97b4bf..0dee835 100644 --- a/src/repr/ast/base/expression/call.rs +++ b/src/repr/ast/base/expression/call.rs @@ -1,10 +1,12 @@ -use crate::ast_node; +use crate::ast_node2; use super::*; -ast_node! { - typed struct Call { - name: FnIdentifier, - args: Vec>, +ast_node2! { + Call { + name: M::FnIdentifier, + args: Vec>, + span, + ty_info, } } diff --git a/src/repr/ast/base/expression/ident.rs b/src/repr/ast/base/expression/ident.rs index 880c7af..1e19536 100644 --- a/src/repr/ast/base/expression/ident.rs +++ b/src/repr/ast/base/expression/ident.rs @@ -1,23 +1,28 @@ use std::hash::Hash; -use crate::ast_node; +use crate::{ast_node2, repr::ast::base::AstMetadata}; -ast_node! { - typed struct Ident { - binding: IdentIdentifier, +ast_node2! { + Ident { + binding: M::IdentIdentifier, + span, + ty_info, } } -impl Hash for Ident { +impl> Hash for Ident { fn hash(&self, state: &mut H) { self.binding.hash(state); } } -impl PartialEq for Ident { +impl> PartialEq for Ident +where + M::IdentIdentifier: PartialEq, +{ fn eq(&self, other: &Self) -> bool { self.binding == other.binding } } -impl Eq for Ident {} +impl Eq for Ident where M::IdentIdentifier: Eq {} diff --git a/src/repr/ast/base/expression/if_else.rs b/src/repr/ast/base/expression/if_else.rs index 0b15a3a..628c6b6 100644 --- a/src/repr/ast/base/expression/if_else.rs +++ b/src/repr/ast/base/expression/if_else.rs @@ -1,11 +1,13 @@ -use crate::ast_node; +use crate::ast_node2; use super::*; -ast_node! { - typed struct If { - condition: Box>, - success: Block, - otherwise: Option>, +ast_node2! { + If { + condition: Box>, + success: Block, + otherwise: Option>, + span, + ty_info, } } diff --git a/src/repr/ast/base/expression/infix.rs b/src/repr/ast/base/expression/infix.rs index f11f206..1b07cdf 100644 --- a/src/repr/ast/base/expression/infix.rs +++ b/src/repr/ast/base/expression/infix.rs @@ -1,4 +1,4 @@ -use crate::{ast_node, repr::token::Token}; +use crate::{ast_node2, repr::token::Token}; use super::Expression; @@ -38,10 +38,12 @@ impl TryFrom for InfixOperation { } } -ast_node! { - typed struct Infix { - left: Box>, +ast_node2! { + Infix { + left: Box>, operation: InfixOperation, - right: Box>, + right: Box>, + span, + ty_info, } } diff --git a/src/repr/ast/base/expression/integer.rs b/src/repr/ast/base/expression/integer.rs index 86265d3..95e9e2f 100644 --- a/src/repr/ast/base/expression/integer.rs +++ b/src/repr/ast/base/expression/integer.rs @@ -1,7 +1,9 @@ -use crate::ast_node; +use crate::ast_node2; -ast_node! { - typed struct Integer { +ast_node2! { + Integer { value: i64, + span, + ty_info, } } diff --git a/src/repr/ast/base/expression/loop_block.rs b/src/repr/ast/base/expression/loop_block.rs index 3fc4b52..afc8484 100644 --- a/src/repr/ast/base/expression/loop_block.rs +++ b/src/repr/ast/base/expression/loop_block.rs @@ -1,9 +1,11 @@ -use crate::ast_node; +use crate::ast_node2; use super::*; -ast_node! { - typed struct Loop { - body: Block, +ast_node2! { + Loop { + body: Block, + span, + ty_info, } } diff --git a/src/repr/ast/base/expression/mod.rs b/src/repr/ast/base/expression/mod.rs index eb35016..d57ae9b 100644 --- a/src/repr/ast/base/expression/mod.rs +++ b/src/repr/ast/base/expression/mod.rs @@ -18,81 +18,68 @@ pub use infix::*; pub use integer::*; pub use loop_block::*; -use crate::{ast_node, util::span::Span}; +use crate::{ast_node2, util::span::Span}; -use super::Statement; +use super::{AstMetadata, Statement}; -ast_node!( - enum Expression { - Infix(Infix), - Integer(Integer), - Boolean(Boolean), - Ident(Ident), - Block(Block), - If(If), - Call(Call), - Loop(Loop), - Assign(Assign), - } -); +ast_node2! { + Expression( + Infix, + Integer, + Boolean, + Ident, + Block, + If, + Call, + Loop, + Assign, + ) +} -impl - Expression -{ - pub fn infix( - left: Expression, - operation: InfixOperation, - right: Expression, - ) -> Self { +impl> Expression { + pub fn infix(left: Expression, operation: InfixOperation, right: Expression) -> Self { let span = left.span().start..right.span().end; - Self::Infix(Infix::::new( + Self::Infix(Infix::::new( Box::new(left), operation, Box::new(right), span, + M::TyInfo::default(), )) } pub fn integer(value: i64, span: Span) -> Self { - Self::Integer(Integer::::new(value, span)) + Self::Integer(Integer::new(value, span, M::TyInfo::default())) } pub fn boolean(value: bool, span: Span) -> Self { - Self::Boolean(Boolean::::new(value, span)) + Self::Boolean(Boolean::new(value, span, M::TyInfo::default())) } - pub fn ident(name: IdentIdentifier, span: Span) -> Self { - Self::Ident(Ident::::new(name, span)) + pub fn ident(name: M::IdentIdentifier, span: Span) -> Self { + Self::Ident(Ident::new(name, span, M::TyInfo::default())) } - pub fn block( - statements: Vec>, - span: Span, - ) -> Self { - Self::Block(Block::::new( - statements, span, - )) + pub fn block(statements: Vec>, span: Span) -> Self { + Self::Block(Block::new(statements, span, M::TyInfo::default())) } pub fn _if( - condition: Expression, - success: Block, - otherwise: Option>, + condition: Expression, + success: Block, + otherwise: Option>, span: Span, ) -> Self { - Self::If(If::::new( + Self::If(If::new( Box::new(condition), success, otherwise, span, + M::TyInfo::default(), )) } - pub fn call( - identifier: FnIdentifier, - args: Vec>, - span: Span, - ) -> Self { - Self::Call(Call::new(identifier, args, span)) + pub fn call(identifier: M::FnIdentifier, args: Vec>, span: Span) -> Self { + Self::Call(Call::new(identifier, args, span, M::TyInfo::default())) } } diff --git a/src/repr/ast/base/function.rs b/src/repr/ast/base/function.rs index 7e1cb80..298af1d 100644 --- a/src/repr/ast/base/function.rs +++ b/src/repr/ast/base/function.rs @@ -1,12 +1,13 @@ -use crate::{ast_node, repr::ty::Ty}; +use crate::{ast_node2, repr::ty::Ty}; use super::*; -ast_node! { - struct Function { - name: FnIdentifier, - parameters: Vec<(IdentIdentifier, Ty)>, +ast_node2! { + Function { + name: M::FnIdentifier, + parameters: Vec<(M::IdentIdentifier, Ty)>, return_ty: Ty, - body: Block, + body: Block, + span, } } diff --git a/src/repr/ast/base/macros.rs b/src/repr/ast/base/macros.rs index d03dbb3..872d0a3 100644 --- a/src/repr/ast/base/macros.rs +++ b/src/repr/ast/base/macros.rs @@ -1,3 +1,71 @@ +#[macro_export] +macro_rules! ast_node2 { + ($name:ident<$metadata:ident> { $($tokens:tt)* }) => { + ast_node2! { @ $name<$metadata> { $($tokens)* } -> () } + }; + + ($name:ident<$metadata:ident>( $($variant:ident,)* )) => { + #[derive(Clone, Debug)] + pub enum $name<$metadata: $crate::repr::ast::base::AstMetadata> { + $($variant($variant<$metadata>),)* + } + + impl<$metadata: $crate::repr::ast::base::AstMetadata> $name<$metadata> { + pub fn get_ty_info(&self) -> &$metadata::TyInfo { + match self { + $(Self::$variant(value) => &value.ty_info),* + } + } + + pub fn span(&self) -> &$metadata::Span { + match self { + $(Self::$variant(value) => &value.span),* + } + } + } + }; + + (@ $name:ident<$metadata:ident> { } -> ( $($field:ident: $ty:ty,)*) ) => { + #[derive(Clone, Debug)] + pub struct $name<$metadata: $crate::repr::ast::base::AstMetadata> { + $(pub $field: $ty,)* + } + + impl<$metadata: $crate::repr::ast::base::AstMetadata> $name<$metadata> { + pub fn new($($field: $ty,)*) -> Self { + Self { $($field,)* } + } + } + }; + + (@ $name:ident<$metadata:ident> { span, $($tokens:tt)* } -> ( $($result:tt)*) ) => { + ast_node2! { + @ $name<$metadata> { $($tokens)* } -> ( + $($result)* + span: $metadata::Span, + ) + } + }; + + (@ $name:ident<$metadata:ident> { ty_info, $($tokens:tt)* } -> ( $($result:tt)*) ) => { + ast_node2! { + @ $name<$metadata> { $($tokens)* } -> ( + $($result)* + ty_info: $metadata::TyInfo, + ) + } + }; + + (@ $name:ident<$metadata:ident> { $field:ident: $ty:ty, $($tokens:tt)* } -> ( $($result:tt)*) ) => { + ast_node2! { + @ $name<$metadata> { $($tokens)* } -> ( + $($result)* + $field: $ty, + ) + } + }; +} + #[macro_export] macro_rules! ast_node { // Common components for all variants of an AST node @@ -68,31 +136,29 @@ macro_rules! ast_node { #[macro_export] macro_rules! generate_ast { - (TyInfo: $ty_info:ty, FnIdentifier: $fn_identifier:ty, IdentIdentifier: $ident_identifier:ty) => { + ($metadata:ty) => { use $crate::repr::ast::base as ast; // Re-export non-typed utilities pub use ast::InfixOperation; - pub type Block = ast::Block<$ty_info, $fn_identifier, $ident_identifier>; - pub type Boolean = ast::Boolean<$ty_info>; - pub type Call = ast::Call<$ty_info, $fn_identifier, $ident_identifier>; - pub type Ident = ast::Ident<$ty_info, $ident_identifier>; - pub type If = ast::If<$ty_info, $fn_identifier, $ident_identifier>; - pub type Loop = ast::Loop<$ty_info, $fn_identifier, $ident_identifier>; - pub type Infix = ast::Infix<$ty_info, $fn_identifier, $ident_identifier>; - pub type Integer = ast::Integer<$ty_info>; - pub type Assign = ast::Assign<$ty_info, $fn_identifier, $ident_identifier>; - pub type Expression = ast::Expression<$ty_info, $fn_identifier, $ident_identifier>; - pub type Function = ast::Function<$ty_info, $fn_identifier, $ident_identifier>; - pub type Program = ast::Program<$ty_info, $fn_identifier, $ident_identifier>; - pub type Statement = ast::Statement<$ty_info, $fn_identifier, $ident_identifier>; - pub type ReturnStatement = - ast::ReturnStatement<$ty_info, $fn_identifier, $ident_identifier>; - pub type LetStatement = ast::LetStatement<$ty_info, $fn_identifier, $ident_identifier>; - pub type ExpressionStatement = - ast::ExpressionStatement<$ty_info, $fn_identifier, $ident_identifier>; - pub type BreakStatement = ast::BreakStatement<$ty_info>; - pub type ContinueStatement = ast::ContinueStatement<$ty_info>; + pub type Block = ast::Block<$metadata>; + pub type Boolean = ast::Boolean<$metadata>; + pub type Call = ast::Call<$metadata>; + pub type Ident = ast::Ident<$metadata>; + pub type If = ast::If<$metadata>; + pub type Loop = ast::Loop<$metadata>; + pub type Infix = ast::Infix<$metadata>; + pub type Integer = ast::Integer<$metadata>; + pub type Assign = ast::Assign<$metadata>; + pub type Expression = ast::Expression<$metadata>; + pub type Function = ast::Function<$metadata>; + pub type Program = ast::Program<$metadata>; + pub type Statement = ast::Statement<$metadata>; + pub type ReturnStatement = ast::Return<$metadata>; + pub type LetStatement = ast::Let<$metadata>; + pub type ExpressionStatement = ast::ExpressionStatement<$metadata>; + pub type BreakStatement = ast::Break<$metadata>; + pub type ContinueStatement = ast::Continue<$metadata>; }; } diff --git a/src/repr/ast/base/mod.rs b/src/repr/ast/base/mod.rs index 996381a..71df8b2 100644 --- a/src/repr/ast/base/mod.rs +++ b/src/repr/ast/base/mod.rs @@ -4,7 +4,16 @@ mod macros; mod program; mod statement; +use std::fmt::Debug; + pub use expression::*; pub use function::*; pub use program::*; pub use statement::*; + +pub trait AstMetadata { + type FnIdentifier: Debug + Clone; + type IdentIdentifier: Debug + Clone; + type TyInfo: Debug + Clone; + type Span: Debug + Clone; +} diff --git a/src/repr/ast/base/program.rs b/src/repr/ast/base/program.rs index 92b3ce5..2e50435 100644 --- a/src/repr/ast/base/program.rs +++ b/src/repr/ast/base/program.rs @@ -1,10 +1,11 @@ -use crate::ast_node; +use crate::ast_node2; use super::*; -ast_node! { - struct Program { - functions: Vec>, - main: Function, +ast_node2! { + Program { + functions: Vec>, + main: Function, + span, } } diff --git a/src/repr/ast/base/statement.rs b/src/repr/ast/base/statement.rs index 95668fb..5eb8355 100644 --- a/src/repr/ast/base/statement.rs +++ b/src/repr/ast/base/statement.rs @@ -1,70 +1,72 @@ -use crate::{ast_node, util::span::Span}; +use crate::ast_node2; use super::*; -ast_node!( - enum Statement { - Return(ReturnStatement), - Let(LetStatement), - Expression(ExpressionStatement), - Break(BreakStatement), - Continue(ContinueStatement), - } -); +ast_node2! { + Statement( + Return, + Let, + ExpressionStatement, + Break, + Continue, + ) +} -impl - Statement -{ - pub fn _return( - expression: Expression, - span: Span, - ) -> Self { - Self::Return(ReturnStatement::new(expression, span)) +impl> Statement { + pub fn _return(expression: Expression, span: M::Span) -> Self { + Self::Return(Return::new(expression, span, M::TyInfo::default())) } - pub fn _let( - name: IdentIdentifier, - value: Expression, - span: Span, - ) -> Self { - Self::Let(LetStatement::new(name, value, span)) + pub fn _let(name: M::IdentIdentifier, value: Expression, span: M::Span) -> Self { + Self::Let(Let::new(name, value, span, M::TyInfo::default())) } - pub fn expression( - expression: Expression, - implicit_return: bool, - span: Span, - ) -> Self { - Self::Expression(ExpressionStatement::new(expression, implicit_return, span)) + pub fn expression(expression: Expression, implicit_return: bool, span: M::Span) -> Self { + Self::ExpressionStatement(ExpressionStatement::new( + expression, + implicit_return, + span, + M::TyInfo::default(), + )) } } -ast_node! { - typed struct ReturnStatement { - value: Expression, +ast_node2! { + Return { + value: Expression, + span, + ty_info, } } -ast_node! { - typed struct LetStatement { - binding: IdentIdentifier, - value: Expression, +ast_node2! { + Let { + binding: M::IdentIdentifier, + value: Expression, + span, + ty_info, } } -ast_node! { - typed struct ExpressionStatement { - expression: Expression, +ast_node2! { + ExpressionStatement { + expression: Expression, implicit_return: bool, + span, + ty_info, } } -ast_node! { - typed struct BreakStatement { +ast_node2! { + Break { + span, + ty_info, } } -ast_node! { - typed struct ContinueStatement { +ast_node2! { + Continue { + span, + ty_info, } } diff --git a/src/repr/ast/typed.rs b/src/repr/ast/typed.rs index d6e7c97..b3f9bbd 100644 --- a/src/repr/ast/typed.rs +++ b/src/repr/ast/typed.rs @@ -1,16 +1,26 @@ use crate::{ generate_ast, - repr::{identifier::*, ty::Ty}, + repr::{ + identifier::{FunctionIdx, ScopedBinding}, + ty::Ty, + }, + util::span::Span, }; +use super::base::AstMetadata; + #[derive(Clone, Debug)] pub struct TyInfo { pub ty: Ty, pub return_ty: Option, } -generate_ast! { - TyInfo: TyInfo, - FnIdentifier: FunctionIdx, - IdentIdentifier: ScopedBinding +pub struct TypedAstMetdata; +impl AstMetadata for TypedAstMetdata { + type FnIdentifier = FunctionIdx; + type IdentIdentifier = ScopedBinding; + type TyInfo = TyInfo; + type Span = Span; } + +generate_ast!(TypedAstMetdata); diff --git a/src/repr/ast/untyped.rs b/src/repr/ast/untyped.rs index d9eb06c..f24c166 100644 --- a/src/repr/ast/untyped.rs +++ b/src/repr/ast/untyped.rs @@ -1,7 +1,14 @@ -use crate::{compiler::Symbol, generate_ast, repr::ty::Ty}; +use crate::{compiler::Symbol, generate_ast, repr::ty::Ty, util::span::Span}; -generate_ast! { - TyInfo: Option, - FnIdentifier: Symbol, - IdentIdentifier: Symbol +use super::base::AstMetadata; + +#[derive(Debug)] +pub struct UntypedAstMetadata; +impl AstMetadata for UntypedAstMetadata { + type FnIdentifier = Symbol; + type IdentIdentifier = Symbol; + type TyInfo = Option; + type Span = Span; } + +generate_ast!(UntypedAstMetadata); diff --git a/src/stage/lower_ir/lowering/mod.rs b/src/stage/lower_ir/lowering/mod.rs index 98cf868..6712d0e 100644 --- a/src/stage/lower_ir/lowering/mod.rs +++ b/src/stage/lower_ir/lowering/mod.rs @@ -196,7 +196,7 @@ fn lower_block( let (loop_start, _) = builder.loop_stack.last().unwrap(); builder.set_terminator(Terminator::Jump(*loop_start)); } - ast::Statement::Expression(ast::ExpressionStatement { + ast::Statement::ExpressionStatement(ast::ExpressionStatement { expression, ty_info, .. diff --git a/src/stage/parse/block.rs b/src/stage/parse/block.rs index 0bdddde..d2e8a35 100644 --- a/src/stage/parse/block.rs +++ b/src/stage/parse/block.rs @@ -32,5 +32,5 @@ pub fn parse_block(compiler: &mut Compiler, tokens: &mut Lexer<'_>) -> Result, ) -> Result { match tokens.next_spanned().unwrap() { - (Token::True, span) => Ok(Boolean::new(true, span)), - (Token::False, span) => Ok(Boolean::new(false, span)), + (Token::True, span) => Ok(Boolean::new(true, span, Default::default())), + (Token::False, span) => Ok(Boolean::new(false, span, Default::default())), (token, _) => { Err(ParseError::ExpectedToken { // WARN: Should be true or false diff --git a/src/stage/parse/expression/e_ident.rs b/src/stage/parse/expression/e_ident.rs index 344d26d..b1db051 100644 --- a/src/stage/parse/expression/e_ident.rs +++ b/src/stage/parse/expression/e_ident.rs @@ -2,7 +2,11 @@ use super::*; pub fn parse_ident(compiler: &mut Compiler, tokens: &mut Lexer<'_>) -> Result { match tokens.next_spanned().unwrap() { - (Token::Ident(ident), span) => Ok(Ident::new(compiler.symbols.get_or_intern(ident), span)), + (Token::Ident(ident), span) => Ok(Ident::new( + compiler.symbols.get_or_intern(ident), + span, + Default::default(), + )), (token, _) => Err(ParseError::ExpectedToken { expected: Box::new(Token::Ident(String::new())), found: Box::new(token), diff --git a/src/stage/parse/expression/e_if.rs b/src/stage/parse/expression/e_if.rs index 9777bfa..26d55ce 100644 --- a/src/stage/parse/expression/e_if.rs +++ b/src/stage/parse/expression/e_if.rs @@ -36,6 +36,7 @@ pub fn parse_if(compiler: &mut Compiler, tokens: &mut Lexer<'_>) -> Result, ) -> Result { match tokens.next_spanned().unwrap() { - (Token::Integer(value), span) => Ok(Integer::new(value, span)), + (Token::Integer(value), span) => Ok(Integer::new(value, span, Default::default())), (token, _) => Err(ParseError::ExpectedToken { expected: Box::new(Token::Integer(0)), found: Box::new(token), diff --git a/src/stage/parse/expression/mod.rs b/src/stage/parse/expression/mod.rs index 1192fa8..912a0c3 100644 --- a/src/stage/parse/expression/mod.rs +++ b/src/stage/parse/expression/mod.rs @@ -106,7 +106,7 @@ pub fn parse_expression( }; let span = name.span.start..end_span.end; - Expression::Call(Call::new(name.binding, args, span)) + Expression::Call(Call::new(name.binding, args, span, Default::default())) } // Regular infix operation (left, token) => { @@ -118,7 +118,13 @@ pub fn parse_expression( let span = left.span().start..right.span().end; - Expression::Infix(Infix::new(Box::new(left), operation, Box::new(right), span)) + Expression::Infix(Infix::new( + Box::new(left), + operation, + Box::new(right), + span, + Default::default(), + )) } else { // Probably aren't in the expression any more return Ok(left); @@ -158,22 +164,22 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Infix( Infix { - span: 0..5, left: Integer( Integer { - span: 0..1, value: 3, + span: 0..1, ty_info: None, }, ), operation: Plus, right: Integer( Integer { - span: 4..5, value: 4, + span: 4..5, ty_info: None, }, ), + span: 0..5, ty_info: None, }, ) @@ -192,36 +198,36 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Infix( Infix { - span: 0..10, left: Infix( Infix { - span: 0..5, left: Integer( Integer { - span: 0..1, value: 3, + span: 0..1, ty_info: None, }, ), operation: Plus, right: Integer( Integer { - span: 4..5, value: 4, + span: 4..5, ty_info: None, }, ), + span: 0..5, ty_info: None, }, ), operation: Plus, right: Integer( Integer { - span: 8..10, value: 10, + span: 8..10, ty_info: None, }, ), + span: 0..10, ty_info: None, }, ) @@ -244,37 +250,37 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" If( If { - span: 0..18, condition: Integer( Integer { - span: 3..4, value: 1, + span: 3..4, ty_info: None, }, ), success: Block { - span: 5..18, statements: [ - Expression( + ExpressionStatement( ExpressionStatement { - span: 7..16, expression: Ident( Ident { - span: 7..16, binding: SymbolU32 { value: 1, }, + span: 7..16, ty_info: None, }, ), implicit_return: true, + span: 7..16, ty_info: None, }, ), ], + span: 5..18, ty_info: None, }, otherwise: None, + span: 0..18, ty_info: None, }, ) @@ -292,8 +298,8 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Integer( Integer { - span: 0..1, value: 1, + span: 0..1, ty_info: None, }, ) @@ -311,10 +317,10 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Ident( Ident { - span: 0..9, binding: SymbolU32 { value: 1, }, + span: 0..9, ty_info: None, }, ) @@ -333,22 +339,22 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Infix( Infix { - span: 0..6, left: Integer( Integer { - span: 0..1, value: 1, + span: 0..1, ty_info: None, }, ), operation: Eq, right: Integer( Integer { - span: 5..6, value: 1, + span: 5..6, ty_info: None, }, ), + span: 0..6, ty_info: None, }, ) @@ -367,36 +373,36 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Infix( Infix { - span: 0..10, left: Integer( Integer { - span: 0..1, value: 1, + span: 0..1, ty_info: None, }, ), operation: Eq, right: Infix( Infix { - span: 5..10, left: Integer( Integer { - span: 5..6, value: 1, + span: 5..6, ty_info: None, }, ), operation: Plus, right: Integer( Integer { - span: 9..10, value: 2, + span: 9..10, ty_info: None, }, ), + span: 5..10, ty_info: None, }, ), + span: 0..10, ty_info: None, }, ) @@ -411,11 +417,11 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Call( Call { - span: 0..6, name: SymbolU32 { value: 1, }, args: [], + span: 0..6, ty_info: None, }, ) @@ -434,19 +440,19 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Call( Call { - span: 0..7, name: SymbolU32 { value: 1, }, args: [ Integer( Integer { - span: 5..6, value: 1, + span: 5..6, ty_info: None, }, ), ], + span: 0..7, ty_info: None, }, ) @@ -465,19 +471,19 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Call( Call { - span: 0..8, name: SymbolU32 { value: 1, }, args: [ Integer( Integer { - span: 5..6, value: 1, + span: 5..6, ty_info: None, }, ), ], + span: 0..8, ty_info: None, }, ) @@ -496,33 +502,33 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Call( Call { - span: 0..13, name: SymbolU32 { value: 1, }, args: [ Integer( Integer { - span: 5..6, value: 1, + span: 5..6, ty_info: None, }, ), Integer( Integer { - span: 8..9, value: 2, + span: 8..9, ty_info: None, }, ), Integer( Integer { - span: 11..12, value: 3, + span: 11..12, ty_info: None, }, ), ], + span: 0..13, ty_info: None, }, ) @@ -541,33 +547,33 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Call( Call { - span: 0..14, name: SymbolU32 { value: 1, }, args: [ Integer( Integer { - span: 5..6, value: 1, + span: 5..6, ty_info: None, }, ), Integer( Integer { - span: 8..9, value: 2, + span: 8..9, ty_info: None, }, ), Integer( Integer { - span: 11..12, value: 3, + span: 11..12, ty_info: None, }, ), ], + span: 0..14, ty_info: None, }, ) @@ -586,40 +592,40 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Call( Call { - span: 0..15, name: SymbolU32 { value: 1, }, args: [ Infix( Infix { - span: 5..10, left: Integer( Integer { - span: 5..6, value: 1, + span: 5..6, ty_info: None, }, ), operation: Plus, right: Integer( Integer { - span: 9..10, value: 2, + span: 9..10, ty_info: None, }, ), + span: 5..10, ty_info: None, }, ), Integer( Integer { - span: 12..13, value: 3, + span: 12..13, ty_info: None, }, ), ], + span: 0..15, ty_info: None, }, ) @@ -638,33 +644,33 @@ mod test { insta::assert_debug_snapshot!(expression, @r###" Infix( Infix { - span: 0..11, left: Call( Call { - span: 0..7, name: SymbolU32 { value: 1, }, args: [ Integer( Integer { - span: 5..6, value: 1, + span: 5..6, ty_info: None, }, ), ], + span: 0..7, ty_info: None, }, ), operation: Plus, right: Integer( Integer { - span: 10..11, value: 2, + span: 10..11, ty_info: None, }, ), + span: 0..11, ty_info: None, }, ) diff --git a/src/stage/parse/statement.rs b/src/stage/parse/statement.rs index 1c1fa23..65952fc 100644 --- a/src/stage/parse/statement.rs +++ b/src/stage/parse/statement.rs @@ -1,4 +1,4 @@ -use crate::repr::ast::base::{BreakStatement, ContinueStatement}; +use crate::repr::ast::base::{Break, Continue}; use super::*; @@ -19,7 +19,7 @@ pub fn parse_statement( // Build the span let span = return_span.start..value.span().end; - Statement::Return(ReturnStatement::new(value, span)) + Statement::Return(ReturnStatement::new(value, span, Default::default())) } Token::Let => { // let token @@ -57,24 +57,25 @@ pub fn parse_statement( compiler.symbols.get_or_intern(name), value, span, + Default::default(), )) } Token::Break => { let (_, break_span) = tokens.next_spanned().unwrap(); - Statement::Break(BreakStatement::new(break_span)) + Statement::Break(Break::new(break_span, Default::default())) } Token::Continue => { let (_, continue_span) = tokens.next_spanned().unwrap(); - Statement::Continue(ContinueStatement::new(continue_span)) + Statement::Continue(Continue::new(continue_span, Default::default())) } _ => { // Parse expression let expression = parse_expression(compiler, tokens, Precedence::Lowest)?; let span = expression.span().clone(); - Statement::Expression(ExpressionStatement::new( + Statement::ExpressionStatement(ExpressionStatement::new( expression, if matches!(tokens.peek_token().unwrap(), Token::SemiColon) { false @@ -84,6 +85,7 @@ pub fn parse_statement( true }, span, + Default::default(), )) } }; diff --git a/src/stage/type_check/expression/block.rs b/src/stage/type_check/expression/block.rs index 25f5196..9469e24 100644 --- a/src/stage/type_check/expression/block.rs +++ b/src/stage/type_check/expression/block.rs @@ -81,6 +81,7 @@ mod test { Statement::_return(Expression::integer(1, Span::default()), Span::default()), ], Span::default(), + Default::default(), ); let ty_info = b @@ -116,6 +117,7 @@ mod test { Statement::_return(Expression::boolean(true, Span::default()), Span::default()), ], Span::default(), + Default::default(), ); let result = b.ty_solve(&mut Compiler::default(), &mut Scope::new()); @@ -143,6 +145,7 @@ mod test { ), ], Span::default(), + Default::default(), ); let ty_info = b diff --git a/src/stage/type_check/expression/boolean.rs b/src/stage/type_check/expression/boolean.rs index 1e7a67d..734e1a9 100644 --- a/src/stage/type_check/expression/boolean.rs +++ b/src/stage/type_check/expression/boolean.rs @@ -23,7 +23,7 @@ mod test_boolean { #[test] fn boolean_infer() { assert_eq!( - Boolean::new(false, Span::default()) + Boolean::new(false, Span::default(), Default::default()) .ty_solve() .unwrap() .ty_info @@ -35,7 +35,7 @@ mod test_boolean { #[test] fn boolean_return() { assert_eq!( - Boolean::new(false, Span::default()) + Boolean::new(false, Span::default(), Default::default()) .ty_solve() .unwrap() .ty_info diff --git a/src/stage/type_check/expression/ident.rs b/src/stage/type_check/expression/ident.rs index 689e22f..dc43603 100644 --- a/src/stage/type_check/expression/ident.rs +++ b/src/stage/type_check/expression/ident.rs @@ -40,7 +40,7 @@ mod test_ident { let mut scope = Scope::new(); scope.register(symbol, Ty::Int); - let i = Ident::new(symbol, Span::default()); + let i = Ident::new(symbol, Span::default(), Default::default()); // Run the type solve let ty_info = i @@ -54,7 +54,11 @@ mod test_ident { #[test] fn ident_infer_missing() { - let i = Ident::new(Symbol::try_from_usize(0).unwrap(), Span::default()); + let i = Ident::new( + Symbol::try_from_usize(0).unwrap(), + Span::default(), + Default::default(), + ); let result = i.ty_solve(&mut Compiler::default(), &mut Scope::new()); diff --git a/src/stage/type_check/expression/infix.rs b/src/stage/type_check/expression/infix.rs index 0712ab5..d6ac37e 100644 --- a/src/stage/type_check/expression/infix.rs +++ b/src/stage/type_check/expression/infix.rs @@ -57,6 +57,7 @@ mod test_infix { InfixOperation::plus(), Box::new(Expression::integer(0, Span::default())), Span::default(), + Default::default(), ); let ty_info = infix @@ -74,6 +75,7 @@ mod test_infix { InfixOperation::plus(), Box::new(Expression::boolean(false, Span::default())), Span::default(), + Default::default(), ); let result = infix.ty_solve(&mut Compiler::default(), &mut Scope::new()); diff --git a/src/stage/type_check/expression/integer.rs b/src/stage/type_check/expression/integer.rs index 9613fdd..14c8552 100644 --- a/src/stage/type_check/expression/integer.rs +++ b/src/stage/type_check/expression/integer.rs @@ -23,7 +23,7 @@ mod test_integer { #[test] fn integer_infer() { assert_eq!( - Integer::new(0, Span::default()) + Integer::new(0, Span::default(), Default::default()) .ty_solve() .unwrap() .ty_info @@ -35,7 +35,7 @@ mod test_integer { #[test] fn integer_return() { assert_eq!( - Integer::new(0, Span::default()) + Integer::new(0, Span::default(), Default::default()) .ty_solve() .unwrap() .ty_info diff --git a/src/stage/type_check/mod.rs b/src/stage/type_check/mod.rs index efe82b7..b8453c3 100644 --- a/src/stage/type_check/mod.rs +++ b/src/stage/type_check/mod.rs @@ -6,6 +6,7 @@ mod statement; use itertools::Itertools; use crate::compiler::Symbol; +use crate::repr::ast::base::AstMetadata; use crate::repr::ast::{base as base_ast, typed::*, untyped as parse_ast}; use crate::repr::ty::Ty; @@ -15,10 +16,8 @@ pub struct FunctionSignature { pub return_ty: Ty, } -impl - From<&base_ast::Function> for FunctionSignature -{ - fn from(function: &base_ast::Function) -> Self { +impl From<&base_ast::Function> for FunctionSignature { + fn from(function: &base_ast::Function) -> Self { Self { arguments: function.parameters.iter().map(|(_, ty)| *ty).collect(), return_ty: function.return_ty, diff --git a/src/stage/type_check/statement.rs b/src/stage/type_check/statement.rs index af6f64b..b216ce9 100644 --- a/src/stage/type_check/statement.rs +++ b/src/stage/type_check/statement.rs @@ -11,8 +11,8 @@ impl parse_ast::Statement { Ok(match self { parse_ast::Statement::Return(s) => Statement::Return(s.ty_solve(compiler, scope)?), parse_ast::Statement::Let(s) => Statement::Let(s.ty_solve(compiler, scope)?), - parse_ast::Statement::Expression(s) => { - Statement::Expression(s.ty_solve(compiler, scope)?) + parse_ast::Statement::ExpressionStatement(s) => { + Statement::ExpressionStatement(s.ty_solve(compiler, scope)?) } parse_ast::Statement::Break(s) => Statement::Break(s.ty_solve(compiler, scope)?), parse_ast::Statement::Continue(s) => Statement::Continue(s.ty_solve(compiler, scope)?),