git.delta.rocks / jrsonnet / refs/commits / d429a484deb0

difftreelog

feat(evaluator) add ability to call functions with values

Лач2020-06-25parent: #eff1bc2.patch.diff
in: master

2 files changed

modifiedcrates/jsonnet-evaluator/src/function.rsdiffbeforeafterboth
--- 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<Context>,
+	params: &ParamsDesc,
+	args: &[Val],
+) -> Result<Context> {
+	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)?)
+}
modifiedcrates/jsonnet-evaluator/src/val.rsdiffbeforeafterboth
1use crate::{1use crate::{
2 create_error, evaluate, function::inline_parse_function_call, Context, Error, ObjValue, Result,2 create_error, evaluate,
3 function::{inline_parse_function_call, place_args},
4 with_state, Context, Error, ObjValue, Result,
3};5};
4use jsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParamsDesc};6use jsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParamsDesc};
5use std::{7use std::{
87 evaluate(ctx, &self.body)89 evaluate(ctx, &self.body)
88 }90 }
91
92 #[inline(always)]
93 pub fn evaluate_values(&self, call_ctx: Context, args: &[Val]) -> Result<Val> {
94 let ctx = place_args(call_ctx, Some(self.ctx.clone()), &self.params, args)?;
95 evaluate(ctx, &self.body)
96 }
89}97}
9098
91#[derive(Debug)]99#[derive(Debug)]