Skip to content

Commit

Permalink
feat: feat: support schema call expr partial eval.
Browse files Browse the repository at this point in the history
  • Loading branch information
Peefy committed Feb 7, 2023
1 parent eceaa50 commit a3fc20d
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 5 deletions.
10 changes: 9 additions & 1 deletion kclvm/compiler/src/codegen/llvm/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1669,9 +1669,17 @@ impl<'ctx> TypedResultWalker<'ctx> for LLVMCodeGenContext<'ctx> {
self.dict_insert(dict_value, name.as_str(), value, 0, -1);
}
let pkgpath = self.native_global_string_value(&self.current_pkgpath());
let is_in_schema = self.schema_stack.borrow().len() > 0;
Ok(self.build_call(
&ApiFunc::kclvm_value_function_invoke.name(),
&[func, self.global_ctx_ptr(), list_value, dict_value, pkgpath],
&[
func,
self.global_ctx_ptr(),
list_value,
dict_value,
pkgpath,
self.bool_value(is_in_schema),
],
))
}

Expand Down
Binary file modified kclvm/runtime/src/_kclvm.bc
Binary file not shown.
2 changes: 1 addition & 1 deletion kclvm/runtime/src/_kclvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ kclvm_value_ref_t* kclvm_value_function_external_invoke(kclvm_value_ref_t* p, kc

kclvm_value_ref_t* kclvm_value_function_get_closure(kclvm_value_ref_t* p);

kclvm_value_ref_t* kclvm_value_function_invoke(kclvm_value_ref_t* p, kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs, kclvm_char_t* pkgpath);
kclvm_value_ref_t* kclvm_value_function_invoke(kclvm_value_ref_t* p, kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs, kclvm_char_t* pkgpath, kclvm_value_ref_t* is_in_schema);

kclvm_bool_t kclvm_value_function_is_external(kclvm_value_ref_t* p);

Expand Down
2 changes: 1 addition & 1 deletion kclvm/runtime/src/_kclvm.ll
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ declare %kclvm_value_ref_t* @kclvm_value_function_external_invoke(%kclvm_value_r

declare %kclvm_value_ref_t* @kclvm_value_function_get_closure(%kclvm_value_ref_t* %p);

declare %kclvm_value_ref_t* @kclvm_value_function_invoke(%kclvm_value_ref_t* %p, %kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs, %kclvm_char_t* %pkgpath);
declare %kclvm_value_ref_t* @kclvm_value_function_invoke(%kclvm_value_ref_t* %p, %kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs, %kclvm_char_t* %pkgpath, %kclvm_value_ref_t* %is_in_schema);

declare %kclvm_bool_t @kclvm_value_function_is_external(%kclvm_value_ref_t* %p);

Expand Down
6 changes: 6 additions & 0 deletions kclvm/runtime/src/_kclvm_addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ pub fn _kclvm_get_fn_ptr_by_name(name: &str) -> u64 {
"kclvm_datetime_now" => crate::kclvm_datetime_now as *const () as u64,
"kclvm_datetime_ticks" => crate::kclvm_datetime_ticks as *const () as u64,
"kclvm_datetime_today" => crate::kclvm_datetime_today as *const () as u64,
"kclvm_default_collection_insert_int_pointer" => {
crate::kclvm_default_collection_insert_int_pointer as *const () as u64
}
"kclvm_default_collection_insert_value" => {
crate::kclvm_default_collection_insert_value as *const () as u64
}
"kclvm_dict_clear" => crate::kclvm_dict_clear as *const () as u64,
"kclvm_dict_get" => crate::kclvm_dict_get as *const () as u64,
"kclvm_dict_get_entry" => crate::kclvm_dict_get_entry as *const () as u64,
Expand Down
4 changes: 2 additions & 2 deletions kclvm/runtime/src/_kclvm_api_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@
// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_value_function_external_invoke(%kclvm_value_ref_t* %p, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs);

// api-spec: kclvm_value_function_invoke
// api-spec(c): kclvm_value_ref_t* kclvm_value_function_invoke(kclvm_value_ref_t* p, kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs, kclvm_char_t* pkgpath);
// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_value_function_invoke(%kclvm_value_ref_t* %p, %kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs, %kclvm_char_t* %pkgpath);
// api-spec(c): kclvm_value_ref_t* kclvm_value_function_invoke(kclvm_value_ref_t* p, kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs, kclvm_char_t* pkgpath, kclvm_value_ref_t* is_in_schema);
// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_value_function_invoke(%kclvm_value_ref_t* %p, %kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs, %kclvm_char_t* %pkgpath, %kclvm_value_ref_t* %is_in_schema);

// api-spec: kclvm_value_function_get_closure
// api-spec(c): kclvm_value_ref_t* kclvm_value_function_get_closure(kclvm_value_ref_t* p);
Expand Down
6 changes: 6 additions & 0 deletions kclvm/runtime/src/value/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ pub extern "C" fn kclvm_value_function_invoke(
args: *mut kclvm_value_ref_t,
kwargs: *const kclvm_value_ref_t,
pkgpath: *const kclvm_char_t,
is_in_schema: *const kclvm_value_ref_t,
) -> *const kclvm_value_ref_t {
let func = ptr_as_ref(p);
let args_ref = mut_ptr_as_ref(args);
Expand Down Expand Up @@ -642,6 +643,11 @@ pub extern "C" fn kclvm_value_function_invoke(
let args = args_ref.clone().into_raw();
call_fn(ctx, args, kwargs)
};
let is_in_schema = ptr_as_ref(is_in_schema);
if is_schema && !is_in_schema.is_truthy() {
let schema_value = ptr_as_ref(value);
schema_value.schema_check_attr_optional(true);
}
ctx_ref.panic_info = now_meta_info;
return value;
};
Expand Down
17 changes: 17 additions & 0 deletions test/grammar/schema/partial_eval/partial_eval_2/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
schema Spec:
data: int
id: int

mixin AMixin:
spec: Spec {
id = 1
}

schema A:
mixin [AMixin]

spec: Spec {
data = 1
}

a = A()
4 changes: 4 additions & 0 deletions test/grammar/schema/partial_eval/partial_eval_2/stdout.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a:
spec:
data: 1
id: 1
17 changes: 17 additions & 0 deletions test/grammar/schema/partial_eval/partial_eval_fail_2/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
schema Spec:
data: int
id: int

mixin AMixin:
spec: Spec = {
id = 1
}

schema A:
mixin [AMixin]

spec: Spec = {
data = 1
}

a = A()
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import sys
import os

import kclvm.kcl.error as kcl_error

cwd = os.path.dirname(os.path.realpath(__file__))

kcl_error.print_kcl_error_message(
kcl_error.get_exception(err_type=kcl_error.ErrType.EvaluationError_TYPE,
file_msgs=[
kcl_error.ErrFileMsg(
filename=cwd + "/main.k",
line_no=17
),
],
arg_msg="attribute 'data' of Spec is required and can't be None or Undefined")
, file=sys.stdout
)

0 comments on commit a3fc20d

Please sign in to comment.