Saved location in tokens post parsing, fixed parsing just skipping stuff
(shoulda thought of that)
This commit is contained in:
		
							parent
							
								
									323d3342a3
								
							
						
					
					
						commit
						d2b0e57ce6
					
				|  | @ -1,55 +1,76 @@ | |||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use crate::tokeniser::tokentype::*; | ||||
| use crate::{common::Loc, tokeniser::tokentype::*}; | ||||
| 
 | ||||
| use super::{typ::Type, Ast}; | ||||
| use super::{typ::{Type, TypeBox}, Ast}; | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct ExprBox { | ||||
|     inner: Expr, | ||||
|     loc: Loc | ||||
| } | ||||
| 
 | ||||
| impl ExprBox { | ||||
|     pub fn new(loc: &Loc, expr: Expr) -> Self { | ||||
|         Self { loc: loc.clone(), inner: expr } | ||||
|     } | ||||
|     pub fn inner(&self) -> &Expr { | ||||
|         &self.inner | ||||
|     } | ||||
|     pub fn inner_mut(&mut self) -> &mut Expr { | ||||
|         &mut self.inner | ||||
|     } | ||||
|     pub fn loc(&self) -> &Loc { | ||||
|         &self.loc | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum Expr { | ||||
|     // Comment(Comment),
 | ||||
|     Group(Box<Expr>), | ||||
|     Group(Box<ExprBox>), | ||||
|     UnOp { | ||||
|         typ: Punctuation, | ||||
|         right: Box<Expr>, | ||||
|         right: Box<ExprBox>, | ||||
|     }, 
 | ||||
|     BinOp { | ||||
|         typ: Punctuation, | ||||
|         left: Box<Expr>, | ||||
|         right: Box<Expr>, | ||||
|         left: Box<ExprBox>, | ||||
|         right: Box<ExprBox>, | ||||
|     }, | ||||
|     Literal(super::literal::Literal), | ||||
|     ArrayIndex { | ||||
|         name: Box<Expr>, | ||||
|         index: Box<Expr>, | ||||
|         name: Box<ExprBox>, | ||||
|         index: Box<ExprBox>, | ||||
|     }, | ||||
|     Path(Path), | ||||
|     Call { | ||||
|         path: Box<Expr>, | ||||
|         params: CallParams, // Expr ~ (, Expr)*
 | ||||
|         path: Box<ExprBox>, | ||||
|         params: CallParams, // ExprBox ~ (, Expr)*
 | ||||
|     }, | ||||
|     //MethodCall {
 | ||||
|     //    var_name: Box<Expr>,
 | ||||
|     //    var_name: Box<ExprBox>,
 | ||||
|     //    method_name: Ident,
 | ||||
|     //    params: CallParams,
 | ||||
|     //},
 | ||||
| 
 | ||||
|     /// the left side only exists on the /.|->/ chain
 | ||||
|     FieldAccess { | ||||
|         left: Box<Option<Expr>>, | ||||
|         right: Box<Expr>, | ||||
|         left: Box<Option<ExprBox>>, | ||||
|         right: Box<ExprBox>, | ||||
|     }, | ||||
|     PtrFieldAccess { | ||||
|         left: Box<Option<Expr>>, | ||||
|         right: Box<Expr>, | ||||
|         left: Box<Option<ExprBox>>, | ||||
|         right: Box<ExprBox>, | ||||
|     }, | ||||
|     ForLoop { | ||||
|         init: Box<Ast>, | ||||
|         test: Box<Expr>, | ||||
|         on_loop: Box<Expr>, | ||||
|         test: Box<ExprBox>, | ||||
|         on_loop: Box<ExprBox>, | ||||
|         body: Block, | ||||
|     }, | ||||
|     WhileLoop { | ||||
|         test: Box<Expr>, | ||||
|         test: Box<ExprBox>, | ||||
|         body: Block, | ||||
|     }, | ||||
|     InfLoop { | ||||
|  | @ -58,20 +79,20 @@ pub enum Expr { | |||
|     If(IfExpr), | ||||
|     Struct { | ||||
|         path: Path, | ||||
|         fields: HashMap<Ident, Expr>, | ||||
|         fields: HashMap<Ident, ExprBox>, | ||||
|     }, | ||||
|     Return(Box<Option<Expr>>), | ||||
|     Return(Box<Option<ExprBox>>), | ||||
|     Break, | ||||
|     Continue, | ||||
|     Cast { | ||||
|         left: Box<Expr>, | ||||
|         right: Box<Type> | ||||
|         left: Box<ExprBox>, | ||||
|         right: Box<TypeBox> | ||||
|     }, | ||||
| } | ||||
| 
 | ||||
| impl Expr { | ||||
| impl ExprBox { | ||||
|     pub fn unwrap_path(&self) -> Path { | ||||
|         let Expr::Path(p) = self else {panic!("Unwrapping")}; | ||||
|         let Expr::Path(p) = self.inner.clone() else {panic!("Unwrapping")}; | ||||
|         p.clone() | ||||
|     } | ||||
| } | ||||
|  | @ -79,7 +100,7 @@ impl Expr { | |||
| 
 | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct CallParams(pub Vec<Expr>); | ||||
| pub struct CallParams(pub Vec<ExprBox>); | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Block(pub Vec<Ast>); | ||||
|  | @ -90,7 +111,7 @@ pub struct Path(pub Vec<Ident>); | |||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct IfExpr { | ||||
|     pub test: Box<Expr>, | ||||
|     pub test: Box<ExprBox>, | ||||
|     pub body: Block, | ||||
|     pub else_if: Option<IfBranchExpr> | ||||
| } | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ use std::collections::HashMap; | |||
| 
 | ||||
| use crate::tokeniser::tokentype::*; | ||||
| 
 | ||||
| use super::{expr::Expr, typ::Type, Ast}; | ||||
| use super::{expr::ExprBox, typ::TypeBox, Ast}; | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum Literal { | ||||
|  | @ -10,10 +10,10 @@ pub enum Literal { | |||
|     Ident(Ident), | ||||
|     String(TString), | ||||
|     Char(Char), | ||||
|     Array(Vec<Expr>), | ||||
|     Array(Vec<ExprBox>), | ||||
|     ArrayRepeat { | ||||
|         typ: Box<Type>, | ||||
|         count: Box<Expr>, | ||||
|         typ: Box<TypeBox>, | ||||
|         count: Box<ExprBox>, | ||||
|     }, | ||||
|     Struct { | ||||
|         name: Ident, | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use typ::Type; | ||||
| use statement::{Enum, Function, Struct, TypeAlias}; | ||||
| 
 | ||||
| pub use crate::tokeniser::tokentype::*; | ||||
| 
 | ||||
|  | @ -12,17 +12,17 @@ pub mod typ; | |||
| #[derive(Debug, Clone)] | ||||
| pub struct Program { | ||||
|     pub ast: expr::Block, | ||||
|     pub structs: HashMap<Ident, HashMap<Ident, usize>>, | ||||
|     pub enums: HashMap<Ident, usize>, | ||||
|     pub types: HashMap<Type, Type>, | ||||
|     pub functions: HashMap<Ident, (Vec<(Ident, Type)>, Type)>, | ||||
|     pub member_functions: HashMap<Ident, HashMap<Ident, (Vec<(Ident, Type)>, Type)>>, | ||||
|     pub structs: HashMap<Ident, Struct>, | ||||
|     pub enums: HashMap<Ident, Enum>, | ||||
|     pub types: HashMap<Ident, TypeAlias>, | ||||
|     pub functions: HashMap<Ident, Function>, | ||||
|     pub member_functions: HashMap<Ident, HashMap<Ident, Function>>, | ||||
| } 
 | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum Ast { | ||||
|     Expr(expr::Expr), | ||||
|     Statement(statement::Statement), | ||||
|     Expr(expr::ExprBox), | ||||
|     Statement(statement::StatementBox), | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,44 +1,77 @@ | |||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use super::{expr::{Block, Expr}, typ::Type, Ident, TString}; | ||||
| use crate::common::Loc; | ||||
| 
 | ||||
| use super::{expr::{Block, ExprBox}, typ::{Type, TypeBox}, Ident, TString}; | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct StatementBox { | ||||
|     inner: Statement, | ||||
|     loc: Loc | ||||
| } | ||||
| 
 | ||||
| impl StatementBox { | ||||
|     pub fn new(loc: &Loc, stat: Statement) -> Self { | ||||
|         Self { loc: loc.clone(), inner: stat } | ||||
|     } | ||||
|     pub fn inner(&self) -> &Statement { | ||||
|         &self.inner | ||||
|     } | ||||
|     pub fn inner_mut(&mut self) -> &mut Statement { | ||||
|         &mut self.inner | ||||
|     } | ||||
|     pub fn loc(&self) -> &Loc { | ||||
|         &self.loc | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum Statement { | ||||
|     Fn { | ||||
|         struct_name: Option<Ident>, | ||||
|         name: Ident, | ||||
|         params: Vec<(Ident, Type)>, | ||||
|         ret_type: Option<Type>, | ||||
|         qual_const: bool, | ||||
|         qual_extern: Option<TString>, // abi
 | ||||
|         body: Option<Block>, // If None then its a type declaration
 | ||||
|     }, | ||||
|     TypeAlias { | ||||
|         name: Ident, | ||||
|         typ: Type, | ||||
|     }, | ||||
|     Struct { | ||||
|         name: Ident, | ||||
|         fields: Vec<(Ident, Type)>, | ||||
|     }, | ||||
|     Enum { | ||||
|         name: Ident, | ||||
|         fields: Vec<Ident>, | ||||
|     }, | ||||
|     Fn(Function), | ||||
|     TypeAlias(TypeAlias), | ||||
|     Struct(Struct), | ||||
|     Enum(Enum), | ||||
|     ConstVar { | ||||
|         name: Ident, | ||||
|         typ: Type, | ||||
|         val: Expr | ||||
|         typ: TypeBox, | ||||
|         val: ExprBox | ||||
|     }, | ||||
|     StaticVar { | ||||
|         name: Ident, | ||||
|         typ: Type, | ||||
|         val: Expr, | ||||
|         typ: TypeBox, | ||||
|         val: ExprBox, | ||||
|     }, | ||||
|     Let { | ||||
|         name: Ident, | ||||
|         typ: Option<Type>, | ||||
|         val: Option<Expr>, | ||||
|         typ: Option<TypeBox>, | ||||
|         val: Option<ExprBox>, | ||||
|     }, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct TypeAlias { | ||||
|     pub name: Ident, | ||||
|     pub typ: TypeBox, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Struct { | ||||
|     pub name: Ident, | ||||
|     pub fields: Vec<(Ident, TypeBox)>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Enum { | ||||
|     pub name: Ident, | ||||
|     pub fields: Vec<Ident>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct Function { | ||||
|     pub struct_name: Option<Ident>, | ||||
|     pub name: Ident, | ||||
|     pub params: Vec<(Ident, TypeBox)>, | ||||
|     pub ret_type: Option<TypeBox>, | ||||
|     pub qual_const: bool, | ||||
|     pub qual_extern: Option<TString>, // abi
 | ||||
|     pub body: Option<Block>, // If None then its a type declaration
 | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,27 @@ | |||
| use super::{expr::Expr, Ident, Number}; | ||||
| use crate::common::Loc; | ||||
| 
 | ||||
| use super::{expr::ExprBox, Ident}; | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub struct TypeBox { | ||||
|     inner: Type, | ||||
|     loc: Loc | ||||
| } | ||||
| 
 | ||||
| impl TypeBox { | ||||
|     pub fn new(loc: &Loc, stat: Type) -> Self { | ||||
|         Self { loc: loc.clone(), inner: stat } | ||||
|     } | ||||
|     pub fn inner(&self) -> &Type { | ||||
|         &self.inner | ||||
|     } | ||||
|     pub fn inner_mut(&mut self) -> &mut Type { | ||||
|         &mut self.inner | ||||
|     } | ||||
|     pub fn loc(&self) -> &Loc { | ||||
|         &self.loc | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum Type { | ||||
|  | @ -11,7 +34,7 @@ pub enum Type { | |||
|     }, | ||||
|     ArrayRepeat { | ||||
|         inner: Box<Type>, | ||||
|         count: Expr, | ||||
|         count: ExprBox, | ||||
|     }, | ||||
|     Owned(Ident), | ||||
| } | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ use anyhow::{bail, Result}; | |||
| 
 | ||||
| use crate::{debug, error, lerror, parser::{typ::parse_type, Punctuation}, tokeniser::Token}; | ||||
| 
 | ||||
| use super::{ast::{expr::{Block, CallParams, Expr, IfBranchExpr, IfExpr, Path}, literal::Literal, TokenType}, parse_item, utils, Delimiter, Keyword}; | ||||
| use super::{ast::{expr::{Block, CallParams, Expr, ExprBox, IfBranchExpr, IfExpr, Path}, literal::Literal, TokenType}, parse_item, utils, Delimiter, Keyword}; | ||||
| 
 | ||||
| const BINOP_LIST: &[TokenType] = &[ | ||||
|     TokenType::Punct(Punctuation::Plus), | ||||
|  | @ -37,7 +37,7 @@ const BINOP_LIST: &[TokenType] = &[ | |||
|     TokenType::Punct(Punctuation::Ge), | ||||
| ]; | ||||
| 
 | ||||
| pub fn parse_expr(tokens: &mut Vec<Token>, precedence: usize, consume_semi: bool) -> Result<Option<Expr>> { | ||||
| pub fn parse_expr(tokens: &mut Vec<Token>, precedence: usize, consume_semi: bool) -> Result<Option<ExprBox>> { | ||||
|     let res = if let Some(_) = utils::check(tokens, TokenType::Delim(Delimiter::ParenL)) { | ||||
|         Some(parse_group(tokens)?) | ||||
|     } else | ||||
|  | @ -73,37 +73,33 @@ pub fn parse_expr(tokens: &mut Vec<Token>, precedence: usize, consume_semi: bool | |||
|         return Ok(Some(parse_inf_loop(tokens)?)); | ||||
|     } else if let Some(_) = utils::check(tokens, TokenType::Keyword(Keyword::Return)) { | ||||
|         return Ok(Some(parse_return(tokens)?)); | ||||
|     } else if let Some(_) = utils::check_consume(tokens, TokenType::Keyword(Keyword::Break)) { | ||||
|         return Ok(Some(Expr::Break)); | ||||
|     } else if let Some(_) = utils::check_consume(tokens, TokenType::Keyword(Keyword::Continue)) { | ||||
|         return Ok(Some(Expr::Continue)); | ||||
|     } else if let Some(_) = utils::check(tokens, TokenType::Keyword(Keyword::If)) { | ||||
|         return Ok(Some(Expr::If(parse_if(tokens)?))); | ||||
|     } else if let Some(kw) = utils::check_consume(tokens, TokenType::Keyword(Keyword::Break)) { | ||||
|         return Ok(Some(ExprBox::new(kw.loc(), Expr::Break))); | ||||
|     } else if let Some(kw) = utils::check_consume(tokens, TokenType::Keyword(Keyword::Continue)) { | ||||
|         return Ok(Some(ExprBox::new(kw.loc(), Expr::Continue))); | ||||
|     } else if let Some(kw) = utils::check(tokens, TokenType::Keyword(Keyword::If)) { | ||||
|         return Ok(Some(ExprBox::new(&kw.loc().clone(), Expr::If(parse_if(tokens)?)))); | ||||
|     } else { | ||||
|         None | ||||
|     }; | ||||
| 
 | ||||
|     
 | ||||
|     if let Some(res) = res { | ||||
|         // check for binop
 | ||||
|         let res = match res { | ||||
|             _ if utils::check(tokens, TokenType::Punct(Punctuation::Fieldaccess)).is_some() => { | ||||
|                 parse_field_access(tokens, res)? | ||||
|             } | ||||
|             _ if utils::check(tokens, TokenType::Punct(Punctuation::Arrow)).is_some() => { | ||||
|                 parse_ptr_field_access(tokens, res)? | ||||
|             } | ||||
|             _ if utils::check(tokens, TokenType::Delim(Delimiter::ParenL)).is_some() => { | ||||
|                 parse_fn_call(tokens, res)? | ||||
|             } | ||||
|             _ if utils::check(tokens, TokenType::Keyword(Keyword::As)).is_some() => { | ||||
|                 parse_cast(tokens, res)? | ||||
|             } | ||||
|             _ if utils::check(tokens, TokenType::Delim(Delimiter::SquareL)).is_some() => { | ||||
|                 parse_array_index(tokens, res)? | ||||
|             } | ||||
|             _ => res | ||||
|         }; | ||||
|     if let Some(mut res) = res { | ||||
|         if utils::check(tokens, TokenType::Punct(Punctuation::Fieldaccess)).is_some() { | ||||
|             res = parse_field_access(tokens, res)?; | ||||
|         } | ||||
|         if utils::check(tokens, TokenType::Punct(Punctuation::Arrow)).is_some() { | ||||
|             res =parse_ptr_field_access(tokens, res)?; | ||||
|         } | ||||
|         if utils::check(tokens, TokenType::Delim(Delimiter::ParenL)).is_some() { | ||||
|             res = parse_fn_call(tokens, res)?; | ||||
|         } | ||||
|         if utils::check(tokens, TokenType::Keyword(Keyword::As)).is_some() { | ||||
|             res = parse_cast(tokens, res)?; | ||||
|         } | ||||
|         if utils::check(tokens, TokenType::Delim(Delimiter::SquareL)).is_some() { | ||||
|             res = parse_array_index(tokens, res)?; | ||||
|         } | ||||
| 
 | ||||
|         if let Some(_) = utils::check_from_many(tokens, BINOP_LIST) { | ||||
|             return Ok(Some(parse_binop(tokens, res, precedence)?)); | ||||
|  | @ -117,19 +113,19 @@ pub fn parse_expr(tokens: &mut Vec<Token>, precedence: usize, consume_semi: bool | |||
|     Ok(res) | ||||
| } | ||||
| 
 | ||||
| fn parse_return(tokens: &mut Vec<Token>) -> Result<Expr> { | ||||
|    _ = utils::check_consume(tokens, TokenType::Keyword(Keyword::Return)); | ||||
| fn parse_return(tokens: &mut Vec<Token>) -> Result<ExprBox> { | ||||
|    let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Return), "")?; | ||||
|    let item = parse_expr(tokens, 0, true)?; | ||||
|    Ok(Expr::Return(Box::new(item))) | ||||
|    Ok(ExprBox::new(kw.loc(), Expr::Return(Box::new(item)))) | ||||
| } | ||||
| 
 | ||||
| fn parse_cast(tokens: &mut Vec<Token>, left: Expr) -> Result<Expr> { | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::As), "")?; | ||||
| fn parse_cast(tokens: &mut Vec<Token>, left: ExprBox) -> Result<ExprBox> { | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::As), "")?; | ||||
|     let typ = parse_type(tokens)?; | ||||
|     Ok(Expr::Cast { 
 | ||||
|     Ok(ExprBox::new(kw.loc(), Expr::Cast { 
 | ||||
|         left: Box::new(left), 
 | ||||
|         right: Box::new(typ) | ||||
|     }) | ||||
|     })) | ||||
| } | ||||
| fn parse_if(tokens: &mut Vec<Token>) -> Result<IfExpr> { | ||||
|     let loc = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::If), "")?; | ||||
|  | @ -172,50 +168,50 @@ fn parse_if(tokens: &mut Vec<Token>) -> Result<IfExpr> { | |||
|         }) | ||||
|     } | ||||
| } | ||||
| fn parse_while_loop(tokens: &mut Vec<Token>) -> Result<Expr> { 
 | ||||
|     let loc = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::While), "")?; | ||||
| fn parse_while_loop(tokens: &mut Vec<Token>) -> Result<ExprBox> { 
 | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::While), "")?; | ||||
|     let Some(test) = parse_expr(tokens, 0, false)? else { | ||||
|         lerror!(loc.loc(), "Expected test comparrison for while loop, got nothing"); | ||||
|         lerror!(kw.loc(), "Expected test comparrison for while loop, got nothing"); | ||||
|         bail!("") | ||||
|     }; | ||||
|     let block = parse_block(tokens)?; | ||||
|     Ok(Expr::WhileLoop { 
 | ||||
|     Ok(ExprBox::new(kw.loc(), Expr::WhileLoop { 
 | ||||
|         test: Box::new(test), 
 | ||||
|         body: block 
 | ||||
|     }) | ||||
|     })) | ||||
| } | ||||
| fn parse_for_loop(tokens: &mut Vec<Token>) -> Result<Expr> { | ||||
|     let loc = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::For), "")?; | ||||
| fn parse_for_loop(tokens: &mut Vec<Token>) -> Result<ExprBox> { | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::For), "")?; | ||||
|     let Some(pre) = parse_item(tokens)? else { | ||||
|         lerror!(loc.loc(), "Expected init stat for a for loop, got nothing"); | ||||
|         lerror!(kw.loc(), "Expected init stat for a for loop, got nothing"); | ||||
|         bail!("") | ||||
|     }; | ||||
|     // Semicolon parsed out by parse_item above
 | ||||
|     let Some(test) = parse_expr(tokens, 0, false)? else { | ||||
|         lerror!(loc.loc(), "Expected test comparrison for a for loop, got nothing"); | ||||
|         lerror!(kw.loc(), "Expected test comparrison for a for loop, got nothing"); | ||||
|         bail!("") | ||||
|     }; | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Semi), ""); | ||||
|     let Some(post) = parse_expr(tokens, 0, false)? else { | ||||
|         lerror!(loc.loc(), "Expected post expression (usually an index increment) for a for loop, got nothing"); | ||||
|         lerror!(kw.loc(), "Expected post expression (usually an index increment) for a for loop, got nothing"); | ||||
|         bail!("") | ||||
|     }; | ||||
|     let block = parse_block(tokens)?; | ||||
| 
 | ||||
|     Ok(Expr::ForLoop { 
 | ||||
|     Ok(ExprBox::new(kw.loc(), Expr::ForLoop { 
 | ||||
|         init: Box::new(pre), 
 | ||||
|         test: Box::new(test), 
 | ||||
|         on_loop: Box::new(post), 
 | ||||
|         body: block | ||||
|     }) | ||||
|     })) | ||||
| } | ||||
| fn parse_inf_loop(tokens: &mut Vec<Token>) -> Result<Expr> { | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Loop), ""); | ||||
| fn parse_inf_loop(tokens: &mut Vec<Token>) -> Result<ExprBox> { | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Loop), "")?; | ||||
|     let block = parse_block(tokens)?; | ||||
|     Ok(Expr::InfLoop { body: block }) | ||||
|     Ok(ExprBox::new(kw.loc(), Expr::InfLoop { body: block })) | ||||
| } | ||||
| fn parse_fn_call(tokens: &mut Vec<Token>, left: Expr) -> Result<Expr> { | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::ParenL), ""); | ||||
| fn parse_fn_call(tokens: &mut Vec<Token>, left: ExprBox) -> Result<ExprBox> { | ||||
|     let start = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::ParenL), "")?; | ||||
|     let mut params = Vec::new(); | ||||
|     
 | ||||
|     while !tokens.is_empty() { | ||||
|  | @ -232,23 +228,23 @@ fn parse_fn_call(tokens: &mut Vec<Token>, left: Expr) -> Result<Expr> { | |||
|         } 
 | ||||
|     } | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::ParenR), ""); | ||||
|     Ok(Expr::Call { path: Box::new(left), params: CallParams(params) }) | ||||
|     Ok(ExprBox::new(start.loc(), Expr::Call { path: Box::new(left), params: CallParams(params) })) | ||||
| } | ||||
| fn parse_array_index(tokens: &mut Vec<Token>, left: Expr) -> Result<Expr> { | ||||
|     let loc = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::SquareL), "")?; | ||||
| fn parse_array_index(tokens: &mut Vec<Token>, left: ExprBox) -> Result<ExprBox> { | ||||
|     let start = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::SquareL), "")?; | ||||
|     let Some(idx) = parse_expr(tokens, 0, false)? else { | ||||
|         lerror!(loc.loc(), "Expected index for in array index but found nothing."); | ||||
|         lerror!(start.loc(), "Expected index for in array index but found nothing."); | ||||
|         bail!("") | ||||
|     }; | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::SquareR), ""); | ||||
|     Ok(Expr::ArrayIndex { 
 | ||||
|     Ok(ExprBox::new(start.loc(), Expr::ArrayIndex { 
 | ||||
|         name: Box::new(left), 
 | ||||
|         index: Box::new(idx) | ||||
|     }) | ||||
|     })) | ||||
| } | ||||
| 
 | ||||
