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

difftreelog

feat(evaluator) better stacktraces

Лач2020-06-04parent: #7bff493.patch.diff
in: master

1 file changed

modifiedcrates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth
236 }) => {236 }) => {
237 let name = evaluate_field_name(context.clone(), &name)?;237 let name = evaluate_field_name(context.clone(), &name)?;
238 new_members.insert(238 new_members.insert(
239 name,239 name.clone(),
240 ObjMember {240 ObjMember {
241 add: plus,241 add: plus,
242 visibility: visibility.clone(),242 visibility: visibility.clone(),
243 invoke: binding!(243 invoke: binding!(
244 closure!(clone value, clone context_creator, |this, super_obj| {244 closure!(clone name, clone value, clone context_creator, |this, super_obj| {
245 push(value.clone(), "object ".to_owned()+&name+" field", ||{
245 let context = context_creator.0(this, super_obj)?;246 let context = context_creator.0(this, super_obj)?;
246 // TODO: Assert
247 evaluate(247 evaluate(
248 context,248 context,
249 &value,249 &value,
250 )?.unwrap_if_lazy()250 )?.unwrap_if_lazy()
251 })
251 })252 })
252 ),253 ),
253 },254 },
290291
291pub fn evaluate(context: Context, expr: &LocExpr) -> Result<Val> {292pub fn evaluate(context: Context, expr: &LocExpr) -> Result<Val> {
292 use Expr::*;293 use Expr::*;
293 push(expr.clone(), "expr".to_owned(), || {294 let locexpr = expr.clone();
294 let LocExpr(expr, loc) = expr;295 let LocExpr(expr, loc) = expr;
295 Ok(match &**expr {296 Ok(match &**expr {
296 Literal(LiteralType::This) => Val::Obj(297 Literal(LiteralType::This) => Val::Obj(
378 Apply(value, ArgsDesc(args)) => {379 Apply(value, ArgsDesc(args)) => {
379 let value = evaluate(context.clone(), value)?.unwrap_if_lazy()?;380 let value = evaluate(context.clone(), value)?.unwrap_if_lazy()?;
380 match value {381 match value {
381 // TODO: Capture context of application
382 Val::Intristic(ns, name) => match (&ns as &str, &name as &str) {382 Val::Intristic(ns, name) => match (&ns as &str, &name as &str) {
383 // arr/string/function383 // arr/string/function
384 ("std", "length") => {384 ("std", "length") => {
441 }441 }
442 (ns, name) => panic!("Intristic not found: {}.{}", ns, name),442 (ns, name) => panic!("Intristic not found: {}.{}", ns, name),
443 },443 },
444 Val::Func(f) => f.evaluate(444 Val::Func(f) => push(locexpr.clone(), "function call".to_owned(), || {
445 f.evaluate(
445 args.clone()446 args.clone()
446 .into_iter()447 .into_iter()
453 )454 )
454 })455 })
455 .collect(),456 .collect(),
456 )?,457 )
458 })?,
457 _ => panic!("{:?} is not a function", value),459 _ => panic!("{:?} is not a function", value),
458 }460 }
459 }461 }
460 Function(params, body) => evaluate_method(context, body, params.clone()),462 Function(params, body) => evaluate_method(context, body, params.clone()),
461 AssertExpr(AssertStmt(value, msg), returned) => {463 AssertExpr(AssertStmt(value, msg), returned) => {
462 if evaluate(context.clone(), &value)?464 if push(value.clone(), "assertion condition".to_owned(), || {
465 evaluate(context.clone(), &value)?
463 .try_cast_bool("assertion condition should be boolean")?466 .try_cast_bool("assertion condition should be boolean")
464 {467 })? {
468 push(
469 returned.clone(),
470 "assert 'return' branch".to_owned(),
465 evaluate(context, returned)?471 || evaluate(context, returned),
472 )?
466 } else if let Some(msg) = msg {473 } else if let Some(msg) = msg {
467 panic!(474 panic!(
468 "assertion failed ({:?}): {}",475 "assertion failed ({:?}): {}",
482 cond_then,488 cond_then,
483 cond_else,489 cond_else,
484 } => {490 } => {
485 if evaluate(context.clone(), &cond.0)?491 if push(cond.0.clone(), "if condition".to_owned(), || {
486 .try_cast_bool("if condition should be boolean")?492 evaluate(context.clone(), &cond.0)?.try_cast_bool("if condition should be boolean")
487 {493 })? {
494 push(
495 cond_then.clone(),
496 "if condition 'then' branch".to_owned(),
488 evaluate(context, cond_then)?497 || evaluate(context, cond_then),
498 )?
489 } else {499 } else {
490 match cond_else {500 match cond_else {
491 Some(v) => evaluate(context, v)?,501 Some(v) => push(v.clone(), "if condition 'else' branch".to_owned(), || {
502 evaluate(context, v)
503 })?,
492 None => Val::Bool(false),504 None => Val::Bool(false),
493 }505 }
494 }506 }
498 LocExpr(expr.clone(), loc.clone())510 LocExpr(expr.clone(), loc.clone())
499 ),511 ),
500 })512 })
501 })
502}513}
503514