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
=, assignment, C-like: the value is the assigned value. "The term on the left side of the operator shall be a variable name.";, separator, as the comma operator of C: the value ofexpris the value of the last subexpression.expr { x = 5*$y + 6*$z; w = $x2 + $y2; v = $w2 + $y2 }
Choices on the open points
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)" = 1for an array element), a variable holding a name ($ref = 1), a function returning a name (varOf([type get $value]) = $this), even a number (2 = 3sets the variable2).name(...)is always a function call, as everywhere inexpr: an array element is written"A(k)"or{A(k)}. Barewords that are boolean values (t,y,on...) are variable names before=.x == 3is still the errorinvalid bareword "x".To discuss: a stricter rule (only a name on the left, an error for
2 = 3or$x = 3) is possible; it was tried during the port and can be restored.Resolution. As by
set: in a procedure, a name that is not qualified is a local variable (global,variableandupvarapply). Variables in expressions stay simple: a qualified name is braced or quoted,::not being part of a bareword (:is an operator ofexpr).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.
Empty statements.
;;,;before)or at the end, and:;(an empty "else") have the empty string as value:x = 1;is "".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 keeps0x10.Compilation.
;pops its left value.=compiles tostoreStk, or tostoreScalarwhen 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
tclCompExpr.c:ASSIGNandSEPARATORlexemes,SeparatorPlacesValid, precedences, barewords before=(AssignFollows), compiled locals,ConvertTreeToTokens.- Tests:
tests/exprAssign.test;parseExpr-16.33,parseExpr-21.2. Documentation:expr.n.
