diff --git a/src/env.rs b/src/env.rs index 129cebb..95a47be 100644 --- a/src/env.rs +++ b/src/env.rs @@ -1,4 +1,7 @@ -use std::{collections::HashMap, sync::{Arc, RwLock}}; +use std::{ + collections::HashMap, + sync::{Arc, RwLock}, +}; use crate::value::Value; @@ -11,7 +14,7 @@ pub struct Env<'env> { impl Env<'_> { pub fn new() -> Self { Env { - values: Default::default(), + values: Arc::default(), parent: None, } } @@ -58,7 +61,7 @@ impl Default for Env<'_> { impl<'env> Env<'env> { pub fn new_with_parent(parent: &'env Env<'env>) -> Self { Env { - values: Default::default(), + values: Arc::default(), parent: Some(parent), } } diff --git a/src/function/function_impl.rs b/src/function/function_impl.rs index 94e0624..1e8f01d 100644 --- a/src/function/function_impl.rs +++ b/src/function/function_impl.rs @@ -14,7 +14,7 @@ macro_rules! impl_function { let total_count = { let mut count = 0; $( - let _: Option<$ty> = None; + let _n: Option<$ty> = None; count += 1; )* count @@ -44,7 +44,7 @@ macro_rules! impl_function { let total_count = { let mut count = 0; $( - let _: Option<$ty> = None; + let _n: Option<$ty> = None; count += 1; )* count @@ -79,7 +79,7 @@ macro_rules! impl_ref_function { let total_count = { let mut count = 1; $( - let _: Option<$ty> = None; + let _n: Option<$ty> = None; count += 1; )* count @@ -114,7 +114,7 @@ macro_rules! impl_ref_function { let total_count = { let mut count = 1; $( - let _: Option<$ty> = None; + let _n: Option<$ty> = None; count += 1; )* count diff --git a/src/function/mod.rs b/src/function/mod.rs index ffd4d2a..46e66ad 100644 --- a/src/function/mod.rs +++ b/src/function/mod.rs @@ -20,7 +20,7 @@ pub struct FunctionMap(HashMap, FunctionType)>); impl FunctionMap { pub fn new() -> Self { - Default::default() + FunctionMap::default() } pub fn insert_native(&mut self, name: S, f: F) @@ -107,7 +107,7 @@ impl Function for InterpreterFunction { for (name, value) in self.parameters.iter().zip(args) { sub_env.set_here(name, value.clone()); } - for stmt in self.body.iter() { + for stmt in &self.body { stmt.eval(&sub_env, map); } Ok(Value::Nothing) diff --git a/src/main.rs b/src/main.rs index 8a596f7..57e1912 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,9 +15,9 @@ mod value; // mod parser; mod pest_parser; -fn run(functions: FunctionMap, statement: Statement) { +fn run(functions: &FunctionMap, statement: &Statement) { let env = Env::new(); - statement.eval(&env, &functions); + statement.eval(&env, functions); } #[derive(Clone, Debug, PartialEq, Eq)] @@ -59,7 +59,7 @@ fn functions(&self) -> Option { fn main() { let f = read_to_string("./test.foo").unwrap(); - let (res, funcs) = pest_parser::parse(f); + let (res, funcs) = pest_parser::parse(&f); let mut m = FunctionMap::new(); m.insert_holder(funcs); m.insert_native("print", |a: &Value| { @@ -68,5 +68,5 @@ fn main() { m.insert_native("waluigi", || "Waluigi"); m.insert_native("native_test", || Foo { x: 41 }); - run(m, res); + run(&m, &res); } diff --git a/src/pest_parser.rs b/src/pest_parser.rs index 1b310df..9118fb6 100644 --- a/src/pest_parser.rs +++ b/src/pest_parser.rs @@ -7,7 +7,7 @@ use crate::{expression::Expression, statement::Statement, value::Value}; #[grammar = "grammar.pest"] pub struct LangParser; -pub fn parse(source: S) -> (Statement, FuncHolder) { +pub fn parse(source: &S) -> (Statement, FuncHolder) { let source = source.to_string(); let pairs = LangParser::parse(Rule::root_statement, &source).unwrap(); handle_rules(pairs) @@ -53,222 +53,179 @@ impl IntoIterator for FuncHolder { } fn handle_rules(mut p: pest::iterators::Pairs) -> (Statement, FuncHolder) { - fn parse_statement(pair: Pair) -> (Statement, FuncHolder) { - match pair.as_rule() { - Rule::root_statement => { - let (z, f) = pair.into_inner().map(parse_statement).unzip(); - (Statement::Body(z), f) - } - Rule::while_block => { - let mut inner = pair.into_inner(); - let expr = inner.next().unwrap(); - let body = inner.next().unwrap(); - ( - Statement::While(parse_expression(expr), Box::new(parse_statement(body).0)), - FuncHolder::default(), - ) - } - Rule::if_block => { - let mut inner = pair.into_inner(); - let mut the_list = vec![]; - let mut the_else = None; - while let Some(expr) = inner.next() { - if expr.as_rule() == Rule::expression { - let body = inner.next().unwrap(); - the_list.push((parse_expression(expr), parse_statement(body).0)); - } else { - the_else = Some(Box::new(parse_statement(expr).0)); - } - } - (Statement::If(the_list, the_else), FuncHolder::default()) - } - Rule::assignment => { - let mut inner = pair.into_inner(); - let name = inner.next().unwrap(); - let expr = inner.next().unwrap(); - ( - Statement::Assignment(name.as_str().to_string(), parse_expression(expr), false), - FuncHolder::default(), - ) - } - Rule::assignment_let => { - let mut inner = pair.into_inner(); - let name = inner.next().unwrap(); - let expr = inner.next().unwrap(); - ( - Statement::Assignment(name.as_str().to_string(), parse_expression(expr), true), - FuncHolder::default(), - ) - } - Rule::expression => ( - Statement::Expression(parse_expression(pair)), + let z = p.next().unwrap(); + parse_statement(z) +} + +fn parse_statement(pair: Pair) -> (Statement, FuncHolder) { + match pair.as_rule() { + Rule::root_statement => { + let (z, f) = pair.into_inner().map(parse_statement).unzip(); + (Statement::Body(z), f) + } + Rule::while_block => { + let mut inner = pair.into_inner(); + let expr = inner.next().unwrap(); + let body = inner.next().unwrap(); + ( + Statement::While(parse_expression(expr), Box::new(parse_statement(body).0)), FuncHolder::default(), - ), - Rule::statement => { - let inner = pair.into_inner().next().unwrap(); - parse_statement(inner) - } - Rule::block => { - let (z, _): (_, FuncHolder) = pair.into_inner().map(parse_statement).unzip(); - (Statement::Body(z), FuncHolder::default()) - } - Rule::def => { - let mut inner = pair.into_inner(); - let name = inner.next().unwrap(); - let args = inner - .next() - .unwrap() - .into_inner() - .map(|a| a.as_str().to_string()) - .collect(); - - let body = inner.next().unwrap(); - let body = parse_statement(body); - ( - Statement::Body(vec![]), - FuncHolder::default().insert(name.as_str().to_string(), args, vec![body.0]), - ) - } - Rule::EOI => (Statement::Body(vec![]), FuncHolder::default()), - x => unreachable!("How did we get to {:?}", x), + ) } - } - - fn parse_expression(pair: Pair) -> Expression { - match pair.as_rule() { - Rule::expression => { - let mut inner = pair.into_inner(); - let expr = parse_expression(inner.next().unwrap()); - if let Some(c) = inner.next() { - let mut inner = c.into_inner(); - let name = inner.next().unwrap(); - let args = inner - .next() - .unwrap() - .into_inner() - .map(parse_expression) - .collect(); - Expression::CallMethod(Box::new(expr), name.as_str().to_string(), args) + Rule::if_block => { + let mut inner = pair.into_inner(); + let mut the_list = vec![]; + let mut the_else = None; + while let Some(expr) = inner.next() { + if expr.as_rule() == Rule::expression { + let body = inner.next().unwrap(); + the_list.push((parse_expression(expr), parse_statement(body).0)); } else { - expr + the_else = Some(Box::new(parse_statement(expr).0)); } } - Rule::equality => { - let mut inner = pair.into_inner(); - let lhs = parse_expression(inner.next().unwrap()); - if let Some(op) = inner.next() { - let rhs = parse_expression(inner.next().unwrap()); - Expression::Binary(Box::new(lhs), op.as_str().parse().unwrap(), Box::new(rhs)) - } else { - lhs - } - } - Rule::inequality => { - let mut inner = pair.into_inner(); - let lhs = parse_expression(inner.next().unwrap()); - if let Some(op) = inner.next() { - let rhs = parse_expression(inner.next().unwrap()); - Expression::Binary(Box::new(lhs), op.as_str().parse().unwrap(), Box::new(rhs)) - } else { - lhs - } - } - Rule::sum => { - let mut inner = pair.into_inner(); - let lhs = parse_expression(inner.next().unwrap()); - if let Some(op) = inner.next() { - let rhs = parse_expression(inner.next().unwrap()); - Expression::Binary(Box::new(lhs), op.as_str().parse().unwrap(), Box::new(rhs)) - } else { - lhs - } - } - Rule::product => { - let mut inner = pair.into_inner(); - let lhs = parse_expression(inner.next().unwrap()); - if let Some(op) = inner.next() { - let rhs = parse_expression(inner.next().unwrap()); - Expression::Binary(Box::new(lhs), op.as_str().parse().unwrap(), Box::new(rhs)) - } else { - lhs - } - } - Rule::value => { - let mut inner = pair.into_inner(); - let v = parse_value(inner.next().unwrap()); - if let Some((name, args)) = method_call(inner.next().unwrap()) { - Expression::CallMethod(Box::new(v), name, args) - } else { - v - } - } - _ => unreachable!(), + (Statement::If(the_list, the_else), FuncHolder::default()) } - } - - fn method_call(pair: Pair) -> Option<(String, Vec)> { - match pair.as_rule() { - Rule::method_call => { - let mut inner = pair.into_inner(); - if let Some(name) = inner.next() { - let args = inner - .next() - .unwrap() - .into_inner() - .map(parse_expression) - .collect(); - Some((name.as_str().to_string(), args)) - } else { - None - } - } - _ => None, + Rule::assignment => { + let mut inner = pair.into_inner(); + let name = inner.next().unwrap(); + let expr = inner.next().unwrap(); + ( + Statement::Assignment(name.as_str().to_string(), parse_expression(expr), false), + FuncHolder::default(), + ) } - } + Rule::assignment_let => { + let mut inner = pair.into_inner(); + let name = inner.next().unwrap(); + let expr = inner.next().unwrap(); + ( + Statement::Assignment(name.as_str().to_string(), parse_expression(expr), true), + FuncHolder::default(), + ) + } + Rule::expression => ( + Statement::Expression(parse_expression(pair)), + FuncHolder::default(), + ), + Rule::statement => { + let inner = pair.into_inner().next().unwrap(); + parse_statement(inner) + } + Rule::block => { + let (z, _): (_, FuncHolder) = pair.into_inner().map(parse_statement).unzip(); + (Statement::Body(z), FuncHolder::default()) + } + Rule::def => { + let mut inner = pair.into_inner(); + let name = inner.next().unwrap(); + let args = inner + .next() + .unwrap() + .into_inner() + .map(|a| a.as_str().to_string()) + .collect(); - fn parse_value(pair: Pair) -> Expression { - match pair.as_rule() { - Rule::const_value => { - Expression::Constant(parse_const_value(pair.into_inner().next().unwrap())) + let body = inner.next().unwrap(); + let body = parse_statement(body); + ( + Statement::Body(vec![]), + FuncHolder::default().insert(name.as_str().to_string(), args, vec![body.0]), + ) + } + Rule::EOI => (Statement::Body(vec![]), FuncHolder::default()), + x => unreachable!("How did we get to {:?}", x), + } +} + +fn parse_expression(pair: Pair) -> Expression { + match pair.as_rule() { + Rule::expression => { + let mut inner = pair.into_inner(); + parse_expression(inner.next().unwrap()) + } + Rule::equality | Rule::inequality | Rule::sum | Rule::product => { + let mut inner = pair.into_inner(); + let lhs = parse_expression(inner.next().unwrap()); + if let Some(op) = inner.next() { + let rhs = parse_expression(inner.next().unwrap()); + Expression::Binary(Box::new(lhs), op.as_str().parse().unwrap(), Box::new(rhs)) + } else { + lhs } - Rule::identifier => Expression::Variable(pair.as_str().to_string()), - Rule::call => { - let mut inner = pair.into_inner(); - let name = inner.next().unwrap(); + } + Rule::value => { + let mut inner = pair.into_inner(); + let v = parse_value(inner.next().unwrap()); + if let Some((name, args)) = method_call(inner.next().unwrap()) { + Expression::CallMethod(Box::new(v), name, args) + } else { + v + } + } + _ => unreachable!(), + } +} + +fn method_call(pair: Pair) -> Option<(String, Vec)> { + match pair.as_rule() { + Rule::method_call => { + let mut inner = pair.into_inner(); + if let Some(name) = inner.next() { let args = inner .next() .unwrap() .into_inner() .map(parse_expression) .collect(); - Expression::Call(name.as_str().to_string(), args) + Some((name.as_str().to_string(), args)) + } else { + None } - Rule::parens => { - let mut inner = pair.into_inner(); - parse_expression(inner.next().unwrap()) - } - _ => unreachable!(), } + _ => None, + } +} + +fn parse_value(pair: Pair) -> Expression { + match pair.as_rule() { + Rule::const_value => { + Expression::Constant(parse_const_value(&pair.into_inner().next().unwrap())) + } + Rule::identifier => Expression::Variable(pair.as_str().to_string()), + Rule::call => { + let mut inner = pair.into_inner(); + let name = inner.next().unwrap(); + let args = inner + .next() + .unwrap() + .into_inner() + .map(parse_expression) + .collect(); + Expression::Call(name.as_str().to_string(), args) + } + Rule::parens => { + let mut inner = pair.into_inner(); + parse_expression(inner.next().unwrap()) + } + _ => unreachable!(), + } +} + +fn parse_const_value(pair: &Pair) -> Value { + match pair.as_rule() { + Rule::number => { + if let Ok(f) = pair.as_str().parse::() { + Value::Int(f) + } else if let Ok(f) = pair.as_str().parse::() { + Value::Float(f) + } else { + unreachable!() + } + } + Rule::string => Value::String(pair.as_str().to_string()), + Rule::boolean => Value::Bool(pair.as_str() == "true"), + Rule::char => Value::Char(pair.as_str().chars().next().unwrap()), + _ => unreachable!(), } - - fn parse_const_value(pair: Pair) -> Value { - match pair.as_rule() { - Rule::number => { - if let Ok(f) = pair.as_str().parse::() { - Value::Int(f) - } else if let Ok(f) = pair.as_str().parse::() { - Value::Float(f) - } else { - unreachable!() - } - } - Rule::string => Value::String(pair.as_str().to_string()), - Rule::boolean => Value::Bool(pair.as_str() == "true"), - Rule::char => Value::Char(pair.as_str().chars().next().unwrap()), - _ => unreachable!(), - } - } - - let z = p.next().unwrap(); - parse_statement(z) } diff --git a/src/value/custom.rs b/src/value/custom.rs index ddadb8b..8a6029b 100644 --- a/src/value/custom.rs +++ b/src/value/custom.rs @@ -30,6 +30,10 @@ pub trait CustomValue: std::fmt::Debug + BoxClone { fn functions(&self) -> Option { None } + + fn to_bool(&self) -> bool { + true + } } impl PartialEq for dyn CustomValue { diff --git a/src/value/mod.rs b/src/value/mod.rs index 0c01363..19ec413 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -34,9 +34,8 @@ impl Value { Value::String(v) => !v.is_empty(), Value::Bool(v) => *v, Value::Char(v) => *v != '\0', - Value::Custom(_) => false, - Value::Nothing => false, - Value::Error => false, + Value::Custom(c) => c.to_bool(), + Value::Nothing | Value::Error => false, } } @@ -155,7 +154,7 @@ impl Display for Value { Value::Char(v) => v.to_string(), Value::Nothing => "()".to_string(), Value::Error => "Error".to_string(), - _ => unreachable!(), + Value::Custom(_) => unreachable!(), } ) } @@ -234,8 +233,7 @@ impl PartialEq for Value { (Value::Char(lhs), Value::Char(rhs)) => lhs == rhs, (Value::Custom(lhs), other) => lhs.as_ref() == other, (other, Value::Custom(rhs)) => rhs.as_ref() == other, - (Value::Nothing, Value::Nothing) => true, - (Value::Error, Value::Error) => true, + (Value::Nothing, Value::Nothing) | (Value::Error, Value::Error) => true, _ => false, } }