| fn parse_field_access(tokens: &mut Vec<Token>, left: Expr) -> Result<Expr> { | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Fieldaccess), "unreachable")?; | ||||
| fn parse_field_access(tokens: &mut Vec<Token>, left: ExprBox) -> Result<ExprBox> { | ||||
|     let start = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Fieldaccess), "unreachable")?; | ||||
| 
 | ||||
|     let right = if let Some(_) = utils::check_2_last(tokens, TokenType::Punct(Punctuation::Arrow)) { | ||||
|         let right = parse_path(tokens)?; | ||||
|  | @ -259,14 +255,14 @@ fn parse_field_access(tokens: &mut Vec<Token>, left: Expr) -> Result<Expr> { | |||
|     } else { | ||||
|         parse_path(tokens)? | ||||
|     }; | ||||
|     Ok(Expr::FieldAccess { 
 | ||||
|     Ok(ExprBox::new(start.loc(), Expr::FieldAccess { 
 | ||||
|         left: Box::new(Some(left)), | ||||
|         right: Box::new(right) | ||||
|     }) | ||||
|     })) | ||||
| } | ||||
| 
 | ||||
| fn parse_ptr_field_access(tokens: &mut Vec<Token>, left: Expr) -> Result<Expr> { | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Arrow), "unreachable")?; | ||||
| fn parse_ptr_field_access(tokens: &mut Vec<Token>, left: ExprBox) -> Result<ExprBox> { | ||||
|     let start = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Arrow), "unreachable")?; | ||||
|     let right = if let Some(_) = utils::check_2_last(tokens, TokenType::Punct(Punctuation::Arrow)) { | ||||
|         let right = parse_path(tokens)?; | ||||
|         parse_ptr_field_access(tokens, right)? | ||||
|  | @ -276,28 +272,28 @@ fn parse_ptr_field_access(tokens: &mut Vec<Token>, left: Expr) -> Result<Expr> { | |||
|     } else { | ||||
|         parse_path(tokens)? | ||||
|     }; | ||||
|     Ok(Expr::PtrFieldAccess { 
 | ||||
|     Ok(ExprBox::new(start.loc(), Expr::PtrFieldAccess { 
 | ||||
|         left: Box::new(Some(left)), | ||||
|         right: Box::new(right) | ||||
|     }) | ||||
|     })) | ||||
| } | ||||
| 
 | ||||
