Merge some more
This commit is contained in:
parent
c42623223c
commit
006a366fb0
10
src/ast.rs
10
src/ast.rs
|
|
@ -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::*;
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
30
src/types.rs
30
src/types.rs
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user