Add function calls to parsing, also Top Level Expressions
This commit is contained in:
		
							parent
							
								
									ee14e18787
								
							
						
					
					
						commit
						42e74f49f8
					
				| @ -8,4 +8,5 @@ let arithmetic = 3 + 2 * 5 + 1 * 2; | |||||||
| let multiplier = 5 * 2; | let multiplier = 5 * 2; | ||||||
| 
 | 
 | ||||||
| let result = arithmetic + multiplier * arithmetic; | let result = arithmetic + multiplier * arithmetic; | ||||||
| print(result); | print(result); | ||||||
|  | function(one, two); | ||||||
| @ -70,6 +70,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Strin | |||||||
|             '*' => Token::Times, |             '*' => Token::Times, | ||||||
|             '(' => Token::ParenOpen, |             '(' => Token::ParenOpen, | ||||||
|             ')' => Token::ParenClose, |             ')' => Token::ParenClose, | ||||||
|  |             ',' => Token::Comma, | ||||||
|             // Invalid token
 |             // Invalid token
 | ||||||
|             _ => Err(format!( |             _ => Err(format!( | ||||||
|                 "Unknown token '{}' at {}, {}", |                 "Unknown token '{}' at {}, {}", | ||||||
| @ -112,6 +113,7 @@ pub enum Token { | |||||||
|     Times, |     Times, | ||||||
|     ParenOpen,  // (
 |     ParenOpen,  // (
 | ||||||
|     ParenClose, // )
 |     ParenClose, // )
 | ||||||
|  |     Comma, | ||||||
| 
 | 
 | ||||||
|     Eof, |     Eof, | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| use crate::{lexer::Token, token_stream::TokenStream}; | use crate::{lexer::Token, token_stream::TokenStream}; | ||||||
| 
 | 
 | ||||||
| pub trait Parseable | pub trait Parse | ||||||
| where | where | ||||||
|     Self: std::marker::Sized, |     Self: std::marker::Sized, | ||||||
| { | { | ||||||
| @ -13,9 +13,10 @@ pub enum Expression { | |||||||
|     ContantI32(i32), |     ContantI32(i32), | ||||||
|     BinopAdd(Box<Expression>, Box<Expression>), |     BinopAdd(Box<Expression>, Box<Expression>), | ||||||
|     BinopMult(Box<Expression>, Box<Expression>), |     BinopMult(Box<Expression>, Box<Expression>), | ||||||
|  |     FunctionCall(Box<FunctionCallExpression>), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Parseable for Expression { | impl Parse for Expression { | ||||||
|     fn parse(mut stream: TokenStream) -> Result<Expression, ()> { |     fn parse(mut stream: TokenStream) -> Result<Expression, ()> { | ||||||
|         let lhs = parse_primary_expression(&mut stream)?; |         let lhs = parse_primary_expression(&mut stream)?; | ||||||
|         parse_binop_rhs(&mut stream, lhs, 0) |         parse_binop_rhs(&mut stream, lhs, 0) | ||||||
| @ -23,14 +24,16 @@ impl Parseable for Expression { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn parse_primary_expression(stream: &mut TokenStream) -> Result<Expression, ()> { | fn parse_primary_expression(stream: &mut TokenStream) -> Result<Expression, ()> { | ||||||
|     if let Some(token) = stream.next() { |     if let Ok(exp) = stream.parse() { | ||||||
|  |         Ok(Expression::FunctionCall(Box::new(exp))) | ||||||
|  |     } else if let Some(token) = stream.next() { | ||||||
|         Ok(match &token { |         Ok(match &token { | ||||||
|             Token::Identifier(v) => Expression::VariableName(v.clone()), |             Token::Identifier(v) => Expression::VariableName(v.clone()), | ||||||
|             Token::DecimalValue(v) => Expression::ContantI32(v.parse().unwrap()), |             Token::DecimalValue(v) => Expression::ContantI32(v.parse().unwrap()), | ||||||
|             _ => Err(())?, |             _ => Err(())?, // TODO: Add error raporting!
 | ||||||
|         }) |         }) | ||||||
|     } else { |     } else { | ||||||
|         Err(()) |         Err(()) // TODO: Add error raporting!
 | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -66,7 +69,7 @@ fn parse_binop_rhs( | |||||||
|             lhs = match &token { |             lhs = match &token { | ||||||
|                 Token::Plus => Expression::BinopAdd(Box::new(lhs), Box::new(rhs)), |                 Token::Plus => Expression::BinopAdd(Box::new(lhs), Box::new(rhs)), | ||||||
|                 Token::Times => Expression::BinopMult(Box::new(lhs), Box::new(rhs)), |                 Token::Times => Expression::BinopMult(Box::new(lhs), Box::new(rhs)), | ||||||
|                 _ => Err(())?, |                 _ => Err(())?, // TODO: Add error raporting!
 | ||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -74,18 +77,53 @@ fn parse_binop_rhs( | |||||||
|     Ok(lhs) |     Ok(lhs) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(Debug, Clone)] | ||||||
|  | pub struct FunctionCallExpression(String, Vec<Expression>); | ||||||
|  | 
 | ||||||
|  | impl Parse for FunctionCallExpression { | ||||||
|  |     fn parse(mut stream: TokenStream) -> Result<Self, ()> { | ||||||
|  |         if let Some(Token::Identifier(name)) = stream.next() { | ||||||
|  |             stream.expect(Token::ParenOpen)?; | ||||||
|  | 
 | ||||||
|  |             let mut args = Vec::new(); | ||||||
|  | 
 | ||||||
|  |             if let Ok(exp) = stream.parse() { | ||||||
|  |                 args.push(exp); | ||||||
|  | 
 | ||||||
|  |                 while stream.expect(Token::Comma).is_ok() { | ||||||
|  |                     args.push(stream.parse()?); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             stream.expect(Token::ParenClose)?; | ||||||
|  | 
 | ||||||
|  |             Ok(FunctionCallExpression(name, args)) | ||||||
|  |         } else { | ||||||
|  |             Err(())? // TODO: Add error raporting!
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub enum TopLevelStatement { | pub enum TopLevelStatement { | ||||||
|     Let(LetStatement), |     Let(LetStatement), | ||||||
|     Import(ImportStatement), |     Import(ImportStatement), | ||||||
|  |     TLExpression(Expression), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Parseable for TopLevelStatement { | impl Parse for TopLevelStatement { | ||||||
|     fn parse(mut stream: TokenStream) -> Result<Self, ()> { |     fn parse(mut stream: TokenStream) -> Result<Self, ()> { | ||||||
|         Ok(match stream.peek() { |         Ok(match stream.peek() { | ||||||
|             Some(Token::LetKeyword) => TopLevelStatement::Let(stream.parse()?), |             Some(Token::LetKeyword) => TopLevelStatement::Let(stream.parse()?), | ||||||
|             Some(Token::ImportKeyword) => TopLevelStatement::Import(stream.parse()?), |             Some(Token::ImportKeyword) => TopLevelStatement::Import(stream.parse()?), | ||||||
|             _ => Err(())?, |             _ => { | ||||||
|  |                 if let Ok(e) = stream.parse() { | ||||||
|  |                     stream.expect(Token::Semicolon)?; | ||||||
|  |                     TopLevelStatement::TLExpression(e) | ||||||
|  |                 } else { | ||||||
|  |                     Err(())? // TODO: Add error raporting!
 | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -93,7 +131,7 @@ impl Parseable for TopLevelStatement { | |||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct LetStatement(String, Expression); | pub struct LetStatement(String, Expression); | ||||||
| 
 | 
 | ||||||
| impl Parseable for LetStatement { | impl Parse for LetStatement { | ||||||
|     fn parse(mut stream: TokenStream) -> Result<LetStatement, ()> { |     fn parse(mut stream: TokenStream) -> Result<LetStatement, ()> { | ||||||
|         stream.expect(Token::LetKeyword)?; |         stream.expect(Token::LetKeyword)?; | ||||||
| 
 | 
 | ||||||
| @ -104,7 +142,7 @@ impl Parseable for LetStatement { | |||||||
|             stream.expect(Token::Semicolon)?; |             stream.expect(Token::Semicolon)?; | ||||||
|             Ok(LetStatement(variable, expression)) |             Ok(LetStatement(variable, expression)) | ||||||
|         } else { |         } else { | ||||||
|             Err(()) |             Err(()) // TODO: Add error raporting!
 | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -112,7 +150,7 @@ impl Parseable for LetStatement { | |||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct ImportStatement(Vec<String>); | pub struct ImportStatement(Vec<String>); | ||||||
| 
 | 
 | ||||||
| impl Parseable for ImportStatement { | impl Parse for ImportStatement { | ||||||
|     fn parse(mut stream: TokenStream) -> Result<Self, ()> { |     fn parse(mut stream: TokenStream) -> Result<Self, ()> { | ||||||
|         stream.expect(Token::ImportKeyword)?; |         stream.expect(Token::ImportKeyword)?; | ||||||
| 
 | 
 | ||||||
| @ -124,11 +162,11 @@ impl Parseable for ImportStatement { | |||||||
|                 if let Some(Token::Identifier(name)) = stream.next() { |                 if let Some(Token::Identifier(name)) = stream.next() { | ||||||
|                     import_list.push(name); |                     import_list.push(name); | ||||||
|                 } else { |                 } else { | ||||||
|                     Err(())? |                     Err(())? // TODO: Add error raporting!
 | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             Err(())? |             Err(())? // TODO: Add error raporting!
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         stream.expect(Token::Semicolon)?; |         stream.expect(Token::Semicolon)?; | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| use crate::{ | use crate::{ | ||||||
|     lexer::{FullToken, Token}, |     lexer::{FullToken, Token}, | ||||||
|     parser::Parseable, |     parser::Parse, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| pub struct TokenStream<'a, 'b> { | pub struct TokenStream<'a, 'b> { | ||||||
| @ -49,7 +49,7 @@ impl<'a, 'b> TokenStream<'a, 'b> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn parse<T: Parseable>(&mut self) -> Result<T, ()> { |     pub fn parse<T: Parse>(&mut self) -> Result<T, ()> { | ||||||
|         let mut ref_pos = self.position; |         let mut ref_pos = self.position; | ||||||
| 
 | 
 | ||||||
|         let position = self.position; |         let position = self.position; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user