From d429a484deb0668321d406f1517db705b6b8adc4 Mon Sep 17 00:00:00 2001 From: Лач Date: Thu, 25 Jun 2020 11:49:46 +0000 Subject: [PATCH] feat(evaluator): add ability to call functions with values --- --- a/crates/jsonnet-evaluator/src/function.rs +++ b/crates/jsonnet-evaluator/src/function.rs @@ -1,4 +1,4 @@ -use crate::{create_error, evaluate, lazy_val, resolved_lazy_val, Context, Error, Result}; +use crate::{create_error, evaluate, lazy_val, resolved_lazy_val, Context, Error, Result, Val}; use closure::closure; use jsonnet_parser::{ArgsDesc, ParamsDesc}; use std::collections::HashMap; @@ -78,3 +78,34 @@ Ok(body_ctx.unwrap_or(ctx).extend(out, None, None, None)?) } + +#[inline(always)] +pub(crate) fn place_args( + ctx: Context, + body_ctx: Option, + params: &ParamsDesc, + args: &[Val], +) -> Result { + let mut out = HashMap::new(); + let mut positioned_args = vec![None; params.0.len()]; + for (id, arg) in args.iter().enumerate() { + if id >= params.len() { + create_error(Error::TooManyArgsFunctionHas(params.len()))?; + } + positioned_args[id] = Some(arg); + } + // Fill defaults + for (id, p) in params.iter().enumerate() { + let val = if let Some(arg) = &positioned_args[id] { + (*arg).clone() + } else if let Some(default) = &p.1 { + evaluate(ctx.clone(), default)? + } else { + create_error(Error::FunctionParameterNotBoundInCall(p.0.clone()))?; + unreachable!() + }; + out.insert(p.0.clone(), resolved_lazy_val!(val)); + } + + Ok(body_ctx.unwrap_or(ctx).extend(out, None, None, None)?) +} --- a/crates/jsonnet-evaluator/src/val.rs +++ b/crates/jsonnet-evaluator/src/val.rs @@ -1,5 +1,7 @@ use crate::{ - create_error, evaluate, function::inline_parse_function_call, Context, Error, ObjValue, Result, + create_error, evaluate, + function::{inline_parse_function_call, place_args}, + with_state, Context, Error, ObjValue, Result, }; use jsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParamsDesc}; use std::{ @@ -86,6 +88,12 @@ )?; evaluate(ctx, &self.body) } + + #[inline(always)] + pub fn evaluate_values(&self, call_ctx: Context, args: &[Val]) -> Result { + let ctx = place_args(call_ctx, Some(self.ctx.clone()), &self.params, args)?; + evaluate(ctx, &self.body) + } } #[derive(Debug)] -- gitstuff