Hi, all...
In light of the recent discussions about math precedence, I've created
a patch to implement my suggestion. Confronted with the following
code:
2 + 3 * 8.
my modified idc aborts with:
bad.st:4: ambiguous arithmetic expression; use explicit parentheses near '*'
However, it compiles without warning for the following:
2 + (3 * 8).
3 * 8 + 2.
(2 + 3) * 8.
There were a handful of .st files that relied on the st80-style
non-precedence, which I added explicit parentheses to.
If this patch (or something morally equivalent) is accepted to the
mainline, I believe we can finally close the precedence discussion. I
hope. ;P
Have fun,
--
Michael FIG <[EMAIL PROTECTED]> //\
http://michael.fig.org/ \//
Enforce explicit operator precedence around math-like selectors.
diff -r f4fccae99d24 function/objects/IdentitySet.st
--- a/function/objects/IdentitySet.st Tue Dec 11 23:40:12 2007 -0600
+++ b/function/objects/IdentitySet.st Tue Dec 11 23:51:23 2007 -0600
@@ -125,7 +125,7 @@ IdentitySet widen
IdentitySet widen
[
"StdOut nextPutAll: 'WIDEN '; print: self size; space; print: lists size + 1 * 2 - 1; cr."
- lists := (self new: lists size + 1 * 2 - 1) addAll: self; lists.
+ lists := (self new: (lists size + 1) * 2 - 1) addAll: self; lists.
]
IdentitySet deepen: list at: listOffset
diff -r f4fccae99d24 object/examples/Makefile
--- a/object/examples/Makefile Tue Dec 11 23:40:12 2007 -0600
+++ b/object/examples/Makefile Tue Dec 11 23:51:23 2007 -0600
@@ -1,5 +1,5 @@ SUBDIRS = avl dispatch echo forward hw i
SUBDIRS = avl dispatch echo forward hw ignore interp libs1 libs2 libs3 parse \
- prototype reflect serialise slots sqvm system this traits typename weak x11
+ precedence prototype reflect serialise slots sqvm system this traits typename weak x11
all : .FORCE
test ! -f ../stage2/clean-examples || $(MAKE) clean
diff -r f4fccae99d24 object/examples/ignore/Makefile
--- a/object/examples/ignore/Makefile Tue Dec 11 23:40:12 2007 -0600
+++ b/object/examples/ignore/Makefile Tue Dec 11 23:51:23 2007 -0600
@@ -5,6 +5,7 @@ all : $(PROGRAM)
all : $(PROGRAM)
run : all
+ @echo "Expect failure:"
$(IDC) -exec ./$(PROGRAM) || :
% : %.st
diff -r f4fccae99d24 object/examples/precedence/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/object/examples/precedence/Makefile Tue Dec 11 23:51:23 2007 -0600
@@ -0,0 +1,23 @@
+IDC = ../idc
+
+all : good bad
+
+run : all
+ $(IDC) -exec ./good
+
+bad : bad.st
+ @echo "Expect failure:"
+ if $(IDC) bad.st; then exit 1; else exit 0; fi
+
+% : %.st
+ $(IDC) $<
+
+tidy: .FORCE
+ rm -f *~
+
+clean : tidy .FORCE
+ rm -f good bad *.exe
+
+spotless : clean .FORCE
+
+.FORCE :
diff -r f4fccae99d24 object/examples/precedence/bad.st
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/object/examples/precedence/bad.st Tue Dec 11 23:51:23 2007 -0600
@@ -0,0 +1,5 @@
+{ import: st80 }
+
+[
+ (2 + 3 * 8) print. '\n' put.
+]
diff -r f4fccae99d24 object/examples/precedence/good.st
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/object/examples/precedence/good.st Tue Dec 11 23:51:23 2007 -0600
@@ -0,0 +1,7 @@
+{ import: st80 }
+
+[
+ (2 + (3 * 8)) print. '\n' put.
+ (3 * 8 + 2) print. '\n' put.
+ ((2 + 3) * 8) print. '\n' put.
+]
diff -r f4fccae99d24 object/examples/sqvm/File.st
--- a/object/examples/sqvm/File.st Tue Dec 11 23:40:12 2007 -0600
+++ b/object/examples/sqvm/File.st Tue Dec 11 23:51:23 2007 -0600
@@ -63,7 +63,7 @@ File read: array startingAt: index size:
[
^(0 < index and: [index + size - 1 <= array size])
ifTrue: [(SmallInteger value_: (self _read_: array _elements
- at_: (index - 1 * array elementSize) _integerValue
+ at_: ((index - 1) * array elementSize) _integerValue
size_: (size * array elementSize) _integerValue))
// array elementSize]
ifFalse: [self errorNoSuchElement]
@@ -79,7 +79,7 @@ File write: array startingAt: index size
[
^(0 < index and: [index + size - 1 <= array size])
ifTrue: [(SmallInteger value_: (self _write_: array _elements
- at_: (index - 1 * array elementSize) _integerValue
+ at_: ((index - 1) * array elementSize) _integerValue
size_: (size * array elementSize) _integerValue))
// array elementSize]
ifFalse: [self errorNoSuchElement]
diff -r f4fccae99d24 object/idc/CCodeGenerator.st
--- a/object/idc/CCodeGenerator.st Tue Dec 11 23:40:12 2007 -0600
+++ b/object/idc/CCodeGenerator.st Tue Dec 11 23:51:23 2007 -0600
@@ -640,7 +640,7 @@ CCodeGenerator implementType: typeNode
gen: ' return "'; gen: name; genl: '"; }';
gen: 'static struct __slotinfo *'; genType: name method: '_slots'; gen: '(oop _closure, oop '; genVariable: 'self'; gen: ') {';
gen: ' static struct __slotinfo info[]= {'.
- typeNode slots doWithIndex: [:slot :index | self gen: ' { "', slot, '", '; gen: (index - 1 * 4) printString; gen: ', 4 },'].
+ typeNode slots doWithIndex: [:slot :index | self gen: ' { "', slot, '", '; gen: ((index - 1) * 4) printString; gen: ', 4 },'].
self
genl: ' { 0, 0, 0 } }; return &info[0]; }'.
]
diff -r f4fccae99d24 object/idc/Parser.st
--- a/object/idc/Parser.st Tue Dec 11 23:40:12 2007 -0600
+++ b/object/idc/Parser.st Tue Dec 11 23:51:23 2007 -0600
@@ -171,6 +171,7 @@ Parser parsePrimary
type == #'('
ifTrue:
[node := self scan; parseExpression.
+ (node isSendNode) ifTrue: [node isExplicit: true].
type == #')' ifFalse: [self error: ''')'' expected'].
self scan.
^node].
@@ -204,15 +205,21 @@ Parser parseUnary
"
].
^node
-]
-
+
+]
Parser parseBinary
[
- | node |
+ | node tok prev |
node := self parseUnary.
[type == #binary]
whileTrue:
- [node := SendNode withReceiver: node selector: token contents position: self position.
+ [tok := token contents.
+ prev := node.
+ node := SendNode withReceiver: node selector: tok position: self position.
+ ((prev isSendNode and: [(prev isExplicit) not and:
+ [(prev selector = '+') or: [prev selector = '-']]]) and:
+ [(tok = '*') or: [tok = '/']])
+ ifTrue: [self error: 'ambiguous arithmetic expression; use explicit parentheses'].
node addArgument: (self scan; parseUnary)].
^node
]
diff -r f4fccae99d24 object/idc/SendNode.st
--- a/object/idc/SendNode.st Tue Dec 11 23:40:12 2007 -0600
+++ b/object/idc/SendNode.st Tue Dec 11 23:51:23 2007 -0600
@@ -30,10 +30,16 @@ SendNode : ParseNode (
cascades "cascaded sends (empty if I am a cascaded send)"
superedType "the type in which to start lookup, or nil for normal send"
specialGenerator "#generate: message for macro/special/arithmetic selector"
+ isExplicit "whether we were surrounded by explicit parentheses"
)
ParseNode isSendNode [ ^false ]
SendNode isSendNode [ ^true ]
+
+SendNode selector [ ^selector ]
+
+SendNode isExplicit: explicit [ isExplicit := explicit ]
+SendNode isExplicit [ ^isExplicit ]
SendNode initialize
[
@@ -48,6 +54,7 @@ SendNode withReceiver: receiverNode sele
self := self withPosition: aPosition.
receiver := receiverNode.
selector := selectorString.
+ isExplicit := false.
]
SendNode addArgument: aNode [ arguments add: aNode ]
_______________________________________________
fonc mailing list
[email protected]
http://vpri.org/mailman/listinfo/fonc