feat: stack var (WIP)
This commit is contained in:
@@ -39,7 +39,7 @@ pub fn builtins_impl(input: TokenStream) -> TokenStream {
|
||||
}
|
||||
};
|
||||
|
||||
let mut pub_item_mod: Vec<proc_macro2::TokenStream> = Vec::new();
|
||||
let mut pub_item_mod = Vec::new();
|
||||
let mut consts = Vec::new();
|
||||
let mut global = Vec::new();
|
||||
let mut scoped = Vec::new();
|
||||
@@ -110,9 +110,9 @@ pub fn builtins_impl(input: TokenStream) -> TokenStream {
|
||||
/// Constant values available in the global scope.
|
||||
pub consts: [(&'static str, ::nixjit_value::Const); #mod_name::CONSTS_LEN],
|
||||
/// Global functions available in the global scope.
|
||||
pub global: [(&'static str, usize, fn(&mut Ctx, Vec<::nixjit_eval::Value>) -> ::nixjit_error::Result<::nixjit_eval::Value>); #mod_name::GLOBAL_LEN],
|
||||
pub global: [(&'static str, usize, fn(&mut Ctx, ::nixjit_eval::Args) -> ::nixjit_error::Result<::nixjit_eval::Value>); #mod_name::GLOBAL_LEN],
|
||||
/// Scoped functions, typically available under the `builtins` attribute set.
|
||||
pub scoped: [(&'static str, usize, fn(&mut Ctx, Vec<::nixjit_eval::Value>) -> ::nixjit_error::Result<::nixjit_eval::Value>); #mod_name::SCOPED_LEN],
|
||||
pub scoped: [(&'static str, usize, fn(&mut Ctx, ::nixjit_eval::Args) -> ::nixjit_error::Result<::nixjit_eval::Value>); #mod_name::SCOPED_LEN],
|
||||
}
|
||||
|
||||
impl<Ctx: BuiltinsContext> Builtins<Ctx> {
|
||||
@@ -169,7 +169,6 @@ fn generate_primop_wrapper(
|
||||
let arg_pats: Vec<_> = user_args.rev().collect();
|
||||
let arg_count = arg_pats.len();
|
||||
|
||||
// Generate code to unpack and convert arguments from the `Vec<Value>`.
|
||||
let arg_unpacks = arg_pats.iter().enumerate().map(|(i, arg)| {
|
||||
let arg_name = format_ident!("_arg{}", i, span = Span::call_site());
|
||||
let arg_ty = match &arg {
|
||||
@@ -178,8 +177,8 @@ fn generate_primop_wrapper(
|
||||
};
|
||||
|
||||
quote! {
|
||||
let #arg_name: #arg_ty = args.pop().ok_or_else(|| ::nixjit_error::Error::EvalError("Not enough arguments provided".to_string()))?
|
||||
.try_into().map_err(|e| ::nixjit_error::Error::EvalError(format!("Argument type conversion failed: {}", e)))?;
|
||||
let #arg_name: #arg_ty = args.pop().ok_or_else(|| ::nixjit_error::Error::eval_error("Not enough arguments provided".to_string()))?
|
||||
.try_into().map_err(|e| ::nixjit_error::Error::eval_error(format!("Argument type conversion failed: {}", e)))?;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -222,16 +221,16 @@ fn generate_primop_wrapper(
|
||||
};
|
||||
|
||||
let arity = arg_names.len();
|
||||
let fn_type = quote! { fn(&mut Ctx, Vec<::nixjit_eval::Value>) -> ::nixjit_error::Result<::nixjit_eval::Value> };
|
||||
let fn_type = quote! { fn(&mut Ctx, ::nixjit_eval::Args) -> ::nixjit_error::Result<::nixjit_eval::Value> };
|
||||
|
||||
// The primop metadata tuple: (name, arity, wrapper_function_pointer)
|
||||
let primop = quote! { (#name_str, #arity, #mod_name::#wrapper_name as #fn_type) };
|
||||
|
||||
// The generated wrapper function.
|
||||
let wrapper = quote! {
|
||||
pub fn #wrapper_name<Ctx: BuiltinsContext>(ctx: &mut Ctx, mut args: Vec<::nixjit_eval::Value>) -> ::nixjit_error::Result<::nixjit_eval::Value> {
|
||||
pub fn #wrapper_name<Ctx: BuiltinsContext>(ctx: &mut Ctx, mut args: ::nixjit_eval::Args) -> ::nixjit_error::Result<::nixjit_eval::Value> {
|
||||
if args.len() != #arg_count {
|
||||
return Err(::nixjit_error::Error::EvalError(format!("Function '{}' expects {} arguments, but received {}", #name_str, #arg_count, args.len())));
|
||||
return Err(::nixjit_error::Error::eval_error(format!("Function '{}' expects {} arguments, but received {}", #name_str, #arg_count, args.len())));
|
||||
}
|
||||
#(#arg_unpacks)*
|
||||
|
||||
|
||||
Reference in New Issue
Block a user