Skip to content

Commit

Permalink
feat: impl backtrack breakpoint for the evaluator (kcl-lang#1201)
Browse files Browse the repository at this point in the history
Signed-off-by: peefy <[email protected]>
  • Loading branch information
Peefy authored Apr 8, 2024
1 parent 00bd13f commit 2958688
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 14 deletions.
16 changes: 16 additions & 0 deletions kclvm/evaluator/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use kclvm_runtime::{BacktraceFrame, MAIN_PKG_PATH};
use crate::{
error as kcl_error,
func::FunctionCaller,
lazy::{BacktrackMeta, Setter},
proxy::{Frame, Proxy},
rule::RuleCaller,
schema::SchemaCaller,
Expand Down Expand Up @@ -244,7 +245,22 @@ impl<'ctx> Evaluator<'ctx> {
if ctx.cfg.debug_mode {
if let Some(backtrace_frame) = ctx.backtrace.pop() {
ctx.panic_info.kcl_func = backtrace_frame.func;
ctx.panic_info.kcl_line = backtrace_frame.line;
ctx.panic_info.kcl_file = backtrace_frame.file;
}
}
}

pub(crate) fn push_backtrack_meta(&self, setter: &Setter) {
let meta = &mut self.backtrack_meta.borrow_mut();
meta.push(BacktrackMeta {
stopped: setter.stopped.clone(),
is_break: false,
});
}

pub(crate) fn pop_backtrack_meta(&self) {
let meta = &mut self.backtrack_meta.borrow_mut();
meta.pop();
}
}
21 changes: 14 additions & 7 deletions kclvm/evaluator/src/lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,29 @@ use crate::Evaluator;
pub type LazyEvalScopeRef = Rc<RefCell<LazyEvalScope>>;

#[macro_export]
macro_rules! check_backtrack_stop {
($ctx: expr, $stmt: expr) => {
macro_rules! backtrack_break_here {
($ctx: expr, $stmt: expr) => {{
// If is break, do not execute the stmt and return immediately.
if $ctx.backtrack_meta.borrow().is_break {
return $ctx.ok_result();
if let Some(meta) = $ctx.backtrack_meta.borrow().last() {
if meta.is_break {
return $ctx.ok_result();
}
}
}};
}

#[macro_export]
macro_rules! backtrack_update_break {
($ctx: expr, $stmt: expr) => {{
// Check whether pass the breakpoint.
{
let meta = &mut $ctx.backtrack_meta.borrow_mut();
if let Some(meta) = $ctx.backtrack_meta.borrow_mut().last_mut() {
if let Some(stopped) = &meta.stopped {
if stopped == &$stmt.id {
meta.is_break = true
}
}
}
};
}};
}

/// LazyEvalScope represents a scope of sequentially independent calculations, where
Expand Down
4 changes: 2 additions & 2 deletions kclvm/evaluator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub struct Evaluator<'ctx> {
/// Local variables in the loop.
pub local_vars: RefCell<HashSet<String>>,
/// Schema attr backtrack meta
pub backtrack_meta: RefCell<BacktrackMeta>,
pub backtrack_meta: RefCell<Vec<BacktrackMeta>>,
}

pub enum EvalContext {
Expand Down Expand Up @@ -113,7 +113,7 @@ impl<'ctx> Evaluator<'ctx> {
import_names: RefCell::new(Default::default()),
pkg_scopes: RefCell::new(Default::default()),
local_vars: RefCell::new(Default::default()),
backtrack_meta: RefCell::new(BacktrackMeta::default()),
backtrack_meta: RefCell::new(Default::default()),
}
}

Expand Down
12 changes: 8 additions & 4 deletions kclvm/evaluator/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ use kclvm_runtime::{
};
use kclvm_sema::{builtin, plugin};

use crate::check_backtrack_stop;
use crate::func::{func_body, FunctionCaller, FunctionEvalContext};
use crate::lazy::Setter;
use crate::proxy::Proxy;
use crate::rule::{rule_body, rule_check, RuleCaller, RuleEvalContext};
use crate::schema::{schema_body, schema_check, SchemaCaller, SchemaEvalContext};
use crate::ty::type_pack_and_check;
use crate::union::union_entry;
use crate::{backtrack_break_here, backtrack_update_break};
use crate::{error as kcl_error, GLOBAL_LEVEL, INNER_LEVEL};
use crate::{EvalResult, Evaluator};

Expand All @@ -36,9 +36,9 @@ impl<'ctx> TypedResultWalker<'ctx> for Evaluator<'ctx> {
*/

fn walk_stmt(&self, stmt: &'ctx ast::Node<ast::Stmt>) -> Self::Result {
check_backtrack_stop!(self, stmt);
backtrack_break_here!(self, stmt);
self.update_ctx_panic_info(stmt);
match &stmt.node {
let value = match &stmt.node {
ast::Stmt::TypeAlias(type_alias) => self.walk_type_alias_stmt(type_alias),
ast::Stmt::Expr(expr_stmt) => self.walk_expr_stmt(expr_stmt),
ast::Stmt::Unification(unification_stmt) => {
Expand All @@ -52,7 +52,9 @@ impl<'ctx> TypedResultWalker<'ctx> for Evaluator<'ctx> {
ast::Stmt::SchemaAttr(schema_attr) => self.walk_schema_attr(schema_attr),
ast::Stmt::Schema(schema_stmt) => self.walk_schema_stmt(schema_stmt),
ast::Stmt::Rule(rule_stmt) => self.walk_rule_stmt(rule_stmt),
}
};
backtrack_update_break!(self, stmt);
value
}

fn walk_expr_stmt(&self, expr_stmt: &'ctx ast::ExprStmt) -> Self::Result {
Expand Down Expand Up @@ -1198,7 +1200,9 @@ impl<'ctx> Evaluator<'ctx> {
if let Some(stmt) = schema.ctx.borrow().node.body.get(setter.stmt) {
self.push_pkgpath(&frame.pkgpath);
self.enter_scope();
self.push_backtrack_meta(setter);
let value = self.walk_stmt(stmt);
self.pop_backtrack_meta();
self.leave_scope();
self.pop_pkgpath();
value
Expand Down
2 changes: 1 addition & 1 deletion kclvm/evaluator/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ impl SchemaEvalContext {
if index >= n {
value
} else {
// Call frame
// Call setter function
s.walk_stmts_with_setter(&self.node.body, &setters[index])
.expect(kcl_error::INTERNAL_ERROR_MSG);
{
Expand Down
11 changes: 11 additions & 0 deletions test/grammar/schema/irrelevant_order/simple_6/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
schema Config:
a: int = b
b: int = 2
if True:
b = 1
b += 3

x0 = Config {}
x1 = Config {
a = 10
}
6 changes: 6 additions & 0 deletions test/grammar/schema/irrelevant_order/simple_6/stdout.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
x0:
a: 4
b: 4
x1:
a: 10
b: 4

0 comments on commit 2958688

Please sign in to comment.