about summary refs log tree commit diff
path: root/users/tazjin
diff options
context:
space:
mode:
Diffstat (limited to 'users/tazjin')
-rw-r--r--users/tazjin/rlox/src/interpreter.rs28
-rw-r--r--users/tazjin/rlox/src/parser.rs23
2 files changed, 36 insertions, 15 deletions
diff --git a/users/tazjin/rlox/src/interpreter.rs b/users/tazjin/rlox/src/interpreter.rs
index c68101cf68a6..5e43e075b03c 100644
--- a/users/tazjin/rlox/src/interpreter.rs
+++ b/users/tazjin/rlox/src/interpreter.rs
@@ -1,5 +1,5 @@
 use crate::errors::{report, Error, ErrorKind};
-use crate::parser::{self, Expr, Literal, Program, Statement};
+use crate::parser::{self, Declaration, Expr, Literal, Program, Statement};
 use crate::scanner::{self, TokenKind};
 
 // Run some Lox code and print it to stdout
@@ -104,16 +104,24 @@ fn eval<'a>(expr: &Expr<'a>) -> Result<Literal, Error> {
     }
 }
 
+fn run_stmt<'a>(stmt: &Statement<'a>) -> Result<(), Error> {
+    match stmt {
+        Statement::Expr(expr) => {
+            eval(expr)?;
+        }
+        Statement::Print(expr) => {
+            let result = eval(expr)?;
+            println!("{:?}", result)
+        }
+    }
+
+    Ok(())
+}
+
 fn run_program<'a>(program: &Program<'a>) -> Result<(), Error> {
-    for stmt in program {
-        match stmt {
-            Statement::Expr(expr) => {
-                eval(expr)?;
-            }
-            Statement::Print(expr) => {
-                let result = eval(expr)?;
-                println!("{:?}", result)
-            }
+    for decl in program {
+        match decl {
+            Declaration::Stmt(stmt) => run_stmt(stmt)?,
         }
     }
 
diff --git a/users/tazjin/rlox/src/parser.rs b/users/tazjin/rlox/src/parser.rs
index d7155fff10a7..91000db9dd90 100644
--- a/users/tazjin/rlox/src/parser.rs
+++ b/users/tazjin/rlox/src/parser.rs
@@ -48,12 +48,20 @@ pub enum Statement<'a> {
     Print(Expr<'a>),
 }
 
-pub type Program<'a> = Vec<Statement<'a>>;
+#[derive(Debug)]
+pub enum Declaration<'a> {
+    Stmt(Statement<'a>),
+}
+
+pub type Program<'a> = Vec<Declaration<'a>>;
 
 // Parser
 
 /*
-program        → statement* EOF ;
+program        → declaration* EOF ;
+
+declaration    → varDecl
+               | statement ;
 
 statement      → exprStmt
                | printStmt ;
@@ -79,10 +87,15 @@ struct Parser<'a> {
 
 type ExprResult<'a> = Result<Expr<'a>, Error>;
 type StmtResult<'a> = Result<Statement<'a>, Error>;
+type DeclResult<'a> = Result<Declaration<'a>, Error>;
 
 impl<'a> Parser<'a> {
     // recursive-descent parser functions
 
+    fn declaration(&mut self) -> DeclResult<'a> {
+        Ok(Declaration::Stmt(self.statement()?))
+    }
+
     fn statement(&mut self) -> StmtResult<'a> {
         if self.match_token(&[TokenKind::Print]) {
             self.print_statement()
@@ -274,13 +287,13 @@ pub fn parse<'a>(tokens: Vec<Token<'a>>) -> Result<Program<'a>, Vec<Error>> {
     let mut errors: Vec<Error> = vec![];
 
     while !parser.is_at_end() {
-        match parser.statement() {
+        match parser.declaration() {
             Err(err) => {
                 errors.push(err);
                 parser.synchronise();
             }
-            Ok(stmt) => {
-                program.push(stmt);
+            Ok(decl) => {
+                program.push(decl);
             }
         }
     }