TSP Type system

July 28, 2015 ยท View on GitHub

Native types

Tcl uses annotation comments to define the proc return type, proc arguments, and variables for type definitions.

TSP compiled types are:

* tsp::boolean - Java boolean or C int
* tsp::int - Java long or C long long (64 bit)
* tsp::double - double in both Java and C
* tsp::string - Java java.lang.String or C Tcl_DString
* tsp::var - Java TclObject or C Tcl_Obj
* tsp::array - uses interpreter array variables, not valid 
  for proc definitions or return types.
* void - valid for procdef return type only

For tsp::procdef argument types, only the type is specified ("boolean", "int", etc.) Note that "array" is not a valid procdef argument or return type; "void" is valid only for proc return type.

Array variables are not defined in compiled code. Instead, they are defined and accessed in the Tcl interpreter. Array elements of course are TclObjects, and can hold any specific TclObject data type. Tcl 8.5+ 'big integer (unlimited precision)' types are not supported.

Conversions and conversion errors

TSP will perform automatic conversions as necessary, the same as the Tcl interpreter. The major difference is when the conversion happens. In ordinary Tcl, conversion takes place when a particular command expects a Tcl variable to be of a certain type (e.g. late binding.) For example, the "llength" command expects it's argument to be a TclList, if it isn't, then the llength command tries to convert the TclObject to a TclList.

For TSP compiled procs, that conversion is done when the variable is assigned, thus potentially generating a conversion error much earlier. This includes the invocation of a Tcl procedure by a compiled or non-compiled code when a procedure argument can not be converted.

Conversions:

to\fromintegerdoublebooleanstringvar
integeryint()true->1, false->0is int?is int?
doubledouble()ytrue->1, false->0is double?is double?
boolean0->false, !0->true0->false, !0->trueyis boolean?is boolean?
stringyyyyy
varyyyyy

The notation "is type?" uses type appropriate Tcl functions to perform conversions. If a conversion fails, a Tcl error is raised as the time of conversion.

In the case of string or var to boolean, any of the Tcl recognized values for true/false can be used, true: any int or double not zero, "true", "yes" false: 0, 0.0, "false", "no"

Implicit declarations

TSP will automatically assign variable types based on their usage, if not previously defined. For instance, if a previously undefined variable is assigned from the results of a "llength", it will be defined as an integer type.

Variables defined on proc entry

TSP compiled procs define variables statically on procedure invocation, unlike Tcl where the variable is defined the first time it is assigned. This could potentially cause subtle differences where the Tcl code may depend on whether the variable is defined in the Tcl interpreter. Note that the "info" command itself may not function as expected for TSP compiled procs anyway, as variables are not automatically exported to the Tcl interpreter.

Global, variable, and upvar commands

Tcl commands global, variable, and upvar are supported. When these commands are used, the variables should be defined as 'var' or 'array'. When variables are defined with these commands, the variable's value is copied to the local native variable when the command is executed. When 'return' is encountered or the end of proc is reached (for proc type 'void'), the value is copied back to the global scope or stack frame.

Procs must use explicit return command

TSP compiled procs require that the return command be used to return a value. Since there is no 'current' value necessarily generated, return must be used to explicitly terminate a proc. The only exception is for procs defined as 'void', where the proc's control flow may terminate at the end of the proc without an explicit return command.

Variable names used by commands and tsp::volatile annotation

Tcl commands that use variable names, rather than their values, that are not otherwise compiled directly by TSP, are 'spilled' into the Tcl interpreter before executing the command. Spilling variables causes a interpreter variable to be created with the same name as the native variable and the value copied from the native variable into the interpreter variable. Examples of Tcl builtin commands that use variable names are lset, regexp, regsub, scan, vwait, and other. After the Tcl command completes, variables are reloaded into native variables.

For user defined procs where a variable name is expected as an argument, the tsp::volatile annotation can be used to explicitly spill a variable into the interpreter. Each invocation of a user command with a variable name as argument must be coded with the tsp::volatile annotation.