Browse Source

INCL/EXCL require constant in second argument.

Vladislav Folts 12 years ago
parent
commit
fa17e7ed8d
5 changed files with 35 additions and 25 deletions
  1. 1 0
      src/code.js
  2. 9 3
      src/procedure.js
  3. 8 8
      test/expected/set.js
  4. 5 5
      test/input/set.ob
  5. 12 9
      test/test_unit.js

+ 1 - 0
src/code.js

@@ -50,6 +50,7 @@ var Expression = Class.extend({
     designator: function(){return this.__designator;},
     constValue: function(){return this.__constValue;},
     maxPrecedence: function(){return this.__maxPrecedence;},
+    isTerm: function(){return !this.__designator && this.__maxPrecedence == undefined;},
     deref: function(){
         if (!this.__designator)
             return this;

+ 9 - 3
src/procedure.js

@@ -174,8 +174,14 @@ function setBitImpl(name, op){
     var args = [new Arg(Type.basic.set, true),
                 new Arg(Type.basic.int, false)];
     function operator(x, y){
+        var value = y.constValue();
+        if (value === undefined || value < 0 || value > 31)
+            throw new Errors.Error("constant (0..31) expected as second argument of " + name);
+        var comment = "bit: " + (y.isTerm() ? value : Code.adjustPrecedence(y, precedence.shift));
+        value = 1 << value;
+        var valueCode = value + "/*" + comment + "*/";
         var code = op(Code.adjustPrecedence(x, precedence.assignment),
-                      Code.adjustPrecedence(y, precedence.shift));
+                      valueCode);
         return new Code.Expression(
             code, undefined, undefined, undefined, precedence.assignment);
     }
@@ -329,8 +335,8 @@ exports.predefined = [
         var symbol = new Type.Symbol("ASSERT", type);
         return symbol;
     }(),
-    setBitImpl("INCL", function(x, y){return x + " |= 1 << " + y;}),
-    setBitImpl("EXCL", function(x, y){return x + " &= ~(1 << " + y + ")";}),
+    setBitImpl("INCL", function(x, y){return x + " |= " + y;}),
+    setBitImpl("EXCL", function(x, y){return x + " &= ~(" + y + ")";}),
     function(){
         var CallGenerator = ProcCallGenerator.extend({
             init: function AbsProcCallGenerator(context, id, type){

+ 8 - 8
test/expected/set.js

@@ -50,6 +50,7 @@ var RTL$ = {
 };
 var m = function (){
 var ci = 3;
+var cb = true;
 var cs1 = 2 | 4;
 var cs2 = 14 & ~18;
 var cs3 = 14 & 18;
@@ -93,12 +94,11 @@ s1 = s1 & ~s2;
 s1 = s1 & s2;
 s1 = s1 ^ s2;
 s1 = ~s2;
-s2 |= 1 << 3;
-s1 |= 1 << ci * 2 + 3;
-s1 |= 1 << ci * 2 - i1 + 3;
-s1 |= 1 << (b ? 1 : 0);
-aSet[0] |= 1 << aInt[0];
-s2 &= ~(1 << 3);
-s2 &= ~(1 << (b ? 1 : 0));
-aSet[0] &= ~(1 << aInt[0]);
+s2 |= 8/*bit: 3*/;
+s1 |= 512/*bit: ci * 2 + 3*/;
+s1 |= 2/*bit: (cb ? 1 : 0)*/;
+aSet[0] |= 8/*bit: 3*/;
+s2 &= ~(8/*bit: 3*/);
+s2 &= ~(1/*bit: (!cb ? 1 : 0)*/);
+aSet[0] &= ~(8/*bit: 3*/);
 }();

+ 5 - 5
test/input/set.ob

@@ -2,6 +2,7 @@ MODULE m;
 
 CONST
 	ci = 3;
+	cb = TRUE;
 	
 	cs1 = {1} + {2};
 	cs2 = {1, 2, 3} - {1, 4};
@@ -55,11 +56,10 @@ BEGIN
 
 	INCL(s2, 3);
 	INCL(s1, ci * 2 + 3);
-	INCL(s1, ci * 2 - i1 + 3);
-	INCL(s1, ORD(b));
-	INCL(aSet[0], aInt[0]);
+	INCL(s1, ORD(cb));
+	INCL(aSet[0], 3);
 
 	EXCL(s2, 3);
-	EXCL(s2, ORD(b));
-	EXCL(aSet[0], aInt[0]);
+	EXCL(s2, ORD(~cb));
+	EXCL(aSet[0], 3);
 END m.

+ 12 - 9
test/test_unit.js

@@ -713,15 +713,18 @@ identifier: function(){
     test.expectError("set1 * b", "type mismatch: expected 'SET', got 'BOOLEAN'");
     test.expectError("set1 / b", "type mismatch: expected 'SET', got 'BOOLEAN'");
 },
-"SET functions": function(){
-    var test = setupWithContext(
-          Grammar.statement
-        , "VAR set1, set2: SET; b: BOOLEAN; i: INTEGER;");
-
-    test.parse("INCL(set1, i)");
-    test.parse("EXCL(set1, i)");
-    test.expectError("INCL({}, i)", "expression cannot be used as VAR parameter");
-},
+"SET functions": testWithContext(
+    context(Grammar.statement,
+            "VAR set1, set2: SET; b: BOOLEAN; i: INTEGER;"),
+    pass("INCL(set1, 0)",
+         "EXCL(set1, 3)"),
+    fail(["INCL({}, i)", "expression cannot be used as VAR parameter"],
+         ["INCL(set1, i)", "constant (0..31) expected as second argument of INCL"],
+         ["EXCL(set1, i)", "constant (0..31) expected as second argument of EXCL"],
+         ["INCL(set1, 32)", "constant (0..31) expected as second argument of INCL"],
+         ["EXCL(set1, -1)", "constant (0..31) expected as second argument of EXCL"]
+        )
+),
 "procedure body": function(){
     var test = setup(Grammar.procedureBody);
     test.parse("END");