| fn parse_literal(tokens: &mut Vec<Token>) -> Result<Expr> { 
 | ||||
| fn parse_literal(tokens: &mut Vec<Token>) -> Result<ExprBox> { 
 | ||||
|     if let Some(tkn) = utils::check_consume(tokens, TokenType::string("", false))  { | ||||
|         let TokenType::String(str) = tkn.tt()  else {unreachable!()}; | ||||
|         return Ok(Expr::Literal(Literal::String(str.clone()))); | ||||
|         return Ok(ExprBox::new(tkn.loc(), Expr::Literal(Literal::String(str.clone())))); | ||||
|     } else | ||||
|     if let Some(tkn) = utils::check_consume(tokens, TokenType::number(0, 0, false))  { | ||||
|         let TokenType::Number(val) = tkn.tt()  else {unreachable!()}; | ||||
|         return Ok(Expr::Literal(Literal::Number(val.clone()))); | ||||
|         return Ok(ExprBox::new(tkn.loc(), Expr::Literal(Literal::Number(val.clone())))); | ||||
|     } else | ||||
|     if let Some(tkn) = utils::check_consume(tokens, TokenType::char('\0'))  { | ||||
|         let TokenType::Char(val) = tkn.tt()  else {unreachable!()}; | ||||
|         return Ok(Expr::Literal(Literal::Char(val.clone()))); | ||||
|         return Ok(ExprBox::new(tkn.loc(), Expr::Literal(Literal::Char(val.clone())))); | ||||
|     } else | ||||
|     if let Some(start) = utils::check_consume(tokens, TokenType::Delim(Delimiter::SquareL))  { | ||||
|         if let Some(_) = utils::check_consume(tokens, TokenType::Delim(Delimiter::SquareR)) { | ||||
|             return Ok(Expr::Literal(Literal::Array(Vec::new()))); | ||||
|             return Ok(ExprBox::new(start.loc(), Expr::Literal(Literal::Array(Vec::new())))); | ||||
|         } | ||||
|         if *tokens[tokens.len()-2].tt() == TokenType::Punct(Punctuation::Comma) { | ||||
|             let first = parse_expr(tokens, 0, false)?; | ||||
|  | @ -314,15 +310,15 @@ fn parse_literal(tokens: &mut Vec<Token>) -> Result<Expr> { | |||
|                 } | ||||
|             } | ||||
|             utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::SquareR), "")?; | ||||
|             return Ok(Expr::Literal(Literal::Array(values))); | ||||
|             return Ok(ExprBox::new(start.loc(), Expr::Literal(Literal::Array(values)))); | ||||
|         } else if *tokens[tokens.len()-2].tt() == TokenType::Punct(Punctuation::Semi) { | ||||
|             let typ = parse_type(tokens)?; | ||||
|             let count = parse_expr(tokens, 0, false)?.unwrap(); | ||||
|             utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::SquareR), "")?; | ||||
|             return Ok(Expr::Literal(Literal::ArrayRepeat { 
 | ||||
|             return Ok(ExprBox::new(start.loc(), Expr::Literal(Literal::ArrayRepeat { 
 | ||||
|                 typ: Box::new(typ), 
 | ||||
|                 count: Box::new(count) 
 | ||||
|             })); | ||||
|             }))); | ||||
|         } else { | ||||
|             if let Some(curr) = tokens.last() { | ||||
|                 lerror!(start.loc(), "Expected a , or ; as a separator in a literal array (normal, or repeating, respectively), but found {}", curr.tt()); | ||||
|  | @ -335,8 +331,8 @@ fn parse_literal(tokens: &mut Vec<Token>) -> Result<Expr> { | |||
|     unreachable!() | ||||
| } | ||||
| 
 | ||||
| fn parse_struct_literal(tokens: &mut Vec<Token>, name: Path) -> Result<Expr> { | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::CurlyL), "")?; | ||||
| fn parse_struct_literal(tokens: &mut Vec<Token>, name: Path) -> Result<ExprBox> { | ||||
|     let start = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::CurlyL), "")?; | ||||
|     let mut fields = HashMap::new(); | ||||
|     while !tokens.is_empty() { | ||||
|         if let Some(_) = utils::check_consume(tokens, TokenType::Delim(Delimiter::CurlyR)) { | ||||
|  | @ -352,21 +348,21 @@ fn parse_struct_literal(tokens: &mut Vec<Token>, name: Path) -> Result<Expr> { | |||
|             break; | ||||
|         } | ||||
|     } | ||||
|     Ok(Expr::Struct { path: name, fields }) | ||||
|     Ok(ExprBox::new(start.loc(), Expr::Struct { path: name, fields })) | ||||
| } | ||||
| 
 | ||||
| fn parse_group(tokens: &mut Vec<Token>) -> Result<Expr> { | ||||
|     let loc = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::ParenL), "")?; | ||||
| fn parse_group(tokens: &mut Vec<Token>) -> Result<ExprBox> { | ||||
|     let start = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::ParenL), "")?; | ||||
|     let Some(expr) = parse_expr(tokens, 0, false)? else { | ||||
|         lerror!(loc.loc(), "Expected expr found nothing"); | ||||
|         lerror!(start.loc(), "Expected expr found nothing"); | ||||
|         bail!("") | ||||
|     }; | ||||
| 
 | ||||
|     utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::ParenR), "")?; | ||||
|     Ok(Expr::Group(Box::new(expr))) | ||||
|     Ok(ExprBox::new(start.loc(), Expr::Group(Box::new(expr)))) | ||||
| } | ||||
| 
 | ||||
| fn parse_path(tokens: &mut Vec<Token>) -> Result<Expr> { | ||||
| fn parse_path(tokens: &mut Vec<Token>) -> Result<ExprBox> { | ||||
|     let mut buf = Vec::new(); | ||||
|     let part = utils::check_consume(tokens, TokenType::ident("")).unwrap(); | ||||
| 
 | ||||
|  | @ -379,10 +375,10 @@ fn parse_path(tokens: &mut Vec<Token>) -> Result<Expr> { | |||
|         buf.push(part.tt().unwrap_ident()); | ||||
|     } | ||||
|     
 | ||||
|     Ok(Expr::Path(Path(buf))) | ||||
|     Ok(ExprBox::new(part.loc(), Expr::Path(Path(buf)))) | ||||
| } | ||||
| 
 | ||||
| fn parse_unop(tokens: &mut Vec<Token>) -> Result<Expr> { | ||||
| fn parse_unop(tokens: &mut Vec<Token>) -> Result<ExprBox> { | ||||
|     let typ = utils::check_consume_or_err_from_many(tokens, &[ | ||||
|         TokenType::Punct(Punctuation::Not), | ||||
|         TokenType::Punct(Punctuation::Plus), | ||||
|  | @ -397,18 +393,20 @@ fn parse_unop(tokens: &mut Vec<Token>) -> Result<Expr> { | |||
|         lerror!(&loc, "Expected expression after unary token, found nothing"); | ||||
|         bail!("") | ||||
|     }; | ||||
|     Ok(Expr::UnOp { 
 | ||||
|     Ok(ExprBox::new(&loc, Expr::UnOp { 
 | ||||
|         typ, 
 | ||||
|         right: Box::new(right) | ||||
|     }) | ||||
|     })) | ||||
| } | ||||
| 
 | ||||
| fn parse_binop(tokens: &mut Vec<Token>, mut lhs: Expr, precedence: usize) -> Result<Expr> { 
 | ||||
| fn parse_binop(tokens: &mut Vec<Token>, mut lhs: ExprBox, precedence: usize) -> Result<ExprBox> { 
 | ||||
|     // TODO: https://en.wikipedia.org/wiki/Operator-precedence_parser#Pseudocode
 | ||||
|      
 | ||||
|     loop { 
 | ||||
|     loop { | ||||
|         let op_loc; | ||||
|         let op = match tokens.last() { | ||||
|             Some(op) if BINOP_LIST.contains(&op.tt()) => { | ||||
|                 op_loc = op.loc().clone(); | ||||
|                 let TokenType::Punct(op) = op.tt() else {unreachable!()}; | ||||
|                 op.clone() | ||||
|             } | ||||
|  | @ -433,11 +431,11 @@ fn parse_binop(tokens: &mut Vec<Token>, mut lhs: Expr, precedence: usize) -> Res | |||
| 
 | ||||
|         _ = tokens.pop(); | ||||
|         let Some(rhs) = parse_expr(tokens, rp, false)? else {break;}; 
 | ||||
|         lhs = Expr::BinOp { 
 | ||||
|         lhs = ExprBox::new(&op_loc, Expr::BinOp { 
 | ||||
|             typ: op, 
 | ||||
|             left: Box::new(lhs), 
 | ||||
|             right: Box::new(rhs) | ||||
|         }; 
 | ||||
|         }); 
 | ||||
|     } | ||||
|     
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,15 +5,15 @@ use crate::parser::ast::TokenType; | |||
| use crate::parser::expr::parse_expr; | ||||
| use crate::parser::{Delimiter, Ident, Keyword, Punctuation}; | ||||
| use crate::tokeniser::Token; | ||||
| use super::ast::typ::Type; | ||||
| use super::ast::typ::{Type, TypeBox}; | ||||
| use super::expr::parse_block; | ||||
| use super::typ::parse_type; | ||||
| use super::utils; | ||||
| use super::ast::statement::Statement; | ||||
| use super::ast::statement::{Enum, Function, Statement, StatementBox, Struct, TypeAlias}; | ||||
| 
 | ||||
| type Result<T> = anyhow::Result<T>; | ||||
| 
 | ||||
| pub fn parse_statement(tokens: &mut Vec<Token>) -> Result<Option<Statement>> { | ||||
| pub fn parse_statement(tokens: &mut Vec<Token>) -> Result<Option<StatementBox>> { | ||||
|     if let Some(_) = utils::check(tokens, TokenType::Keyword(Keyword::Fn)) { | ||||
|         Ok(Some(parse_fn(tokens)?)) | ||||
|     } else | ||||
|  | @ -39,8 +39,8 @@ pub fn parse_statement(tokens: &mut Vec<Token>) -> Result<Option<Statement>> { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| fn parse_enum(tokens: &mut Vec<Token>) -> Result<Statement> { | ||||
|     _ = utils::check_consume(tokens, TokenType::Keyword(Keyword::Enum)); | ||||
| fn parse_enum(tokens: &mut Vec<Token>) -> Result<StatementBox> { | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Enum), "")?; | ||||
|     let name = utils::check_consume_or_err(tokens, TokenType::ident(""), "")?.tt().unwrap_ident(); | ||||
|     _ = utils::check_consume(tokens, TokenType::Delim(Delimiter::CurlyL)); | ||||
|     let mut fields = Vec::new(); | ||||
|  | @ -60,11 +60,11 @@ fn parse_enum(tokens: &mut Vec<Token>) -> Result<Statement> { | |||
|         fields.push(field_name); | ||||
|     } | ||||
| 
 | ||||
|     Ok(Statement::Enum { name, fields }) | ||||
|     Ok(StatementBox::new(kw.loc(), Statement::Enum(Enum { name, fields }))) | ||||
| } | ||||
| 
 | ||||
| fn parse_struct(tokens: &mut Vec<Token>) -> Result<Statement> { | ||||
|     _ = utils::check_consume(tokens, TokenType::Keyword(Keyword::Struct)); | ||||
| fn parse_struct(tokens: &mut Vec<Token>) -> Result<StatementBox> { | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Struct), "")?; | ||||
|     let name = utils::check_consume_or_err(tokens, TokenType::ident(""), "")?.tt().unwrap_ident(); | ||||
|     _ = utils::check_consume(tokens, TokenType::Delim(Delimiter::CurlyL)); | ||||
|     let mut fields = Vec::new(); | ||||
|  | @ -86,11 +86,11 @@ fn parse_struct(tokens: &mut Vec<Token>) -> Result<Statement> { | |||
|         fields.push((field_name, typ)); | ||||
|     } | ||||
| 
 | ||||
|     Ok(Statement::Struct { name, fields }) | ||||
|     Ok(StatementBox::new(kw.loc(), Statement::Struct(Struct { name, fields }))) | ||||
| } | ||||
| 
 | ||||
| fn parse_static(tokens: &mut Vec<Token>) -> Result<Statement> { | ||||
|     _ = utils::check_consume(tokens, TokenType::Keyword(Keyword::Static)); | ||||
| fn parse_static(tokens: &mut Vec<Token>) -> Result<StatementBox> { | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Static), "")?; | ||||
| 
 | ||||
|     let name = utils::check_consume_or_err(tokens, TokenType::ident(""), "")?.tt().unwrap_ident(); | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Colon), "")?; | ||||
|  | @ -101,11 +101,11 @@ fn parse_static(tokens: &mut Vec<Token>) -> Result<Statement> { | |||
|         bail!("") | ||||
|     }; | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Semi), "")?; | ||||
|     Ok(Statement::StaticVar { name, typ, val }) | ||||
|     Ok(StatementBox::new(kw.loc(), Statement::StaticVar { name, typ, val })) | ||||
| } | ||||
| 
 | ||||
| fn parse_let(tokens: &mut Vec<Token>) -> Result<Statement> { | ||||
|     _ = utils::check_consume(tokens, TokenType::Keyword(Keyword::Let)); | ||||
| fn parse_let(tokens: &mut Vec<Token>) -> Result<StatementBox> { | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Let), "")?; | ||||
|     let name = utils::check_consume_or_err(tokens, TokenType::ident(""), "")?.tt().unwrap_ident(); | ||||
|     let mut typ = None; | ||||
|     let mut val = None; | ||||
|  | @ -120,10 +120,10 @@ fn parse_let(tokens: &mut Vec<Token>) -> Result<Statement> { | |||
|         val = Some(_val); | ||||
|     } | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Semi), "")?; | ||||
|     Ok(Statement::Let { name, typ, val }) | ||||
|     Ok(StatementBox::new(kw.loc(), Statement::Let { name, typ, val })) | ||||
| } | ||||
| fn parse_constant(tokens: &mut Vec<Token>) -> Result<Statement> { | ||||
|     _ = utils::check_consume(tokens, TokenType::Keyword(Keyword::Const)); | ||||
| fn parse_constant(tokens: &mut Vec<Token>) -> Result<StatementBox> { | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Const), "")?; | ||||
| 
 | ||||
|     if let Some(_) = utils::check(tokens, TokenType::Keyword(Keyword::Fn)) { | ||||
|         unimplemented!() | ||||
|  | @ -137,22 +137,22 @@ fn parse_constant(tokens: &mut Vec<Token>) -> Result<Statement> { | |||
|         bail!("") | ||||
|     }; | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Semi), "")?; | ||||
|     Ok(Statement::ConstVar { name, typ, val }) | ||||
|     Ok(StatementBox::new(kw.loc(), Statement::ConstVar { name, typ, val })) | ||||
| } | ||||
| 
 | ||||
