[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/WhyNot135/daScript/master/daslib/instance_function.das [Back]  [Original]

options gen2
options indenting = 4
options strict_smart_pointers = true

module instance_function shared private

//! Generic function instantiation annotation.
//!
//! ``[instance_function(generic_name, TT="int")]`` replaces the body of the annotated
//! function with an instantiation of the named generic, substituting the specified
//! type parameters. Useful for creating concrete exports of generic functions.

require daslib/ast
require daslib/rtti
require daslib/ast_boost
require daslib/templates_boost
require daslib/defer
require strings

[function_macro(name="instance_function")]
class InstanceFunctionAnnotation : AstFunctionAnnotation {
    //! [instance_function(generic_name,type1=type1r,type2=type2r,...)] macro creates instance of the generic function with a particular set of types.
    //! In the followin example body of the function inst will be replaced with body of the function print_zero with type int::
    //!
    //!     def print_zero ( a : auto(TT) )
    //!         print("{[[TT]]}\n")
    //!     [export, instance_function(print_zero,TT="int")]
    //!     def inst {}
    def override apply(var func : FunctionPtr; var group : ModuleGroup; args : AnnotationArgumentList; var errors : das_string) : bool {
        var generic_name = ""
        var rules : Template
        for (argv in args) {
            let val = get_annotation_argument_value(argv)
            if (val is tBool) {
                if (!empty(generic_name)) {
                    errors := "unexpected {argv.name}, name of the generic or function is already specified as {generic_name}"
                    return false
                }
                generic_name = "{argv.name}"
            } elif (val is tString) {
                rules |> replaceType("{argv.name}", "{val as tString}")
            } else {
                errors := "invalid argument type {argv.name}"
                return false
            }
        }
        if (empty(generic_name)) {
            errors := "expecting name of the generic or function"
            return false
        }
        var fn = compiling_module() |> find_unique_generic(generic_name)
        if (fn == null) {
            errors := "generic not found {generic_name}"
            return false
        }
        func.body = clone_expression(fn.body)
        apply_template(rules, func.at, func.body)
        return true
    }
}

Web Proxy Viewer  |  New URL  |  Original Page