From 006a366fb0f99c81e35bce679b55a786155ea64f Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 20 Apr 2025 14:02:28 +0300 Subject: [PATCH] Merge some more --- src/ast.rs | 10 ++++++++-- src/twopass.rs | 21 ++++++++------------- src/types.rs | 30 +++++++++++++----------------- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 9cd7807..2930776 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -28,7 +28,7 @@ pub enum Location { #[derive(Debug, Clone)] pub enum Expression { - Constant(Scalar), + Literal(Scalar), Variable(Location), Call(Call), Function(Function), @@ -75,7 +75,7 @@ impl Location { impl Expression { pub fn new_constant(value: impl Into) -> Self { - Self::Constant(value.into()) + Self::Literal(value.into()) } pub fn new_variable(name: impl Into) -> Self { @@ -94,6 +94,12 @@ impl Expression { } } +impl> From for Expression { + fn from(value: T) -> Self { + Self::Literal(value.into()) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/twopass.rs b/src/twopass.rs index e378154..2ead3e6 100644 --- a/src/twopass.rs +++ b/src/twopass.rs @@ -173,7 +173,7 @@ fn lookup(scope: &BuildContext<'_>, loc: &ast::Location) -> Location { .expect("_ENV must be always available"); Location::Field { table: Box::new(Expression::Variable(Location::Variable { id: env })), - index: Box::new(Expression::Constant(Scalar::String(name.clone()))), + index: Box::new(Expression::Constant(name.clone().into())), } } ast::Location::Field { table, index } => { @@ -186,7 +186,7 @@ fn lookup(scope: &BuildContext<'_>, loc: &ast::Location) -> Location { fn build_expression(scope: &BuildContext<'_>, code: &ast::Expression) -> Expression { match code { - ast::Expression::Constant(c) => Expression::Constant(c.clone()), + ast::Expression::Literal(c) => Expression::Constant(c.clone()), ast::Expression::Variable(loc) => Expression::Variable(lookup(scope, loc)), ast::Expression::Call(call) => Expression::Call(build_call(scope, call)), ast::Expression::Function(f) => Expression::Function(build_function(scope, f)), @@ -316,12 +316,7 @@ trait Eval { impl Eval for Scalar { fn eval(&self, _ctx: &RunContext) -> Value { - match self { - Self::Nil => Nil, - Self::Boolean(value) => Value::Boolean(*value), - Self::Number(value) => Value::Number(*value), - Self::String(value) => Value::String(value.clone()), - } + self.clone().into() } } @@ -478,15 +473,15 @@ mod tests { body: vec![ Statement::Assign { target: Location::new_variable("x"), - source: Box::new(Expression::new_constant(1)), + source: Box::new(1.into()), }, Statement::Local { name: "x".into(), - init: Some(Box::new(Expression::new_constant(2))), + init: Some(Box::new(2.into())), }, Statement::Assign { target: Location::new_variable("x"), - source: Box::new(Expression::new_constant(3)), + source: Box::new(3.into()), }, ], ret: Some(Box::new(Expression::new_variable("x"))), @@ -506,7 +501,7 @@ mod tests { body: vec![ Statement::Assign { target: Location::new_variable("x"), - source: Box::new(Expression::new_constant(42)), + source: Box::new(42.into()), }, Statement::Local { name: "x".into(), @@ -514,7 +509,7 @@ mod tests { }, Statement::Assign { target: Location::new_field(Expression::new_variable("_ENV"), "x"), - source: Box::new(Expression::new_constant(666)), + source: Box::new(666.into()), }, Statement::Local { name: "y".into(), diff --git a/src/types.rs b/src/types.rs index e262be9..e4957fc 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,5 +1,7 @@ use std::{cell::RefCell, collections::HashMap, fmt::Debug, hash::Hash, rc::Rc}; +use crate::scalar::Scalar; + #[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] pub enum Value { #[default] @@ -13,6 +15,17 @@ pub enum Value { pub use Value::Nil; +impl> From for Value { + fn from(value: T) -> Self { + match value.into() { + Scalar::Nil => Nil, + Scalar::Boolean(value) => Value::Boolean(value), + Scalar::Number(value) => Value::Number(value), + Scalar::String(value) => Value::String(value), + } + } +} + macro_rules! impl_from { ($as: ident, $from: ty) => { impl From<$from> for Value { @@ -21,25 +34,8 @@ macro_rules! impl_from { } } }; - (try $as: ident, $from: ty) => { - impl TryFrom<$from> for Value { - type Error = ::std::num::TryFromIntError; - fn try_from(value: $from) -> Result { - Ok(Self::$as(value.try_into()?)) - } - } - }; } -impl_from!(Boolean, bool); -impl_from!(try Number, isize); -impl_from!(try Number, usize); -impl_from!(try Number, i64); -impl_from!(try Number, u64); -impl_from!(Number, u32); -impl_from!(Number, i32); -impl_from!(String, String); -impl_from!(String, &str); impl_from!(Table, Table); impl_from!(Function, Function);