diff options
| -rw-r--r-- | crates/sloth/src/main.rs | 9 | ||||
| -rw-r--r-- | crates/sloth/src/parser/mod.rs | 4 | ||||
| -rw-r--r-- | crates/sloth/src/parser/stmt.rs | 92 | ||||
| -rw-r--r-- | examples/guessing.sloth | 4 |
4 files changed, 76 insertions, 33 deletions
diff --git a/crates/sloth/src/main.rs b/crates/sloth/src/main.rs index fd4a1eb..0d33e91 100644 --- a/crates/sloth/src/main.rs +++ b/crates/sloth/src/main.rs @@ -31,5 +31,12 @@ fn main() { }; let tokens = Lexer::new(&source).collect_vec(); - let _parser = AstParser::new(tokens); + // for t in &tokens{ + // println!("{:#?}", t); + // } + let mut parser = AstParser::new(tokens); + // println!("{:#?}", parser); + let parsed = &parser.parse(); + + println!("{:?}", parsed); } diff --git a/crates/sloth/src/parser/mod.rs b/crates/sloth/src/parser/mod.rs index c900168..9d77acc 100644 --- a/crates/sloth/src/parser/mod.rs +++ b/crates/sloth/src/parser/mod.rs @@ -3,7 +3,7 @@ pub mod expr; pub mod stmt; use crate::lexer::{Token, TokenType}; - +#[derive(Debug)] pub struct AstParser<'a> { tokens: Vec<Token<'a>>, index: usize, @@ -46,7 +46,7 @@ impl<'a> AstParser<'a> { pub fn consume(&mut self, next: TokenType, error: &str) { if std::mem::discriminant(&self.peek().tt) != std::mem::discriminant(&next) { - panic!("{error}"); + panic!("{error} at index {:?}", self.index); } self.advance(); } diff --git a/crates/sloth/src/parser/stmt.rs b/crates/sloth/src/parser/stmt.rs index 9049f6c..c35c4e3 100644 --- a/crates/sloth/src/parser/stmt.rs +++ b/crates/sloth/src/parser/stmt.rs @@ -52,7 +52,7 @@ impl<'a> AstParser<'a> { }; self.advance(); // Advancing from the identifier TODO: Check for type - self.consume(TokenType::Eq, "Expected '=' after identifier"); + self.consume(TokenType::Eq, "Expected '=' after identifier at "); let value = self.expression(); @@ -95,7 +95,7 @@ impl<'a> AstParser<'a> { while !self.eof() && self.peek().tt != TokenType::ClosingBrace { body.push(self.statement()); } - + self.advance(); Stmt::If { expr: (condition), body: (body), @@ -141,7 +141,7 @@ impl<'a> AstParser<'a> { while !self.eof() && self.peek().tt != TokenType::ClosingBrace { body.push(self.statement()); } - + self.advance(); Stmt::While { condition, body } } @@ -215,7 +215,7 @@ mod tests { use super::{AstParser, Stmt}; use crate::lexer::Lexer; - use crate::parser::ast::{BinaryOp, Expr, FuncArgs, Literal}; + use crate::parser::ast::{BinaryOp, Expr, FuncArgs, Literal, UnaryOp}; #[test] fn basic_statement_a() { @@ -307,16 +307,33 @@ mod tests { } #[test] fn basic_statement_d() { - let lexer = Lexer::new("while true {\nprint(\"Hello World\");}"); + let lexer = Lexer::new("while true {\nprint(\"Hello World\");\n\nprintln(5 + 7/-3);}"); let tokens = lexer.collect_vec(); println!("{tokens:?}"); let expected_ast = Stmt::While { condition: (Expr::Literal(Literal::Bool(true))), - body: (vec![Stmt::ExprStmt(Expr::Call { - ident: (Box::new(Expr::Literal(Literal::String("print".to_string())))), - args: (vec![Expr::Literal(Literal::String("Hello World".to_string()))]), - })]), + body: (vec![ + Stmt::ExprStmt(Expr::Call { + ident: (Box::new(Expr::Literal(Literal::String("print".to_string())))), + args: (vec![Expr::Literal(Literal::String("Hello World".to_string()))]), + }), + Stmt::ExprStmt(Expr::Call { + ident: (Box::new(Expr::Literal(Literal::String("println".to_string())))), + args: (vec![Expr::BinaryOp { + op: (BinaryOp::Add), + lhs: (Box::new(Expr::Literal(Literal::Integer(5)))), + rhs: (Box::new(Expr::BinaryOp { + op: (BinaryOp::Div), + lhs: (Box::new(Expr::Literal(Literal::Integer(7)))), + rhs: (Box::new(Expr::UnaryOp { + op: (UnaryOp::Neg), + value: (Box::new(Expr::Literal(Literal::Integer(3)))), + })), + })), + }]), + }), + ]), }; let mut parser = AstParser::new(tokens); @@ -329,30 +346,49 @@ mod tests { } #[test] fn basic_statement_e() { - let lexer = Lexer::new("if a+5 > 10 {\nprint(a);\n}"); + let lexer = Lexer::new("if a+5 > 10 {\nprint(a);\n}\nif a+5 < 10 {\nprint(10);\n}"); let tokens = lexer.collect_vec(); println!("{tokens:?}"); - let expected_ast = Stmt::If { - expr: (Expr::BinaryOp { - op: (BinaryOp::Gt), - lhs: (Box::new(Expr::BinaryOp { - op: (BinaryOp::Add), - lhs: (Box::new(Expr::Variable("a".to_string()))), - rhs: (Box::new(Expr::Literal(Literal::Integer(5)))), - })), - rhs: (Box::new(Expr::Literal(Literal::Integer(10)))), - }), - body: (vec![Stmt::ExprStmt(Expr::Call { - ident: (Box::new(Expr::Literal(Literal::String("print".to_string())))), - args: (vec![Expr::Variable("a".to_string())]), - })]), - else_if: (Vec::new()), - els: (None), - }; + let expected_ast = vec![ + Stmt::If { + expr: (Expr::BinaryOp { + op: (BinaryOp::Gt), + lhs: (Box::new(Expr::BinaryOp { + op: (BinaryOp::Add), + lhs: (Box::new(Expr::Variable("a".to_string()))), + rhs: (Box::new(Expr::Literal(Literal::Integer(5)))), + })), + rhs: (Box::new(Expr::Literal(Literal::Integer(10)))), + }), + body: (vec![Stmt::ExprStmt(Expr::Call { + ident: (Box::new(Expr::Literal(Literal::String("print".to_string())))), + args: (vec![Expr::Variable("a".to_string())]), + })]), + else_if: (Vec::new()), + els: (None), + }, + Stmt::If { + expr: (Expr::BinaryOp { + op: (BinaryOp::Lt), + lhs: (Box::new(Expr::BinaryOp { + op: (BinaryOp::Add), + lhs: (Box::new(Expr::Variable("a".to_string()))), + rhs: (Box::new(Expr::Literal(Literal::Integer(5)))), + })), + rhs: (Box::new(Expr::Literal(Literal::Integer(10)))), + }), + body: (vec![Stmt::ExprStmt(Expr::Call { + ident: (Box::new(Expr::Literal(Literal::String("print".to_string())))), + args: (vec![Expr::Literal(Literal::Integer(10))]), + })]), + else_if: (Vec::new()), + els: (None), + }, + ]; let mut parser = AstParser::new(tokens); - let generated_ast = parser.statement(); + let generated_ast = parser.parse(); println!("Expected AST:\n{expected_ast:#?}\n\n"); println!("Generated AST:\n{generated_ast:#?}\n\n"); diff --git a/examples/guessing.sloth b/examples/guessing.sloth index 1938269..01f0796 100644 --- a/examples/guessing.sloth +++ b/examples/guessing.sloth @@ -9,7 +9,7 @@ while !correct { if human == computer { println("You guessed the same number as me!"); - correct = true; + var correct = true; } if human > computer { @@ -20,7 +20,7 @@ while !correct { println("Your guess was too low."); } - tries = tries + 1; + var tries = tries + 1; } println("\nIt took you ", tries, " tries to guess correctly!"); |
