From ec695bd22ea2f04d40286d2f1e1c64530bfadb50 Mon Sep 17 00:00:00 2001 From: Anand Krishnamoorthi Date: Sat, 4 Mar 2023 04:34:10 -0800 Subject: [PATCH] debugging::print builtin Signed-off-by: Anand Krishnamoorthi --- src/builtins/debugging.rs | 31 +++++++++++++++++++++++++++++++ src/builtins/mod.rs | 33 ++++++++++++++++++++++++++++----- src/interpreter.rs | 3 ++- 3 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 src/builtins/debugging.rs diff --git a/src/builtins/debugging.rs b/src/builtins/debugging.rs new file mode 100644 index 0000000..34d0624 --- /dev/null +++ b/src/builtins/debugging.rs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +use crate::ast::Expr; +use crate::builtins; +use crate::lexer::Span; +use crate::value::Value; + +use std::collections::HashMap; + +use anyhow::Result; + +pub fn register(m: &mut HashMap<&'static str, builtins::BuiltinFcn>) { + m.insert("print", print); +} + +// Symbol analyzer must ensure that vars used by print are defined before +// the print statement. Scheduler must ensure the above constraint. +// Additionally interpreter must allow undefined inputs to print. +fn print(span: &Span, _params: &[Expr], args: &[Value]) -> Result { + let mut msg = String::default(); + for a in args { + match a { + Value::Undefined => msg += "", + _ => msg += format!("{a}").as_str(), + }; + } + + span.message("print", msg.as_str()); + Ok(Value::Bool(true)) +} diff --git a/src/builtins/mod.rs b/src/builtins/mod.rs index b55db45..5562779 100644 --- a/src/builtins/mod.rs +++ b/src/builtins/mod.rs @@ -1,14 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -pub mod aggregates; -pub mod arrays; +mod aggregates; +mod arrays; pub mod comparison; +mod debugging; pub mod numbers; pub mod sets; -pub mod strings; +mod strings; pub mod types; -pub mod utils; +mod utils; use crate::ast::Expr; use crate::lexer::Span; @@ -31,8 +32,30 @@ lazy_static! { aggregates::register(&mut m); arrays::register(&mut m); sets::register(&mut m); - types::register(&mut m); + //objects::register(&mut m); strings::register(&mut m); + //regex::register(&mut m); + //glob::register(&mut m); + //bitwise::register(&mut m); + //conversions::register(&mut m); + //units::register(&mut m); + types::register(&mut m); + //encoding::register(&mut m); + //token_signing::register(&mut m); + //token_verification::register(&mut m); + //time::register(&mut m); + //cryptography::register(&mut m); + //graphs::register(&mut m); + //graphql::register(&mut m); + //http::register(&mut m); + //cryptography::register(&mut m); + //net::register(&mut m); + //uuid::register(&mut m); + //semantic_versions::register(&mut m); + //rego::register(&mut m); + //opa::register(&mut m); + debugging::register(&mut m); + //tracing::register(&mut m); m }; diff --git a/src/interpreter.rs b/src/interpreter.rs index 8ee4c8c..01687b5 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -1187,10 +1187,11 @@ impl<'source> Interpreter<'source> { params: &'source Vec>, ) -> Result { let mut args = vec![]; + let allow_undefined = name == "print"; // TODO: with modifier for p in params { match self.eval_expr(p)? { // If any argument is undefined, then the call is undefined. - Value::Undefined => return Ok(Value::Undefined), + Value::Undefined if !allow_undefined => return Ok(Value::Undefined), p => args.push(p), } }