| fn parse_type_alias(tokens: &mut Vec<Token>) -> Result<Statement> { | ||||
|     _ = utils::check_consume(tokens, TokenType::Keyword(Keyword::Type)); | ||||
| fn parse_type_alias(tokens: &mut Vec<Token>) -> Result<StatementBox> { | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Type), "")?; | ||||
|     let name = utils::check_consume_or_err(tokens, TokenType::ident(""), "")?.tt().unwrap_ident(); | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Eq), "")?; | ||||
|     let typ = parse_type(tokens)?; | ||||
|     _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Semi), "")?; | ||||
| 
 | ||||
|     Ok(Statement::TypeAlias { name, typ }) | ||||
|     Ok(StatementBox::new(kw.loc(), Statement::TypeAlias(TypeAlias { name, typ }))) | ||||
| } | ||||
| 
 | ||||
| fn parse_fn(tokens: &mut Vec<Token>) -> Result<Statement> { | ||||
| fn parse_fn(tokens: &mut Vec<Token>) -> Result<StatementBox> { | ||||
|     // Just remove the kw since we checked it before
 | ||||
|     _ = utils::check_consume(tokens, TokenType::Keyword(Keyword::Fn)); | ||||
|     let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Fn), "")?; | ||||
| 
 | ||||
|     let mut struct_name = None; | ||||
|     let mut name = utils::check_consume_or_err(tokens, TokenType::ident(""), "")?.tt().unwrap_ident(); | ||||
|  | @ -176,7 +176,8 @@ fn parse_fn(tokens: &mut Vec<Token>) -> Result<Statement> { | |||
|         _ = utils::check_consume_or_err(tokens, TokenType::Punct(Punctuation::Semi), "")?; | ||||
|         body = None; | ||||
|     } | ||||
|     Ok(Statement::Fn { | ||||
| 
 | ||||
|     Ok(StatementBox::new(kw.loc(), Statement::Fn(Function{ | ||||
|         struct_name, 
 | ||||
|         name, 
 | ||||
|         params, 
 | ||||
|  | @ -184,12 +185,12 @@ fn parse_fn(tokens: &mut Vec<Token>) -> Result<Statement> { | |||
|         qual_const: false, 
 | ||||
|         qual_extern: None, 
 | ||||
|         body, | ||||
|     }) | ||||
|     }))) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| fn parse_fn_params(tokens: &mut Vec<Token>) -> Result<Vec<(Ident, Type)>> { | ||||
| fn parse_fn_params(tokens: &mut Vec<Token>) -> Result<Vec<(Ident, TypeBox)>> { | ||||
|     let mut args = Vec::new(); | ||||
|     utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::ParenL), "")?; | ||||
|     while !tokens.is_empty() { | ||||
|  |  | |||
|  | @ -2,11 +2,15 @@ use anyhow::Result; | |||
| 
 | ||||
| use crate::{parser::Delimiter, tokeniser::Token}; | ||||
| 
 | ||||
| use super::{ast::{typ::Type, TokenType}, expr::parse_expr, utils, Keyword, Punctuation}; | ||||
| use super::{ast::{typ::{Type, TypeBox}, TokenType}, expr::parse_expr, utils, Keyword, Punctuation}; | ||||
| 
 | ||||
| pub fn parse_type(tokens: &mut Vec<Token>) -> Result<Type> { | ||||
| pub fn parse_type(tokens: &mut Vec<Token>) -> Result<TypeBox> { | ||||
|     let mut ref_cnt = Vec::new(); | ||||
|     let mut loc = None; | ||||
|     while let Some(tok) = utils::check_consume(tokens, TokenType::Punct(Punctuation::Ampersand)) { | ||||
|         if let None = loc { | ||||
|             loc = Some(tok.loc().clone()); | ||||
|         } | ||||
|         if let Some(tok) = utils::check_consume(tokens, TokenType::Keyword(Keyword::Mut)) { | ||||
|             ref_cnt.push(tok.clone()); | ||||
|         } else { | ||||
|  | @ -15,23 +19,29 @@ pub fn parse_type(tokens: &mut Vec<Token>) -> Result<Type> { | |||
|     } | ||||
|     
 | ||||
|     let mut typ; | ||||
|     if let Some(_) = utils::check_consume(tokens, TokenType::Delim(super::Delimiter::SquareL)) { | ||||
|     if let Some(start) = utils::check_consume(tokens, TokenType::Delim(super::Delimiter::SquareL)) { | ||||
|         if let None = loc { | ||||
|             loc = Some(start.loc().clone()); | ||||
|         } | ||||
|         let itm_typ = parse_type(tokens)?; | ||||
|         if let Some(_) = utils::check_consume(tokens, TokenType::Punct(Punctuation::Semi)) { | ||||
|            let count = parse_expr(tokens, 0, false)?.unwrap(); | ||||
|            typ = Type::ArrayRepeat { 
 | ||||
|                inner: Box::new(itm_typ), 
 | ||||
|                inner: Box::new(itm_typ.inner().clone()), 
 | ||||
|                count 
 | ||||
|            } | ||||
|         } else { | ||||
|             typ = Type::Array { 
 | ||||
|                inner: Box::new(itm_typ), 
 | ||||
|                inner: Box::new(itm_typ.inner().clone()), 
 | ||||
|            } | ||||
|         } | ||||
|         _ = utils::check_consume_or_err(tokens, TokenType::Delim(Delimiter::SquareR), "")?; | ||||
|     } else { | ||||
|         let ident = utils::check_consume_or_err(tokens, TokenType::ident(""), "a")?; | ||||
|         typ = Type::Owned(ident.tt().unwrap_ident()); | ||||
|         if let None = loc { | ||||
|             loc = Some(ident.loc().clone()); | ||||
|         } | ||||
|     } | ||||
|     while let Some(reft) = ref_cnt.pop() { | ||||
|         match reft.tt() { | ||||
|  | @ -50,5 +60,5 @@ pub fn parse_type(tokens: &mut Vec<Token>) -> Result<Type> { | |||
|             _ => unreachable!() | ||||
|         } | ||||
|     } | ||||
|     Ok(typ) | ||||
|     Ok(TypeBox::new(&loc.unwrap(), typ)) | ||||
| } | ||||
|  |  | |||
|  | @ -2,29 +2,47 @@ Program { | |||
|     ast: Block( | ||||
|         [ | ||||
|             Statement( | ||||
|                 Enum { | ||||
|                     name: Ident( | ||||
|                         "Foo", | ||||
|                 StatementBox { | ||||
|                     inner: Enum( | ||||
|                         Enum { | ||||
|                             name: Ident( | ||||
|                                 "Foo", | ||||
|                             ), | ||||
|                             fields: [], | ||||
|                         }, | ||||
|                     ), | ||||
|                     fields: [], | ||||
|                     loc: Loc { | ||||
|                         file: "parser/enumerations.mcl", | ||||
|                         line: 1, | ||||
|                         col: 5, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Statement( | ||||
|                 Enum { | ||||
|                     name: Ident( | ||||
|                         "Bar", | ||||
|                 StatementBox { | ||||
|                     inner: Enum( | ||||
|                         Enum { | ||||
|                             name: Ident( | ||||
|                                 "Bar", | ||||
|                             ), | ||||
|                             fields: [ | ||||
|                                 Ident( | ||||
|                                     "A", | ||||
|                                 ), | ||||
|                                 Ident( | ||||
|                                     "B", | ||||
|                                 ), | ||||
|                                 Ident( | ||||
|                                     "C", | ||||
|                                 ), | ||||
|                             ], | ||||
|                         }, | ||||
|                     ), | ||||
|                     fields: [ | ||||
|                         Ident( | ||||
|                             "A", | ||||
|                         ), | ||||
|                         Ident( | ||||
|                             "B", | ||||
|                         ), | ||||
|                         Ident( | ||||
|                             "C", | ||||
|                         ), | ||||
|                     ], | ||||
|                     loc: Loc { | ||||
|                         file: "parser/enumerations.mcl", | ||||
|                         line: 3, | ||||
|                         col: 5, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|         ], | ||||
|  |  | |||
|  | @ -1,53 +1,900 @@ | |||
| Program { | ||||
|     ast: Block( | ||||
|         [ | ||||
|             Expr( | ||||
|                 BinOp { | ||||
|                     typ: Eq, | ||||
|                     left: UnOp { | ||||
|                         typ: Star, | ||||
|                         right: Path( | ||||
|                             Path( | ||||
|                                 [ | ||||
|                                     Ident( | ||||
|                                         "a", | ||||
|                                     ), | ||||
|                                 ], | ||||
|                             ), | ||||
|             Statement( | ||||
|                 StatementBox { | ||||
|                     inner: Let { | ||||
|                         name: Ident( | ||||
|                             "a", | ||||
|                         ), | ||||
|                         typ: None, | ||||
|                         val: Some( | ||||
|                             ExprBox { | ||||
|                                 inner: BinOp { | ||||
|                                     typ: EqEq, | ||||
|                                     left: ExprBox { | ||||
|                                         inner: BinOp { | ||||
|                                             typ: Star, | ||||
|                                             left: ExprBox { | ||||
|                                                 inner: Literal( | ||||
|                                                     Number( | ||||
|                                                         Number { | ||||
|                                                             val: 1, | ||||
|                                                             base: 10, | ||||
|                                                             signed: false, | ||||
|                                                         }, | ||||
|                                                     ), | ||||
|                                                 ), | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 1, | ||||
|                                                     col: 10, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                             right: ExprBox { | ||||
|                                                 inner: Literal( | ||||
|                                                     Number( | ||||
|                                                         Number { | ||||
|                                                             val: 3, | ||||
|                                                             base: 10, | ||||
|                                                             signed: false, | ||||
|                                                         }, | ||||
|                                                     ), | ||||
|                                                 ), | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 1, | ||||
|                                                     col: 14, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 1, | ||||
|                                             col: 12, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                     right: ExprBox { | ||||
|                                         inner: Literal( | ||||
|                                             Number( | ||||
|                                                 Number { | ||||
|                                                     val: 4, | ||||
|                                                     base: 10, | ||||
|                                                     signed: false, | ||||
|                                                 }, | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 1, | ||||
|                                             col: 18, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                                 loc: Loc { | ||||
|                                     file: "parser/expressions.mcl", | ||||
|                                     line: 1, | ||||
|                                     col: 16, | ||||
|                                 }, | ||||
|                             }, | ||||
|                         ), | ||||
|                     }, | ||||
|                     right: BinOp { | ||||
|                         typ: EqEq, | ||||
|                         left: BinOp { | ||||
|                             typ: Star, | ||||
|                             left: Literal( | ||||
|                                 Number( | ||||
|                                     Number { | ||||
|                                         val: 1, | ||||
|                                         base: 10, | ||||
|                                         signed: false, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                             ), | ||||
|                             right: Literal( | ||||
|                                 Number( | ||||
|                                     Number { | ||||
|                                         val: 3, | ||||
|                                         base: 10, | ||||
|                                         signed: false, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                             ), | ||||
|                         }, | ||||
|                         right: Literal( | ||||
|                             Number( | ||||
|                                 Number { | ||||
|                                     val: 4, | ||||
|                                     base: 10, | ||||
|                                     signed: false, | ||||
|                                 }, | ||||
|                             ), | ||||
|                     loc: Loc { | ||||
|                         file: "parser/expressions.mcl", | ||||
|                         line: 1, | ||||
|                         col: 4, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Statement( | ||||
|                 StatementBox { | ||||
|                     inner: Let { | ||||
|                         name: Ident( | ||||
|                             "b", | ||||
|                         ), | ||||
|                         typ: None, | ||||
|                         val: Some( | ||||
|                             ExprBox { | ||||
|                                 inner: BinOp { | ||||
|                                     typ: EqEq, | ||||
|                                     left: ExprBox { | ||||
|                                         inner: BinOp { | ||||
|                                             typ: Div, | ||||
|                                             left: ExprBox { | ||||
|                                                 inner: Literal( | ||||
|                                                     Number( | ||||
|                                                         Number { | ||||
|                                                             val: 3, | ||||
|                                                             base: 10, | ||||
|                                                             signed: false, | ||||
|                                                         }, | ||||
|                                                     ), | ||||
|                                                 ), | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 2, | ||||
|                                                     col: 10, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                             right: ExprBox { | ||||
|                                                 inner: Literal( | ||||
|                                                     Number( | ||||
|                                                         Number { | ||||
|                                                             val: 4, | ||||
|                                                             base: 10, | ||||
|                                                             signed: false, | ||||
|                                                         }, | ||||
|                                                     ), | ||||
|                                                 ), | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 2, | ||||
|                                                     col: 12, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 2, | ||||
|                                             col: 11, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                     right: ExprBox { | ||||
|                                         inner: UnOp { | ||||
|                                             typ: Star, | ||||
|                                             right: ExprBox { | ||||
|                                                 inner: Path( | ||||
|                                                     Path( | ||||
|                                                         [ | ||||
|                                                             Ident( | ||||
|                                                                 "a", | ||||
|                                                             ), | ||||
|                                                         ], | ||||
|                                                     ), | ||||
|                                                 ), | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 2, | ||||
|                                                     col: 17, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 2, | ||||
|                                             col: 16, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                                 loc: Loc { | ||||
|                                     file: "parser/expressions.mcl", | ||||
|                                     line: 2, | ||||
|                                     col: 14, | ||||
|                                 }, | ||||
|                             }, | ||||
|                         ), | ||||
|                     }, | ||||
|                     loc: Loc { | ||||
|                         file: "parser/expressions.mcl", | ||||
|                         line: 2, | ||||
|                         col: 4, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Statement( | ||||
|                 StatementBox { | ||||
|                     inner: Let { | ||||
|                         name: Ident( | ||||
|                             "c", | ||||
|                         ), | ||||
|                         typ: None, | ||||
|                         val: Some( | ||||
|                             ExprBox { | ||||
|                                 inner: BinOp { | ||||
|                                     typ: Div, | ||||
|                                     left: ExprBox { | ||||
|                                         inner: Group( | ||||
|                                             ExprBox { | ||||
|                                                 inner: PtrFieldAccess { | ||||
|                                                     left: Some( | ||||
|                                                         ExprBox { | ||||
|                                                             inner: Path( | ||||
|                                                                 Path( | ||||
|                                                                     [ | ||||
|                                                                         Ident( | ||||
|                                                                             "a", | ||||
|                                                                         ), | ||||
|                                                                     ], | ||||
|                                                                 ), | ||||
|                                                             ), | ||||
|                                                             loc: Loc { | ||||
|                                                                 file: "parser/expressions.mcl", | ||||
|                                                                 line: 3, | ||||
|                                                                 col: 11, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                     ), | ||||
|                                                     right: ExprBox { | ||||
|                                                         inner: FieldAccess { | ||||
|                                                             left: Some( | ||||
|                                                                 ExprBox { | ||||
|                                                                     inner: Path( | ||||
|                                                                         Path( | ||||
|                                                                             [ | ||||
|                                                                                 Ident( | ||||
|                                                                                     "b", | ||||
|                                                                                 ), | ||||
|                                                                             ], | ||||
|                                                                         ), | ||||
|                                                                     ), | ||||
|                                                                     loc: Loc { | ||||
|                                                                         file: "parser/expressions.mcl", | ||||
|                                                                         line: 3, | ||||
|                                                                         col: 13, | ||||
|                                                                     }, | ||||
|                                                                 }, | ||||
|                                                             ), | ||||
|                                                             right: ExprBox { | ||||
|                                                                 inner: PtrFieldAccess { | ||||
|                                                                     left: Some( | ||||
|                                                                         ExprBox { | ||||
|                                                                             inner: Path( | ||||
|                                                                                 Path( | ||||
|                                                                                     [ | ||||
|                                                                                         Ident( | ||||
|                                                                                             "c", | ||||
|                                                                                         ), | ||||
|                                                                                     ], | ||||
|                                                                                 ), | ||||
|                                                                             ), | ||||
|                                                                             loc: Loc { | ||||
|                                                                                 file: "parser/expressions.mcl", | ||||
|                                                                                 line: 3, | ||||
|                                                                                 col: 15, | ||||
|                                                                             }, | ||||
|                                                                         }, | ||||
|                                                                     ), | ||||
|                                                                     right: ExprBox { | ||||
|                                                                         inner: Path( | ||||
|                                                                             Path( | ||||
|                                                                                 [ | ||||
|                                                                                     Ident( | ||||
|                                                                                         "d", | ||||
|                                                                                     ), | ||||
|                                                                                 ], | ||||
|                                                                             ), | ||||
|                                                                         ), | ||||
|                                                                         loc: Loc { | ||||
|                                                                             file: "parser/expressions.mcl", | ||||
|                                                                             line: 3, | ||||
|                                                                             col: 17, | ||||
|                                                                         }, | ||||
|                                                                     }, | ||||
|                                                                 }, | ||||
|                                                                 loc: Loc { | ||||
|                                                                     file: "parser/expressions.mcl", | ||||
|                                                                     line: 3, | ||||
|                                                                     col: 16, | ||||
|                                                                 }, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                         loc: Loc { | ||||
|                                                             file: "parser/expressions.mcl", | ||||
|                                                             line: 3, | ||||
|                                                             col: 14, | ||||
|                                                         }, | ||||
|                                                     }, | ||||
|                                                 }, | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 3, | ||||
|                                                     col: 12, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                         ), | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 3, | ||||
|                                             col: 10, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                     right: ExprBox { | ||||
|                                         inner: Literal( | ||||
|                                             Number( | ||||
|                                                 Number { | ||||
|                                                     val: 2, | ||||
|                                                     base: 10, | ||||
|                                                     signed: false, | ||||
|                                                 }, | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 3, | ||||
|                                             col: 22, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                                 loc: Loc { | ||||
|                                     file: "parser/expressions.mcl", | ||||
|                                     line: 3, | ||||
|                                     col: 20, | ||||
|                                 }, | ||||
|                             }, | ||||
|                         ), | ||||
|                     }, | ||||
|                     loc: Loc { | ||||
|                         file: "parser/expressions.mcl", | ||||
|                         line: 3, | ||||
|                         col: 4, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Statement( | ||||
|                 StatementBox { | ||||
|                     inner: Let { | ||||
|                         name: Ident( | ||||
|                             "d", | ||||
|                         ), | ||||
|                         typ: None, | ||||
|                         val: Some( | ||||
|                             ExprBox { | ||||
|                                 inner: BinOp { | ||||
|                                     typ: Div, | ||||
|                                     left: ExprBox { | ||||
|                                         inner: Literal( | ||||
|                                             Number( | ||||
|                                                 Number { | ||||
|                                                     val: 2, | ||||
|                                                     base: 10, | ||||
|                                                     signed: false, | ||||
|                                                 }, | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 4, | ||||
|                                             col: 10, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                     right: ExprBox { | ||||
|                                         inner: PtrFieldAccess { | ||||
|                                             left: Some( | ||||
|                                                 ExprBox { | ||||
|                                                     inner: Path( | ||||
|                                                         Path( | ||||
|                                                             [ | ||||
|                                                                 Ident( | ||||
|                                                                     "a", | ||||
|                                                                 ), | ||||
|                                                             ], | ||||
|                                                         ), | ||||
|                                                     ), | ||||
|                                                     loc: Loc { | ||||
|                                                         file: "parser/expressions.mcl", | ||||
|                                                         line: 4, | ||||
|                                                         col: 14, | ||||
|                                                     }, | ||||
|                                                 }, | ||||
|                                             ), | ||||
|                                             right: ExprBox { | ||||
|                                                 inner: FieldAccess { | ||||
|                                                     left: Some( | ||||
|                                                         ExprBox { | ||||
|                                                             inner: Path( | ||||
|                                                                 Path( | ||||
|                                                                     [ | ||||
|                                                                         Ident( | ||||
|                                                                             "b", | ||||
|                                                                         ), | ||||
|                                                                     ], | ||||
|                                                                 ), | ||||
|                                                             ), | ||||
|                                                             loc: Loc { | ||||
|                                                                 file: "parser/expressions.mcl", | ||||
|                                                                 line: 4, | ||||
|                                                                 col: 16, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                     ), | ||||
|                                                     right: ExprBox { | ||||
|                                                         inner: PtrFieldAccess { | ||||
|                                                             left: Some( | ||||
|                                                                 ExprBox { | ||||
|                                                                     inner: Path( | ||||
|                                                                         Path( | ||||
|                                                                             [ | ||||
|                                                                                 Ident( | ||||
|                                                                                     "c", | ||||
|                                                                                 ), | ||||
|                                                                             ], | ||||
|                                                                         ), | ||||
|                                                                     ), | ||||
|                                                                     loc: Loc { | ||||
|                                                                         file: "parser/expressions.mcl", | ||||
|                                                                         line: 4, | ||||
|                                                                         col: 18, | ||||
|                                                                     }, | ||||
|                                                                 }, | ||||
|                                                             ), | ||||
|                                                             right: ExprBox { | ||||
|                                                                 inner: Path( | ||||
|                                                                     Path( | ||||
|                                                                         [ | ||||
|                                                                             Ident( | ||||
|                                                                                 "d", | ||||
|                                                                             ), | ||||
|                                                                         ], | ||||
|                                                                     ), | ||||
|                                                                 ), | ||||
|                                                                 loc: Loc { | ||||
|                                                                     file: "parser/expressions.mcl", | ||||
|                                                                     line: 4, | ||||
|                                                                     col: 20, | ||||
|                                                                 }, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                         loc: Loc { | ||||
|                                                             file: "parser/expressions.mcl", | ||||
|                                                             line: 4, | ||||
|                                                             col: 19, | ||||
|                                                         }, | ||||
|                                                     }, | ||||
|                                                 }, | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 4, | ||||
|                                                     col: 17, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 4, | ||||
|                                             col: 15, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                                 loc: Loc { | ||||
|                                     file: "parser/expressions.mcl", | ||||
|                                     line: 4, | ||||
|                                     col: 12, | ||||
|                                 }, | ||||
|                             }, | ||||
|                         ), | ||||
|                     }, | ||||
|                     loc: Loc { | ||||
|                         file: "parser/expressions.mcl", | ||||
|                         line: 4, | ||||
|                         col: 4, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Statement( | ||||
|                 StatementBox { | ||||
|                     inner: Let { | ||||
|                         name: Ident( | ||||
|                             "e", | ||||
|                         ), | ||||
|                         typ: None, | ||||
|                         val: Some( | ||||
|                             ExprBox { | ||||
|                                 inner: BinOp { | ||||
|                                     typ: Div, | ||||
|                                     left: ExprBox { | ||||
|                                         inner: PtrFieldAccess { | ||||
|                                             left: Some( | ||||
|                                                 ExprBox { | ||||
|                                                     inner: Path( | ||||
|                                                         Path( | ||||
|                                                             [ | ||||
|                                                                 Ident( | ||||
|                                                                     "a", | ||||
|                                                                 ), | ||||
|                                                             ], | ||||
|                                                         ), | ||||
|                                                     ), | ||||
|                                                     loc: Loc { | ||||
|                                                         file: "parser/expressions.mcl", | ||||
|                                                         line: 5, | ||||
|                                                         col: 10, | ||||
|                                                     }, | ||||
|                                                 }, | ||||
|                                             ), | ||||
|                                             right: ExprBox { | ||||
|                                                 inner: FieldAccess { | ||||
|                                                     left: Some( | ||||
|                                                         ExprBox { | ||||
|                                                             inner: Path( | ||||
|                                                                 Path( | ||||
|                                                                     [ | ||||
|                                                                         Ident( | ||||
|                                                                             "b", | ||||
|                                                                         ), | ||||
|                                                                     ], | ||||
|                                                                 ), | ||||
|                                                             ), | ||||
|                                                             loc: Loc { | ||||
|                                                                 file: "parser/expressions.mcl", | ||||
|                                                                 line: 5, | ||||
|                                                                 col: 12, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                     ), | ||||
|                                                     right: ExprBox { | ||||
|                                                         inner: PtrFieldAccess { | ||||
|                                                             left: Some( | ||||
|                                                                 ExprBox { | ||||
|                                                                     inner: Path( | ||||
|                                                                         Path( | ||||
|                                                                             [ | ||||
|                                                                                 Ident( | ||||
|                                                                                     "c", | ||||
|                                                                                 ), | ||||
|                                                                             ], | ||||
|                                                                         ), | ||||
|                                                                     ), | ||||
|                                                                     loc: Loc { | ||||
|                                                                         file: "parser/expressions.mcl", | ||||
|                                                                         line: 5, | ||||
|                                                                         col: 14, | ||||
|                                                                     }, | ||||
|                                                                 }, | ||||
|                                                             ), | ||||
|                                                             right: ExprBox { | ||||
|                                                                 inner: Path( | ||||
|                                                                     Path( | ||||
|                                                                         [ | ||||
|                                                                             Ident( | ||||
|                                                                                 "d", | ||||
|                                                                             ), | ||||
|                                                                         ], | ||||
|                                                                     ), | ||||
|                                                                 ), | ||||
|                                                                 loc: Loc { | ||||
|                                                                     file: "parser/expressions.mcl", | ||||
|                                                                     line: 5, | ||||
|                                                                     col: 16, | ||||
|                                                                 }, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                         loc: Loc { | ||||
|                                                             file: "parser/expressions.mcl", | ||||
|                                                             line: 5, | ||||
|                                                             col: 15, | ||||
|                                                         }, | ||||
|                                                     }, | ||||
|                                                 }, | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 5, | ||||
|                                                     col: 13, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 5, | ||||
|                                             col: 11, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                     right: ExprBox { | ||||
|                                         inner: Literal( | ||||
|                                             Number( | ||||
|                                                 Number { | ||||
|                                                     val: 2, | ||||
|                                                     base: 10, | ||||
|                                                     signed: false, | ||||
|                                                 }, | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 5, | ||||
|                                             col: 20, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                                 loc: Loc { | ||||
|                                     file: "parser/expressions.mcl", | ||||
|                                     line: 5, | ||||
|                                     col: 18, | ||||
|                                 }, | ||||
|                             }, | ||||
|                         ), | ||||
|                     }, | ||||
|                     loc: Loc { | ||||
|                         file: "parser/expressions.mcl", | ||||
|                         line: 5, | ||||
|                         col: 4, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Statement( | ||||
|                 StatementBox { | ||||
|                     inner: Let { | ||||
|                         name: Ident( | ||||
|                             "f", | ||||
|                         ), | ||||
|                         typ: None, | ||||
|                         val: Some( | ||||
|                             ExprBox { | ||||
|                                 inner: BinOp { | ||||
|                                     typ: Div, | ||||
|                                     left: ExprBox { | ||||
|                                         inner: FieldAccess { | ||||
|                                             left: Some( | ||||
|                                                 ExprBox { | ||||
|                                                     inner: Path( | ||||
|                                                         Path( | ||||
|                                                             [ | ||||
|                                                                 Ident( | ||||
|                                                                     "a", | ||||
|                                                                 ), | ||||
|                                                             ], | ||||
|                                                         ), | ||||
|                                                     ), | ||||
|                                                     loc: Loc { | ||||
|                                                         file: "parser/expressions.mcl", | ||||
|                                                         line: 6, | ||||
|                                                         col: 10, | ||||
|                                                     }, | ||||
|                                                 }, | ||||
|                                             ), | ||||
|                                             right: ExprBox { | ||||
|                                                 inner: FieldAccess { | ||||
|                                                     left: Some( | ||||
|                                                         ExprBox { | ||||
|                                                             inner: Path( | ||||
|                                                                 Path( | ||||
|                                                                     [ | ||||
|                                                                         Ident( | ||||
|                                                                             "b", | ||||
|                                                                         ), | ||||
|                                                                     ], | ||||
|                                                                 ), | ||||
|                                                             ), | ||||
|                                                             loc: Loc { | ||||
|                                                                 file: "parser/expressions.mcl", | ||||
|                                                                 line: 6, | ||||
|                                                                 col: 12, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                     ), | ||||
|                                                     right: ExprBox { | ||||
|                                                         inner: FieldAccess { | ||||
|                                                             left: Some( | ||||
|                                                                 ExprBox { | ||||
|                                                                     inner: Path( | ||||
|                                                                         Path( | ||||
|                                                                             [ | ||||
|                                                                                 Ident( | ||||
|                                                                                     "c", | ||||
|                                                                                 ), | ||||
|                                                                             ], | ||||
|                                                                         ), | ||||
|                                                                     ), | ||||
|                                                                     loc: Loc { | ||||
|                                                                         file: "parser/expressions.mcl", | ||||
|                                                                         line: 6, | ||||
|                                                                         col: 14, | ||||
|                                                                     }, | ||||
|                                                                 }, | ||||
|                                                             ), | ||||
|                                                             right: ExprBox { | ||||
|                                                                 inner: Path( | ||||
|                                                                     Path( | ||||
|                                                                         [ | ||||
|                                                                             Ident( | ||||
|                                                                                 "d", | ||||
|                                                                             ), | ||||
|                                                                         ], | ||||
|                                                                     ), | ||||
|                                                                 ), | ||||
|                                                                 loc: Loc { | ||||
|                                                                     file: "parser/expressions.mcl", | ||||
|                                                                     line: 6, | ||||
|                                                                     col: 16, | ||||
|                                                                 }, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                         loc: Loc { | ||||
|                                                             file: "parser/expressions.mcl", | ||||
|                                                             line: 6, | ||||
|                                                             col: 15, | ||||
|                                                         }, | ||||
|                                                     }, | ||||
|                                                 }, | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 6, | ||||
|                                                     col: 13, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 6, | ||||
|                                             col: 11, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                     right: ExprBox { | ||||
|                                         inner: Literal( | ||||
|                                             Number( | ||||
|                                                 Number { | ||||
|                                                     val: 2, | ||||
|                                                     base: 10, | ||||
|                                                     signed: false, | ||||
|                                                 }, | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 6, | ||||
|                                             col: 20, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                                 loc: Loc { | ||||
|                                     file: "parser/expressions.mcl", | ||||
|                                     line: 6, | ||||
|                                     col: 18, | ||||
|                                 }, | ||||
|                             }, | ||||
|                         ), | ||||
|                     }, | ||||
|                     loc: Loc { | ||||
|                         file: "parser/expressions.mcl", | ||||
|                         line: 6, | ||||
|                         col: 4, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Statement( | ||||
|                 StatementBox { | ||||
|                     inner: Let { | ||||
|                         name: Ident( | ||||
|                             "g", | ||||
|                         ), | ||||
|                         typ: None, | ||||
|                         val: Some( | ||||
|                             ExprBox { | ||||
|                                 inner: BinOp { | ||||
|                                     typ: Star, | ||||
|                                     left: ExprBox { | ||||
|                                         inner: ArrayIndex { | ||||
|                                             name: ExprBox { | ||||
|                                                 inner: FieldAccess { | ||||
|                                                     left: Some( | ||||
|                                                         ExprBox { | ||||
|                                                             inner: Path( | ||||
|                                                                 Path( | ||||
|                                                                     [ | ||||
|                                                                         Ident( | ||||
|                                                                             "a", | ||||
|                                                                         ), | ||||
|                                                                     ], | ||||
|                                                                 ), | ||||
|                                                             ), | ||||
|                                                             loc: Loc { | ||||
|                                                                 file: "parser/expressions.mcl", | ||||
|                                                                 line: 7, | ||||
|                                                                 col: 10, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                     ), | ||||
|                                                     right: ExprBox { | ||||
|                                                         inner: Path( | ||||
|                                                             Path( | ||||
|                                                                 [ | ||||
|                                                                     Ident( | ||||
|                                                                         "b", | ||||
|                                                                     ), | ||||
|                                                                 ], | ||||
|                                                             ), | ||||
|                                                         ), | ||||
|                                                         loc: Loc { | ||||
|                                                             file: "parser/expressions.mcl", | ||||
|                                                             line: 7, | ||||
|                                                             col: 12, | ||||
|                                                         }, | ||||
|                                                     }, | ||||
|                                                 }, | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 7, | ||||
|                                                     col: 11, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                             index: ExprBox { | ||||
|                                                 inner: UnOp { | ||||
|                                                     typ: Star, | ||||
|                                                     right: ExprBox { | ||||
|                                                         inner: FieldAccess { | ||||
|                                                             left: Some( | ||||
|                                                                 ExprBox { | ||||
|                                                                     inner: Path( | ||||
|                                                                         Path( | ||||
|                                                                             [ | ||||
|                                                                                 Ident( | ||||
|                                                                                     "a", | ||||
|                                                                                 ), | ||||
|                                                                             ], | ||||
|                                                                         ), | ||||
|                                                                     ), | ||||
|                                                                     loc: Loc { | ||||
|                                                                         file: "parser/expressions.mcl", | ||||
|                                                                         line: 7, | ||||
|                                                                         col: 15, | ||||
|                                                                     }, | ||||
|                                                                 }, | ||||
|                                                             ), | ||||
|                                                             right: ExprBox { | ||||
|                                                                 inner: Path( | ||||
|                                                                     Path( | ||||
|                                                                         [ | ||||
|                                                                             Ident( | ||||
|                                                                                 "c", | ||||
|                                                                             ), | ||||
|                                                                         ], | ||||
|                                                                     ), | ||||
|                                                                 ), | ||||
|                                                                 loc: Loc { | ||||
|                                                                     file: "parser/expressions.mcl", | ||||
|                                                                     line: 7, | ||||
|                                                                     col: 17, | ||||
|                                                                 }, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                         loc: Loc { | ||||
|                                                             file: "parser/expressions.mcl", | ||||
|                                                             line: 7, | ||||
|                                                             col: 16, | ||||
|                                                         }, | ||||
|                                                     }, | ||||
|                                                 }, | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/expressions.mcl", | ||||
|                                                     line: 7, | ||||
|                                                     col: 14, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 7, | ||||
|                                             col: 13, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                     right: ExprBox { | ||||
|                                         inner: Literal( | ||||
|                                             Number( | ||||
|                                                 Number { | ||||
|                                                     val: 5, | ||||
|                                                     base: 10, | ||||
|                                                     signed: false, | ||||
|                                                 }, | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/expressions.mcl", | ||||
|                                             line: 7, | ||||
|                                             col: 22, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                                 loc: Loc { | ||||
|                                     file: "parser/expressions.mcl", | ||||
|                                     line: 7, | ||||
|                                     col: 20, | ||||
|                                 }, | ||||
|                             }, | ||||
|                         ), | ||||
|                     }, | ||||
|                     loc: Loc { | ||||
|                         file: "parser/expressions.mcl", | ||||
|                         line: 7, | ||||
|                         col: 4, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| *a = 1 * 3 == 4; | ||||
| b.c = 3/4 == *a; | ||||
| c->d = (a->b.c->d) / 2; | ||||
| *d->e.f = 2 / a->b.c->d; | ||||
| e = a->b.c->d / 2; | ||||
| f = a.b.c.d / 2; | ||||
| g = a.b[*a.c] * 5; | ||||
| let a = 1 * 3 == 4; | ||||
| let b = 3/4 == *a; | ||||
| let c = (a->b.c->d) / 2; | ||||
| let d = 2 / a->b.c->d; | ||||
| let e = a->b.c->d / 2; | ||||
| let f = a.b.c.d / 2; | ||||
| let g = a.b[*a.c] * 5; | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,187 +2,298 @@ Program { | |||
|     ast: Block( | ||||
|         [ | ||||
|             Statement( | ||||
|                 Fn { | ||||
|                     struct_name: None, | ||||
|                     name: Ident( | ||||
|                         "main", | ||||
|                     ), | ||||
|                     params: [ | ||||
|                         ( | ||||
|                             Ident( | ||||
|                                 "argc", | ||||
|                 StatementBox { | ||||
|                     inner: Fn( | ||||
|                         Function { | ||||
|                             struct_name: None, | ||||
|                             name: Ident( | ||||
|                                 "main", | ||||
|                             ), | ||||
|                             Owned( | ||||
|                                 Ident( | ||||
|                                     "i32", | ||||
|                                 ), | ||||
|                             ), | ||||
|                         ), | ||||
|                         ( | ||||
|                             Ident( | ||||
|                                 "argv", | ||||
|                             ), | ||||
|                             Ref { | ||||
|                                 inner: Array { | ||||
|                                     inner: Owned( | ||||
|                                         Ident( | ||||
|                                             "Str", | ||||
|                                         ), | ||||
|                             params: [ | ||||
|                                 ( | ||||
|                                     Ident( | ||||
|                                         "argc", | ||||
|                                     ), | ||||
|                                 }, | ||||
|                                 mutable: false, | ||||
|                             }, | ||||
|                         ), | ||||
|                     ], | ||||
|                     ret_type: Some( | ||||
|                         Owned( | ||||
|                             Ident( | ||||
|                                 "i32", | ||||
|                             ), | ||||
|                         ), | ||||
|                     ), | ||||
|                     qual_const: false, | ||||
|                     qual_extern: None, | ||||
|                     body: Some( | ||||
|                         Block( | ||||
|                             [ | ||||
|                                 Expr( | ||||
|                                     Return( | ||||
|                                         Some( | ||||
|                                             Literal( | ||||
|                                                 Number( | ||||
|                                                     Number { | ||||
|                                                         val: 0, | ||||
|                                                         base: 10, | ||||
|                                                         signed: false, | ||||
|                                                     }, | ||||
|                                                 ), | ||||
|                                     TypeBox { | ||||
|                                         inner: Owned( | ||||
|                                             Ident( | ||||
|                                                 "i32", | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/functions.mcl", | ||||
|                                             line: 1, | ||||
|                                             col: 18, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                                 ( | ||||
|                                     Ident( | ||||
|                                         "argv", | ||||
|                                     ), | ||||
|                                     TypeBox { | ||||
|                                         inner: Ref { | ||||
|                                             inner: Array { | ||||
|                                                 inner: Owned( | ||||
|                                                     Ident( | ||||
|                                                         "Str", | ||||
|                                                     ), | ||||
|                                                 ), | ||||
|                                             }, | ||||
|                                             mutable: false, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/functions.mcl", | ||||
|                                             line: 1, | ||||
|                                             col: 27, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                             ], | ||||
|                         ), | ||||
|                             ret_type: Some( | ||||
|                                 TypeBox { | ||||
|                                     inner: Owned( | ||||
|                                         Ident( | ||||
|                                             "i32", | ||||
|                                         ), | ||||
|                                     ), | ||||
|                                     loc: Loc { | ||||
|                                         file: "parser/functions.mcl", | ||||
|                                         line: 1, | ||||
|                                         col: 39, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                             ), | ||||
|                             qual_const: false, | ||||
|                             qual_extern: None, | ||||
|                             body: Some( | ||||
|                                 Block( | ||||
|                                     [ | ||||
|                                         Expr( | ||||
|                                             ExprBox { | ||||
|                                                 inner: Return( | ||||
|                                                     Some( | ||||
|                                                         ExprBox { | ||||
|                                                             inner: Literal( | ||||
|                                                                 Number( | ||||
|                                                                     Number { | ||||
|                                                                         val: 0, | ||||
|                                                                         base: 10, | ||||
|                                                                         signed: false, | ||||
|                                                                     }, | ||||
|                                                                 ), | ||||
|                                                             ), | ||||
|                                                             loc: Loc { | ||||
|                                                                 file: "parser/functions.mcl", | ||||
|                                                                 line: 2, | ||||
|                                                                 col: 13, | ||||
|                                                             }, | ||||
|                                                         }, | ||||
|                                                     ), | ||||
|                                                 ), | ||||
|                                                 loc: Loc { | ||||
|                                                     file: "parser/functions.mcl", | ||||
|                                                     line: 2, | ||||
|                                                     col: 11, | ||||
|                                                 }, | ||||
|                                             }, | ||||
|                                         ), | ||||
|                                     ], | ||||
|                                 ), | ||||
|                             ), | ||||
|                         }, | ||||
|                     ), | ||||
|                     loc: Loc { | ||||
|                         file: "parser/functions.mcl", | ||||
|                         line: 1, | ||||
|                         col: 3, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Statement( | ||||
|                 Fn { | ||||
|                     struct_name: Some( | ||||
|                         Ident( | ||||
|                             "Baz", | ||||
|                         ), | ||||
|                     ), | ||||
|                     name: Ident( | ||||
|                         "main", | ||||
|                     ), | ||||
|                     params: [ | ||||
|                         ( | ||||
|                             Ident( | ||||
|                                 "self", | ||||
|                             ), | ||||
|                             Ref { | ||||
|                                 inner: Owned( | ||||
|                                     Ident( | ||||
|                                         "Baz", | ||||
|                                     ), | ||||
|                                 ), | ||||
|                                 mutable: true, | ||||
|                             }, | ||||
|                         ), | ||||
|                         ( | ||||
|                             Ident( | ||||
|                                 "a", | ||||
|                             ), | ||||
|                             Ref { | ||||
|                                 inner: Owned( | ||||
|                                     Ident( | ||||
|                                         "Foo", | ||||
|                                     ), | ||||
|                                 ), | ||||
|                                 mutable: false, | ||||
|                             }, | ||||
|                         ), | ||||
|                         ( | ||||
|                             Ident( | ||||
|                                 "b", | ||||
|                             ), | ||||
|                             Ref { | ||||
|                                 inner: Owned( | ||||
|                                     Ident( | ||||
|                                         "Bar", | ||||
|                                     ), | ||||
|                                 ), | ||||
|                                 mutable: true, | ||||
|                             }, | ||||
|                         ), | ||||
|                     ], | ||||
|                     ret_type: Some( | ||||
|                         Ref { | ||||
|                             inner: Owned( | ||||
|                 StatementBox { | ||||
|                     inner: Fn( | ||||
|                         Function { | ||||
|                             struct_name: Some( | ||||
|                                 Ident( | ||||
|                                     "Nya", | ||||
|                                     "Baz", | ||||
|                                 ), | ||||
|                             ), | ||||
|                             mutable: false, | ||||
|                             name: Ident( | ||||
|                                 "main", | ||||
|                             ), | ||||
|                             params: [ | ||||
|                                 ( | ||||
|                                     Ident( | ||||
|                                         "self", | ||||
|                                     ), | ||||
|                                     TypeBox { | ||||
|                                         inner: Ref { | ||||
|                                             inner: Owned( | ||||
|                                                 Ident( | ||||
|                                                     "Baz", | ||||
|                                                 ), | ||||
|                                             ), | ||||
|                                             mutable: true, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/functions.mcl", | ||||
|                                             line: 4, | ||||
|                                             col: 20, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                                 ( | ||||
|                                     Ident( | ||||
|                                         "a", | ||||
|                                     ), | ||||
|                                     TypeBox { | ||||
|                                         inner: Ref { | ||||
|                                             inner: Owned( | ||||
|                                                 Ident( | ||||
|                                                     "Foo", | ||||
|                                                 ), | ||||
|                                             ), | ||||
|                                             mutable: false, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/functions.mcl", | ||||
|                                             line: 4, | ||||
|                                             col: 33, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                                 ( | ||||
|                                     Ident( | ||||
|                                         "b", | ||||
|                                     ), | ||||
|                                     TypeBox { | ||||
|                                         inner: Ref { | ||||
|                                             inner: Owned( | ||||
|                                                 Ident( | ||||
|                                                     "Bar", | ||||
|                                                 ), | ||||
|                                             ), | ||||
|                                             mutable: true, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/functions.mcl", | ||||
|                                             line: 4, | ||||
|                                             col: 42, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                             ], | ||||
|                             ret_type: Some( | ||||
|                                 TypeBox { | ||||
|                                     inner: Ref { | ||||
|                                         inner: Owned( | ||||
|                                             Ident( | ||||
|                                                 "Nya", | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                         mutable: false, | ||||
|                                     }, | ||||
|                                     loc: Loc { | ||||
|                                         file: "parser/functions.mcl", | ||||
|                                         line: 4, | ||||
|                                         col: 54, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                             ), | ||||
|                             qual_const: false, | ||||
|                             qual_extern: None, | ||||
|                             body: None, | ||||
|                         }, | ||||
|                     ), | ||||
|                     qual_const: false, | ||||
|                     qual_extern: None, | ||||
|                     body: None, | ||||
|                     loc: Loc { | ||||
|                         file: "parser/functions.mcl", | ||||
|                         line: 4, | ||||
|                         col: 3, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Statement( | ||||
|                 Fn { | ||||
|                     struct_name: Some( | ||||
|                         Ident( | ||||
|                             "Baz", | ||||
|                         ), | ||||
|                     ), | ||||
|                     name: Ident( | ||||
|                         "main", | ||||
|                     ), | ||||
|                     params: [ | ||||
|                         ( | ||||
|                             Ident( | ||||
|                                 "a", | ||||
|                             ), | ||||
|                             Ref { | ||||
|                                 inner: Owned( | ||||
|                                     Ident( | ||||
|                                         "Foo", | ||||
|                                     ), | ||||
|                                 ), | ||||
|                                 mutable: false, | ||||
|                             }, | ||||
|                         ), | ||||
|                         ( | ||||
|                             Ident( | ||||
|                                 "b", | ||||
|                             ), | ||||
|                             Ref { | ||||
|                                 inner: Owned( | ||||
|                                     Ident( | ||||
|                                         "Bar", | ||||
|                                     ), | ||||
|                                 ), | ||||
|                                 mutable: true, | ||||
|                             }, | ||||
|                         ), | ||||
|                     ], | ||||
|                     ret_type: Some( | ||||
|                         Ref { | ||||
|                             inner: Owned( | ||||
|                 StatementBox { | ||||
|                     inner: Fn( | ||||
|                         Function { | ||||
|                             struct_name: Some( | ||||
|                                 Ident( | ||||
|                                     "Nya", | ||||
|                                     "Baz", | ||||
|                                 ), | ||||
|                             ), | ||||
|                             mutable: false, | ||||
|                             name: Ident( | ||||
|                                 "main", | ||||
|                             ), | ||||
|                             params: [ | ||||
|                                 ( | ||||
|                                     Ident( | ||||
|                                         "a", | ||||
|                                     ), | ||||
|                                     TypeBox { | ||||
|                                         inner: Ref { | ||||
|                                             inner: Owned( | ||||
|                                                 Ident( | ||||
|                                                     "Foo", | ||||
|                                                 ), | ||||
|                                             ), | ||||
|                                             mutable: false, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/functions.mcl", | ||||
|                                             line: 5, | ||||
|                                             col: 17, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                                 ( | ||||
|                                     Ident( | ||||
|                                         "b", | ||||
|                                     ), | ||||
|                                     TypeBox { | ||||
|                                         inner: Ref { | ||||
|                                             inner: Owned( | ||||
|                                                 Ident( | ||||
|                                                     "Bar", | ||||
|                                                 ), | ||||
|                                             ), | ||||
|                                             mutable: true, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/functions.mcl", | ||||
|                                             line: 5, | ||||
|                                             col: 26, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                             ], | ||||
|                             ret_type: Some( | ||||
|                                 TypeBox { | ||||
|                                     inner: Ref { | ||||
|                                         inner: Owned( | ||||
|                                             Ident( | ||||
|                                                 "Nya", | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                         mutable: false, | ||||
|                                     }, | ||||
|                                     loc: Loc { | ||||
|                                         file: "parser/functions.mcl", | ||||
|                                         line: 5, | ||||
|                                         col: 38, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                             ), | ||||
|                             qual_const: false, | ||||
|                             qual_extern: None, | ||||
|                             body: None, | ||||
|                         }, | ||||
|                     ), | ||||
|                     qual_const: false, | ||||
|                     qual_extern: None, | ||||
|                     body: None, | ||||
|                     loc: Loc { | ||||
|                         file: "parser/functions.mcl", | ||||
|                         line: 5, | ||||
|                         col: 3, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|         ], | ||||
|  |  | |||
|  | @ -2,35 +2,63 @@ Program { | |||
|     ast: Block( | ||||
|         [ | ||||
|             Expr( | ||||
|                 If( | ||||
|                     IfExpr { | ||||
|                         test: BinOp { | ||||
|                             typ: Gt, | ||||
|                             left: Path( | ||||
|                                 Path( | ||||
|                                     [ | ||||
|                                         Ident( | ||||
|                                             "i", | ||||
|                 ExprBox { | ||||
|                     inner: If( | ||||
|                         IfExpr { | ||||
|                             test: ExprBox { | ||||
|                                 inner: BinOp { | ||||
|                                     typ: Gt, | ||||
|                                     left: ExprBox { | ||||
|                                         inner: Path( | ||||
|                                             Path( | ||||
|                                                 [ | ||||
|                                                     Ident( | ||||
|                                                         "i", | ||||
|                                                     ), | ||||
|                                                 ], | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                     ], | ||||
|                                 ), | ||||
|                             ), | ||||
|                             right: Literal( | ||||
|                                 Number( | ||||
|                                     Number { | ||||
|                                         val: 3, | ||||
|                                         base: 10, | ||||
|                                         signed: false, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/if-statements.mcl", | ||||
|                                             line: 2, | ||||
|                                             col: 5, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                                     right: ExprBox { | ||||
|                                         inner: Literal( | ||||
|                                             Number( | ||||
|                                                 Number { | ||||
|                                                     val: 3, | ||||
|                                                     base: 10, | ||||
|                                                     signed: false, | ||||
|                                                 }, | ||||
|                                             ), | ||||
|                                         ), | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/if-statements.mcl", | ||||
|                                             line: 2, | ||||
|                                             col: 9, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                                 loc: Loc { | ||||
|                                     file: "parser/if-statements.mcl", | ||||
|                                     line: 2, | ||||
|                                     col: 7, | ||||
|                                 }, | ||||
|                             }, | ||||
|                             body: Block( | ||||
|                                 [], | ||||
|                             ), | ||||
|                             else_if: None, | ||||
|                         }, | ||||
|                         body: Block( | ||||
|                             [], | ||||
|                         ), | ||||
|                         else_if: None, | ||||
|                     ), | ||||
|                     loc: Loc { | ||||
|                         file: "parser/if-statements.mcl", | ||||
|                         line: 2, | ||||
|                         col: 3, | ||||
|                     }, | ||||
|                 ), | ||||
|                 }, | ||||
|             ), | ||||
|         ], | ||||
|     ), | ||||
|  |  | |||
|  | @ -2,106 +2,204 @@ Program { | |||
|     ast: Block( | ||||
|         [ | ||||
|             Expr( | ||||
|                 ForLoop { | ||||
|                     init: Statement( | ||||
|                         Let { | ||||
|                             name: Ident( | ||||
|                                 "i", | ||||
|                             ), | ||||
|                             typ: None, | ||||
|                             val: Some( | ||||
|                                 Literal( | ||||
|                                     Number( | ||||
|                                         Number { | ||||
|                                             val: 0, | ||||
|                                             base: 10, | ||||
|                                             signed: false, | ||||
|                 ExprBox { | ||||
|                     inner: ForLoop { | ||||
|                         init: Statement( | ||||
|                             StatementBox { | ||||
|                                 inner: Let { | ||||
|                                     name: Ident( | ||||
|                                         "i", | ||||
|                                     ), | ||||
|                                     typ: None, | ||||
|                                     val: Some( | ||||
|                                         ExprBox { | ||||
|                                             inner: Literal( | ||||
|                                                 Number( | ||||
|                                                     Number { | ||||
|                                                         val: 0, | ||||
|                                                         base: 10, | ||||
|                                                         signed: false, | ||||
|                                                     }, | ||||
|                                                 ), | ||||
|                                             ), | ||||
|                                             loc: Loc { | ||||
|                                                 file: "parser/loops.mcl", | ||||
|                                                 line: 1, | ||||
|                                                 col: 14, | ||||
|                                             }, | ||||
|                                         }, | ||||
|                                     ), | ||||
|                                 ), | ||||
|                             ), | ||||
|                                 }, | ||||
|                                 loc: Loc { | ||||
|                                     file: "parser/loops.mcl", | ||||
|                                     line: 1, | ||||
|                                     col: 8, | ||||
|                                 }, | ||||
|                             }, | ||||
|                         ), | ||||
|                         test: ExprBox { | ||||
|                             inner: BinOp { | ||||
|                                 typ: Lt, | ||||
|                                 left: ExprBox { | ||||
|                                     inner: Path( | ||||
|                                         Path( | ||||
|                                             [ | ||||
|                                                 Ident( | ||||
|                                                     "i", | ||||
|                                                 ), | ||||
|                                             ], | ||||
|                                         ), | ||||
|                                     ), | ||||
|                                     loc: Loc { | ||||
|                                         file: "parser/loops.mcl", | ||||
|                                         line: 1, | ||||
|                                         col: 17, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                                 right: ExprBox { | ||||
|                                     inner: Literal( | ||||
|                                         Number( | ||||
|                                             Number { | ||||
|                                                 val: 10, | ||||
|                                                 base: 10, | ||||
|                                                 signed: false, | ||||
|                                             }, | ||||
|                                         ), | ||||
|                                     ), | ||||
|                                     loc: Loc { | ||||
|                                         file: "parser/loops.mcl", | ||||
|                                         line: 1, | ||||
|                                         col: 22, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                             }, | ||||
|                             loc: Loc { | ||||
|                                 file: "parser/loops.mcl", | ||||
|                                 line: 1, | ||||
|                                 col: 19, | ||||
|                             }, | ||||
|                         }, | ||||
|                     ), | ||||
|                     test: BinOp { | ||||
|                         typ: Lt, | ||||
|                         left: Path( | ||||
|                             Path( | ||||
|                                 [ | ||||
|                                     Ident( | ||||
|                                         "i", | ||||
|                         on_loop: ExprBox { | ||||
|                             inner: BinOp { | ||||
|                                 typ: AddEq, | ||||
|                                 left: ExprBox { | ||||
|                                     inner: Path( | ||||
|                                         Path( | ||||
|                                             [ | ||||
|                                                 Ident( | ||||
|                                                     "i", | ||||
|                                                 ), | ||||
|                                             ], | ||||
|                                         ), | ||||
|                                     ), | ||||
|                                 ], | ||||
|                             ), | ||||
|                         ), | ||||
|                         right: Literal( | ||||
|                             Number( | ||||
|                                 Number { | ||||
|                                     val: 10, | ||||
|                                     base: 10, | ||||
|                                     signed: false, | ||||
|                                     loc: Loc { | ||||
|                                         file: "parser/loops.mcl", | ||||
|                                         line: 1, | ||||
|                                         col: 25, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                             ), | ||||
|                                 right: ExprBox { | ||||
|                                     inner: Literal( | ||||
|                                         Number( | ||||
|                                             Number { | ||||
|                                                 val: 1, | ||||
|                                                 base: 10, | ||||
|                                                 signed: false, | ||||
|                                             }, | ||||
|                                         ), | ||||
|                                     ), | ||||
|                                     loc: Loc { | ||||
|                                         file: "parser/loops.mcl", | ||||
|                                         line: 1, | ||||
|                                         col: 29, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                             }, | ||||
|                             loc: Loc { | ||||
|                                 file: "parser/loops.mcl", | ||||
|                                 line: 1, | ||||
|                                 col: 27, | ||||
|                             }, | ||||
|                         }, | ||||
|                         body: Block( | ||||
|                             [], | ||||
|                         ), | ||||
|                     }, | ||||
|                     on_loop: BinOp { | ||||
|                         typ: AddEq, | ||||
|                         left: Path( | ||||
|                             Path( | ||||
|                                 [ | ||||
|                                     Ident( | ||||
|                                         "i", | ||||
|                                     ), | ||||
|                                 ], | ||||
|                             ), | ||||
|                         ), | ||||
|                         right: Literal( | ||||
|                             Number( | ||||
|                                 Number { | ||||
|                                     val: 1, | ||||
|                                     base: 10, | ||||
|                                     signed: false, | ||||
|                                 }, | ||||
|                             ), | ||||
|                         ), | ||||
|                     loc: Loc { | ||||
|                         file: "parser/loops.mcl", | ||||
|                         line: 1, | ||||
|                         col: 4, | ||||
|                     }, | ||||
|                     body: Block( | ||||
|                         [], | ||||
|                     ), | ||||
|                 }, | ||||
|             ), | ||||
|             Expr( | ||||
|                 WhileLoop { | ||||
|                     test: BinOp { | ||||
|                         typ: Gt, | ||||
|                         left: Path( | ||||
|                             Path( | ||||
|                                 [ | ||||
|                                     Ident( | ||||
|                                         "i", | ||||
|                 ExprBox { | ||||
|                     inner: WhileLoop { | ||||
|                         test: ExprBox { | ||||
|                             inner: BinOp { | ||||
|                                 typ: Gt, | ||||
|                                 left: ExprBox { | ||||
|                                     inner: Path( | ||||
|                                         Path( | ||||
|                                             [ | ||||
|                                                 Ident( | ||||
|                                                     "i", | ||||
|                                                 ), | ||||
|                                             ], | ||||
|                                         ), | ||||
|                                     ), | ||||
|                                 ], | ||||
|                             ), | ||||
|                         ), | ||||
|                         right: Literal( | ||||
|                             Number( | ||||
|                                 Number { | ||||
|                                     val: 3, | ||||
|                                     base: 10, | ||||
|                                     signed: false, | ||||
|                                     loc: Loc { | ||||
|                                         file: "parser/loops.mcl", | ||||
|                                         line: 2, | ||||
|                                         col: 8, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                             ), | ||||
|                                 right: ExprBox { | ||||
|                                     inner: Literal( | ||||
|                                         Number( | ||||
|                                             Number { | ||||
|                                                 val: 3, | ||||
|                                                 base: 10, | ||||
|                                                 signed: false, | ||||
|                                             }, | ||||
|                                         ), | ||||
|                                     ), | ||||
|                                     loc: Loc { | ||||
|                                         file: "parser/loops.mcl", | ||||
|                                         line: 2, | ||||
|                                         col: 12, | ||||
|                                     }, | ||||
|                                 }, | ||||
|                             }, | ||||
|                             loc: Loc { | ||||
|                                 file: "parser/loops.mcl", | ||||
|                                 line: 2, | ||||
|                                 col: 10, | ||||
|                             }, | ||||
|                         }, | ||||
|                         body: Block( | ||||
|                             [], | ||||
|                         ), | ||||
|                     }, | ||||
|                     body: Block( | ||||
|                         [], | ||||
|                     ), | ||||
|                     loc: Loc { | ||||
|                         file: "parser/loops.mcl", | ||||
|                         line: 2, | ||||
|                         col: 6, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Expr( | ||||
|                 InfLoop { | ||||
|                     body: Block( | ||||
|                         [], | ||||
|                     ), | ||||
|                 ExprBox { | ||||
|                     inner: InfLoop { | ||||
|                         body: Block( | ||||
|                             [], | ||||
|                         ), | ||||
|                     }, | ||||
|                     loc: Loc { | ||||
|                         file: "parser/loops.mcl", | ||||
|                         line: 3, | ||||
|                         col: 5, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|         ], | ||||
|  |  | |||
|  | @ -2,33 +2,58 @@ Program { | |||
|     ast: Block( | ||||
|         [ | ||||
|             Statement( | ||||
|                 Struct { | ||||
|                     name: Ident( | ||||
|                         "foo_t", | ||||
|                 StatementBox { | ||||
|                     inner: Struct( | ||||
|                         Struct { | ||||
|                             name: Ident( | ||||
|                                 "foo_t", | ||||
|                             ), | ||||
|                             fields: [], | ||||
|                         }, | ||||
|                     ), | ||||
|                     fields: [], | ||||
|                     loc: Loc { | ||||
|                         file: "parser/structs.mcl", | ||||
|                         line: 2, | ||||
|                         col: 7, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|             Statement( | ||||
|                 Struct { | ||||
|                     name: Ident( | ||||
|                         "bar_t", | ||||
|                     ), | ||||
|                     fields: [ | ||||
|                         ( | ||||
|                             Ident( | ||||
|                                 "a", | ||||
|                 StatementBox { | ||||
|                     inner: Struct( | ||||
|                         Struct { | ||||
|                             name: Ident( | ||||
|                                 "bar_t", | ||||
|                             ), | ||||
|                             Ref { | ||||
|                                 inner: Owned( | ||||
|                             fields: [ | ||||
|                                 ( | ||||
|                                     Ident( | ||||
|                                         "bar_t", | ||||
|                                         "a", | ||||
|                                     ), | ||||
|                                     TypeBox { | ||||
|                                         inner: Ref { | ||||
|                                             inner: Owned( | ||||
|                                                 Ident( | ||||
|                                                     "bar_t", | ||||
|                                                 ), | ||||
|                                             ), | ||||
|                                             mutable: false, | ||||
|                                         }, | ||||
|                                         loc: Loc { | ||||
|                                             file: "parser/structs.mcl", | ||||
|                                             line: 5, | ||||
|                                             col: 9, | ||||
|                                         }, | ||||
|                                     }, | ||||
|                                 ), | ||||
|                                 mutable: false, | ||||
|                             }, | ||||
|                         ), | ||||
|                     ], | ||||
|                             ], | ||||
|                         }, | ||||
|                     ), | ||||
|                     loc: Loc { | ||||
|                         file: "parser/structs.mcl", | ||||
|                         line: 4, | ||||
|                         col: 7, | ||||
|                     }, | ||||
|                 }, | ||||
|             ), | ||||
|         ], | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user