Support "a bit more concatenative" syntax.
Chris Pressey
1 year, 10 months ago
313 | 313 |
fac1 =& dup int[0] gt!;
|
314 | 314 |
fac2 =| fac3 fac4;
|
315 | 315 |
fac3 =& dup int[1] eq!;
|
316 | |
fac4 =& dup int[1] sub fact mul;
|
317 | |
|
318 | |
There! Are you happy now?
|
|
316 |
fac4 =& pop dup int[1] sub fact mul;
|
|
317 |
main =& int[5] fact;
|
|
318 |
==> OK([120])
|
|
319 |
|
|
320 |
There! <s>Are you happy now?</s> Don't that just beat all?
|
|
321 |
In light of this stellar feature it is expected that serious
|
|
322 |
programmers would treat the plain `=` form of definition as
|
|
323 |
a sort of "wimpmode" and shun it.
|
|
324 |
|
|
325 |
|
|
0 |
fact =& fac1 fac2;
|
|
1 |
fac1 =& dup int[0] gt!;
|
|
2 |
fac2 =| fac3 fac4;
|
|
3 |
fac3 =& dup int[1] eq!;
|
|
4 |
fac4 =& pop dup int[1] sub fact mul;
|
|
5 |
main =& int[5] fact;
|
2 | 2 |
|
3 | 3 |
#
|
4 | 4 |
# Program ::= {Definition}.
|
5 | |
# Definition ::= name<def> "=" Expression ";".
|
|
5 |
# Definition ::= name<def> ("=" Expression | "=&" Term | "=|" Term) ";".
|
6 | 6 |
# Expression ::= Term {"|" Term}.
|
7 | 7 |
# Term ::= Atom {Atom}.
|
8 | 8 |
# Atom ::= "(" Expression ")" | name<use> [bracketedtext].
|
|
25 | 25 |
def definition(self):
|
26 | 26 |
name = self.scanner.token
|
27 | 27 |
self.scanner.scan()
|
28 | |
self.scanner.expect('=')
|
29 | |
expr = self.expression()
|
|
28 |
if self.scanner.consume('='):
|
|
29 |
expr = self.expression()
|
|
30 |
elif self.scanner.consume('=&'):
|
|
31 |
expr = self.term()
|
|
32 |
elif self.scanner.consume('=|'):
|
|
33 |
expr = self.term(constructor=Else)
|
|
34 |
else:
|
|
35 |
raise ParseError('Expected `=`, `=&`, or `=|`')
|
30 | 36 |
self.scanner.expect(';')
|
31 | 37 |
self.definitions[name] = expr
|
32 | 38 |
|
|
37 | 43 |
t1 = Else(t1, t2)
|
38 | 44 |
return t1
|
39 | 45 |
|
40 | |
def term(self):
|
|
46 |
def term(self, constructor=Then):
|
41 | 47 |
a1 = self.atom()
|
42 | 48 |
while self.scanner.on_type('word') or self.scanner.token == '(':
|
43 | 49 |
a2 = self.atom()
|
44 | |
a1 = Then(a1, a2)
|
|
50 |
a1 = constructor(a1, a2)
|
45 | 51 |
return a1
|
46 | 52 |
|
47 | 53 |
def atom(self):
|
34 | 34 |
self.token = None
|
35 | 35 |
self.type = 'EOF'
|
36 | 36 |
return
|
37 | |
if self.scan_pattern(u'\\|', 'operator'):
|
|
37 |
if self.scan_pattern(r'\||\=\&|\=\||\=', 'operator'):
|
38 | 38 |
return
|
39 | 39 |
if self.scan_pattern(r'\;', 'punct'):
|
40 | 40 |
return
|