Merge some more

This commit is contained in:
numzero 2025-04-20 14:02:28 +03:00
parent c42623223c
commit 006a366fb0
3 changed files with 29 additions and 32 deletions

View File

@ -28,7 +28,7 @@ pub enum Location {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Expression { pub enum Expression {
Constant(Scalar), Literal(Scalar),
Variable(Location), Variable(Location),
Call(Call), Call(Call),
Function(Function), Function(Function),
@ -75,7 +75,7 @@ impl Location {
impl Expression { impl Expression {
pub fn new_constant(value: impl Into<Scalar>) -> Self { pub fn new_constant(value: impl Into<Scalar>) -> Self {
Self::Constant(value.into()) Self::Literal(value.into())
} }
pub fn new_variable(name: impl Into<String>) -> Self { pub fn new_variable(name: impl Into<String>) -> Self {
@ -94,6 +94,12 @@ impl Expression {
} }
} }
impl<T: Into<Scalar>> From<T> for Expression {
fn from(value: T) -> Self {
Self::Literal(value.into())
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -173,7 +173,7 @@ fn lookup(scope: &BuildContext<'_>, loc: &ast::Location) -> Location {
.expect("_ENV must be always available"); .expect("_ENV must be always available");
Location::Field { Location::Field {
table: Box::new(Expression::Variable(Location::Variable { id: env })), 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 } => { 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 { fn build_expression(scope: &BuildContext<'_>, code: &ast::Expression) -> Expression {
match code { 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::Variable(loc) => Expression::Variable(lookup(scope, loc)),
ast::Expression::Call(call) => Expression::Call(build_call(scope, call)), ast::Expression::Call(call) => Expression::Call(build_call(scope, call)),
ast::Expression::Function(f) => Expression::Function(build_function(scope, f)), ast::Expression::Function(f) => Expression::Function(build_function(scope, f)),
@ -316,12 +316,7 @@ trait Eval {
impl Eval for Scalar { impl Eval for Scalar {
fn eval(&self, _ctx: &RunContext) -> Value { fn eval(&self, _ctx: &RunContext) -> Value {
match self { self.clone().into()
Self::Nil => Nil,
Self::Boolean(value) => Value::Boolean(*value),
Self::Number(value) => Value::Number(*value),
Self::String(value) => Value::String(value.clone()),
}
} }
} }
@ -478,15 +473,15 @@ mod tests {
body: vec![ body: vec![
Statement::Assign { Statement::Assign {
target: Location::new_variable("x"), target: Location::new_variable("x"),
source: Box::new(Expression::new_constant(1)), source: Box::new(1.into()),
}, },
Statement::Local { Statement::Local {
name: "x".into(), name: "x".into(),
init: Some(Box::new(Expression::new_constant(2))), init: Some(Box::new(2.into())),
}, },
Statement::Assign { Statement::Assign {
target: Location::new_variable("x"), 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"))), ret: Some(Box::new(Expression::new_variable("x"))),
@ -506,7 +501,7 @@ mod tests {
body: vec![ body: vec![
Statement::Assign { Statement::Assign {
target: Location::new_variable("x"), target: Location::new_variable("x"),
source: Box::new(Expression::new_constant(42)), source: Box::new(42.into()),
}, },
Statement::Local { Statement::Local {
name: "x".into(), name: "x".into(),
@ -514,7 +509,7 @@ mod tests {
}, },
Statement::Assign { Statement::Assign {
target: Location::new_field(Expression::new_variable("_ENV"), "x"), target: Location::new_field(Expression::new_variable("_ENV"), "x"),
source: Box::new(Expression::new_constant(666)), source: Box::new(666.into()),
}, },
Statement::Local { Statement::Local {
name: "y".into(), name: "y".into(),

View File

@ -1,5 +1,7 @@
use std::{cell::RefCell, collections::HashMap, fmt::Debug, hash::Hash, rc::Rc}; use std::{cell::RefCell, collections::HashMap, fmt::Debug, hash::Hash, rc::Rc};
use crate::scalar::Scalar;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
pub enum Value { pub enum Value {
#[default] #[default]
@ -13,6 +15,17 @@ pub enum Value {
pub use Value::Nil; pub use Value::Nil;
impl<T: Into<Scalar>> From<T> 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 { macro_rules! impl_from {
($as: ident, $from: ty) => { ($as: ident, $from: ty) => {
impl From<$from> for Value { 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<Self, Self::Error> {
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!(Table, Table);
impl_from!(Function, Function); impl_from!(Function, Function);