TIP 282: Enhanced Expression Syntax — implementation notes

Login

TIP 282 (Will Duquette and Don Porter, 2006, Tcl-Version 9.1, Draft) is kept as it is. This note describes the implementation proposed for it, patch 0004-TIP-282-4-7-assignment-and-separator-in-expressions.patch, and the choices made on the points the TIP leaves open. It could become the TIP's "Reference implementation" section.

Branch: tip-759d-tcl91-282 (core.tcl-lang.org/tcl). Its authors could put it in the Tcl-Branch: field of TIP 282.

What TIP 282 specifies

Choices on the open points

  1. Left side. A bareword is the name itself (x = 1). Any other operand is evaluated and its value is the name: a braced or quoted name ({::ns::v} = 1, "A($i)" = 1 for an array element), a variable holding a name ($ref = 1), a function returning a name (varOf([type get $value]) = $this), even a number (2 = 3 sets the variable 2). name(...) is always a function call, as everywhere in expr: an array element is written "A(k)" or {A(k)}. Barewords that are boolean values (t, y, on...) are variable names before =. x == 3 is still the error invalid bareword "x".

    To discuss: a stricter rule (only a name on the left, an error for 2 = 3 or $x = 3) is possible; it was tried during the port and can be restored.

  2. Resolution. As by set: in a procedure, a name that is not qualified is a local variable (global, variable and upvar apply). Variables in expressions stay simple: a qualified name is braced or quoted, :: not being part of a bareword (: is an operator of expr).

  3. Precedence and associativity. = binds looser than ?: and groups right-to-left (a = b = 0); ; binds looser than = and tighter than the comma.

3b. No bare ; between arguments or elements. A sequence may not be an argument of a function or an element of a list (lists of TIP 759) unless it is enclosed in parentheses: max(1; 5, 3), (1, 2; 3), abs(1; -2) and a = 1; $a, 2 are errors (";" is not allowed between the arguments of a function or the elements of a list: use parentheses, error code TCL PARSE EXPR SEPARATOR); max((1; 5), 3) and a = 1; ($a, 2) are valid. Read with the precedences above, a bare ; would silently end only one element, (1, 2; 3) giving 1 3, whereas a reader expects ; to end the statement. The arguments of a function are written as the elements of a list. Assignments are valid elements: (x = 1, y = 2) sets both and is 1 2.

  1. Empty statements. ;;, ; before ) or at the end, and :; (an empty "else") have the empty string as value: x = 1; is "".

  2. Value. The value of the assignment is the assigned value, then converted to a number at the end of the expression as any expr result: expr {s = "0x10"} returns 16, the variable keeps 0x10.

  3. Compilation. ; pops its left value. = compiles to storeStk, or to storeScalar when the name is a compiled local of a procedure; an assignment is never folded as a constant.

Future work

Declaring the variables known to expr, for instance with the is operator of TIP 764 (A is array; A(0) = 1), would let A(k) name an array element instead of calling a function, without quotes, and could later allow reading variables without $. In a procedure, the flags of the compiled locals (VAR_ARRAY) can serve as the register. To be designed together with the register of raw commands.

Compatibility

= alone used to be the error incomplete operator "=", ; an invalid character; both were errors. Tests parseExpr-21.2 and parseExpr-16.33 (2=+3, an assignment now) are updated.

Implementation