working on function parser
This commit is contained in:
		
					parent
					
						
							
								42e6b66eb5
							
						
					
				
			
			
				commit
				
					
						3200a352d3
					
				
			
		
					 3 changed files with 56 additions and 34 deletions
				
			
		|  | @ -42,5 +42,8 @@ pub enum Expr { | |||
|     // fun helloWorld() { ... }
 | ||||
|     FunctionExpr(Function), | ||||
| 
 | ||||
|     // ->
 | ||||
|     ReturnExpr, | ||||
| 
 | ||||
|     Error, | ||||
| } | ||||
|  |  | |||
|  | @ -145,7 +145,7 @@ pub struct Binary { | |||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct Function { | ||||
|     pub name: String, | ||||
|     pub params: Option<Vec<(Identifier, Type)>>, | ||||
|     pub params: Option<Vec<(String, Type)>>, | ||||
|     pub return_type: Option<Type>, | ||||
|     pub body: Option<BlockExpression>, | ||||
|     pub body_expr: Option<Box<Expr>>, // ' -> (return)'
 | ||||
|  |  | |||
|  | @ -28,13 +28,10 @@ pub fn parse(source: &str) -> Result<Vec<Expr>, Vec<Rich<'_, Token>>> { | |||
|         .spanned() | ||||
|         .map(|(token, span)| (token.unwrap_or(Token::Error), span.into())); | ||||
|     let end_of_input: SimpleSpan = (0..source.len()).into(); | ||||
|     let token_stream = Stream::from_iter(token_iter) | ||||
|         // Tell chumsky to split the (Token, SimpleSpan) stream into its parts so that it can handle the spans for us
 | ||||
|         // This involves giving chumsky an 'end of input' span: we just use a zero-width span at the end of the string
 | ||||
|         .map( | ||||
|             (0..end_of_input.into_iter().len()).into(), | ||||
|             |(t, s): (_, _)| (t, s), | ||||
|         ); | ||||
|     let token_stream = Stream::from_iter(token_iter).map( | ||||
|         (0..end_of_input.into_iter().len()).into(), | ||||
|         |(t, s): (_, _)| (t, s), | ||||
|     ); | ||||
| 
 | ||||
|     parser().parse(token_stream).into_result() | ||||
| } | ||||
|  | @ -120,35 +117,57 @@ where | |||
|                 }) | ||||
|             }); | ||||
| 
 | ||||
|         let type_parser = choice(( | ||||
|             just(Token::IntType).to(Type::Integer), | ||||
|             just(Token::FloatType).to(Type::Float), | ||||
|             just(Token::BoolType).to(Type::Bool), | ||||
|             just(Token::StringType).to(Type::String), | ||||
|         )); | ||||
| 
 | ||||
|         let return_type_parser = just(Token::Colon).ignore_then(type_parser.clone()).or_not(); | ||||
| 
 | ||||
|         //---------------------------------------------------------------------------------------
 | ||||
|         // Function Parser
 | ||||
|         //---------------------------------------------------------------------------------------
 | ||||
|         let fun = just(Token::Fun) | ||||
|             .ignore_then(ident.clone()) | ||||
|             .then_ignore(just(Token::LParen)) | ||||
|             //.then(param_parser().separated_by(just(Token::Comma)).or_not().map(|p| p.unwrap_or_default()))
 | ||||
|             .then_ignore(just(Token::RParen)) | ||||
|             .ignore_then(ident) // function name
 | ||||
|             .then( | ||||
|                 just(Token::LBrace) | ||||
|                     .then_ignore(just(Token::NewLine).or_not()) | ||||
|                     .ignore_then(decl.clone().repeated()) | ||||
|                     .then_ignore(just(Token::RBrace)) | ||||
|                     .map(|stmts| (Some(stmts), None)) | ||||
|                     .or(just(Token::Return) | ||||
|                         .ignore_then(expr.clone()) | ||||
|                         .map(|e| (None, Some(e)))), | ||||
|                 ident | ||||
|                     .then_ignore(just(Token::Colon)) | ||||
|                     .then(type_parser.clone()) | ||||
|                     .separated_by(just(Token::Comma)) | ||||
|                     .allow_trailing() | ||||
|                     .collect::<Vec<_>>() | ||||
|                     .delimited_by(just(Token::LParen), just(Token::RParen)) | ||||
|                     .or_not(), | ||||
|             ) | ||||
|             .then_ignore(just(Token::NewLine).or_not()) | ||||
|             .map(|(name, (body, body_expr))| { | ||||
|             .then(return_type_parser.clone()) | ||||
|             .then_ignore(just(Token::LBrace)) | ||||
|             .then_ignore(just(Token::NewLine).repeated()) | ||||
|             .then( | ||||
|                 expr.clone() | ||||
|                     .then_ignore(just(Token::NewLine)) | ||||
|                     .repeated() | ||||
|                     .collect::<Vec<_>>(), | ||||
|             ) | ||||
|             .then_ignore(just(Token::RBrace)) | ||||
|             .map(|(((name, params), return_ty), stmts)| { | ||||
|                 Expr::FunctionExpr(Function { | ||||
|                     name, | ||||
|                     params: None, | ||||
|                     return_type: None, | ||||
|                     body: None, | ||||
|                     name: name, | ||||
|                     params, | ||||
|                     return_type: return_ty, | ||||
|                     body: Some(stmts), | ||||
|                     body_expr: None, | ||||
|                 }) | ||||
|             }); | ||||
| 
 | ||||
|         var.or(fun).or(expr) | ||||
|     }); | ||||
| 
 | ||||
|     decl.repeated().collect() | ||||
|     decl.clone() | ||||
|         .then_ignore(just(Token::NewLine).repeated()) | ||||
|         .repeated() | ||||
|         .collect() | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
|  | @ -232,9 +251,9 @@ mod tests { | |||
|             empty_fun.clone().unwrap(), | ||||
|             vec![Expr::FunctionExpr(Function { | ||||
|                 name: String::from("helloWorld"), | ||||
|                 params: None, | ||||
|                 params: Some([].to_vec()), | ||||
|                 return_type: None, | ||||
|                 body: None, | ||||
|                 body: Some([].to_vec()), | ||||
|                 body_expr: None, | ||||
|             })] | ||||
|         ); | ||||
|  | @ -250,9 +269,9 @@ mod tests { | |||
|             empty_fun_with_new_lines.clone().unwrap(), | ||||
|             vec![Expr::FunctionExpr(Function { | ||||
|                 name: String::from("emptyMulLines"), | ||||
|                 params: None, | ||||
|                 params: Some([].to_vec()), | ||||
|                 return_type: None, | ||||
|                 body: None, | ||||
|                 body: Some([].to_vec()), | ||||
|                 body_expr: None, | ||||
|             })] | ||||
|         ); | ||||
|  | @ -265,13 +284,13 @@ mod tests { | |||
|         ",
 | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             empty_fun_with_new_lines.clone().unwrap(), | ||||
|             fun_that_returns_int.clone().unwrap(), | ||||
|             vec![Expr::FunctionExpr(Function { | ||||
|                 name: String::from("returnsInt"), | ||||
|                 params: None, | ||||
|                 return_type: Some(Type::Integer), | ||||
|                 body: None, | ||||
|                 body_expr: Some(Box::new(Expr::IntLiteral(12))), | ||||
|                 body: Some(vec![Expr::IntLiteral(12)]), | ||||
|                 body_expr: Some(Box::new(Expr::ReturnExpr)), | ||||
|             })] | ||||
|         ) | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue