Extract ast::Constant as scalar::Scalar

This commit is contained in:
numzero 2025-04-20 13:49:06 +03:00
parent 8559220aa3
commit c42623223c
4 changed files with 55 additions and 53 deletions

View File

@ -1,3 +1,5 @@
use crate::scalar::Scalar;
pub type Ident = String; pub type Ident = String;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -26,7 +28,7 @@ pub enum Location {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Expression { pub enum Expression {
Constant(Constant), Constant(Scalar),
Variable(Location), Variable(Location),
Call(Call), Call(Call),
Function(Function), Function(Function),
@ -58,15 +60,6 @@ pub struct Function {
pub ret: Option<Box<Expression>>, pub ret: Option<Box<Expression>>,
} }
#[derive(Debug, Clone, Default)]
pub enum Constant {
#[default]
Nil,
Boolean(bool),
Number(i64),
String(String),
}
impl Location { impl Location {
pub fn new_variable(name: impl Into<String>) -> Self { pub fn new_variable(name: impl Into<String>) -> Self {
Self::Variable { name: name.into() } Self::Variable { name: name.into() }
@ -81,7 +74,7 @@ impl Location {
} }
impl Expression { impl Expression {
pub fn new_constant(value: impl Into<Constant>) -> Self { pub fn new_constant(value: impl Into<Scalar>) -> Self {
Self::Constant(value.into()) Self::Constant(value.into())
} }
@ -101,40 +94,6 @@ impl Expression {
} }
} }
impl From<()> for Constant {
fn from(_value: ()) -> Self {
Self::Nil
}
}
macro_rules! impl_from {
($as: ident, $from: ty) => {
impl From<$from> for Constant {
fn from(value: $from) -> Self {
Self::$as(value.into())
}
}
};
(try $as: ident, $from: ty) => {
impl TryFrom<$from> for Constant {
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);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -1,3 +1,4 @@
pub mod ast; pub mod ast;
pub mod scalar;
pub mod twopass; pub mod twopass;
pub mod types; pub mod types;

41
src/scalar.rs Normal file
View File

@ -0,0 +1,41 @@
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum Scalar {
#[default]
Nil,
Boolean(bool),
Number(i64),
String(String),
}
macro_rules! impl_from {
($as: ident, $from: ty) => {
impl From<$from> for Scalar {
fn from(value: $from) -> Self {
Self::$as(value.into())
}
}
};
(try $as: ident, $from: ty) => {
impl TryFrom<$from> for Scalar {
type Error = ::std::num::TryFromIntError;
fn try_from(value: $from) -> Result<Self, Self::Error> {
Ok(Self::$as(value.try_into()?))
}
}
};
}
impl From<()> for Scalar {
fn from(_value: ()) -> Self {
Self::Nil
}
}
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);

View File

@ -2,6 +2,7 @@ use std::{cell::RefCell, rc::Rc};
use crate::{ use crate::{
ast, ast,
scalar::Scalar,
types::{self, Nil, Value}, types::{self, Nil, Value},
}; };
@ -47,7 +48,7 @@ enum Location {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Expression { enum Expression {
Constant(ast::Constant), Constant(Scalar),
Variable(Location), Variable(Location),
Call(Call), Call(Call),
Function(Function), Function(Function),
@ -172,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(ast::Constant::String(name.clone()))), index: Box::new(Expression::Constant(Scalar::String(name.clone()))),
} }
} }
ast::Location::Field { table, index } => { ast::Location::Field { table, index } => {
@ -258,7 +259,7 @@ fn build_function(parent: &BuildContext<'_>, code: &ast::Function) -> Function {
let ret = Box::new(if let Some(ret) = &code.ret { let ret = Box::new(if let Some(ret) = &code.ret {
build_expression(&scope, &ret) build_expression(&scope, &ret)
} else { } else {
Expression::Constant(ast::Constant::Nil) Expression::Constant(Scalar::Nil)
}); });
let scope = scope.scope.into_inner().finish(); let scope = scope.scope.into_inner().finish();
Function { Function {
@ -313,13 +314,13 @@ trait Eval {
fn eval(&self, ctx: &RunContext) -> Value; fn eval(&self, ctx: &RunContext) -> Value;
} }
impl Eval for ast::Constant { impl Eval for Scalar {
fn eval(&self, _ctx: &RunContext) -> Value { fn eval(&self, _ctx: &RunContext) -> Value {
match self { match self {
ast::Constant::Nil => Nil, Self::Nil => Nil,
ast::Constant::Boolean(value) => Value::Boolean(*value), Self::Boolean(value) => Value::Boolean(*value),
ast::Constant::Number(value) => Value::Number(*value), Self::Number(value) => Value::Number(*value),
ast::Constant::String(value) => Value::String(value.clone()), Self::String(value) => Value::String(value.clone()),
} }
} }
} }