Skip to content

Commit

Permalink
feat: add function mode for the evaluator
Browse files Browse the repository at this point in the history
Signed-off-by: peefy <[email protected]>
  • Loading branch information
Peefy committed Aug 5, 2024
1 parent 96b6ae8 commit 330ee2a
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 5 deletions.
19 changes: 16 additions & 3 deletions kclvm/evaluator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,26 @@ impl<'ctx> Evaluator<'ctx> {
pub fn run(self: &Evaluator<'ctx>) -> Result<(String, String)> {
if let Some(modules) = self.program.pkgs.get(kclvm_ast::MAIN_PKG) {
self.init_scope(kclvm_ast::MAIN_PKG);
self.compile_ast_modules(modules)
self.compile_ast_modules(modules);
}
Ok(self.plan_globals_to_string())
}

/// Evaluate the program with the function mode and return the JSON and YAML result,
/// which means treating the files in the entire main package as a function run to
/// return the result of the function run, rather than a dictionary composed of each
/// configuration attribute.
pub fn run_as_function(self: &Evaluator<'ctx>) -> ValueRef {
if let Some(modules) = self.program.pkgs.get(kclvm_ast::MAIN_PKG) {
self.init_scope(kclvm_ast::MAIN_PKG);
self.compile_ast_modules(modules)
} else {
ValueRef::undefined()
}
}

/// Plan globals to a planed json and yaml string.
pub fn plan_globals_to_string(&self) -> (String, String) {
pub(crate) fn plan_globals_to_string(&self) -> (String, String) {
let current_pkgpath = self.current_pkgpath();
let pkg_scopes = &self.pkg_scopes.borrow();
let scopes = pkg_scopes
Expand Down Expand Up @@ -177,7 +190,7 @@ impl<'ctx> Evaluator<'ctx> {
Ok(self.undefined_value())
}

fn plan_value(&self, value: &ValueRef) -> (String, String) {
pub fn plan_value(&self, value: &ValueRef) -> (String, String) {
let mut ctx = self.runtime_ctx.borrow_mut();
let value = match ctx.buffer.custom_manifests_output.clone() {
Some(output) => ValueRef::from_yaml_stream(&mut ctx, &output).unwrap(),
Expand Down
8 changes: 6 additions & 2 deletions kclvm/evaluator/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use kclvm_ast::ast;
use kclvm_ast::walker::TypedResultWalker;
use kclvm_runtime::ValueRef;

use super::Evaluator;
use crate::error as kcl_error;
Expand Down Expand Up @@ -80,7 +81,7 @@ impl<'ctx> Evaluator<'ctx> {
/// 1. scan all possible global variables and allocate undefined values to global pointers.
/// 2. build all user-defined schema/rule types.
/// 3. evaluate all codes for the third time.
pub(crate) fn compile_ast_modules(&self, modules: &'ctx [ast::Module]) {
pub(crate) fn compile_ast_modules(&self, modules: &'ctx [ast::Module]) -> ValueRef {
// Scan global variables
for ast_module in modules {
// Pre define global variables with undefined values
Expand All @@ -90,10 +91,13 @@ impl<'ctx> Evaluator<'ctx> {
for ast_module in modules {
self.compile_module_import_and_types(ast_module);
}
let mut result = ValueRef::undefined();
// Compile the ast module in the pkgpath.
for ast_module in modules {
self.walk_module(ast_module)
result = self
.walk_module(ast_module)
.expect(kcl_error::RUNTIME_ERROR_MSG);
}
result
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: evaluator/src/tests.rs
expression: "format!(\"{}\", evaluator.run_as_function().to_string())"
---
"bar"
31 changes: 31 additions & 0 deletions kclvm/evaluator/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,37 @@ macro_rules! evaluator_snapshot {
};
}

#[macro_export]
macro_rules! evaluator_function_snapshot {
($name:ident, $src:expr) => {
#[test]
fn $name() {
let p = load_packages(&LoadPackageOptions {
paths: vec!["test.k".to_string()],
load_opts: Some(LoadProgramOptions {
k_code_list: vec![$src.to_string()],
..Default::default()
}),
load_builtin: false,
..Default::default()
})
.unwrap();
let evaluator = Evaluator::new(&p.program);
insta::assert_snapshot!(format!("{}", evaluator.run_as_function().to_string()));
}
};
}

evaluator_function_snapshot! {function_stmt_0, r#"
import json
config = {
foo: "bar"
}
json.encode("${config.foo}")
"#}

evaluator_snapshot! {expr_stmt_0, "1"}
evaluator_snapshot! {expr_stmt_1, "2.0"}
evaluator_snapshot! {expr_stmt_2, "True"}
Expand Down

0 comments on commit 330ee2a

Please sign in to comment.