Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support config mutref except arguments. #413

Merged
merged 1 commit into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 22 additions & 2 deletions kclvm/compiler/src/codegen/llvm/context.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2021 The KCL Authors. All rights reserved.

use indexmap::IndexMap;
use indexmap::{IndexMap, IndexSet};
use inkwell::basic_block::BasicBlock;
use inkwell::builder::Builder;
use inkwell::context::Context;
Expand Down Expand Up @@ -57,6 +57,7 @@ pub type CompileResult<'a> = Result<BasicValueEnum<'a>, kcl_error::KCLError>;
pub struct Scope<'ctx> {
pub variables: RefCell<IndexMap<String, PointerValue<'ctx>>>,
pub closures: RefCell<IndexMap<String, PointerValue<'ctx>>>,
pub arguments: RefCell<IndexSet<String>>,
}

/// Schema internal order independent computation backtracking meta information.
Expand Down Expand Up @@ -957,6 +958,7 @@ impl<'ctx> ProgramCodeGen for LLVMCodeGenContext<'ctx> {
let scopes = vec![Rc::new(Scope {
variables: RefCell::new(IndexMap::default()),
closures: RefCell::new(IndexMap::default()),
arguments: RefCell::new(IndexSet::default()),
})];
pkg_scopes.insert(String::from(pkgpath), scopes);
}
Expand Down Expand Up @@ -1026,6 +1028,7 @@ impl<'ctx> ProgramCodeGen for LLVMCodeGenContext<'ctx> {
let scope = Rc::new(Scope {
variables: RefCell::new(IndexMap::default()),
closures: RefCell::new(IndexMap::default()),
arguments: RefCell::new(IndexSet::default()),
});
scopes.push(scope);
}
Expand Down Expand Up @@ -1399,6 +1402,18 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
}
}

/// Store the argument named `name` in the current scope.
pub(crate) fn store_argument_in_current_scope(&self, name: &str) {
// Find argument name in the scope
let current_pkgpath = self.current_pkgpath();
let mut pkg_scopes = self.pkg_scopes.borrow_mut();
let msg = format!("pkgpath {} is not found", current_pkgpath);
let scopes = pkg_scopes.get_mut(&current_pkgpath).expect(&msg);
let index = scopes.len() - 1;
let mut arguments_mut = scopes[index].arguments.borrow_mut();
arguments_mut.insert(name.to_string());
}

/// Store the variable named `name` with `value` from the current scope, return false when not found
pub fn store_variable_in_current_scope(&self, name: &str, value: BasicValueEnum<'ctx>) -> bool {
// Find argument name in the scope
Expand Down Expand Up @@ -1465,7 +1480,12 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
let variables_mut = scopes[index].variables.borrow_mut();
match variables_mut.get(&name.to_string()) {
// If the local varibale is found, store the new value for the variable.
Some(ptr) if index > GLOBAL_LEVEL && !self.local_vars.borrow().contains(name) => {
// We cannot update rule/lambda/schema arguments because they are read-only.
Some(ptr)
if index > GLOBAL_LEVEL
&& !self.local_vars.borrow().contains(name)
&& !scopes[index].arguments.borrow().contains(name) =>
{
self.builder.build_store(*ptr, value);
existed = true;
}
Expand Down
1 change: 1 addition & 0 deletions kclvm/compiler/src/codegen/llvm/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2585,6 +2585,7 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
} else {
self.none_value()
};
self.store_argument_in_current_scope(&arg_name.get_name());
self.walk_identifier_with_ctx(arg_name, &ast::ExprContext::Store, Some(arg_value))
.expect(kcl_error::COMPILE_ERROR_MSG);
}
Expand Down
17 changes: 17 additions & 0 deletions test/grammar/datatype/dict/mutual_ref_13/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
schema Data:
id: int = 1

schema Config[data: Data]:
spec: {str:} = {
internal.data = data.id
id = data.id
}

Func = lambda data: Data {
{
internal.data = data.id
id = data.id
}
}
spec = Func(Data())
config = Config(Data())
9 changes: 9 additions & 0 deletions test/grammar/datatype/dict/mutual_ref_13/stdout.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
spec:
internal:
data: 1
id: 1
config:
spec:
internal:
data: 1
id: 1