Bläddra i källkod

LEN procedure + fix record/array passing to procedures.

Vladislav Folts 12 år sedan
förälder
incheckning
68045f82e6
10 ändrade filer med 144 tillägg och 3 borttagningar
  1. 1 0
      src/context.js
  2. 32 1
      src/procedure.js
  3. 9 0
      test/expected/array.js
  4. 41 0
      test/expected/len.js
  5. 9 0
      test/expected/record.js
  6. 11 0
      test/input/array.ob
  7. 20 0
      test/input/len.ob
  8. 12 1
      test/input/record.ob
  9. 1 1
      test/test.js
  10. 8 0
      test/test_unit.js

+ 1 - 0
src/context.js

@@ -258,6 +258,7 @@ exports.Designator = ChainedContext.extend({
 		if (this.__derefCode)
 			return this.rtl().makeRef(this.__derefCode, this.__propCode);
 		if (!(this.__currentType instanceof Type.Array)
+			&& !(this.__currentType instanceof Type.Record)
 			&& this.__info instanceof Type.Variable && !this.__info.isVar())
 			return "{set: function($v){" + code + " = $v;}, get: function(){return " + code + ";}}";
 		return code;

+ 32 - 1
src/procedure.js

@@ -52,7 +52,10 @@ var ProcCallGenerator = Class.extend({
 		if (designator){
 			var info = designator.info();
 			if (info instanceof Type.Variable)
-				if (info.isVar() && !isVarArg)
+				if (info.isVar() && !isVarArg 
+					&& !(type instanceof Type.Array)
+					&& !(type instanceof Type.Record)
+					)
 					code += ".get()";
 				else if (!info.isVar() && isVarArg)
 					code = designator.refCode();
@@ -201,6 +204,34 @@ exports.predefined = [
 		var symbol = new Type.Symbol(name, type);
 		return symbol;
 	}(),
+	function(){
+		var LenProcCallGenerator = ProcCallGenerator.extend({
+			init: function LenProcCallGenerator(context, id, type){
+				ProcCallGenerator.prototype.init.call(this, context, id, type);
+			},
+			prolog: function(id){return "";},
+			checkArgument: function(pos, type, designator){
+				ProcCallGenerator.prototype.checkArgument.call(this, pos, type, designator);
+				if (!(type instanceof Type.Array))
+					throw new Errors.Error("ARRAY expected, got '"
+										 + type.name() + "'");
+				return new CheckArgumentResult(type, false);
+			},
+			epilog: function(){return ".length";}
+		});
+
+		var name = "LEN";
+		var args = [new Arg(undefined, false)];
+		var type = new Type.Procedure(new ProcType(
+			"predefined procedure LEN",
+			args,
+			Type.basic.int,
+			function(context, id, type){
+				return new LenProcCallGenerator(context, id, type);
+			}));
+		var symbol = new Type.Symbol(name, type);
+		return symbol;
+	}(),
 	function(){
 		var AssertProcCallGenerator = ProcCallGenerator.extend({
 			init: function AssertProcCallGenerator(context, id, type){

+ 9 - 0
test/expected/array.js

@@ -56,9 +56,18 @@ function p(){
 	var a3 = RTL$.makeArray(1, 0);
 	a3[0] = 1;
 }
+
+function p1(a/*ARRAY OF INTEGER*/){
+}
+
+function p2(a/*VAR ARRAY OF INTEGER*/){
+	p1(a);
+}
 a1[0] = 1;
 a3[1] = true;
 a4[1][2] = true;
 a4[1][2] = true;
+p1(a1);
+p2(a1);
 RTL$.copy(a11, a1);
 }();

+ 41 - 0
test/expected/len.js

@@ -0,0 +1,41 @@
+var RTL$ = {
+	makeArray: function (/*dimensions, initializer*/){
+        var forward = Array.prototype.slice.call(arguments);
+        var result = new Array(forward.shift());
+        var i;
+        if (forward.length == 1){
+            var init = forward[0];
+            if (typeof init == "function")
+                for(i = 0; i < result.length; ++i)
+                    result[i] = init();
+            else
+                for(i = 0; i < result.length; ++i)
+                    result[i] = init;
+        }
+        else
+            for(i = 0; i < result.length; ++i)
+                result[i] = RTLMakeArray.apply(this, forward);
+        return result;
+    },
+	assert: function (condition, code){
+        if (!condition)
+            throw new Error("assertion failed"
+                          + ((code !== undefined) ? " with code " + code : ""));
+    }
+};
+var m = function (){
+var a1 = RTL$.makeArray(10, 0);
+var a2 = RTL$.makeArray(15, false);
+var a3 = RTL$.makeArray(20, 0);
+
+function p1(a/*ARRAY OF INTEGER*/){
+	return a.length;
+}
+
+function p2(a/*VAR ARRAY OF BOOLEAN*/){
+	return a.length;
+}
+p1(a1);
+p2(a2);
+RTL$.assert(a3.length == 20);
+}();

+ 9 - 0
test/expected/record.js

@@ -34,5 +34,14 @@ var T1 = Base1.extend({
 });
 var b1 = new Base1();
 var r1 = new T1();
+
+function p1(r/*T1*/){
+}
+
+function p2(r/*VAR T1*/){
+	p1(r);
+}
 RTL$.copy(r1, b1);
+p1(r1);
+p2(r1);
 }();

+ 11 - 0
test/input/array.ob

@@ -21,11 +21,22 @@ BEGIN
     a3[0] := 1 
 END p;
 
+PROCEDURE p1(a: T1);
+END p1;
+
+PROCEDURE p2(VAR a: T1);
+BEGIN
+    p1(a)
+END p2;
+
 BEGIN
     a1[0] := 1;
     a3[1] := TRUE;
 	a4[1][2] := TRUE;
 	a4[1, 2] := TRUE;
 
+    p1(a1);
+    p2(a1);
+
     a1 := a11
 END m.

+ 20 - 0
test/input/len.ob

@@ -0,0 +1,20 @@
+MODULE m;
+                
+VAR
+    a1: ARRAY 10 OF INTEGER;
+    a2: ARRAY 15 OF BOOLEAN;
+    a3: ARRAY 20 OF CHAR;
+
+PROCEDURE p1(a: ARRAY OF INTEGER): INTEGER;
+    RETURN LEN(a)
+END p1;
+
+PROCEDURE p2(VAR a: ARRAY OF BOOLEAN): INTEGER;
+    RETURN LEN(a)
+END p2;
+
+BEGIN
+	p1(a1);
+	p2(a2);
+	ASSERT(LEN(a3) = 20)
+END m.

+ 12 - 1
test/input/record.ob

@@ -5,6 +5,17 @@ TYPE
 VAR
 	b1: Base1;
 	r1: T1;
+
+PROCEDURE p1(r: T1);
+END p1;
+
+PROCEDURE p2(VAR r: T1);
 BEGIN
-	b1 := r1
+    p1(r)
+END p2;
+
+BEGIN
+	b1 := r1;
+    p1(r1);
+    p2(r1)
 END m.

+ 1 - 1
test/test.js

@@ -44,7 +44,7 @@ function run(tests){
 
     var start = Date.now();
     if (typeof process != "undefined" && process.argv.length > 2)
-        runTest(process.argv[2], tests, "");
+        runTest(process.argv[2], tests, stat, "");
     else
         runImpl(tests, stat, "");
     var stop = Date.now();

+ 8 - 0
test/test_unit.js

@@ -322,6 +322,14 @@ expression: function(){
 	test.expectError("PROCEDURE readOnlyPointers(a: ARRAY OF P); BEGIN NEW(a[0]) END readOnlyPointers",
 					 "read-only variable cannot be used as VAR parameter");
 },
+"LEN": function(){
+	var test = setup(Grammar.procedureDeclaration);
+
+	test.parse("PROCEDURE p(a: ARRAY OF INTEGER): INTEGER; RETURN LEN(a) END p");
+	test.parse("PROCEDURE p(VAR a: ARRAY OF BOOLEAN): INTEGER; RETURN LEN(a) END p");
+	test.expectError("PROCEDURE p(a: ARRAY OF INTEGER): INTEGER; RETURN LEN(a[0]) END p",
+					 "ARRAY expected, got 'INTEGER'");
+},
 "assignment statement": function(){
 	var test = setupWithContext(
 		  Grammar.statement