Transform AST into MIR successfully, completing the chain
This commit is contained in:
		
							parent
							
								
									a66fc61c07
								
							
						
					
					
						commit
						61ba00ea58
					
				| @ -6,7 +6,7 @@ | ||||
| # Do note this file is extremely simply for my own personal convenience | ||||
| 
 | ||||
| export .env | ||||
| cargo run --example testcodegen && \ | ||||
| cargo run --example $1 && \ | ||||
| # clang hello.o -o main && \ | ||||
| ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \ | ||||
|    -o main /usr/lib/crt1.o hello.o -lc  && \ | ||||
|  | ||||
							
								
								
									
										11
									
								
								reid/examples/fibonacci.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								reid/examples/fibonacci.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| use reid::compile; | ||||
| 
 | ||||
| pub static FIBONACCI: &str = include_str!("./reid/fibonacci.reid"); | ||||
| 
 | ||||
| fn main() { | ||||
|     let text = match compile(FIBONACCI) { | ||||
|         Ok(t) => t, | ||||
|         Err(e) => panic!("{}", e), | ||||
|     }; | ||||
|     println!("{}", text); | ||||
| } | ||||
| @ -3,12 +3,11 @@ | ||||
| fn main() { | ||||
|     let test = 9; | ||||
|     let simpleAdd = 2 + 2; | ||||
|     let simpleMult = 7 * 2; // 14 | ||||
|     let arithmetic = 3 + 2 * 5 + 1 * 2; // 15 | ||||
|     let simpleSub = 7 - 2; // 14 | ||||
|      | ||||
|     if simpleAdd < test { | ||||
|         return 3; | ||||
|     } | ||||
| 
 | ||||
|     return arithmetic + simpleMult * arithmetic; | ||||
|     return test + simpleSub; | ||||
| } | ||||
| @ -11,101 +11,108 @@ fn main() { | ||||
|         kind: FunctionDefinitionKind::Local( | ||||
|             Block { | ||||
|                 statements: vec![Statement( | ||||
|                     StmtKind::If(IfExpression( | ||||
|                         // If N < 3
 | ||||
|                         Box::new(Expression( | ||||
|                             ExprKind::BinOp( | ||||
|                                 BinaryOperator::Logic(LogicOperator::GreaterThan), | ||||
|                                 Box::new(Expression( | ||||
|                                     ExprKind::Variable(VariableReference( | ||||
|                                         TypeKind::I32, | ||||
|                                         "N".to_string(), | ||||
|                     StmtKind::Expression(Expression( | ||||
|                         ExprKind::If(IfExpression( | ||||
|                             // If N < 3
 | ||||
|                             Box::new(Expression( | ||||
|                                 ExprKind::BinOp( | ||||
|                                     BinaryOperator::Logic(LogicOperator::GreaterThan), | ||||
|                                     Box::new(Expression( | ||||
|                                         ExprKind::Variable(VariableReference( | ||||
|                                             TypeKind::I32, | ||||
|                                             "N".to_string(), | ||||
|                                             Default::default(), | ||||
|                                         )), | ||||
|                                         Default::default(), | ||||
|                                     )), | ||||
|                                     Default::default(), | ||||
|                                 )), | ||||
|                                 Box::new(Expression( | ||||
|                                     ExprKind::Literal(Literal::I32(2)), | ||||
|                                     Default::default(), | ||||
|                                 )), | ||||
|                             ), | ||||
|                             Default::default(), | ||||
|                         )), | ||||
|                         // Then
 | ||||
|                         Block { | ||||
|                             statements: vec![], | ||||
|                             return_expression: Some(( | ||||
|                                 ReturnKind::HardReturn, | ||||
|                                 // return fibonacci(n-1) + fibonacci(n-2)
 | ||||
|                                 Box::new(Expression( | ||||
|                                     ExprKind::BinOp( | ||||
|                                         BinaryOperator::Add, | ||||
|                                         // fibonacci(n-1)
 | ||||
|                                         Box::new(Expression( | ||||
|                                             ExprKind::FunctionCall(FunctionCall { | ||||
|                                                 name: fibonacci_name.clone(), | ||||
|                                                 return_type: TypeKind::I32, | ||||
|                                                 parameters: vec![Expression( | ||||
|                                                     ExprKind::BinOp( | ||||
|                                                         BinaryOperator::Minus, | ||||
|                                                         Box::new(Expression( | ||||
|                                                             ExprKind::Variable(VariableReference( | ||||
|                                                                 TypeKind::I32, | ||||
|                                                                 fibonacci_n.clone(), | ||||
|                                                                 Default::default(), | ||||
|                                                             )), | ||||
|                                                             Default::default(), | ||||
|                                                         )), | ||||
|                                                         Box::new(Expression( | ||||
|                                                             ExprKind::Literal(Literal::I32(1)), | ||||
|                                                             Default::default(), | ||||
|                                                         )), | ||||
|                                                     ), | ||||
|                                                     Default::default(), | ||||
|                                                 )], | ||||
|                                             }), | ||||
|                                             Default::default(), | ||||
|                                         )), | ||||
|                                         // fibonacci(n-2)
 | ||||
|                                         Box::new(Expression( | ||||
|                                             ExprKind::FunctionCall(FunctionCall { | ||||
|                                                 name: fibonacci_name.clone(), | ||||
|                                                 return_type: TypeKind::I32, | ||||
|                                                 parameters: vec![Expression( | ||||
|                                                     ExprKind::BinOp( | ||||
|                                                         BinaryOperator::Minus, | ||||
|                                                         Box::new(Expression( | ||||
|                                                             ExprKind::Variable(VariableReference( | ||||
|                                                                 TypeKind::I32, | ||||
|                                                                 fibonacci_n.clone(), | ||||
|                                                                 Default::default(), | ||||
|                                                             )), | ||||
|                                                             Default::default(), | ||||
|                                                         )), | ||||
|                                                         Box::new(Expression( | ||||
|                                                             ExprKind::Literal(Literal::I32(2)), | ||||
|                                                             Default::default(), | ||||
|                                                         )), | ||||
|                                                     ), | ||||
|                                                     Default::default(), | ||||
|                                                 )], | ||||
|                                             }), | ||||
|                                             Default::default(), | ||||
|                                         )), | ||||
|                                     ), | ||||
|                                     Default::default(), | ||||
|                                 )), | ||||
|                                     Box::new(Expression( | ||||
|                                         ExprKind::Literal(Literal::I32(2)), | ||||
|                                         Default::default(), | ||||
|                                     )), | ||||
|                                 ), | ||||
|                                 Default::default(), | ||||
|                             )), | ||||
|                             meta: Default::default(), | ||||
|                         }, | ||||
|                         // No else-block
 | ||||
|                         None, | ||||
|                             // Then
 | ||||
|                             Block { | ||||
|                                 statements: vec![], | ||||
|                                 return_expression: Some(( | ||||
|                                     ReturnKind::Hard, | ||||
|                                     // return fibonacci(n-1) + fibonacci(n-2)
 | ||||
|                                     Box::new(Expression( | ||||
|                                         ExprKind::BinOp( | ||||
|                                             BinaryOperator::Add, | ||||
|                                             // fibonacci(n-1)
 | ||||
|                                             Box::new(Expression( | ||||
|                                                 ExprKind::FunctionCall(FunctionCall { | ||||
|                                                     name: fibonacci_name.clone(), | ||||
|                                                     return_type: TypeKind::I32, | ||||
|                                                     parameters: vec![Expression( | ||||
|                                                         ExprKind::BinOp( | ||||
|                                                             BinaryOperator::Minus, | ||||
|                                                             Box::new(Expression( | ||||
|                                                                 ExprKind::Variable( | ||||
|                                                                     VariableReference( | ||||
|                                                                         TypeKind::I32, | ||||
|                                                                         fibonacci_n.clone(), | ||||
|                                                                         Default::default(), | ||||
|                                                                     ), | ||||
|                                                                 ), | ||||
|                                                                 Default::default(), | ||||
|                                                             )), | ||||
|                                                             Box::new(Expression( | ||||
|                                                                 ExprKind::Literal(Literal::I32(1)), | ||||
|                                                                 Default::default(), | ||||
|                                                             )), | ||||
|                                                         ), | ||||
|                                                         Default::default(), | ||||
|                                                     )], | ||||
|                                                 }), | ||||
|                                                 Default::default(), | ||||
|                                             )), | ||||
|                                             // fibonacci(n-2)
 | ||||
|                                             Box::new(Expression( | ||||
|                                                 ExprKind::FunctionCall(FunctionCall { | ||||
|                                                     name: fibonacci_name.clone(), | ||||
|                                                     return_type: TypeKind::I32, | ||||
|                                                     parameters: vec![Expression( | ||||
|                                                         ExprKind::BinOp( | ||||
|                                                             BinaryOperator::Minus, | ||||
|                                                             Box::new(Expression( | ||||
|                                                                 ExprKind::Variable( | ||||
|                                                                     VariableReference( | ||||
|                                                                         TypeKind::I32, | ||||
|                                                                         fibonacci_n.clone(), | ||||
|                                                                         Default::default(), | ||||
|                                                                     ), | ||||
|                                                                 ), | ||||
|                                                                 Default::default(), | ||||
|                                                             )), | ||||
|                                                             Box::new(Expression( | ||||
|                                                                 ExprKind::Literal(Literal::I32(2)), | ||||
|                                                                 Default::default(), | ||||
|                                                             )), | ||||
|                                                         ), | ||||
|                                                         Default::default(), | ||||
|                                                     )], | ||||
|                                                 }), | ||||
|                                                 Default::default(), | ||||
|                                             )), | ||||
|                                         ), | ||||
|                                         Default::default(), | ||||
|                                     )), | ||||
|                                 )), | ||||
|                                 meta: Default::default(), | ||||
|                             }, | ||||
|                             // No else-block
 | ||||
|                             None, | ||||
|                         )), | ||||
|                         Default::default(), | ||||
|                     )), | ||||
|                     Default::default(), | ||||
|                 )], | ||||
|                 // return 1
 | ||||
|                 return_expression: Some(( | ||||
|                     ReturnKind::SoftReturn, | ||||
|                     ReturnKind::Soft, | ||||
|                     Box::new(Expression( | ||||
|                         ExprKind::Literal(Literal::I32(1)), | ||||
|                         Default::default(), | ||||
| @ -124,7 +131,7 @@ fn main() { | ||||
|             Block { | ||||
|                 statements: vec![], | ||||
|                 return_expression: Some(( | ||||
|                     ReturnKind::SoftReturn, | ||||
|                     ReturnKind::Soft, | ||||
|                     Box::new(Expression( | ||||
|                         ExprKind::FunctionCall(FunctionCall { | ||||
|                             name: fibonacci_name.clone(), | ||||
|  | ||||
							
								
								
									
										109
									
								
								reid/src/ast/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								reid/src/ast/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | ||||
| use crate::token_stream::TokenRange; | ||||
| 
 | ||||
| pub mod parse; | ||||
| pub mod process; | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub struct Type(pub TypeKind, pub TokenRange); | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub enum TypeKind { | ||||
|     I32, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum Literal { | ||||
|     I32(i32), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Expression(pub ExpressionKind, pub TokenRange); | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum ExpressionKind { | ||||
|     VariableName(String), | ||||
|     Literal(Literal), | ||||
|     Binop(BinaryOperator, Box<Expression>, Box<Expression>), | ||||
|     FunctionCall(Box<FunctionCallExpression>), | ||||
|     BlockExpr(Box<Block>), | ||||
|     IfExpr(Box<IfExpression>), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub enum BinaryOperator { | ||||
|     Add, | ||||
|     Minus, | ||||
|     Mult, | ||||
| 
 | ||||
|     And, | ||||
|     LessThan, | ||||
| } | ||||
| 
 | ||||
| impl BinaryOperator { | ||||
|     pub fn get_precedence(&self) -> i8 { | ||||
|         use BinaryOperator::*; | ||||
|         match &self { | ||||
|             Add => 10, | ||||
|             Minus => 10, | ||||
|             Mult => 20, | ||||
|             And => 100, | ||||
|             LessThan => 100, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct FunctionCallExpression(pub String, pub Vec<Expression>, pub TokenRange); | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct IfExpression(pub Expression, pub Block, pub Option<Block>, pub TokenRange); | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct LetStatement(pub String, pub Expression, pub TokenRange); | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct ImportStatement(Vec<String>, pub TokenRange); | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct FunctionDefinition(pub FunctionSignature, pub Block, pub TokenRange); | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct FunctionSignature { | ||||
|     pub name: String, | ||||
|     pub args: Vec<(String, Type)>, | ||||
|     pub return_type: Option<Type>, | ||||
|     pub range: TokenRange, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub enum ReturnType { | ||||
|     Soft, | ||||
|     Hard, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Block( | ||||
|     pub Vec<BlockLevelStatement>, | ||||
|     pub Option<(ReturnType, Expression)>, | ||||
|     pub TokenRange, | ||||
| ); | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum BlockLevelStatement { | ||||
|     Let(LetStatement), | ||||
|     Import(ImportStatement), | ||||
|     Expression(Expression), | ||||
|     Return(ReturnType, Expression), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum TopLevelStatement { | ||||
|     Import(ImportStatement), | ||||
|     FunctionDefinition(FunctionDefinition), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Module { | ||||
|     pub name: String, | ||||
|     pub top_level_statements: Vec<TopLevelStatement>, | ||||
| } | ||||
| @ -1,3 +1,4 @@ | ||||
| use crate::ast::*; | ||||
| use crate::{ | ||||
|     lexer::Token, | ||||
|     token_stream::{Error, TokenRange, TokenStream}, | ||||
| @ -10,14 +11,6 @@ where | ||||
|     fn parse(stream: TokenStream) -> Result<Self, Error>; | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Type(pub TypeKind, pub TokenRange); | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum TypeKind { | ||||
|     I32, | ||||
| } | ||||
| 
 | ||||
| impl Parse for Type { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         let kind = if let Some(Token::Identifier(ident)) = stream.next() { | ||||
| @ -33,24 +26,6 @@ impl Parse for Type { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum Literal { | ||||
|     I32(i32), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Expression(pub ExpressionKind, pub TokenRange); | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum ExpressionKind { | ||||
|     VariableName(String), | ||||
|     Literal(Literal), | ||||
|     Binop(BinaryOperator, Box<Expression>, Box<Expression>), | ||||
|     FunctionCall(Box<FunctionCallExpression>), | ||||
|     BlockExpr(Box<Block>), | ||||
|     IfExpr(Box<IfExpression>), | ||||
| } | ||||
| 
 | ||||
| impl Parse for Expression { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Expression, Error> { | ||||
|         let lhs = parse_primary_expression(&mut stream)?; | ||||
| @ -142,16 +117,6 @@ fn parse_binop_rhs( | ||||
|     Ok(lhs) | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub enum BinaryOperator { | ||||
|     Add, | ||||
|     Minus, | ||||
|     Mult, | ||||
| 
 | ||||
|     And, | ||||
|     LessThan, | ||||
| } | ||||
| 
 | ||||
| impl Parse for BinaryOperator { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         Ok(match (stream.next(), stream.peek()) { | ||||
| @ -169,22 +134,6 @@ impl Parse for BinaryOperator { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl BinaryOperator { | ||||
|     pub fn get_precedence(&self) -> i8 { | ||||
|         use BinaryOperator::*; | ||||
|         match &self { | ||||
|             Add => 10, | ||||
|             Minus => 10, | ||||
|             Mult => 20, | ||||
|             And => 100, | ||||
|             LessThan => 100, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct FunctionCallExpression(pub String, pub Vec<Expression>, pub TokenRange); | ||||
| 
 | ||||
| impl Parse for FunctionCallExpression { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         if let Some(Token::Identifier(name)) = stream.next() { | ||||
| @ -213,23 +162,18 @@ impl Parse for FunctionCallExpression { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct IfExpression(pub Expression, pub Block, pub TokenRange); | ||||
| 
 | ||||
| impl Parse for IfExpression { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         stream.expect(Token::If)?; | ||||
|         Ok(IfExpression( | ||||
|             stream.parse()?, | ||||
|             stream.parse()?, | ||||
|             None, | ||||
|             stream.get_range().unwrap(), | ||||
|         )) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct LetStatement(pub String, pub Expression, pub TokenRange); | ||||
| 
 | ||||
| impl Parse for LetStatement { | ||||
|     fn parse(mut stream: TokenStream) -> Result<LetStatement, Error> { | ||||
|         stream.expect(Token::LetKeyword)?; | ||||
| @ -250,9 +194,6 @@ impl Parse for LetStatement { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct ImportStatement(Vec<String>, pub TokenRange); | ||||
| 
 | ||||
| impl Parse for ImportStatement { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         stream.expect(Token::ImportKeyword)?; | ||||
| @ -278,9 +219,6 @@ impl Parse for ImportStatement { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct FunctionDefinition(pub FunctionSignature, pub Block, pub TokenRange); | ||||
| 
 | ||||
| impl Parse for FunctionDefinition { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         stream.expect(Token::FnKeyword)?; | ||||
| @ -292,14 +230,6 @@ impl Parse for FunctionDefinition { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct FunctionSignature { | ||||
|     pub name: String, | ||||
|     pub args: Vec<(String, Type)>, | ||||
|     pub return_type: Option<Type>, | ||||
|     pub range: TokenRange, | ||||
| } | ||||
| 
 | ||||
| impl Parse for FunctionSignature { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         if let Some(Token::Identifier(name)) = stream.next() { | ||||
| @ -331,19 +261,6 @@ impl Parse for FunctionSignature { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub enum ReturnType { | ||||
|     Soft, | ||||
|     Hard, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Block( | ||||
|     pub Vec<BlockLevelStatement>, | ||||
|     pub Option<(ReturnType, Expression)>, | ||||
|     pub TokenRange, | ||||
| ); | ||||
| 
 | ||||
| impl Parse for Block { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         let mut statements = Vec::new(); | ||||
| @ -382,14 +299,6 @@ impl Parse for Block { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum BlockLevelStatement { | ||||
|     Let(LetStatement), | ||||
|     Import(ImportStatement), | ||||
|     Expression(Expression), | ||||
|     Return(ReturnType, Expression), | ||||
| } | ||||
| 
 | ||||
| impl Parse for BlockLevelStatement { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         use BlockLevelStatement as Stmt; | ||||
| @ -417,12 +326,6 @@ impl Parse for BlockLevelStatement { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum TopLevelStatement { | ||||
|     Import(ImportStatement), | ||||
|     FunctionDefinition(FunctionDefinition), | ||||
| } | ||||
| 
 | ||||
| impl Parse for TopLevelStatement { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         use TopLevelStatement as Stmt; | ||||
							
								
								
									
										541
									
								
								reid/src/ast/process.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										541
									
								
								reid/src/ast/process.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,541 @@ | ||||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use crate::{ | ||||
|     ast, | ||||
|     mir::{self, StmtKind, VariableReference}, | ||||
|     token_stream::TokenRange, | ||||
| }; | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub enum InferredType { | ||||
|     FromVariable(String, TokenRange), | ||||
|     FunctionReturn(String, TokenRange), | ||||
|     Static(mir::TypeKind, TokenRange), | ||||
|     OneOf(Vec<InferredType>), | ||||
|     Void(TokenRange), | ||||
|     DownstreamError(IntoMIRError, TokenRange), | ||||
| } | ||||
| 
 | ||||
| fn all_ok<T, E>(result: Vec<Result<T, E>>) -> Option<Vec<T>> { | ||||
|     let mut res = Vec::with_capacity(result.len()); | ||||
|     for item in result { | ||||
|         if let Ok(item) = item { | ||||
|             res.push(item); | ||||
|         } else { | ||||
|             return None; | ||||
|         } | ||||
|     } | ||||
|     Some(res) | ||||
| } | ||||
| 
 | ||||
| impl InferredType { | ||||
|     fn collapse( | ||||
|         &self, | ||||
|         state: &mut State, | ||||
|         scope: &VirtualScope, | ||||
|     ) -> Result<mir::TypeKind, IntoMIRError> { | ||||
|         match self { | ||||
|             InferredType::FromVariable(name, token_range) => { | ||||
|                 if let Some(inferred) = scope.get_var(name) { | ||||
|                     let temp = inferred.collapse(state, scope); | ||||
|                     state.note(temp) | ||||
|                 } else { | ||||
|                     state.err(IntoMIRError::VariableNotDefined(name.clone(), *token_range)) | ||||
|                 } | ||||
|             } | ||||
|             InferredType::FunctionReturn(name, token_range) => { | ||||
|                 if let Some(type_kind) = scope.get_return_type(name) { | ||||
|                     Ok(*type_kind) | ||||
|                 } else { | ||||
|                     state.err(IntoMIRError::VariableNotDefined(name.clone(), *token_range)) | ||||
|                 } | ||||
|             } | ||||
|             InferredType::Static(type_kind, _) => Ok(*type_kind), | ||||
|             InferredType::OneOf(inferred_types) => { | ||||
|                 let collapsed = all_ok( | ||||
|                     inferred_types | ||||
|                         .iter() | ||||
|                         .map(|t| { | ||||
|                             let temp = t.collapse(state, scope); | ||||
|                             state.note(temp) | ||||
|                         }) | ||||
|                         .collect(), | ||||
|                 ); | ||||
|                 if let Some(list) = collapsed { | ||||
|                     if let Some(first) = list.first() { | ||||
|                         if list.iter().all(|i| i == first) { | ||||
|                             Ok((*first).into()) | ||||
|                         } else { | ||||
|                             state.err(IntoMIRError::ConflictingType(self.get_range())) | ||||
|                         } | ||||
|                     } else { | ||||
|                         state.err(IntoMIRError::VoidType(self.get_range())) | ||||
|                     } | ||||
|                 } else { | ||||
|                     state.err(IntoMIRError::DownstreamError(self.get_range())) | ||||
|                 } | ||||
|             } | ||||
|             InferredType::Void(token_range) => state.err(IntoMIRError::VoidType(*token_range)), | ||||
|             InferredType::DownstreamError(e, _) => state.err(e.clone()), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn get_range(&self) -> TokenRange { | ||||
|         match &self { | ||||
|             InferredType::FromVariable(_, token_range) => *token_range, | ||||
|             InferredType::FunctionReturn(_, token_range) => *token_range, | ||||
|             InferredType::Static(_, token_range) => *token_range, | ||||
|             InferredType::OneOf(inferred_types) => { | ||||
|                 inferred_types.iter().map(|i| i.get_range()).sum() | ||||
|             } | ||||
|             InferredType::Void(token_range) => *token_range, | ||||
|             InferredType::DownstreamError(_, range) => *range, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct VirtualVariable { | ||||
|     name: String, | ||||
|     inferred: InferredType, | ||||
|     meta: mir::Metadata, | ||||
| } | ||||
| 
 | ||||
| pub struct VirtualFunctionSignature { | ||||
|     name: String, | ||||
|     return_type: mir::TypeKind, | ||||
|     parameter_types: Vec<mir::TypeKind>, | ||||
|     metadata: mir::Metadata, | ||||
| } | ||||
| 
 | ||||
| pub enum VirtualStorageError { | ||||
|     KeyAlreadyExists(String), | ||||
| } | ||||
| 
 | ||||
| pub struct VirtualStorage<T> { | ||||
|     storage: HashMap<String, Vec<T>>, | ||||
| } | ||||
| 
 | ||||
| impl<T> VirtualStorage<T> { | ||||
|     fn set(&mut self, name: String, value: T) -> Result<(), VirtualStorageError> { | ||||
|         let result = if let Some(list) = self.storage.get_mut(&name) { | ||||
|             list.push(value); | ||||
|             Err(VirtualStorageError::KeyAlreadyExists(name.clone())) | ||||
|         } else { | ||||
|             self.storage.insert(name, vec![value]); | ||||
|             Ok(()) | ||||
|         }; | ||||
| 
 | ||||
|         result | ||||
|     } | ||||
| 
 | ||||
|     fn get(&self, name: &String) -> Option<&T> { | ||||
|         if let Some(list) = self.storage.get(name) { | ||||
|             list.first() | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T> Default for VirtualStorage<T> { | ||||
|     fn default() -> Self { | ||||
|         Self { | ||||
|             storage: Default::default(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug)] | ||||
| pub enum IntoMIRError { | ||||
|     DuplicateVariable(String, TokenRange), | ||||
|     DuplicateFunction(String, TokenRange), | ||||
|     VariableNotDefined(String, TokenRange), | ||||
|     FunctionNotDefined(String, TokenRange), | ||||
|     DownstreamError(TokenRange), | ||||
|     ConflictingType(TokenRange), | ||||
|     VoidType(TokenRange), | ||||
| } | ||||
| 
 | ||||
| pub struct VirtualScope { | ||||
|     variables: VirtualStorage<VirtualVariable>, | ||||
|     functions: VirtualStorage<VirtualFunctionSignature>, | ||||
| } | ||||
| 
 | ||||
| impl VirtualScope { | ||||
|     pub fn set_var(&mut self, variable: VirtualVariable) -> Result<(), IntoMIRError> { | ||||
|         let range = variable.meta.range; | ||||
|         match self.variables.set(variable.name.clone(), variable) { | ||||
|             Ok(_) => Ok(()), | ||||
|             Err(VirtualStorageError::KeyAlreadyExists(n)) => { | ||||
|                 Err(IntoMIRError::DuplicateVariable(n, range)) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn set_fun(&mut self, function: VirtualFunctionSignature) -> Result<(), IntoMIRError> { | ||||
|         let range = function.metadata.range; | ||||
|         match self.functions.set(function.name.clone(), function) { | ||||
|             Ok(_) => Ok(()), | ||||
|             Err(VirtualStorageError::KeyAlreadyExists(n)) => { | ||||
|                 Err(IntoMIRError::DuplicateVariable(n, range)) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_var(&self, name: &String) -> Option<&InferredType> { | ||||
|         self.variables.get(name).map(|v| &v.inferred) | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_return_type(&self, name: &String) -> Option<&mir::TypeKind> { | ||||
|         self.functions.get(name).map(|v| &v.return_type) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Default for VirtualScope { | ||||
|     fn default() -> Self { | ||||
|         Self { | ||||
|             variables: Default::default(), | ||||
|             functions: Default::default(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct State { | ||||
|     errors: Vec<IntoMIRError>, | ||||
|     fatal: bool, | ||||
| } | ||||
| 
 | ||||
| impl State { | ||||
|     fn note<T: std::fmt::Debug>( | ||||
|         &mut self, | ||||
|         value: Result<T, IntoMIRError>, | ||||
|     ) -> Result<T, IntoMIRError> { | ||||
|         dbg!(&value); | ||||
|         if let Err(e) = &value { | ||||
|             self.errors.push(e.clone()); | ||||
|         } | ||||
|         value | ||||
|     } | ||||
| 
 | ||||
|     fn err<T>(&mut self, error: IntoMIRError) -> Result<T, IntoMIRError> { | ||||
|         self.errors.push(error.clone()); | ||||
|         Err(error) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Default for State { | ||||
|     fn default() -> Self { | ||||
|         Self { | ||||
|             errors: Default::default(), | ||||
|             fatal: false, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ast::Module { | ||||
|     pub fn process(&self) -> mir::Module { | ||||
|         let mut state = State::default(); | ||||
|         let mut scope = VirtualScope::default(); | ||||
| 
 | ||||
|         for stmt in &self.top_level_statements { | ||||
|             match stmt { | ||||
|                 FunctionDefinition(ast::FunctionDefinition(signature, _, range)) => { | ||||
|                     state.note(scope.set_fun(VirtualFunctionSignature { | ||||
|                         name: signature.name.clone(), | ||||
|                         return_type: signature.return_type.into(), | ||||
|                         parameter_types: signature.args.iter().map(|p| p.1.into()).collect(), | ||||
|                         metadata: (*range).into(), | ||||
|                     })); | ||||
|                 } | ||||
|                 _ => {} | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         let mut imports = Vec::new(); | ||||
|         let mut functions = Vec::new(); | ||||
| 
 | ||||
|         use ast::TopLevelStatement::*; | ||||
|         for stmt in &self.top_level_statements { | ||||
|             match stmt { | ||||
|                 Import(import) => { | ||||
|                     for name in &import.0 { | ||||
|                         imports.push(mir::Import(name.clone(), import.1.into())); | ||||
|                     } | ||||
|                 } | ||||
|                 FunctionDefinition(ast::FunctionDefinition(signature, block, range)) => { | ||||
|                     for (name, ptype) in &signature.args { | ||||
|                         state.note(scope.set_var(VirtualVariable { | ||||
|                             name: name.clone(), | ||||
|                             inferred: InferredType::Static((*ptype).into(), *range), | ||||
|                             meta: ptype.1.into(), | ||||
|                         })); | ||||
|                     } | ||||
| 
 | ||||
|                     dbg!(&signature); | ||||
| 
 | ||||
|                     if let Some(mir_block) = block.process(&mut state, &mut scope) { | ||||
|                         let def = mir::FunctionDefinition { | ||||
|                             name: signature.name.clone(), | ||||
|                             parameters: signature | ||||
|                                 .args | ||||
|                                 .iter() | ||||
|                                 .cloned() | ||||
|                                 .map(|p| (p.0, p.1.into())) | ||||
|                                 .collect(), | ||||
|                             kind: mir::FunctionDefinitionKind::Local(mir_block, (*range).into()), | ||||
|                         }; | ||||
|                         functions.push(def); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         dbg!(&state); | ||||
| 
 | ||||
|         // TODO do something with state here
 | ||||
| 
 | ||||
|         mir::Module { | ||||
|             name: self.name.clone(), | ||||
|             imports, | ||||
|             functions, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ast::Block { | ||||
|     pub fn process(&self, state: &mut State, scope: &mut VirtualScope) -> Option<mir::Block> { | ||||
|         let mut mir_statements = Vec::new(); | ||||
| 
 | ||||
|         for statement in &self.0 { | ||||
|             let (kind, range): (Option<mir::StmtKind>, TokenRange) = match statement { | ||||
|                 ast::BlockLevelStatement::Let(s_let) => { | ||||
|                     let res = s_let.1.infer_return_type().collapse(state, scope); | ||||
|                     let collapsed = state.note(res); | ||||
|                     let inferred = match &collapsed { | ||||
|                         Ok(t) => InferredType::Static(*t, s_let.2), | ||||
|                         Err(e) => InferredType::DownstreamError(e.clone(), s_let.2), | ||||
|                     }; | ||||
|                     scope.set_var(VirtualVariable { | ||||
|                         name: s_let.0.clone(), | ||||
|                         inferred, | ||||
|                         meta: s_let.2.into(), | ||||
|                     }); | ||||
| 
 | ||||
|                     ( | ||||
|                         collapsed.ok().and_then(|t| { | ||||
|                             s_let.1.process(state, scope).map(|e| { | ||||
|                                 mir::StmtKind::Let( | ||||
|                                     mir::VariableReference(t, s_let.0.clone(), s_let.2.into()), | ||||
|                                     e, | ||||
|                                 ) | ||||
|                             }) | ||||
|                         }), | ||||
|                         s_let.2, | ||||
|                     ) | ||||
|                 } | ||||
|                 ast::BlockLevelStatement::Import(_) => todo!(), | ||||
|                 ast::BlockLevelStatement::Expression(e) => ( | ||||
|                     e.process(state, scope).map(|e| StmtKind::Expression(e)), | ||||
|                     e.1, | ||||
|                 ), | ||||
|                 ast::BlockLevelStatement::Return(_, e) => ( | ||||
|                     e.process(state, scope).map(|e| StmtKind::Expression(e)), | ||||
|                     e.1, | ||||
|                 ), | ||||
|             }; | ||||
| 
 | ||||
|             if let Some(kind) = kind { | ||||
|                 mir_statements.push(mir::Statement(kind, range.into())); | ||||
|             } else { | ||||
|                 state.fatal = true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         let return_expression = if let Some(r) = &self.1 { | ||||
|             if let Some(expr) = r.1.process(state, scope) { | ||||
|                 Some((r.0.into(), Box::new(expr))) | ||||
|             } else { | ||||
|                 None? | ||||
|             } | ||||
|         } else { | ||||
|             None | ||||
|         }; | ||||
| 
 | ||||
|         Some(mir::Block { | ||||
|             statements: mir_statements, | ||||
|             return_expression, | ||||
|             meta: self.2.into(), | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn infer_return_type(&self) -> InferredType { | ||||
|         self.1 | ||||
|             .as_ref() | ||||
|             .map(|(_, expr)| expr.infer_return_type()) | ||||
|             .unwrap_or(InferredType::Void(self.2)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<ast::ReturnType> for mir::ReturnKind { | ||||
|     fn from(value: ast::ReturnType) -> Self { | ||||
|         match value { | ||||
|             ast::ReturnType::Soft => mir::ReturnKind::Soft, | ||||
|             ast::ReturnType::Hard => mir::ReturnKind::Hard, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ast::Expression { | ||||
|     fn process(&self, state: &mut State, scope: &mut VirtualScope) -> Option<mir::Expression> { | ||||
|         let kind = match &self.0 { | ||||
|             ast::ExpressionKind::VariableName(name) => { | ||||
|                 let ty = scope.get_var(name); | ||||
|                 if let Some(ty) = ty { | ||||
|                     let res = ty.collapse(state, scope); | ||||
|                     state | ||||
|                         .note(res) | ||||
|                         .map(|result| { | ||||
|                             mir::ExprKind::Variable(VariableReference( | ||||
|                                 result, | ||||
|                                 name.clone(), | ||||
|                                 self.1.into(), | ||||
|                             )) | ||||
|                         }) | ||||
|                         .ok() | ||||
|                 } else { | ||||
|                     state | ||||
|                         .err(IntoMIRError::VariableNotDefined( | ||||
|                             name.clone(), | ||||
|                             self.1.into(), | ||||
|                         )) | ||||
|                         .ok() | ||||
|                 } | ||||
|             } | ||||
|             ast::ExpressionKind::Literal(literal) => Some(mir::ExprKind::Literal(literal.mir())), | ||||
|             ast::ExpressionKind::Binop(binary_operator, lhs, rhs) => { | ||||
|                 let mir_lhs = lhs.process(state, scope); | ||||
|                 let mir_rhs = rhs.process(state, scope); | ||||
|                 Some(mir::ExprKind::BinOp( | ||||
|                     binary_operator.mir(), | ||||
|                     Box::new(mir_lhs?), | ||||
|                     Box::new(mir_rhs?), | ||||
|                 )) | ||||
|             } | ||||
|             ast::ExpressionKind::FunctionCall(fn_call_expr) => { | ||||
|                 if let Some(fn_type) = scope.get_return_type(&fn_call_expr.0).cloned() { | ||||
|                     let parameters = all_ok( | ||||
|                         fn_call_expr | ||||
|                             .1 | ||||
|                             .iter() | ||||
|                             .map(|e| { | ||||
|                                 e.process(state, scope) | ||||
|                                     .ok_or(IntoMIRError::DownstreamError(self.1.into())) | ||||
|                             }) | ||||
|                             .collect(), | ||||
|                     ); | ||||
|                     if let Some(parameters) = parameters { | ||||
|                         Some(mir::ExprKind::FunctionCall(mir::FunctionCall { | ||||
|                             name: fn_call_expr.0.clone(), | ||||
|                             return_type: fn_type, | ||||
|                             parameters, | ||||
|                         })) | ||||
|                     } else { | ||||
|                         None | ||||
|                     } | ||||
|                 } else { | ||||
|                     state | ||||
|                         .err(IntoMIRError::FunctionNotDefined( | ||||
|                             fn_call_expr.0.clone(), | ||||
|                             self.1, | ||||
|                         )) | ||||
|                         .ok() | ||||
|                 } | ||||
|             } | ||||
|             ast::ExpressionKind::BlockExpr(block) => { | ||||
|                 block.process(state, scope).map(|b| mir::ExprKind::Block(b)) | ||||
|             } | ||||
|             ast::ExpressionKind::IfExpr(if_expression) => { | ||||
|                 let cond = if_expression.0.process(state, scope); | ||||
|                 let then_block = if_expression.1.process(state, scope); | ||||
|                 let else_block = if let Some(el) = &if_expression.2 { | ||||
|                     Some(el.process(state, scope)?) | ||||
|                 } else { | ||||
|                     None | ||||
|                 }; | ||||
|                 Some(mir::ExprKind::If(mir::IfExpression( | ||||
|                     Box::new(cond?), | ||||
|                     then_block?, | ||||
|                     else_block, | ||||
|                 ))) | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         kind.map(|k| mir::Expression(k, self.1.into())) | ||||
|     } | ||||
| 
 | ||||
|     fn infer_return_type(&self) -> InferredType { | ||||
|         use ast::ExpressionKind::*; | ||||
|         match &self.0 { | ||||
|             VariableName(name) => InferredType::FromVariable(name.clone(), self.1), | ||||
|             Literal(lit) => InferredType::Static(lit.mir().as_type(), self.1), | ||||
|             Binop(_, lhs, rhs) => { | ||||
|                 InferredType::OneOf(vec![lhs.infer_return_type(), rhs.infer_return_type()]) | ||||
|             } | ||||
|             FunctionCall(fncall) => InferredType::FunctionReturn(fncall.0.clone(), self.1), | ||||
|             BlockExpr(block) => block.infer_return_type(), | ||||
|             IfExpr(exp) => { | ||||
|                 let mut types = vec![exp.1.infer_return_type()]; | ||||
|                 if let Some(e) = &exp.2 { | ||||
|                     types.push(e.infer_return_type()) | ||||
|                 } | ||||
|                 InferredType::OneOf(types) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ast::BinaryOperator { | ||||
|     fn mir(&self) -> mir::BinaryOperator { | ||||
|         match self { | ||||
|             ast::BinaryOperator::Add => mir::BinaryOperator::Add, | ||||
|             ast::BinaryOperator::Minus => mir::BinaryOperator::Minus, | ||||
|             ast::BinaryOperator::Mult => mir::BinaryOperator::Mult, | ||||
|             ast::BinaryOperator::And => mir::BinaryOperator::And, | ||||
|             ast::BinaryOperator::LessThan => { | ||||
|                 mir::BinaryOperator::Logic(mir::LogicOperator::LessThan) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ast::Literal { | ||||
|     fn mir(&self) -> mir::Literal { | ||||
|         match *self { | ||||
|             ast::Literal::I32(v) => mir::Literal::I32(v), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<ast::TypeKind> for mir::TypeKind { | ||||
|     fn from(value: ast::TypeKind) -> Self { | ||||
|         match value { | ||||
|             ast::TypeKind::I32 => mir::TypeKind::I32, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<ast::Type> for mir::TypeKind { | ||||
|     fn from(value: ast::Type) -> Self { | ||||
|         value.0.into() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<Option<ast::Type>> for mir::TypeKind { | ||||
|     fn from(value: Option<ast::Type>) -> Self { | ||||
|         match value { | ||||
|             Some(v) => v.into(), | ||||
|             None => mir::TypeKind::Void, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -107,12 +107,9 @@ impl mir::Statement { | ||||
|                 scope.stack_values.insert(name.clone(), value); | ||||
|                 None | ||||
|             } | ||||
|             mir::StmtKind::If(if_expression) => if_expression.codegen(scope), | ||||
|             // mir::StmtKind::If(if_expression) => if_expression.codegen(scope),
 | ||||
|             mir::StmtKind::Import(_) => todo!(), | ||||
|             mir::StmtKind::Expression(expression) => { | ||||
|                 let value = expression.codegen(scope).unwrap(); | ||||
|                 Some(value) | ||||
|             } | ||||
|             mir::StmtKind::Expression(expression) => expression.codegen(scope), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -249,11 +246,11 @@ impl mir::Block { | ||||
|         if let Some((kind, expr)) = &self.return_expression { | ||||
|             let ret = expr.codegen(&mut scope).unwrap(); | ||||
|             match kind { | ||||
|                 mir::ReturnKind::HardReturn => { | ||||
|                 mir::ReturnKind::Hard => { | ||||
|                     scope.block.ret(&ret).unwrap(); | ||||
|                     None | ||||
|                 } | ||||
|                 mir::ReturnKind::SoftReturn => Some(ret), | ||||
|                 mir::ReturnKind::Soft => Some(ret), | ||||
|             } | ||||
|         } else { | ||||
|             None | ||||
| @ -276,6 +273,7 @@ impl TypeKind { | ||||
|         match &self { | ||||
|             TypeKind::I32 => TypeEnum::Integer(context.type_i32()), | ||||
|             TypeKind::I16 => TypeEnum::Integer(context.type_i16()), | ||||
|             TypeKind::Void => panic!("Void not a supported type"), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,13 +1,11 @@ | ||||
| use old_codegen::{form_context, from_statements}; | ||||
| use reid_lib::Context; | ||||
| 
 | ||||
| use crate::{lexer::Token, parser::TopLevelStatement, token_stream::TokenStream}; | ||||
| use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream}; | ||||
| 
 | ||||
| mod ast; | ||||
| mod codegen; | ||||
| mod lexer; | ||||
| pub mod mir; | ||||
| mod old_codegen; | ||||
| mod parser; | ||||
| // mod llvm_ir;
 | ||||
| pub mod codegen; | ||||
| mod token_stream; | ||||
| 
 | ||||
| // TODO:
 | ||||
| @ -41,8 +39,21 @@ pub fn compile(source: &str) -> Result<String, ReidError> { | ||||
|         statements.push(statement); | ||||
|     } | ||||
| 
 | ||||
|     let mut context = form_context(); | ||||
|     let mut module = from_statements(&mut context, statements).unwrap(); | ||||
|     let text = module.print_to_string().unwrap(); | ||||
|     Ok(text.to_owned()) | ||||
|     let ast_module = ast::Module { | ||||
|         name: "test".to_owned(), | ||||
|         top_level_statements: statements, | ||||
|     }; | ||||
| 
 | ||||
|     dbg!(&ast_module); | ||||
|     let mir_module = ast_module.process(); | ||||
| 
 | ||||
|     dbg!(&mir_module); | ||||
| 
 | ||||
|     let mut context = Context::new(); | ||||
|     let cogegen_module = mir_module.codegen(&mut context); | ||||
| 
 | ||||
|     Ok(match cogegen_module.module.print_to_string() { | ||||
|         Ok(v) => v, | ||||
|         Err(e) => panic!("Err: {:?}", e), | ||||
|     }) | ||||
| } | ||||
|  | ||||
| @ -1,17 +1,19 @@ | ||||
| /// In this module are defined structs that are used for performing passes on
 | ||||
| /// Reid. It contains a simplified version of Reid which must already be
 | ||||
| /// type-checked beforehand.
 | ||||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use types::*; | ||||
| 
 | ||||
| use crate::token_stream::TokenRange; | ||||
| 
 | ||||
| pub mod types; | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub struct Metadata { | ||||
|     range: TokenRange, | ||||
|     pub range: TokenRange, | ||||
| } | ||||
| 
 | ||||
| impl From<TokenRange> for Metadata { | ||||
|     fn from(value: TokenRange) -> Self { | ||||
|         Metadata { range: value } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Default for Metadata { | ||||
| @ -22,10 +24,11 @@ impl Default for Metadata { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Copy)] | ||||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||||
| pub enum TypeKind { | ||||
|     I32, | ||||
|     I16, | ||||
|     Void, | ||||
| } | ||||
| 
 | ||||
| impl TypeKind { | ||||
| @ -36,14 +39,14 @@ impl TypeKind { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Copy)] | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub enum Literal { | ||||
|     I32(i32), | ||||
|     I16(i16), | ||||
| } | ||||
| 
 | ||||
| impl Literal { | ||||
|     fn as_type(self: &Literal) -> TypeKind { | ||||
|     pub fn as_type(self: &Literal) -> TypeKind { | ||||
|         match self { | ||||
|             Literal::I32(_) => TypeKind::I32, | ||||
|             Literal::I16(_) => TypeKind::I16, | ||||
| @ -68,14 +71,17 @@ pub enum LogicOperator { | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub enum ReturnKind { | ||||
|     HardReturn, | ||||
|     SoftReturn, | ||||
|     Hard, | ||||
|     Soft, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct VariableReference(pub TypeKind, pub String, pub Metadata); | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Import(pub String, pub Metadata); | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum ExprKind { | ||||
|     Variable(VariableReference), | ||||
|     Literal(Literal), | ||||
| @ -85,23 +91,28 @@ pub enum ExprKind { | ||||
|     Block(Block), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Expression(pub ExprKind, pub Metadata); | ||||
| 
 | ||||
| /// Condition, Then, Else
 | ||||
| #[derive(Debug)] | ||||
| pub struct IfExpression(pub Box<Expression>, pub Block, pub Option<Block>); | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct FunctionCall { | ||||
|     pub name: String, | ||||
|     pub return_type: TypeKind, | ||||
|     pub parameters: Vec<Expression>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct FunctionDefinition { | ||||
|     pub name: String, | ||||
|     pub parameters: Vec<(String, TypeKind)>, | ||||
|     pub kind: FunctionDefinitionKind, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum FunctionDefinitionKind { | ||||
|     /// Actual definition block and surrounding signature range
 | ||||
|     Local(Block, Metadata), | ||||
| @ -109,6 +120,7 @@ pub enum FunctionDefinitionKind { | ||||
|     Extern(TypeKind), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Block { | ||||
|     /// List of non-returning statements
 | ||||
|     pub statements: Vec<Statement>, | ||||
| @ -116,16 +128,18 @@ pub struct Block { | ||||
|     pub meta: Metadata, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Statement(pub StmtKind, pub Metadata); | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum StmtKind { | ||||
|     /// Variable name+type, evaluation
 | ||||
|     Let(VariableReference, Expression), | ||||
|     If(IfExpression), | ||||
|     Import(Import), | ||||
|     Expression(Expression), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Module { | ||||
|     pub name: String, | ||||
|     pub imports: Vec<Import>, | ||||
|  | ||||
| @ -26,7 +26,6 @@ impl ReturnType for Statement { | ||||
|         use StmtKind::*; | ||||
|         match &self.0 { | ||||
|             Expression(e) => e.return_type(), | ||||
|             If(e) => e.return_type(), | ||||
|             Import(_) => Err(ReturnTypeOther::Import(self.1.range)), | ||||
|             Let(_, _) => Err(ReturnTypeOther::Let(self.1.range)), | ||||
|         } | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| use crate::{ | ||||
|     ast::parse::Parse, | ||||
|     lexer::{FullToken, Position, Token}, | ||||
|     parser::Parse, | ||||
| }; | ||||
| 
 | ||||
| pub struct TokenStream<'a, 'b> { | ||||
| @ -188,6 +188,16 @@ impl std::ops::Add for TokenRange { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl std::iter::Sum for TokenRange { | ||||
|     fn sum<I: Iterator<Item = Self>>(mut iter: I) -> Self { | ||||
|         let mut start = iter.next().unwrap_or(Default::default()); | ||||
|         for item in iter { | ||||
|             start = start + item; | ||||
|         } | ||||
|         start | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(thiserror::Error, Debug)] | ||||
| pub enum Error { | ||||
|     #[error("Expected {} at Ln {}, Col {}, got {:?}", .0, (.2).1, (.2).0, .1)] | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user