BRiX
Advanced Computing Environment
Hosted by SourceForge
brix-os project page

Previous: Closures ----- Up: Contents ----- Next: Hygienic Macros

Extensions

show notes
Features that need to be added to the page or ideas that haven't been thought out.
  • finish the complex parameters section - if more than a couple parameters are needed then a flag can be used to enable an extension in the body of the extension or type where complex and adaptive interfaces can be described. interfaces must be well defined so the language can track API changes.
  • extensions are not standard objects and variables containing them are special. the extension can be stored in a variable which is always immutable and can not be referenced to retrieve the extension for storage in another variable.
  • RECURSE can be used in extensions with function-style evaluated parameters. CALLPARENT can only be used in functions to call parent functions.
  • the ASM extension detects a DEF or DEFX scope and adapts to always generate runtime code, never needing # when used in extensions

The DEFX extension makes a compile-time function and returns a reference to it. Extensions are compiled code like functions but they are dispatched at compile-time and used to generate runtime code or modify the compiler environment. Extensions are the heart of Tetra and allow the programmer to easily extend the language or create simple macros for common blocks of code. They are immediately compiled to a temporary binary, linked into the compiler and available for use within the module being compiled. Private extensions are only used when compiling the module and then discarded, never having been stored in a binary file.

DEFX `open (parameters) -> rtype X-body
  • `open -- optional flag for open parameters
  • parameters -- parameter list, parentheses required even when empty
  • -> -- required syntax when return type is given
  • rtype -- return type or list of return types, optional
  • X-body -- single or block expression
	add = defx (a:Int, b:Int ...) -> Int {
	  // add values, return result
	  asm ia32 mov r1: a	// virtual register r1 = a
	  each b with e ->	// for each element of b do
	    asm ia32 add r1 e	//   add element to r1
	  asm ia32 vpush r1	// push r1 to virtual stack
	}

	// 1 + 2 + 3 + 4 + 5
	a := add(1, 2, 3, 4, 5)
The add extension above is executed at compile-time and outputs five assembler instructions to be processed at runtime with the final value loaded into the a variable. The virtual vpush instruction places assembler data on the expression stack to be returned to the caller. The same RETURN extension used by functions is also available but can't be used to return values if some have already been returned with vpush.

Unpacked Collections
Placing the ... symbol after the last parameter will create a non-empty list in the last parameter with the parameter type becoming the list element type. Unpacked collections are not available with open parameters.

Function-style Parameters
Extensions with parentheses around pre-evaluated parameters use the same rules as functions: immutable parameters by default, modified with the `nullable, `mutable and `inout flags and also default parameter values. The `ref flag is meaningless since parameters are all passed as internal references within the compiler. Callers may even use labels to mark or reorder the parameters.

Flag Parameters
See the flag parameters section on the Functions page.

Complex Parameters
All parameters must be declared in the interface using a special flag syntax to generate complex patterns. The parameters are then processed in the extension body. More to come later...

Open Parameters
The `open flag for DEFX gets rid of the parentheses around parameters and enables unevaluated mode for complex parameters.

Previous: Closures ----- Up: Contents ----- Next: Hygienic Macros