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

Reply via email to