lang_func

Macro lang_func 

Source
macro_rules! lang_func {
    ( $func:ident, $metadata:expr $(,)? ) => { ... };
    ( $func:ident, $value_dependencies:expr, $metadata:expr $(,)? ) => { ... };
}
Expand description

This macro generates a Function instance for the given function identifier and metadata combination

The return type of this macro is (FunctionMetadata, Box<dyn NativeFunctionAdapter>)

The function provided to this macro must start with a parameter of type &mut Interpreter and the must be an implementation of FromLangArgs for the tuple of all parameter types after the &mut Interpreter.

The return type of the function must one of the following:

  • Result<OptionDataObjectRef, NativeError>
  • Result<DataObjectRet, NativeError>
  • Result<(), NativeError>
  • OptionDataObjectRef
  • DataObjectRef
  • () (= No return value)

If move is used to capture local values in a closure, a copy for basic values (like i32) or a clone for Arc/Rc/Gc values must be created and must be provided to the second argument ($value_dependencies) (After function name and before function metadata) of this macro

§Arguments

§2 Argument variant

  • $func - An identifier of a rust function or lambda
  • $metadata - The Lang function metadata (FunctionMetadata)

§3 Argument variant

  • $func - An identifier of a rust function or lambda
  • $value_dependencies - A vector (vec![val1, val2, ...]) which contains all dependencies which are captured inside closure function (This is important for the equals and strict equals operators when comparing lang functions)
  • $metadata - The Lang function metadata (FunctionMetadata)

§Examples

use lang_interpreter::interpreter::data::{DataObject, DataObjectRef};
use lang_interpreter::interpreter::data::function::{Function, FunctionMetadata, FunctionPointerObject, Parameter, ParameterType};
use lang_interpreter::interpreter::{conversions, Interpreter};
use lang_interpreter::{lang_func, lang_func_metadata};
use lang_interpreter::lexer::CodePosition;

//The rust implementation of the lang native function "func.trim"
fn trim_function(
    interpreter: &mut Interpreter,
    text_object: DataObjectRef,
) -> DataObjectRef {
    DataObjectRef::new(DataObject::new_text(
        conversions::to_text(interpreter, &text_object, CodePosition::EMPTY).trim(),
    ))
}

let (metadata, function): (FunctionMetadata, Function) = lang_func!(
    trim_function,
    lang_func_metadata!(
        name="trim",
        return_type_constraint(
            allowed=["TEXT"],
        ),
        parameter(
            name="$text",
        ),
    ),
);

FunctionPointerObject::new can be used to create a FunctionPointerObject with a single non-overloaded function:

use lang_interpreter::interpreter::data::function::FunctionPointerObject;

//`(metadata, function)` is used from the example above

let fp: FunctionPointerObject = FunctionPointerObject::new(&metadata, function);

assert_eq!(fp.function_name(), Some("trim"));
assert_eq!(fp.function_info(), None);
assert_eq!(fp.functions().len(), 1);

Overloaded functions can be created with FunctionPointerObject::create_function_pointer_objects_from_native_functions:

use std::collections::HashMap;
use lang_interpreter::interpreter::data::function::FunctionPointerObject;

//`(metadata, function)` is used from the example above

let overloaded_functions: HashMap<Box<str>, FunctionPointerObject> = FunctionPointerObject::create_function_pointer_objects_from_native_functions(vec![
    (metadata, function),
]);

assert_eq!(overloaded_functions.len(), 1);

let fp = &overloaded_functions["trim"];

assert_eq!(fp.function_name(), Some("trim"));
assert_eq!(fp.function_info(), None);
assert_eq!(fp.functions().len(), 1);