SPPCompiler.SemanticAnalysis.AstUtils.AstFunctionUtils module

class SPPCompiler.SemanticAnalysis.AstUtils.AstFunctionUtils.AstFunctionUtils

Bases: object

This class contains static methods for ASTs that are related to functions. This includes getting function scopes, converting method calls to function calls, and inferring generic arguments for functions.

static get_function_owner_type_and_function_name(sm, lhs, **kwargs)

Get the function owner type, scope and name from an expression AST. This is used to determine information related to getting the overloads of a function. The function owner type is the type of the class the method belongs to if the callable is a method rather than a free-function. The scope id for the function itself, not its owner. This following cases are handled:

  • object.method(): runtime access into an object.

  • Type::method(): static access into a type.

  • namespace::function(): direct access into a namespaced free function.

  • function(): direct function call.

  • <anything else>(): lambda identifier or invalid function call.

Parameters:
  • sm – The scope manager to access function scopes.

  • lhs – The left-hand side of the function call.

  • kwargs – Additional keyword arguments.

Returns:

A 3-tuple containing: the function owner type, the function owner scope, and the function name. Given

the function MyType::my_function():
  • The owner type is “MyType”.

  • The scope is the scope of “my_function” (found inside a superimposition scope of “MyType”).

  • The name is “my_function”.

static convert_method_to_function_form(sm, function_owner_type, function_name, lhs, fn, **kwargs)

This conversion function is used to normalize all different function calls, such as converting runtime function access into static access functions with self arguments. For example, “t.method(1)” becomes “T::method(t, 1)”. Note that this will only be called for function calls of the form “t.method()”, so the function owner type is always valid.

Parameters:
  • sm – The scope manager to access function scopes.

  • function_owner_type – The owning type of the function.

  • function_name – The name of the method on the type.

  • lhs – The AST representing the left-hand side of the function call (entire expression before “fn”).

  • fn – The AST representing the function call (parenthesis and arguments).

Returns:

A 2-tuple containing the new function access, and the new function call. The function access is the static accessor, such as “T::method”, and the function call is the actual function call, such as “(t, 1)” (can be applied to the function access).

static get_all_function_scopes(target_function_name, target_scope, *, for_override=False)

Get all the function scopes, and their generic argument groups for a function name in a scope. This is used to get all possible overloads for a function, by iterating the valid scopes a function might be found in, and matching by name. The generic arguments from the outer scope (ie superimposition) are saved,so they can be inherited into the function signature for generic substitution.

Parameters:
  • target_function_name – The name of the function to get the overloads for.

  • target_scope – The scope of the class or module that the functions should belong to.

  • for_override – If the overloads are being checked for an override.

Returns:

A list of 3-tuples, containing for each overload, the scope o the function the overload is represented by, the function prototype of the overload, and associated generic arguments in the owning context that must be inherited into the function signature.

static check_for_conflicting_overload(this_scope, target_scope, new_func)
Return type:

Optional[Asts.FunctionPrototypeAst]

static check_for_conflicting_override(this_scope, target_scope, new_func, *, exclude=None)
Return type:

Optional[Asts.FunctionPrototypeAst]

static name_function_arguments(arguments, parameters, sm)

! Name all function arguments being passed to a function call, by removing used names from the parameter list, and then applying the leftover parameter names for the resulting arguments. Special care is taken for the case of a variadic parameter, which requires a tuple of the remaining arguments.

@param arguments The list of arguments being passed to the function. @param parameters The list of parameters the function accepts. @param sm The scope manager to access the current scope.

@return None (the arguments are modified in-place).

@throw SemanticErrors.ArgumentNameInvalidError If an argument name is invalid (doesn’t match a parameter name).

static name_generic_arguments(arguments, parameters, sm, owner, is_tuple_owner=False)

Name all generic arguments being passed to a function call or a type declaration, by removing used names from the parameter list, and then applying the leftover parameter names for the resulting arguments. Special care is taken for the case of a variadic parameter, which requires a tuple of the remaining arguments.

There are many similarities to the function argument naming function, but this function is more complex due to the more expressive application of generic arguments; they are not only constrained to function calls, but any place a type is defined. As such, further checks are needed to ensure the generic arguments are correctly named.

Parameters:
  • arguments – The list of generic arguments being passed to the function.

  • parameters – The list of generic parameters the function accepts.

  • sm – The scope manager to access the current scope.

  • owner – The type that owns the generic arguments (the type being instantiated).

  • is_tuple_owner – If the owner type is a tuple (early return).

Raises:
static infer_generic_arguments(generic_parameters, optional_generic_parameters, explicit_generic_arguments, infer_source, infer_target, sm, owner=None, owner_ast=None, owner_scope=None, variadic_parameter_identifier=None, is_tuple_owner=False, **kwargs)

This function infers the generic parameters’ values based not only on explicit generic arguments, but on other values’ true types, that were originally declared as generic. For example a generic type T can be inferred from an argument’s type, whose corresponding parameter is the generic T type. The same goes for object initializer arguments and class attributes.

cls Point[T, U, V, W] {

x: T y: U z: V

}

let p = Point[W=Bool](x=1, y=”hello”, z=False)

  • generic_parameter: [T, U, V, W]

  • explicit_generic_arguments: [W=Bool]

  • infer_source: {x: BigInt, y: Str, z: Bool}

  • infer_target: {x: T, y: U, z: V}

Todo: variadic generic parameters combined with variadic function parameters.
  • Needs to append the type to the tuple rather than set it as a value and then check for matches.

Parameters:
  • generic_parameters – The generic parameters that need the values assigned via inference.

  • optional_generic_parameters – The defaults to fill missing generic arguments with.

  • explicit_generic_arguments – Any explicit generic arguments that have been given with [] syntax.

  • infer_source – Function or object initializer arguments.

  • infer_target – Function parameters or attributes (that have generic type annotations).

  • sm – The scope manager to access the current scope.

  • owner – An optional “owner” type (exclusive to types rather than function calls).

  • variadic_parameter_identifier – An optional parameter name that is known to be variadic.

  • is_tuple_owner – If the owner is a tuple type, which prevents creating Tup[Tup[…]] infinitely.

Returns:

A list of generic arguments with inferred values.

Raises:
static is_target_callable(expr, sm, **kwargs)

This function checks that, given provided information during function overload resolution, if the expression provided represents a callable type or not. The check is only executed if there are no provided overloads, and if the type is functional (one of the FunXXX types, then the type is returned). :type expr: :param expr: The expression to check. :type sm: :param sm: The scope manager. :type kwargs: :param kwargs: Additional keyword arguments. :return: The function type is the expression is a function type, otherwise None.

static create_callable_prototype(expr_type)

This function generates a dummy prototype for a callable type. This is for when a callable variable exists; there is no “function prototype” to point to, because any function could have been assigned to it, given the signature matches, so a temporary dummy prototype is created. :type expr_type: :param expr_type: The type of the callable variable. :return: The dummy prototype for the callable variable.