aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/sloth/src/main.rs9
-rw-r--r--crates/sloth/src/parser/mod.rs4
-rw-r--r--crates/sloth/src/parser/stmt.rs92
-rw-r--r--examples/guessing.sloth4
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!");