syntax

A newline ends a statement if it can, otherwise it acts like any white space.

i1 : 2+
     3+
     4

o1 = 9

Parsing is determined by a triple of numbers attached to each token. The following table (produced by seeParsing), displays each of these numbers.

i2 : seeParsing()


word      precedence scope strength

<WORDS>          64     64     64
                 64     62     64
!                68     68     68
#                70     70     62
%                60     60     60
&                46     46     46
(                64      4     72
)                 4      0      0
*                60     60     60
+                52     52     52
,                10     10     10
-                52     52     52
.                70     70     70
/                60     60     60
:                38     36     38
;                 8      8      8
<                32     32     32
=                16     14     16
>                32     32     32
?                32     32     32
@                62     60     62
[                56      4     72
\\               60     58     60
]                 4      0      0
^                70     70     70
_                70     70     70
{                64      4     72
|                42     42     42
}                 4      0      0
~                48     48     48
else             14     14     14
!=               32     32     32
#?               70     70     70
=!=              32     32     32
&&               36     36     36
**               54     54     54
++               52     52     52
->               16     14     16
..               50     50     50
.?               70     70     70
//               60     60     60
/^               70     70     70
and              28     28     28
:=               16     14     16
<-               16     14     16
<<               22     22     22
<=               32     32     32
==               32     32     32
=>               20     18     20
>=               32     32     32
>>               24     22     24
@@               66     66     66
===              32     32     32
--newline--       8      8      8
local            64     14     14
\\\\             58     56     58
^^               44     44     44
do               14     14     14
if               64     14     14
of               18     18     18
or               26     26     26
||               34     34     34
timing           64     14     14
shield           64     14     14
then             14     14     14
try              64     14     14
time             64     14     14
global           64     14     14
while            64     14     14
new              64     18     18
quote            64     14     14
not              30     30     30
from             18     18     18

Here is the way these numbers work. The parser maintains a number which we will call the current parsing level, or simply, the level. The parser builds up an expression until it encounters an input token whose precedence is less than or equal to the current level. The tokens preceding the offending token are bundled into an expression appropriately and incorporated into the containing expression.

When an operator or token is encountered, its scope serves as the level for parsing the subsequent expression, unless the current level is higher, in which case it is used.

Consider a binary operator such as *. The relationship between its scope and its precedence turns out to determine whether a*b*c is parsed as (a*b)*c or as a*(b*c). When the parser encounters the second *, the current parsing level is equal to the scope of the first *. If the scope is less than the precedence, then the second * becomes part of the right hand operand of the first *, and the expression is parsed as a*(b*c). Otherwise, the expression is parsed as (a*b)*c.

For unary operators, the strength is used instead of the scope to reset the current level. The reason for having both numbers is that some operators can be either unary or binary, depending on the context. A good example is # which binds as tightly as . when used as an infix operator, and binds as loosely as adjacency or function application when used as a prefix operator.

To handle expressions like b c d, where there are no tokens present which can serve as a binary multiplication operator, after parsing b, the level will be set to 1 less than the precedence of an identifier, so that b c d will be parsed as b (c d).

The exclamation point is allowed as a unary operator either to the right or to the left of its operand. The other unary operators occur to the left of their operands.

Three operators are treated specially, in that the empty expression is allowed to the right of them. These are newline, comma, and semicolon.


topindexpreviousupnext