Refactor Ast to ScopedBlock
This commit is contained in:
parent
cbea567d65
commit
4dbc3adfd5
11
src/ast.rs
11
src/ast.rs
@ -97,7 +97,7 @@ pub struct Loop {
|
|||||||
/// This is executed after each loop to advance the condition variables
|
/// This is executed after each loop to advance the condition variables
|
||||||
pub advancement: Option<Expression>,
|
pub advancement: Option<Expression>,
|
||||||
/// The loop body that is executed each loop
|
/// The loop body that is executed each loop
|
||||||
pub body: Ast,
|
pub body: BlockScope,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
@ -105,9 +105,9 @@ pub struct If {
|
|||||||
/// The condition
|
/// The condition
|
||||||
pub condition: Expression,
|
pub condition: Expression,
|
||||||
/// The body that is executed when condition is true
|
/// The body that is executed when condition is true
|
||||||
pub body_true: Ast,
|
pub body_true: BlockScope,
|
||||||
/// The if body that is executed when the condition is false
|
/// The if body that is executed when the condition is false
|
||||||
pub body_false: Ast,
|
pub body_false: BlockScope,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
@ -118,10 +118,7 @@ pub enum Statement {
|
|||||||
Print(Expression),
|
Print(Expression),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Default)]
|
pub type BlockScope = Vec<Statement>;
|
||||||
pub struct Ast {
|
|
||||||
pub prog: Vec<Statement>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BinOpType {
|
impl BinOpType {
|
||||||
/// Get the precedence for a binary operator. Higher value means the OP is stronger binding.
|
/// Get the precedence for a binary operator. Higher value means the OP is stronger binding.
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use std::{fmt::Display, rc::Rc};
|
use std::{fmt::Display, rc::Rc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Ast, BinOpType, Expression, If, Statement, UnOpType},
|
ast::{BlockScope, BinOpType, Expression, If, Statement, UnOpType},
|
||||||
lexer::lex,
|
lexer::lex,
|
||||||
parser::parse,
|
parser::parse,
|
||||||
};
|
};
|
||||||
@ -63,9 +63,9 @@ impl Interpreter {
|
|||||||
self.run(&ast);
|
self.run(&ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self, prog: &Ast) {
|
pub fn run(&mut self, prog: &BlockScope) {
|
||||||
let vartable_len = self.vartable.len();
|
let vartable_len = self.vartable.len();
|
||||||
for stmt in &prog.prog {
|
for stmt in prog {
|
||||||
match stmt {
|
match stmt {
|
||||||
Statement::Expr(expr) => {
|
Statement::Expr(expr) => {
|
||||||
self.resolve_expr(expr);
|
self.resolve_expr(expr);
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use crate::ast::*;
|
|||||||
use crate::token::Token;
|
use crate::token::Token;
|
||||||
|
|
||||||
/// Parse the given tokens into an abstract syntax tree
|
/// Parse the given tokens into an abstract syntax tree
|
||||||
pub fn parse<T: Iterator<Item = Token>, A: IntoIterator<IntoIter = T>>(tokens: A) -> Ast {
|
pub fn parse<T: Iterator<Item = Token>, A: IntoIterator<IntoIter = T>>(tokens: A) -> BlockScope {
|
||||||
let mut parser = Parser::new(tokens);
|
let mut parser = Parser::new(tokens);
|
||||||
parser.parse()
|
parser.parse()
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
|
|||||||
|
|
||||||
/// Parse tokens into an abstract syntax tree. This will continuously parse statements until
|
/// Parse tokens into an abstract syntax tree. This will continuously parse statements until
|
||||||
/// encountering end-of-file or a block end '}' .
|
/// encountering end-of-file or a block end '}' .
|
||||||
fn parse(&mut self) -> Ast {
|
fn parse(&mut self) -> BlockScope {
|
||||||
let mut prog = Vec::new();
|
let mut prog = Vec::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -37,7 +37,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast { prog }
|
prog
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a single statement from the tokens.
|
/// Parse a single statement from the tokens.
|
||||||
@ -92,7 +92,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
|
|||||||
panic!("Error lexing if: Expected '}}'")
|
panic!("Error lexing if: Expected '}}'")
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut body_false = Ast::default();
|
let mut body_false = BlockScope::default();
|
||||||
|
|
||||||
if matches!(self.peek(), Token::Else) {
|
if matches!(self.peek(), Token::Else) {
|
||||||
self.next();
|
self.next();
|
||||||
@ -249,7 +249,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::{parse, BinOpType, Expression};
|
use super::{parse, BinOpType, Expression};
|
||||||
use crate::{
|
use crate::{
|
||||||
parser::{Ast, Statement},
|
parser::Statement,
|
||||||
token::Token,
|
token::Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -284,9 +284,7 @@ mod tests {
|
|||||||
Expression::I64(4).into(),
|
Expression::I64(4).into(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let expected = Ast {
|
let expected = vec![expected];
|
||||||
prog: vec![expected],
|
|
||||||
};
|
|
||||||
|
|
||||||
let actual = parse(tokens);
|
let actual = parse(tokens);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user