Fix some clippy pedantic errors
This commit is contained in:
parent
699ebeda48
commit
7236b204b9
|
@ -1,4 +1,7 @@
|
||||||
use std::{collections::HashMap, sync::{Arc, RwLock}};
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
|
||||||
|
@ -11,7 +14,7 @@ pub struct Env<'env> {
|
||||||
impl Env<'_> {
|
impl Env<'_> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Env {
|
Env {
|
||||||
values: Default::default(),
|
values: Arc::default(),
|
||||||
parent: None,
|
parent: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +61,7 @@ impl Default for Env<'_> {
|
||||||
impl<'env> Env<'env> {
|
impl<'env> Env<'env> {
|
||||||
pub fn new_with_parent(parent: &'env Env<'env>) -> Self {
|
pub fn new_with_parent(parent: &'env Env<'env>) -> Self {
|
||||||
Env {
|
Env {
|
||||||
values: Default::default(),
|
values: Arc::default(),
|
||||||
parent: Some(parent),
|
parent: Some(parent),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ macro_rules! impl_function {
|
||||||
let total_count = {
|
let total_count = {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
$(
|
$(
|
||||||
let _: Option<$ty> = None;
|
let _n: Option<$ty> = None;
|
||||||
count += 1;
|
count += 1;
|
||||||
)*
|
)*
|
||||||
count
|
count
|
||||||
|
@ -44,7 +44,7 @@ macro_rules! impl_function {
|
||||||
let total_count = {
|
let total_count = {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
$(
|
$(
|
||||||
let _: Option<$ty> = None;
|
let _n: Option<$ty> = None;
|
||||||
count += 1;
|
count += 1;
|
||||||
)*
|
)*
|
||||||
count
|
count
|
||||||
|
@ -79,7 +79,7 @@ macro_rules! impl_ref_function {
|
||||||
let total_count = {
|
let total_count = {
|
||||||
let mut count = 1;
|
let mut count = 1;
|
||||||
$(
|
$(
|
||||||
let _: Option<$ty> = None;
|
let _n: Option<$ty> = None;
|
||||||
count += 1;
|
count += 1;
|
||||||
)*
|
)*
|
||||||
count
|
count
|
||||||
|
@ -114,7 +114,7 @@ macro_rules! impl_ref_function {
|
||||||
let total_count = {
|
let total_count = {
|
||||||
let mut count = 1;
|
let mut count = 1;
|
||||||
$(
|
$(
|
||||||
let _: Option<$ty> = None;
|
let _n: Option<$ty> = None;
|
||||||
count += 1;
|
count += 1;
|
||||||
)*
|
)*
|
||||||
count
|
count
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub struct FunctionMap(HashMap<String, (Box<dyn Function>, FunctionType)>);
|
||||||
|
|
||||||
impl FunctionMap {
|
impl FunctionMap {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
FunctionMap::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_native<S, P, F>(&mut self, name: S, f: F)
|
pub fn insert_native<S, P, F>(&mut self, name: S, f: F)
|
||||||
|
@ -107,7 +107,7 @@ impl Function for InterpreterFunction {
|
||||||
for (name, value) in self.parameters.iter().zip(args) {
|
for (name, value) in self.parameters.iter().zip(args) {
|
||||||
sub_env.set_here(name, value.clone());
|
sub_env.set_here(name, value.clone());
|
||||||
}
|
}
|
||||||
for stmt in self.body.iter() {
|
for stmt in &self.body {
|
||||||
stmt.eval(&sub_env, map);
|
stmt.eval(&sub_env, map);
|
||||||
}
|
}
|
||||||
Ok(Value::Nothing)
|
Ok(Value::Nothing)
|
||||||
|
|
|
@ -15,9 +15,9 @@ mod value;
|
||||||
// mod parser;
|
// mod parser;
|
||||||
mod pest_parser;
|
mod pest_parser;
|
||||||
|
|
||||||
fn run(functions: FunctionMap, statement: Statement) {
|
fn run(functions: &FunctionMap, statement: &Statement) {
|
||||||
let env = Env::new();
|
let env = Env::new();
|
||||||
statement.eval(&env, &functions);
|
statement.eval(&env, functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -59,7 +59,7 @@ fn functions(&self) -> Option<FunctionMap> {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let f = read_to_string("./test.foo").unwrap();
|
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();
|
let mut m = FunctionMap::new();
|
||||||
m.insert_holder(funcs);
|
m.insert_holder(funcs);
|
||||||
m.insert_native("print", |a: &Value| {
|
m.insert_native("print", |a: &Value| {
|
||||||
|
@ -68,5 +68,5 @@ fn main() {
|
||||||
m.insert_native("waluigi", || "Waluigi");
|
m.insert_native("waluigi", || "Waluigi");
|
||||||
m.insert_native("native_test", || Foo { x: 41 });
|
m.insert_native("native_test", || Foo { x: 41 });
|
||||||
|
|
||||||
run(m, res);
|
run(&m, &res);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{expression::Expression, statement::Statement, value::Value};
|
||||||
#[grammar = "grammar.pest"]
|
#[grammar = "grammar.pest"]
|
||||||
pub struct LangParser;
|
pub struct LangParser;
|
||||||
|
|
||||||
pub fn parse<S: ToString>(source: S) -> (Statement, FuncHolder) {
|
pub fn parse<S: ToString>(source: &S) -> (Statement, FuncHolder) {
|
||||||
let source = source.to_string();
|
let source = source.to_string();
|
||||||
let pairs = LangParser::parse(Rule::root_statement, &source).unwrap();
|
let pairs = LangParser::parse(Rule::root_statement, &source).unwrap();
|
||||||
handle_rules(pairs)
|
handle_rules(pairs)
|
||||||
|
@ -53,222 +53,179 @@ impl IntoIterator for FuncHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_rules(mut p: pest::iterators::Pairs<Rule>) -> (Statement, FuncHolder) {
|
fn handle_rules(mut p: pest::iterators::Pairs<Rule>) -> (Statement, FuncHolder) {
|
||||||
fn parse_statement(pair: Pair<Rule>) -> (Statement, FuncHolder) {
|
let z = p.next().unwrap();
|
||||||
match pair.as_rule() {
|
parse_statement(z)
|
||||||
Rule::root_statement => {
|
}
|
||||||
let (z, f) = pair.into_inner().map(parse_statement).unzip();
|
|
||||||
(Statement::Body(z), f)
|
fn parse_statement(pair: Pair<Rule>) -> (Statement, FuncHolder) {
|
||||||
}
|
match pair.as_rule() {
|
||||||
Rule::while_block => {
|
Rule::root_statement => {
|
||||||
let mut inner = pair.into_inner();
|
let (z, f) = pair.into_inner().map(parse_statement).unzip();
|
||||||
let expr = inner.next().unwrap();
|
(Statement::Body(z), f)
|
||||||
let body = inner.next().unwrap();
|
}
|
||||||
(
|
Rule::while_block => {
|
||||||
Statement::While(parse_expression(expr), Box::new(parse_statement(body).0)),
|
let mut inner = pair.into_inner();
|
||||||
FuncHolder::default(),
|
let expr = inner.next().unwrap();
|
||||||
)
|
let body = inner.next().unwrap();
|
||||||
}
|
(
|
||||||
Rule::if_block => {
|
Statement::While(parse_expression(expr), Box::new(parse_statement(body).0)),
|
||||||
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)),
|
|
||||||
FuncHolder::default(),
|
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),
|
|
||||||
}
|
}
|
||||||
}
|
Rule::if_block => {
|
||||||
|
let mut inner = pair.into_inner();
|
||||||
fn parse_expression(pair: Pair<Rule>) -> Expression {
|
let mut the_list = vec![];
|
||||||
match pair.as_rule() {
|
let mut the_else = None;
|
||||||
Rule::expression => {
|
while let Some(expr) = inner.next() {
|
||||||
let mut inner = pair.into_inner();
|
if expr.as_rule() == Rule::expression {
|
||||||
let expr = parse_expression(inner.next().unwrap());
|
let body = inner.next().unwrap();
|
||||||
if let Some(c) = inner.next() {
|
the_list.push((parse_expression(expr), parse_statement(body).0));
|
||||||
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)
|
|
||||||
} else {
|
} else {
|
||||||
expr
|
the_else = Some(Box::new(parse_statement(expr).0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rule::equality => {
|
(Statement::If(the_list, the_else), FuncHolder::default())
|
||||||
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!(),
|
|
||||||
}
|
}
|
||||||
}
|
Rule::assignment => {
|
||||||
|
let mut inner = pair.into_inner();
|
||||||
fn method_call(pair: Pair<Rule>) -> Option<(String, Vec<Expression>)> {
|
let name = inner.next().unwrap();
|
||||||
match pair.as_rule() {
|
let expr = inner.next().unwrap();
|
||||||
Rule::method_call => {
|
(
|
||||||
let mut inner = pair.into_inner();
|
Statement::Assignment(name.as_str().to_string(), parse_expression(expr), false),
|
||||||
if let Some(name) = inner.next() {
|
FuncHolder::default(),
|
||||||
let args = inner
|
)
|
||||||
.next()
|
|
||||||
.unwrap()
|
|
||||||
.into_inner()
|
|
||||||
.map(parse_expression)
|
|
||||||
.collect();
|
|
||||||
Some((name.as_str().to_string(), args))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
}
|
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<Rule>) -> Expression {
|
let body = inner.next().unwrap();
|
||||||
match pair.as_rule() {
|
let body = parse_statement(body);
|
||||||
Rule::const_value => {
|
(
|
||||||
Expression::Constant(parse_const_value(pair.into_inner().next().unwrap()))
|
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<Rule>) -> 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 => {
|
Rule::value => {
|
||||||
let mut inner = pair.into_inner();
|
let mut inner = pair.into_inner();
|
||||||
let name = inner.next().unwrap();
|
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<Rule>) -> Option<(String, Vec<Expression>)> {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::method_call => {
|
||||||
|
let mut inner = pair.into_inner();
|
||||||
|
if let Some(name) = inner.next() {
|
||||||
let args = inner
|
let args = inner
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_inner()
|
.into_inner()
|
||||||
.map(parse_expression)
|
.map(parse_expression)
|
||||||
.collect();
|
.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<Rule>) -> 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<Rule>) -> Value {
|
||||||
|
match pair.as_rule() {
|
||||||
|
Rule::number => {
|
||||||
|
if let Ok(f) = pair.as_str().parse::<i32>() {
|
||||||
|
Value::Int(f)
|
||||||
|
} else if let Ok(f) = pair.as_str().parse::<f32>() {
|
||||||
|
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<Rule>) -> Value {
|
|
||||||
match pair.as_rule() {
|
|
||||||
Rule::number => {
|
|
||||||
if let Ok(f) = pair.as_str().parse::<i32>() {
|
|
||||||
Value::Int(f)
|
|
||||||
} else if let Ok(f) = pair.as_str().parse::<f32>() {
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,10 @@ pub trait CustomValue: std::fmt::Debug + BoxClone {
|
||||||
fn functions(&self) -> Option<FunctionMap> {
|
fn functions(&self) -> Option<FunctionMap> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_bool(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<Value> for dyn CustomValue {
|
impl PartialEq<Value> for dyn CustomValue {
|
||||||
|
|
|
@ -34,9 +34,8 @@ impl Value {
|
||||||
Value::String(v) => !v.is_empty(),
|
Value::String(v) => !v.is_empty(),
|
||||||
Value::Bool(v) => *v,
|
Value::Bool(v) => *v,
|
||||||
Value::Char(v) => *v != '\0',
|
Value::Char(v) => *v != '\0',
|
||||||
Value::Custom(_) => false,
|
Value::Custom(c) => c.to_bool(),
|
||||||
Value::Nothing => false,
|
Value::Nothing | Value::Error => false,
|
||||||
Value::Error => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +154,7 @@ impl Display for Value {
|
||||||
Value::Char(v) => v.to_string(),
|
Value::Char(v) => v.to_string(),
|
||||||
Value::Nothing => "()".to_string(),
|
Value::Nothing => "()".to_string(),
|
||||||
Value::Error => "Error".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::Char(lhs), Value::Char(rhs)) => lhs == rhs,
|
||||||
(Value::Custom(lhs), other) => lhs.as_ref() == other,
|
(Value::Custom(lhs), other) => lhs.as_ref() == other,
|
||||||
(other, Value::Custom(rhs)) => rhs.as_ref() == other,
|
(other, Value::Custom(rhs)) => rhs.as_ref() == other,
|
||||||
(Value::Nothing, Value::Nothing) => true,
|
(Value::Nothing, Value::Nothing) | (Value::Error, Value::Error) => true,
|
||||||
(Value::Error, Value::Error) => true,
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue