diff options
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/mod.rs | 9 | ||||
| -rw-r--r-- | src/eval/scope.rs | 20 | ||||
| -rw-r--r-- | src/eval/value.rs | 33 |
3 files changed, 34 insertions, 28 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 4992f70c..dc4ab7ee 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -17,6 +17,7 @@ use std::rc::Rc; use crate::cache::Cache; use crate::diag::{Diag, DiagSet, Pass}; +use crate::eco::EcoString; use crate::geom::{Angle, Fractional, Length, Relative}; use crate::loading::{FileHash, Loader}; use crate::parse::parse; @@ -528,7 +529,7 @@ impl Eval for ClosureExpr { visitor.finish() }; - let name = self.name.as_ref().map(|id| id.to_string()); + let name = self.name.as_ref().map(|name| name.string.clone()); Value::Func(FuncValue::new(name, move |ctx, args| { // Don't leak the scopes from the call site. Instead, we use the // scope of captured variables we collected earlier. @@ -555,7 +556,7 @@ impl Eval for WithExpr { let callee = self.callee.eval(ctx); if let Some(func) = ctx.cast::<FuncValue>(callee, self.callee.span()) { let applied = self.args.eval(ctx); - let name = func.name().map(|s| s.to_string()); + let name = func.name().cloned(); Value::Func(FuncValue::new(name, move |ctx, args| { // Remove named arguments that were overridden. let kept: Vec<_> = applied @@ -698,7 +699,7 @@ impl Eval for ImportExpr { fn eval(&self, ctx: &mut EvalContext) -> Self::Output { let path = self.path.eval(ctx); - if let Some(path) = ctx.cast::<String>(path, self.path.span()) { + if let Some(path) = ctx.cast::<EcoString>(path, self.path.span()) { if let Some(hash) = ctx.import(&path, self.path.span()) { let mut module = &ctx.modules[&hash]; match &self.imports { @@ -734,7 +735,7 @@ impl Eval for IncludeExpr { fn eval(&self, ctx: &mut EvalContext) -> Self::Output { let path = self.path.eval(ctx); - if let Some(path) = ctx.cast::<String>(path, self.path.span()) { + if let Some(path) = ctx.cast::<EcoString>(path, self.path.span()) { if let Some(hash) = ctx.import(&path, self.path.span()) { return Value::Template(ctx.modules[&hash].template.clone()); } diff --git a/src/eval/scope.rs b/src/eval/scope.rs index 3f7c4c62..05bbeda2 100644 --- a/src/eval/scope.rs +++ b/src/eval/scope.rs @@ -4,7 +4,7 @@ use std::fmt::{self, Debug, Display, Formatter}; use std::iter; use std::rc::Rc; -use super::{AnyValue, EvalContext, FuncArgs, FuncValue, Type, Value}; +use super::{AnyValue, EcoString, EvalContext, FuncArgs, FuncValue, Type, Value}; /// A slot where a variable is stored. pub type Slot = Rc<RefCell<Value>>; @@ -39,17 +39,17 @@ impl<'a> Scopes<'a> { } /// Define a constant variable with a value in the active scope. - pub fn def_const(&mut self, var: impl Into<String>, value: impl Into<Value>) { + pub fn def_const(&mut self, var: impl Into<EcoString>, value: impl Into<Value>) { self.top.def_const(var, value); } /// Define a mutable variable with a value in the active scope. - pub fn def_mut(&mut self, var: impl Into<String>, value: impl Into<Value>) { + pub fn def_mut(&mut self, var: impl Into<EcoString>, value: impl Into<Value>) { self.top.def_mut(var, value); } /// Define a variable with a slot in the active scope. - pub fn def_slot(&mut self, var: impl Into<String>, slot: Slot) { + pub fn def_slot(&mut self, var: impl Into<EcoString>, slot: Slot) { self.top.def_slot(var, slot); } @@ -66,7 +66,7 @@ impl<'a> Scopes<'a> { #[derive(Default, Clone, PartialEq)] pub struct Scope { /// The mapping from names to slots. - values: HashMap<String, Slot>, + values: HashMap<EcoString, Slot>, } impl Scope { @@ -76,7 +76,7 @@ impl Scope { } /// Define a constant variable with a value. - pub fn def_const(&mut self, var: impl Into<String>, value: impl Into<Value>) { + pub fn def_const(&mut self, var: impl Into<EcoString>, value: impl Into<Value>) { let cell = RefCell::new(value.into()); // Make it impossible to write to this value again. @@ -87,7 +87,7 @@ impl Scope { } /// Define a constant function. - pub fn def_func<F>(&mut self, name: impl Into<String>, f: F) + pub fn def_func<F>(&mut self, name: impl Into<EcoString>, f: F) where F: Fn(&mut EvalContext, &mut FuncArgs) -> Value + 'static, { @@ -96,7 +96,7 @@ impl Scope { } /// Define a constant variable with a value of variant `Value::Any`. - pub fn def_any<T>(&mut self, var: impl Into<String>, any: T) + pub fn def_any<T>(&mut self, var: impl Into<EcoString>, any: T) where T: Type + Debug + Display + Clone + PartialEq + 'static, { @@ -104,12 +104,12 @@ impl Scope { } /// Define a mutable variable with a value. - pub fn def_mut(&mut self, var: impl Into<String>, value: impl Into<Value>) { + pub fn def_mut(&mut self, var: impl Into<EcoString>, value: impl Into<Value>) { self.values.insert(var.into(), Rc::new(RefCell::new(value.into()))); } /// Define a variable with a slot. - pub fn def_slot(&mut self, var: impl Into<String>, slot: Slot) { + pub fn def_slot(&mut self, var: impl Into<EcoString>, slot: Slot) { self.values.insert(var.into(), slot); } diff --git a/src/eval/value.rs b/src/eval/value.rs index 07552c84..2881399b 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -5,8 +5,7 @@ use std::fmt::{self, Debug, Display, Formatter}; use std::ops::Deref; use std::rc::Rc; -use super::ops; -use super::EvalContext; +use super::*; use crate::color::{Color, RgbaColor}; use crate::exec::ExecContext; use crate::geom::{Angle, Fractional, Length, Linear, Relative}; @@ -38,7 +37,7 @@ pub enum Value { /// A color value: `#f79143ff`. Color(Color), /// A string: `"string"`. - Str(String), + Str(EcoString), /// An array value: `(1, "hi", 12cm)`. Array(ArrayValue), /// A dictionary value: `(color: #f79143, pattern: dashed)`. @@ -76,7 +75,7 @@ impl Value { Self::Linear(_) => Linear::TYPE_NAME, Self::Fractional(_) => Fractional::TYPE_NAME, Self::Color(_) => Color::TYPE_NAME, - Self::Str(_) => String::TYPE_NAME, + Self::Str(_) => EcoString::TYPE_NAME, Self::Array(_) => ArrayValue::TYPE_NAME, Self::Dict(_) => DictValue::TYPE_NAME, Self::Template(_) => TemplateValue::TYPE_NAME, @@ -151,7 +150,7 @@ impl Default for Value { pub type ArrayValue = Vec<Value>; /// A dictionary value: `(color: #f79143, pattern: dashed)`. -pub type DictValue = BTreeMap<String, Value>; +pub type DictValue = BTreeMap<EcoString, Value>; /// A template value: `[*Hi* there]`. pub type TemplateValue = Rc<Vec<TemplateNode>>; @@ -171,7 +170,7 @@ pub enum TemplateNode { map: ExprMap, }, /// A template that was converted from a string. - Str(String), + Str(EcoString), /// A function template that can implement custom behaviour. Func(TemplateFunc), } @@ -224,14 +223,14 @@ impl Debug for TemplateFunc { pub struct FuncValue { /// The string is boxed to make the whole struct fit into 24 bytes, so that /// a [`Value`] fits into 32 bytes. - name: Option<Box<String>>, + name: Option<Box<EcoString>>, /// The closure that defines the function. f: Rc<dyn Fn(&mut EvalContext, &mut FuncArgs) -> Value>, } impl FuncValue { /// Create a new function value from a rust function or closure. - pub fn new<F>(name: Option<String>, f: F) -> Self + pub fn new<F>(name: Option<EcoString>, f: F) -> Self where F: Fn(&mut EvalContext, &mut FuncArgs) -> Value + 'static, { @@ -239,8 +238,8 @@ impl FuncValue { } /// The name of the function. - pub fn name(&self) -> Option<&str> { - self.name.as_ref().map(|s| s.as_str()) + pub fn name(&self) -> Option<&EcoString> { + self.name.as_ref().map(|s| &**s) } } @@ -342,7 +341,7 @@ impl FuncArgs { let index = self .items .iter() - .position(|arg| arg.name.as_ref().map_or(false, |other| name == other))?; + .position(|arg| arg.name.as_ref().map_or(false, |other| other == name))?; let value = self.items.remove(index).value; let span = value.span; @@ -381,7 +380,7 @@ pub struct FuncArg { /// The span of the whole argument. pub span: Span, /// The name of the argument (`None` for positional arguments). - pub name: Option<String>, + pub name: Option<EcoString>, /// The value of the argument. pub value: Spanned<Value>, } @@ -608,7 +607,7 @@ primitive! { } primitive! { Fractional: "fractional", Value::Fractional } primitive! { Color: "color", Value::Color } -primitive! { String: "string", Value::Str } +primitive! { EcoString: "string", Value::Str } primitive! { ArrayValue: "array", Value::Array } primitive! { DictValue: "dictionary", Value::Dict } primitive! { @@ -624,9 +623,15 @@ impl From<usize> for Value { } } +impl From<String> for Value { + fn from(v: String) -> Self { + Self::Str(v.into()) + } +} + impl From<&str> for Value { fn from(v: &str) -> Self { - Self::Str(v.to_string()) + Self::Str(v.into()) } } |
