We have parentheticals
This commit is contained in:
+18
-3
@@ -9,6 +9,11 @@ enum VarType {
|
||||
//Mut,
|
||||
}
|
||||
|
||||
enum BlockType {
|
||||
Block,
|
||||
Parenthetical,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterpreterError {
|
||||
description: String,
|
||||
@@ -64,7 +69,7 @@ macro_rules! apply_op {
|
||||
|
||||
type Scope = HashMap<String, VarType>;
|
||||
|
||||
fn interpret_block(ast: Vec<ASTNode>, scopes: &mut Vec<Scope>) -> Result<Vec<Value>, InterpreterError> {
|
||||
fn interpret_block(ast: Vec<ASTNode>, scopes: &mut Vec<Scope>, block_type: BlockType) -> Result<Vec<Value>, InterpreterError> {
|
||||
let mut ast = ast.clone();
|
||||
ast.reverse();
|
||||
let mut stack = vec![];
|
||||
@@ -74,10 +79,14 @@ fn interpret_block(ast: Vec<ASTNode>, scopes: &mut Vec<Scope>) -> Result<Vec<Val
|
||||
None => return Ok(stack),
|
||||
Some(ASTNode::Block(tokens)) => {
|
||||
scopes.push(HashMap::new());
|
||||
let mut result = interpret_block(tokens, scopes)?;
|
||||
let mut result = interpret_block(tokens, scopes, BlockType::Block)?;
|
||||
scopes.pop();
|
||||
stack.append(&mut result);
|
||||
},
|
||||
Some(ASTNode::Parenthetical(tokens)) => {
|
||||
let mut result = interpret_block(tokens, scopes, BlockType::Parenthetical)?;
|
||||
stack.append(&mut result);
|
||||
},
|
||||
Some(ASTNode::Val(v)) => stack.push(v),
|
||||
Some(ASTNode::BinOp(op)) => {
|
||||
let b = some_or_error!(stack.pop(), InterpreterError::new("right value needed"));
|
||||
@@ -110,6 +119,9 @@ fn interpret_block(ast: Vec<ASTNode>, scopes: &mut Vec<Scope>) -> Result<Vec<Val
|
||||
}));
|
||||
},
|
||||
Some(ASTNode::ConstDecl) => {
|
||||
if let BlockType::Parenthetical = block_type {
|
||||
return Err(InterpreterError::new("let bindings not allowed in parenthetical"));
|
||||
}
|
||||
let rhs = some_or_error!(stack.pop(), InterpreterError::new("rhs value needed"));
|
||||
let lhs = some_or_error!(stack.pop(), InterpreterError::new("lhs value needed"));
|
||||
let rhs: TeaValue = get_value(rhs, scopes)?;
|
||||
@@ -126,6 +138,9 @@ fn interpret_block(ast: Vec<ASTNode>, scopes: &mut Vec<Scope>) -> Result<Vec<Val
|
||||
}
|
||||
},
|
||||
Some(ASTNode::StatementEnd) => {
|
||||
if let BlockType::Parenthetical = block_type {
|
||||
return Err(InterpreterError::new("statements not allowed in parenthetical"));
|
||||
}
|
||||
if !stack.is_empty() {
|
||||
return Err(InterpreterError::new("stack not empty"));
|
||||
}
|
||||
@@ -136,5 +151,5 @@ fn interpret_block(ast: Vec<ASTNode>, scopes: &mut Vec<Scope>) -> Result<Vec<Val
|
||||
|
||||
pub fn interpret(ast: Vec<ASTNode>) -> Result<Vec<Value>, InterpreterError> {
|
||||
let mut scopes = vec![HashMap::new()];
|
||||
interpret_block(ast, &mut scopes)
|
||||
interpret_block(ast, &mut scopes, BlockType::Block)
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@ pub fn lex_tokens(s: &str) -> Result<Vec<Token>, (Vec<Token>, &str)> {
|
||||
let mut tokens: Vec<Token> = vec![];
|
||||
loop {
|
||||
if input.is_empty() {
|
||||
println!("tokens: {tokens:?}\n\n");
|
||||
return Ok(tokens);
|
||||
}
|
||||
try_parse!(parse_literal(input), tokens, input);
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ pub enum ASTNode {
|
||||
UnaryMinus,
|
||||
StatementEnd,
|
||||
Block(Vec<ASTNode>),
|
||||
Parenthetical(Vec<ASTNode>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -153,7 +154,7 @@ fn parse_expr(tokens: &[Token]) -> Result<(Vec<ASTNode>, usize), ParseError> {
|
||||
Some(Token::Sym(Symbol::OpenParen)) => {
|
||||
let end = next_paren_end(&tokens[(index + 1)..])?;
|
||||
let (expr, count) = parse_expr(&tokens[(index + 1)..(index + end + 1)])?;
|
||||
ast.push(ASTNode::Block(expr));
|
||||
ast.push(ASTNode::Parenthetical(expr));
|
||||
index += count + 1;
|
||||
},
|
||||
Some(Token::Sym(Symbol::CloseParen)) => {
|
||||
|
||||
+1
-7
@@ -1,8 +1,2 @@
|
||||
|
||||
let x = 5;
|
||||
let y = {
|
||||
let x = -x;
|
||||
x + 1 * -x
|
||||
};
|
||||
x + y
|
||||
|
||||
(5 + 6) * 4
|
||||
|
||||
Reference in New Issue
Block a user