Vladislav Folts преди 12 години
родител
ревизия
6d38bacab1
променени са 3 файла, в които са добавени 59 реда и са изтрити 29 реда
  1. 20 12
      src/context.js
  2. 16 16
      src/rtl.js
  3. 23 1
      test/test_unit.js

+ 20 - 12
src/context.js

@@ -1239,18 +1239,26 @@ exports.Assignment = ChainedContext.extend({
 			this.__code.write(this.__leftOp + (d_info.isVar() ? ".set(" : " = "));
 			this.__code.write(this.__leftOp + (d_info.isVar() ? ".set(" : " = "));
 	},
 	},
 	handleExpression: function(type, value, designator){
 	handleExpression: function(type, value, designator){
-		if (type instanceof Type.String
-			&& this.__type instanceof Type.Array
-			&& this.__type.elementsType() == basicTypes.char){
-			if (this.__type.length() === undefined)
-				throw new Errors.Error("string cannot be assigned to open " + this.__type.description());
-			if (type.length() > this.__type.length())
-				throw new Errors.Error(
-					this.__type.length() + "-character ARRAY is too small for " 
-					+ type.length() + "-character string");
-			this.__code = new Code.SimpleGenerator(
-				this.rtl().assignArrayFromString(this.__leftOp, this.__code.result()));
-		}
+		if (this.__type instanceof Type.Array)
+			if (this.__type.elementsType() == basicTypes.char)
+				if (type instanceof Type.String){
+					if (this.__type.length() === undefined)
+						throw new Errors.Error("string cannot be assigned to open " + this.__type.description());
+					if (type.length() > this.__type.length())
+						throw new Errors.Error(
+							this.__type.length() + "-character ARRAY is too small for " 
+							+ type.length() + "-character string");
+					this.__code = new Code.SimpleGenerator(
+						this.rtl().assignArrayFromString(this.__leftOp, this.__code.result()));
+				}
+				else
+					throw new Errors.Error("'" + this.__leftOp
+										 + "' is '" + this.__type.description()
+								 		 + "' and can be assigned to a string only (got '" + type.description() + "' expression intead)");
+			else
+				throw new Errors.Error("'" + this.__leftOp
+									 + "' is '" + this.__type.description()
+									 + "' and cannot be assigned");
 		else if (!Cast.implicit(type, this.__type))
 		else if (!Cast.implicit(type, this.__type))
 			throw new Errors.Error("type mismatch: '" + this.__leftOp
 			throw new Errors.Error("type mismatch: '" + this.__leftOp
 								 + "' is '" + this.__type.description()
 								 + "' is '" + this.__type.description()

+ 16 - 16
src/rtl.js

@@ -84,28 +84,13 @@ var impl = {
 	}
 	}
 };
 };
 
 
-function makeOnDemandFunction(name){
-	return function(){
-		if (!this.__entries[name])
-			this.__entries[name] = impl[name];
-		var result = "RTL$." + name + "(";
-		for(var a = 0; a < arguments.length; ++a){
-			if (a)
-				result += ", ";
-			result += arguments[a];
-		}
-		result += ")";
-		return result;
-	};
-}
-
 exports.Class = Class;
 exports.Class = Class;
 exports.RTL = Class.extend({
 exports.RTL = Class.extend({
 	init: function RTL(){
 	init: function RTL(){
 		this.__entries = {};
 		this.__entries = {};
 		this.__supportJS = false;
 		this.__supportJS = false;
 		for(var fName in impl){
 		for(var fName in impl){
-			this[fName] = makeOnDemandFunction(fName);
+			this[fName] = this.__makeOnDemand(fName);
 		}
 		}
 	},
 	},
 	supportJS: function(){this.__supportJS = true;},
 	supportJS: function(){this.__supportJS = true;},
@@ -132,5 +117,20 @@ exports.RTL = Class.extend({
 		if (this.__supportJS)
 		if (this.__supportJS)
 			result += "var JS = function(){return this;}();\n";
 			result += "var JS = function(){return this;}();\n";
 		return result;
 		return result;
+	},
+	__makeOnDemand: function(name){
+		return function(){
+			if (!this.__entries[name])
+				this.__entries[name] = impl[name];
+			var result = "RTL$." + name + "(";
+			if (arguments.length){
+				result += arguments[0];
+				for(var a = 1; a < arguments.length; ++a)
+					result += ", " + arguments[a];
+			}
+			result += ")";
+			return result;
+		};
 	}
 	}
+
 });
 });

+ 23 - 1
test/test_unit.js

@@ -364,7 +364,7 @@ expression: function(){
 	test.expectError("VAR a: ARRAY 10 OF BOOLEAN; BEGIN a[0,0] := TRUE END"
 	test.expectError("VAR a: ARRAY 10 OF BOOLEAN; BEGIN a[0,0] := TRUE END"
 				   , "ARRAY expected, got 'BOOLEAN'");
 				   , "ARRAY expected, got 'BOOLEAN'");
 	test.expectError("VAR a: ARRAY 10, 20 OF BOOLEAN; BEGIN a[0] := TRUE END"
 	test.expectError("VAR a: ARRAY 10, 20 OF BOOLEAN; BEGIN a[0] := TRUE END"
-				   , "type mismatch: 'a[0]' is 'ARRAY OF BOOLEAN' and cannot be assigned to 'BOOLEAN' expression");
+				   , "'a[0]' is 'ARRAY OF BOOLEAN' and cannot be assigned");
 	test.expectError("VAR a: ARRAY 10 OF INTEGER; BEGIN a[10] := 0 END"
 	test.expectError("VAR a: ARRAY 10 OF INTEGER; BEGIN a[10] := 0 END"
 				   , "index out of bounds: maximum possible index is 9, got 10");
 				   , "index out of bounds: maximum possible index is 9, got 10");
 	test.expectError("CONST c1 = 5; VAR a: ARRAY 10 OF INTEGER; BEGIN a[10 + c1] := 0 END"
 	test.expectError("CONST c1 = 5; VAR a: ARRAY 10 OF INTEGER; BEGIN a[10 + c1] := 0 END"
@@ -758,12 +758,34 @@ procedure: function(){
 	var test = setupWithContext(
 	var test = setupWithContext(
 		  Grammar.statement
 		  Grammar.statement
 		, "VAR a1: ARRAY 3 OF CHAR;"
 		, "VAR a1: ARRAY 3 OF CHAR;"
+			+ "ch1: CHAR;"
+			+ "intArray: ARRAY 10 OF INTEGER;"
 		);
 		);
 	test.parse("a1 := \"abc\"");
 	test.parse("a1 := \"abc\"");
 	test.parse("a1 := \"ab\"");
 	test.parse("a1 := \"ab\"");
 	test.parse("a1 := \"a\"");
 	test.parse("a1 := \"a\"");
 	test.parse("a1 := 22X");
 	test.parse("a1 := 22X");
+	test.parse("ch1 := \"A\"");
+	test.parse("ch1 := 22X");
 	test.expectError("a1 := \"abcd\"", "3-character ARRAY is too small for 4-character string");
 	test.expectError("a1 := \"abcd\"", "3-character ARRAY is too small for 4-character string");
+	test.expectError("intArray := \"abcd\""
+				   , "'intArray' is 'ARRAY OF INTEGER' and cannot be assigned");
+},
+"array assignment fails": function(){
+	var test = setupWithContext(
+		  Grammar.statement
+		, "VAR charArray: ARRAY 3 OF CHAR;"
+			+ "intArray: ARRAY 10 OF INTEGER;"
+		);
+	test.expectError("intArray := intArray"
+				   , "'intArray' is 'ARRAY OF INTEGER' and cannot be assigned");
+},
+"open array assignment fails": function(){
+	var test = setup(Grammar.procedureDeclaration);
+	test.expectError("PROCEDURE p(s1, s2: ARRAY OF CHAR); BEGIN s1 := s2 END p"
+				   , "cannot assign to read-only variable");
+	test.expectError("PROCEDURE p(VAR s1, s2: ARRAY OF CHAR); BEGIN s1 := s2 END p"
+				   , "'s1' is 'ARRAY OF CHAR' and can be assigned to a string only (got 'ARRAY OF CHAR' expression intead)");
 },
 },
 "string assignment to open array fails": function(){
 "string assignment to open array fails": function(){
 	var test = setup(Grammar.procedureDeclaration);
 	var test = setup(Grammar.procedureDeclaration);