feat(tazjin/rlox): Add support for statements

First part of
https://craftinginterpreters.com/statements-and-state.html

Supports print statements, as well as evaluation for the sake of
it (i.e. future side-effects).

Change-Id: Ic6653b568f98d6cfe3f297615b7113c0ba1d9a70
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2287
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2020-12-20 23:55:40 +01:00 committed by tazjin
parent c3bbb861b8
commit 75ae25daa9
3 changed files with 73 additions and 35 deletions

View file

@ -1,33 +1,25 @@
use crate::errors::{report, Error, ErrorKind};
use crate::parser::{self, Expr, Literal};
use crate::scanner::{self, Token, TokenKind};
use crate::parser::{self, Expr, Literal, Program, Statement};
use crate::scanner::{self, TokenKind};
// Run some Lox code and print it to stdout
pub fn run(code: &str) {
let chars: Vec<char> = code.chars().collect();
match scanner::scan(&chars) {
Ok(tokens) => {
print_tokens(&tokens);
match parser::parse(tokens) {
Ok(expr) => {
println!("Expression:\n{:?}", expr);
println!("Result: {:?}", eval(&expr));
Ok(tokens) => match parser::parse(tokens) {
Ok(program) => {
println!("Program:\n{:?}", program);
if let Err(err) = run_program(&program) {
println!("Error in program: {:?}", err);
}
Err(errors) => report_errors(errors),
}
}
Err(errors) => report_errors(errors),
},
Err(errors) => report_errors(errors),
}
}
fn print_tokens<'a>(tokens: &Vec<Token<'a>>) {
println!("Tokens:");
for token in tokens {
println!("{:?}", token);
}
}
fn report_errors(errors: Vec<Error>) {
for error in errors {
report(&error);
@ -111,3 +103,19 @@ fn eval<'a>(expr: &Expr<'a>) -> Result<Literal, Error> {
Expr::Binary(binary) => eval_binary(binary),
}
}
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)
}
}
}
Ok(())
}