difftreelog
refactor drop ArgsLike abstraction
in: master
17 files changed
bindings/jsonnet/src/lib.rsdiffbeforeafterboth--- a/bindings/jsonnet/src/lib.rs
+++ b/bindings/jsonnet/src/lib.rs
@@ -22,11 +22,11 @@
use jrsonnet_evaluator::{
apply_tla, bail,
- function::TlaArg,
gc::WithCapacityExt as _,
manifest::{JsonFormat, ManifestFormat, ToStringFormat},
rustc_hash::FxHashMap,
stack::set_stack_depth_limit,
+ tla::TlaArg,
trace::{CompactFormat, PathResolver, TraceFormat},
AsPathLike, FileImportResolver, IStr, ImportResolver, Result, State, Val,
};
@@ -40,6 +40,7 @@
pub extern "C" fn _start() {}
/// Return the version string of the Jsonnet interpreter.
+///
/// Conforms to [semantic versioning](http://semver.org/).
/// If this does not match `LIB_JSONNET_VERSION`
/// then there is a mismatch between header and compiled library.
bindings/jsonnet/src/vars_tlas.rsdiffbeforeafterboth--- a/bindings/jsonnet/src/vars_tlas.rs
+++ b/bindings/jsonnet/src/vars_tlas.rs
@@ -2,7 +2,8 @@
use std::{ffi::CStr, os::raw::c_char};
-use jrsonnet_evaluator::{function::TlaArg, IStr};
+use jrsonnet_evaluator::tla::TlaArg;
+use jrsonnet_evaluator::IStr;
use crate::VM;
crates/jrsonnet-cli/src/stdlib.rsdiffbeforeafterboth--- a/crates/jrsonnet-cli/src/stdlib.rs
+++ b/crates/jrsonnet-cli/src/stdlib.rs
@@ -1,7 +1,8 @@
use std::str::FromStr;
use clap::Parser;
-use jrsonnet_evaluator::{function::TlaArg, trace::PathResolver, Result};
+use jrsonnet_evaluator::tla::TlaArg;
+use jrsonnet_evaluator::{trace::PathResolver, Result};
use jrsonnet_stdlib::ContextInitializer;
#[derive(Clone)]
crates/jrsonnet-cli/src/tla.rsdiffbeforeafterboth--- a/crates/jrsonnet-cli/src/tla.rs
+++ b/crates/jrsonnet-cli/src/tla.rs
@@ -1,7 +1,6 @@
use clap::Parser;
-use jrsonnet_evaluator::{
- error::Result, function::TlaArg, gc::WithCapacityExt as _, rustc_hash::FxHashMap, IStr,
-};
+use jrsonnet_evaluator::tla::TlaArg;
+use jrsonnet_evaluator::{error::Result, gc::WithCapacityExt as _, rustc_hash::FxHashMap, IStr};
use crate::{ExtFile, ExtStr};
crates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/arr/mod.rs
+++ b/crates/jrsonnet-evaluator/src/arr/mod.rs
@@ -9,7 +9,7 @@
use jrsonnet_interner::IBytes;
use jrsonnet_parser::{Expr, Spanned};
-use crate::{typed::NativeFn, Context, Result, Thunk, Val};
+use crate::{function::NativeFn, Context, Result, Thunk, Val};
mod spec;
pub use spec::{ArrayLike, *};
crates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/arr/spec.rs
+++ b/crates/jrsonnet-evaluator/src/arr/spec.rs
@@ -6,8 +6,7 @@
use jrsonnet_parser::{Expr, Spanned};
use super::ArrValue;
-use crate::typed::NativeFn;
-use crate::val::NumValue;
+use crate::function::NativeFn;
use crate::{
error::ErrorKind::InfiniteRecursionDetected, evaluate, typed::Typed, val::ThunkValue, Context,
Error, ObjValue, Result, Thunk, Val,
crates/jrsonnet-evaluator/src/function/arglike.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/arglike.rs
+++ /dev/null
@@ -1,197 +0,0 @@
-use std::collections::HashMap;
-use std::rc::Rc;
-
-use jrsonnet_gcmodule::Trace;
-use jrsonnet_interner::IStr;
-use jrsonnet_parser::{ArgsDesc, Expr, SourceFifo, SourcePath, Spanned};
-
-use crate::{evaluate, typed::Typed, with_state, Context, Result, Thunk, Val};
-
-pub trait ArgLike {
- fn evaluate_arg(&self, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>>;
-}
-
-impl ArgLike for &Rc<Spanned<Expr>> {
- fn evaluate_arg(&self, ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {
- Ok(if tailstrict {
- Thunk::evaluated(evaluate(ctx, self)?)
- } else {
- let expr = (*self).clone();
- Thunk!(move || evaluate(ctx, &expr))
- })
- }
-}
-
-impl<T> ArgLike for T
-where
- T: Typed + Clone,
-{
- fn evaluate_arg(&self, _ctx: Context, tailstrict: bool) -> Result<Thunk<Val>> {
- if T::provides_lazy() && !tailstrict {
- return Ok(T::into_lazy_untyped(self.clone()));
- }
- let val = T::into_untyped(self.clone())?;
- Ok(Thunk::evaluated(val))
- }
-}
-
-#[derive(Clone, Trace)]
-pub enum TlaArg {
- String(IStr),
- Val(Val),
- Lazy(Thunk<Val>),
- Import(String),
- ImportStr(String),
- InlineCode(String),
-}
-impl TlaArg {
- pub fn evaluate_tailstrict(&self) -> Result<Val> {
- match self {
- Self::String(s) => Ok(Val::string(s.clone())),
- Self::Val(val) => Ok(val.clone()),
- Self::Lazy(lazy) => Ok(lazy.evaluate()?),
- Self::Import(p) => with_state(|s| {
- let resolved = s.resolve_from_default(&p.as_str())?;
- s.import_resolved(resolved)
- }),
- Self::ImportStr(p) => with_state(|s| {
- let resolved = s.resolve_from_default(&p.as_str())?;
- s.import_resolved_str(resolved).map(Val::string)
- }),
- Self::InlineCode(p) => with_state(|s| {
- let resolved =
- SourcePath::new(SourceFifo("<inline code>".to_owned(), p.as_bytes().into()));
- s.import_resolved(resolved)
- }),
- }
- }
- pub fn evaluate(&self) -> Result<Thunk<Val>> {
- match self {
- Self::String(s) => Ok(Thunk::evaluated(Val::string(s.clone()))),
- Self::Val(val) => Ok(Thunk::evaluated(val.clone())),
- Self::Lazy(lazy) => Ok(lazy.clone()),
- Self::Import(p) => with_state(|s| {
- let resolved = s.resolve_from_default(&p.as_str())?;
- Ok(Thunk!(move || s.import_resolved(resolved)))
- }),
- Self::ImportStr(p) => with_state(|s| {
- let resolved = s.resolve_from_default(&p.as_str())?;
- Ok(Thunk!(move || s
- .import_resolved_str(resolved)
- .map(Val::string)))
- }),
- Self::InlineCode(p) => with_state(|s| {
- let resolved =
- SourcePath::new(SourceFifo("<inline code>".to_owned(), p.as_bytes().into()));
- Ok(Thunk!(move || s.import_resolved(resolved)))
- }),
- }
- }
-}
-
-pub trait ArgsLike {
- fn unnamed_len(&self) -> usize;
- fn unnamed_iter(
- &self,
- ctx: Context,
- tailstrict: bool,
- handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,
- ) -> Result<()>;
- fn named_iter(
- &self,
- ctx: Context,
- tailstrict: bool,
- handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,
- ) -> Result<()>;
- fn named_names(&self, handler: &mut dyn FnMut(&IStr));
- fn is_empty(&self) -> bool;
-}
-
-impl ArgsLike for Vec<Val> {
- fn unnamed_len(&self) -> usize {
- self.len()
- }
- fn unnamed_iter(
- &self,
- _ctx: Context,
- _tailstrict: bool,
- handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,
- ) -> Result<()> {
- for (idx, el) in self.iter().enumerate() {
- handler(idx, Thunk::evaluated(el.clone()))?;
- }
- Ok(())
- }
- fn named_iter(
- &self,
- _ctx: Context,
- _tailstrict: bool,
- _handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,
- ) -> Result<()> {
- Ok(())
- }
- fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {}
- fn is_empty(&self) -> bool {
- self.is_empty()
- }
-}
-
-impl ArgsLike for ArgsDesc {
- fn unnamed_len(&self) -> usize {
- self.unnamed.len()
- }
-
- fn unnamed_iter(
- &self,
- ctx: Context,
- tailstrict: bool,
- handler: &mut dyn FnMut(usize, Thunk<Val>) -> Result<()>,
- ) -> Result<()> {
- for (id, arg) in self.unnamed.iter().enumerate() {
- handler(
- id,
- if tailstrict {
- Thunk::evaluated(evaluate(ctx.clone(), arg)?)
- } else {
- let ctx = ctx.clone();
- let arg = arg.clone();
-
- Thunk!(move || evaluate(ctx, &arg))
- },
- )?;
- }
- Ok(())
- }
-
- fn named_iter(
- &self,
- ctx: Context,
- tailstrict: bool,
- handler: &mut dyn FnMut(&IStr, Thunk<Val>) -> Result<()>,
- ) -> Result<()> {
- for (name, arg) in &self.named {
- handler(
- name,
- if tailstrict {
- Thunk::evaluated(evaluate(ctx.clone(), arg)?)
- } else {
- let ctx = ctx.clone();
- let arg = arg.clone();
-
- Thunk!(move || evaluate(ctx, &arg))
- },
- )?;
- }
- Ok(())
- }
-
- fn named_names(&self, handler: &mut dyn FnMut(&IStr)) {
- for (name, _) in &self.named {
- handler(name);
- }
- }
-
- fn is_empty(&self) -> bool {
- self.unnamed.is_empty() && self.named.is_empty()
- }
-}
crates/jrsonnet-evaluator/src/function/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/mod.rs
+++ b/crates/jrsonnet-evaluator/src/function/mod.rs
@@ -1,11 +1,10 @@
use std::{fmt::Debug, rc::Rc};
-pub use arglike::{ArgLike, ArgsLike, TlaArg};
use educe::Educe;
use jrsonnet_gcmodule::{Cc, Trace};
use jrsonnet_interner::IStr;
pub use jrsonnet_macros::builtin;
-use jrsonnet_parser::{Destruct, Expr, ExprParams, Span, Spanned};
+use jrsonnet_parser::{ArgsDesc, Destruct, Expr, ExprParams, Span, Spanned};
use self::{
builtin::{Builtin, StaticBuiltin},
@@ -17,12 +16,12 @@
Result, Thunk, Val,
};
-pub mod arglike;
pub mod builtin;
-pub mod native;
-pub mod parse;
+mod native;
+mod parse;
mod prepared;
+pub use native::NativeFn;
pub use prepared::PreparedFuncVal;
pub use jrsonnet_parser::function::*;
@@ -81,10 +80,10 @@
}
/// Create context, with which body code will run
- pub fn call_body_context(
+ pub(crate) fn call_body_context(
&self,
call_ctx: Context,
- args: &dyn ArgsLike,
+ args: &ArgsDesc,
tailstrict: bool,
) -> Result<Context> {
parse_function_call(call_ctx, self.ctx.clone(), &self.params, args, tailstrict)
@@ -170,7 +169,7 @@
&self,
call_ctx: Context,
loc: CallLocation<'_>,
- args: &dyn ArgsLike,
+ args: &ArgsDesc,
tailstrict: bool,
) -> Result<Val> {
match self {
@@ -179,7 +178,7 @@
evaluate(body_ctx, &func.body)
}
Self::Thunk(thunk) => {
- if !args.is_empty() {
+ if !args.named.is_empty() || !args.unnamed.is_empty() {
bail!(TooManyArgsFunctionHas(0, FunctionSignature::empty()))
}
thunk.evaluate()
crates/jrsonnet-evaluator/src/function/native.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/native.rs
+++ b/crates/jrsonnet-evaluator/src/function/native.rs
@@ -1,2 +1,68 @@
+use std::marker::PhantomData;
+
+use jrsonnet_gcmodule::Trace;
+
use super::PreparedFuncVal;
-use crate::{typed::Typed, CallLocation, Result, Thunk};
+use crate::{bail, function::FuncVal, typed::Typed, CallLocation, Result, Val};
+use jrsonnet_types::{ComplexValType, ValType};
+
+#[derive(Debug, Trace, Clone)]
+pub struct NativeFn<D: 'static>(pub(crate) PreparedFuncVal, PhantomData<D>);
+macro_rules! impl_native_desc {
+ ($i:expr; $($gen:ident)*) => {
+ impl<$($gen,)* O> NativeFn<($($gen,)* O,)>
+ where
+ $($gen: Typed,)*
+ O: Typed,
+ {
+ #[allow(non_snake_case, clippy::too_many_arguments)]
+ pub fn call(
+ &self,
+ $($gen: $gen,)*
+ ) -> Result<O> {
+ let val = self.0.call(
+ CallLocation::native(),
+ &[$(Typed::into_lazy_untyped($gen),)*],
+ &[],
+ )?;
+ O::from_untyped(val)
+ }
+ }
+ impl<$($gen,)* O> Typed for NativeFn<($($gen,)* O,)> {
+ const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);
+
+ fn into_untyped(_typed: Self) -> Result<Val> {
+ bail!("can only convert functions from jsonnet to native")
+ }
+
+ fn from_untyped(untyped: Val) -> Result<Self> {
+ let func = FuncVal::from_untyped(untyped)?;
+ Ok(Self(
+ PreparedFuncVal::new(func, $i, &[])?,
+ PhantomData,
+ ))
+ }
+ }
+ };
+ ($i:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {
+ impl_native_desc!($i; $($cur)*);
+ impl_native_desc!($i + 1; $($cur)* $c @ $($rest)*);
+ };
+ ($i:expr; $($cur:ident)* @) => {
+ impl_native_desc!($i; $($cur)*);
+ }
+}
+
+impl_native_desc! {
+ 0; @ A B C D E F G H I J K L
+}
+
+mod native_macro {
+ #[macro_export]
+ macro_rules! NativeFn {
+ (($($t:ty),* $(,)?) -> $res:ty) => {
+ NativeFn<($($t,)* $res)>
+ }
+ }
+}
+pub use crate::NativeFn;
crates/jrsonnet-evaluator/src/function/parse.rsdiffbeforeafterboth1use std::rc::Rc;21use jrsonnet_parser::{3use jrsonnet_parser::{2 function::{FunctionSignature, ParamName},4 function::{FunctionSignature, ParamName},3 ExprParams,5 ArgsDesc, Expr, ExprParams, Spanned,4};6};5use rustc_hash::FxHashMap;7use rustc_hash::FxHashMap;687use super::arglike::ArgsLike;8use crate::{9use crate::{9 bail,10 bail,10 destructure::destruct,11 destructure::destruct,11 error::{ErrorKind::*, Result},12 error::{ErrorKind::*, Result},12 evaluate_named_param,13 evaluate, evaluate_named_param,13 gc::WithCapacityExt as _,14 gc::WithCapacityExt as _,14 Context, Pending, Thunk, Val,15 Context, Pending, Thunk, Val,15};16};1718fn eval_arg(ctx: Context, arg: &Rc<Spanned<Expr>>, tailstrict: bool) -> Result<Thunk<Val>> {19 if tailstrict {20 Ok(Thunk::evaluated(evaluate(ctx, arg)?))21 } else {22 let arg = arg.clone();23 Ok(Thunk!(move || evaluate(ctx, &arg)))24 }25}162617/// Creates correct [context](Context) for function body evaluation returning error on invalid call.27/// Creates correct [context](Context) for function body evaluation returning error on invalid call.18///28///22/// * `params`: function parameters' definition32/// * `params`: function parameters' definition23/// * `args`: passed function arguments33/// * `args`: passed function arguments24/// * `tailstrict`: if set to `true` function arguments are eagerly executed, otherwise - lazily34/// * `tailstrict`: if set to `true` function arguments are eagerly executed, otherwise - lazily25pub fn parse_function_call(35pub(crate) fn parse_function_call(26 ctx: Context,36 ctx: Context,27 body_ctx: Context,37 body_ctx: Context,28 params: &ExprParams,38 params: &ExprParams,29 args: &dyn ArgsLike,39 args: &ArgsDesc,30 tailstrict: bool,40 tailstrict: bool,31) -> Result<Context> {41) -> Result<Context> {32 let mut passed_args = FxHashMap::with_capacity(params.binds_len());42 let mut passed_args = FxHashMap::with_capacity(params.binds_len());33 if args.unnamed_len() > params.signature.len() {43 if args.unnamed.len() > params.signature.len() {34 bail!(TooManyArgsFunctionHas(44 bail!(TooManyArgsFunctionHas(35 params.signature.len(),45 params.signature.len(),36 params.signature.clone(),46 params.signature.clone(),40 let mut filled_named = 0;50 let mut filled_named = 0;41 let mut filled_positionals = 0;51 let mut filled_positionals = 0;425243 args.unnamed_iter(ctx.clone(), tailstrict, &mut |id, arg| {53 for (id, arg) in args.unnamed.iter().enumerate() {44 destruct(54 destruct(45 ¶ms.exprs[id].destruct,55 ¶ms.exprs[id].destruct,46 arg,56 eval_arg(ctx.clone(), arg, tailstrict)?,47 Pending::new_filled(ctx.clone()),57 Pending::new_filled(ctx.clone()),48 &mut passed_args,58 &mut passed_args,49 )?;59 )?;50 filled_positionals += 1;60 filled_positionals += 1;51 Ok(())52 })?;61 }536254 args.named_iter(ctx, tailstrict, &mut |name, value| {63 for (name, value) in &args.named {55 // FIXME: O(n) for arg existence check64 // FIXME: O(n) for arg existence check56 if !params.exprs.iter().any(|p| &p.destruct.name() == name) {65 if !params.exprs.iter().any(|p| &p.destruct.name() == name) {57 bail!(UnknownFunctionParameter(name.clone()));66 bail!(UnknownFunctionParameter(name.clone()));58 }67 }59 if passed_args.insert(name.clone(), value).is_some() {68 if passed_args69 .insert(name.clone(), eval_arg(ctx.clone(), value, tailstrict)?)70 .is_some()71 {60 bail!(BindingParameterASecondTime(name.clone()));72 bail!(BindingParameterASecondTime(name.clone()));61 }73 }62 filled_named += 1;74 filled_named += 1;63 Ok(())64 })?;75 }657666 if filled_named + filled_positionals < params.len() {77 if filled_named + filled_positionals < params.len() {67 // Some args are unset, but maybe we have defaults for them78 // Some args are unset, but maybe we have defaults for them104115105 // Some args still weren't filled116 // Some args still weren't filled106 if filled_named + filled_positionals != params.len() {117 if filled_named + filled_positionals != params.len() {107 for param in params.exprs.iter().skip(args.unnamed_len()) {118 for param in params.exprs.iter().skip(args.unnamed.len()) {108 let mut found = false;119 let mut found = false;109 args.named_names(&mut |name| {120 for (name, _) in &args.named {110 if ¶m.destruct.name() == name {121 if ¶m.destruct.name() == name {111 found = true;122 found = true;112 }123 }113 });124 }114 if !found {125 if !found {115 bail!(FunctionParameterNotBoundInCall(126 bail!(FunctionParameterNotBoundInCall(116 param.destruct.name(),127 param.destruct.name(),141pub fn parse_builtin_call(152pub fn parse_builtin_call(142 ctx: Context,153 ctx: Context,143 params: FunctionSignature,154 params: FunctionSignature,144 args: &dyn ArgsLike,155 args: &ArgsDesc,145 tailstrict: bool,156 tailstrict: bool,146) -> Result<Vec<Option<Thunk<Val>>>> {157) -> Result<Vec<Option<Thunk<Val>>>> {147 let mut passed_args: Vec<Option<Thunk<Val>>> = vec![None; params.len()];158 let mut passed_args: Vec<Option<Thunk<Val>>> = vec![None; params.len()];148 if args.unnamed_len() > params.len() {159 if args.unnamed.len() > params.len() {149 bail!(TooManyArgsFunctionHas(params.len(), params,))160 bail!(TooManyArgsFunctionHas(params.len(), params,))150 }161 }151162152 let mut filled_args = 0;163 let mut filled_args = 0;153164154 args.unnamed_iter(ctx.clone(), tailstrict, &mut |id, arg| {165 for (id, arg) in args.unnamed.iter().enumerate() {155 passed_args[id] = Some(arg);166 passed_args[id] = Some(eval_arg(ctx.clone(), arg, tailstrict)?);156 filled_args += 1;167 filled_args += 1;157 Ok(())158 })?;168 }159169160 args.named_iter(ctx, tailstrict, &mut |name, arg| {170 for (name, arg) in &args.named {161 // FIXME: O(n) for arg existence check171 // FIXME: O(n) for arg existence check162 let id = params172 let id = params163 .iter()173 .iter()164 .position(|p| p.name() == name)174 .position(|p| p.name() == name)165 .ok_or_else(|| UnknownFunctionParameter(name.clone()))?;175 .ok_or_else(|| UnknownFunctionParameter(name.clone()))?;166 if passed_args[id].replace(arg).is_some() {176 if passed_args[id]177 .replace(eval_arg(ctx.clone(), arg, tailstrict)?)178 .is_some()179 {167 bail!(BindingParameterASecondTime(name.clone()));180 bail!(BindingParameterASecondTime(name.clone()));168 }181 }169 filled_args += 1;182 filled_args += 1;170 Ok(())171 })?;183 }172184173 if filled_args < params.len() {185 if filled_args < params.len() {174 for (id, _) in params.iter().enumerate().filter(|(_, p)| p.has_default()) {186 for (id, _) in params.iter().enumerate().filter(|(_, p)| p.has_default()) {180192181 // Some args still wasn't filled193 // Some args still wasn't filled182 if filled_args != params.len() {194 if filled_args != params.len() {183 for param in params.iter().skip(args.unnamed_len()) {195 for param in params.iter().skip(args.unnamed.len()) {184 let mut found = false;196 let mut found = false;185 args.named_names(&mut |name| {197 for (name, _) in &args.named {186 if param.name() == name {198 if param.name() == name {187 found = true;199 found = true;188 }200 }189 });201 }190 if !found {202 if !found {191 bail!(FunctionParameterNotBoundInCall(203 bail!(FunctionParameterNotBoundInCall(192 param.name().clone(),204 param.name().clone(),crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -19,7 +19,7 @@
mod obj;
pub mod stack;
pub mod stdlib;
-mod tla;
+pub mod tla;
pub mod trace;
pub mod typed;
pub mod val;
crates/jrsonnet-evaluator/src/tla.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/tla.rs
+++ b/crates/jrsonnet-evaluator/src/tla.rs
@@ -1,12 +1,68 @@
use std::{collections::HashMap, hash::BuildHasher};
+use jrsonnet_gcmodule::Trace;
use jrsonnet_interner::IStr;
+use jrsonnet_parser::{SourceFifo, SourcePath};
use crate::{
- function::{CallLocation, PreparedFuncVal, TlaArg},
- in_description_frame, Result, Val,
+ function::{CallLocation, PreparedFuncVal},
+ in_description_frame, with_state, Result, Thunk, Val,
};
+#[derive(Clone, Trace)]
+pub enum TlaArg {
+ String(IStr),
+ Val(Val),
+ Lazy(Thunk<Val>),
+ Import(String),
+ ImportStr(String),
+ InlineCode(String),
+}
+impl TlaArg {
+ pub fn evaluate_tailstrict(&self) -> Result<Val> {
+ match self {
+ Self::String(s) => Ok(Val::string(s.clone())),
+ Self::Val(val) => Ok(val.clone()),
+ Self::Lazy(lazy) => Ok(lazy.evaluate()?),
+ Self::Import(p) => with_state(|s| {
+ let resolved = s.resolve_from_default(&p.as_str())?;
+ s.import_resolved(resolved)
+ }),
+ Self::ImportStr(p) => with_state(|s| {
+ let resolved = s.resolve_from_default(&p.as_str())?;
+ s.import_resolved_str(resolved).map(Val::string)
+ }),
+ Self::InlineCode(p) => with_state(|s| {
+ let resolved =
+ SourcePath::new(SourceFifo("<inline code>".to_owned(), p.as_bytes().into()));
+ s.import_resolved(resolved)
+ }),
+ }
+ }
+ pub fn evaluate(&self) -> Result<Thunk<Val>> {
+ match self {
+ Self::String(s) => Ok(Thunk::evaluated(Val::string(s.clone()))),
+ Self::Val(val) => Ok(Thunk::evaluated(val.clone())),
+ Self::Lazy(lazy) => Ok(lazy.clone()),
+ Self::Import(p) => with_state(|s| {
+ let resolved = s.resolve_from_default(&p.as_str())?;
+ Ok(Thunk!(move || s.import_resolved(resolved)))
+ }),
+ Self::ImportStr(p) => with_state(|s| {
+ let resolved = s.resolve_from_default(&p.as_str())?;
+ Ok(Thunk!(move || s
+ .import_resolved_str(resolved)
+ .map(Val::string)))
+ }),
+ Self::InlineCode(p) => with_state(|s| {
+ let resolved =
+ SourcePath::new(SourceFifo("<inline code>".to_owned(), p.as_bytes().into()));
+ Ok(Thunk!(move || s.import_resolved(resolved)))
+ }),
+ }
+ }
+}
+
pub fn apply_tla<H: BuildHasher>(args: &HashMap<IStr, TlaArg, H>, val: Val) -> Result<Val> {
Ok(if let Val::Func(func) = val {
in_description_frame(
crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/typed/conversions.rs
+++ b/crates/jrsonnet-evaluator/src/typed/conversions.rs
@@ -8,7 +8,7 @@
use crate::{
arr::{ArrValue, BytesArray},
bail,
- function::{CallLocation, FuncDesc, FuncVal, PreparedFuncVal},
+ function::{FuncDesc, FuncVal},
typed::CheckType,
val::{IndexableVal, NumValue, StrValue, ThunkMapper},
ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,
@@ -671,69 +671,9 @@
Ok(None)
} else {
T::from_untyped(untyped).map(Some)
- }
- }
-}
-
-#[derive(Debug, Trace, Clone)]
-pub struct NativeFn<D: 'static>(pub(crate) PreparedFuncVal, PhantomData<D>);
-macro_rules! impl_native_desc {
- ($i:expr; $($gen:ident)*) => {
- impl<$($gen,)* O> NativeFn<($($gen,)* O,)>
- where
- $($gen: Typed,)*
- O: Typed,
- {
- pub fn call(
- &self,
- $($gen: $gen,)*
- ) -> Result<O> {
- let val = self.0.call(
- CallLocation::native(),
- &[$(Typed::into_lazy_untyped($gen),)*],
- &[],
- )?;
- O::from_untyped(val)
- }
- }
- impl<$($gen,)* O> Typed for NativeFn<($($gen,)* O,)> {
- const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Func);
-
- fn into_untyped(_typed: Self) -> Result<Val> {
- bail!("can only convert functions from jsonnet to native")
- }
-
- fn from_untyped(untyped: Val) -> Result<Self> {
- let func = FuncVal::from_untyped(untyped)?;
- Ok(Self(
- PreparedFuncVal::new(func, $i, &[])?,
- PhantomData,
- ))
- }
}
- };
- ($i:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => {
- impl_native_desc!($i; $($cur)*);
- impl_native_desc!($i + 1; $($cur)* $c @ $($rest)*);
- };
- ($i:expr; $($cur:ident)* @) => {
- impl_native_desc!($i; $($cur)*);
}
-}
-
-impl_native_desc! {
- 0; @ A B C D E F G H I J K L
}
-
-mod native_macro {
- #[macro_export]
- macro_rules! NativeFn {
- (($($t:ty),* $(,)?) -> $res:ty) => {
- NativeFn<($($t,)* $res)>
- }
- }
-}
-pub use crate::NativeFn;
impl Typed for NumValue {
const TYPE: &'static ComplexValType = &ComplexValType::Simple(ValType::Num);
crates/jrsonnet-macros/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-macros/src/lib.rs
+++ b/crates/jrsonnet-macros/src/lib.rs
@@ -405,7 +405,7 @@
const _: () = {
use ::jrsonnet_evaluator::{
State, Val,
- function::{builtin::{Builtin, StaticBuiltin}, FunctionSignature, ParamParse, ParamName, ParamDefault, CallLocation, ArgsLike, parse::parse_builtin_call},
+ function::{builtin::{Builtin, StaticBuiltin}, FunctionSignature, ParamParse, ParamName, ParamDefault, CallLocation},
Result, Context, typed::Typed,
parser::Span, params, Thunk,
};
crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/arrays.rs
+++ b/crates/jrsonnet-stdlib/src/arrays.rs
@@ -2,9 +2,9 @@
use jrsonnet_evaluator::{
bail,
- function::{builtin, FuncVal},
+ function::{builtin, FuncVal, NativeFn},
runtime_error,
- typed::{BoundedI32, BoundedUsize, Either2, NativeFn, Typed},
+ typed::{BoundedI32, BoundedUsize, Either2, Typed},
val::{equals, ArrValue, IndexableVal},
Either, IStr, ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,
};
crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -13,7 +13,8 @@
pub use hash::*;
use jrsonnet_evaluator::{
error::Result,
- function::{CallLocation, FuncVal, TlaArg},
+ function::{CallLocation, FuncVal},
+ tla::TlaArg,
trace::PathResolver,
val::NumValue,
ContextBuilder, IStr, ObjValue, ObjValueBuilder, Thunk, Val,
tests/tests/cpp_test_suite.rsdiffbeforeafterboth--- a/tests/tests/cpp_test_suite.rs
+++ b/tests/tests/cpp_test_suite.rs
@@ -6,10 +6,10 @@
use jrsonnet_evaluator::{
FileImportResolver, IStr, ObjValueBuilder, State, Val, apply_tla,
- function::TlaArg,
gc::WithCapacityExt as _,
manifest::JsonFormat,
rustc_hash::FxHashMap,
+ tla::TlaArg,
trace::{CompactFormat, PathResolver, TraceFormat},
};
use jrsonnet_stdlib::ContextInitializer;