Răsfoiți Sursa

RECORD assigning

Vladislav Folts 12 ani în urmă
părinte
comite
23c8541e59

+ 5 - 4
src/cast.js

@@ -16,15 +16,16 @@ function implicitCast(from, to){
 	}
 	else if (from instanceof ArrayType && to instanceof ArrayType)
 		return implicitCast(from.elementsType(), to.elementsType());
-	else if (from instanceof PointerType && to instanceof PointerType){
-		toR = to.baseType();
-		fromR = from.baseType();
+	else if ((from instanceof PointerType && to instanceof PointerType)
+		|| (from instanceof Type.Record && to instanceof Type.Record)){
+		var toR = to instanceof PointerType ? to.baseType() : to;
+		var fromR = from.baseType();
 		while (fromR && fromR != toR)
 			fromR = fromR.baseType();
 		if (fromR)
 			return true;
 	}
-	else if (from == Type.nil 
+	else if (from == Type.nil
 		&& (to instanceof PointerType || to.isProcedure()))
 		return true;
 	else if (from.isProcedure() && to.isProcedure()){

+ 8 - 5
src/context.js

@@ -888,7 +888,7 @@ exports.Expression = ChainedContext.extend({
 		}
 		else if (type === undefined || this.__type === undefined)
 			this.__type = type;
-		else if (type !== this.__type)
+		else if (!Cast.implicit(type, this.__type))
 			throw new Errors.Error("type mismatch: expected '" + this.__type.name()
 								 + "', got '" + type.name() + "'");
 	},
@@ -1235,7 +1235,8 @@ exports.Assignment = ChainedContext.extend({
 			throw new Errors.Error("cannot assign to " + d_info.idType());
 		this.__leftOp = d.code();
 		this.__type = d.type();
-		if (!(this.__type instanceof Type.Array))
+		if (!(this.__type instanceof Type.Array)
+			&& !(this.__type instanceof Type.Record))
 			this.__code.write(this.__leftOp + (d_info.isVar() ? ".set(" : " = "));
 	},
 	handleExpression: function(type, value, designator){
@@ -1272,8 +1273,9 @@ exports.Assignment = ChainedContext.extend({
 				throw new Errors.Error("array size mismatch: '" + this.__leftOp
 									 + "' has size " + this.__type.length()
 									 + " and cannot be assigned to the array with size " + type.length());
-			else
-				this.__code = new Code.SimpleGenerator(
+		
+		if (isArray || type instanceof Type.Record)
+			this.__code = new Code.SimpleGenerator(
 					this.rtl().copy(this.__code.result(), this.__leftOp));
 
 		if (designator)
@@ -1341,6 +1343,7 @@ exports.FieldListDeclaration = ChainedContext.extend({
 		this.__idents = [];
 		this.__type = undefined;
 	},
+	typeName: function(){return undefined;},
 	setIdent: function(id) {this.__idents.push(id);},
 	setType: function(type) {this.__type = type;},
 	endParse: function(){
@@ -1440,7 +1443,7 @@ exports.RecordDecl = ChainedContext.extend({
 		gen.write("init: function " + type.name() + "()");
 		gen.openScope();
 		if (baseType)
-			gen.write(baseType.name() + ".prototype.init.bind(this)();\n");
+			gen.write(baseType.name() + ".prototype.init.call(this);\n");
 		var ownFields = type.ownFields();
 		for(var f in ownFields)
 			gen.write("this." + f + " = " + ownFields[f].initializer() + ";\n");

+ 144 - 142
src/rtl.js

@@ -1,156 +1,158 @@
 function Class(){}
 Class.extend = function extend(methods){
-		methods.__proto__ = this.prototype; // make instanceof work
+        methods.__proto__ = this.prototype; // make instanceof work
 
-		// to see constructor name in diagnostic
-		var result = methods.init;
-		methods.constructor = result.prototype.constructor;
+        // to see constructor name in diagnostic
+        var result = methods.init;
+        methods.constructor = result.prototype.constructor;
 
-		result.prototype = methods;
-		result.extend = extend;
-		return result;
-	};
+        result.prototype = methods;
+        result.extend = extend;
+        return result;
+    };
 
 var impl = {
-	typeGuard: function(from, to){
-		if (!(from instanceof to))
-			throw new Error("typeguard assertion failed");
-		return from;
-	},
-	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;
-	},
-	makeSet: function(/*...*/){
-		var result = 0;
-		
-		function checkBit(b){
-			if (b < 0 || b > 31)
-				throw new Error("integes between 0 and 31 expected, got " + b);
-		}
+    typeGuard: function(from, to){
+        if (!(from instanceof to))
+            throw new Error("typeguard assertion failed");
+        return from;
+    },
+    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;
+    },
+    makeSet: function(/*...*/){
+        var result = 0;
+        
+        function checkBit(b){
+            if (b < 0 || b > 31)
+                throw new Error("integes between 0 and 31 expected, got " + b);
+        }
 
-		function setBit(b){
-			checkBit(b);
-			result |= 1 << b;
-		}
-		
-		for(var i = 0; i < arguments.length; ++i){
-			var b = arguments[i];
-			if (b instanceof Array){
-				var from = b[0];
-				var to = b[1];
-				if (from < to)
-					throw new Error("invalid SET diapason: " + from + ".." + to);
-				for(var bi = from; bi <= to; ++bi)
-					setBit(bi);
-			}
-			else
-				setBit(b);
-		}
-		return result;
-	},
-	makeRef: function(obj, prop){
-	    return {set: function(v){ obj[prop] = v; },
-	            get: function(){ return obj[prop]; }};
-	},
-	setInclL: function(l, r){return l & r == l;},
-	setInclR: function(l, r){return l & r == r;},
-	assignArrayFromString: function(a, s){
-		var i;
-		for(i = 0; i < s.length; ++i)
-			a[i] = s.charCodeAt(i);
-		for(i = s.length; i < a.length; ++i)
-			a[i] = 0;
-	},
-	strToArray: function(s){
-		var result = new Array(s.length);
-		for(i = 0; i < s.length; ++i)
-			result[i] = s.charCodeAt(i);
-		return result;
-	},
-	copy: function(from, to){
-        for(var prop in from){
-            var v = from[prop];
-            if (typeof v == "object")
-                this.copy(v, to[prop]);
-            else if (typeof v != "function")
-                to[prop] = v;
+        function setBit(b){
+            checkBit(b);
+            result |= 1 << b;
+        }
+        
+        for(var i = 0; i < arguments.length; ++i){
+            var b = arguments[i];
+            if (b instanceof Array){
+                var from = b[0];
+                var to = b[1];
+                if (from < to)
+                    throw new Error("invalid SET diapason: " + from + ".." + to);
+                for(var bi = from; bi <= to; ++bi)
+                    setBit(bi);
+            }
+            else
+                setBit(b);
         }
-	},
-	assert: function(condition, code){
-		if (!condition)
-			throw new Error("assertion failed"
-						  + ((code !== undefined) ? " with code " + code : ""));
-	}
+        return result;
+    },
+    makeRef: function(obj, prop){
+        return {set: function(v){ obj[prop] = v; },
+                get: function(){ return obj[prop]; }};
+    },
+    setInclL: function(l, r){return l & r == l;},
+    setInclR: function(l, r){return l & r == r;},
+    assignArrayFromString: function(a, s){
+        var i;
+        for(i = 0; i < s.length; ++i)
+            a[i] = s.charCodeAt(i);
+        for(i = s.length; i < a.length; ++i)
+            a[i] = 0;
+    },
+    strToArray: function(s){
+        var result = new Array(s.length);
+        for(i = 0; i < s.length; ++i)
+            result[i] = s.charCodeAt(i);
+        return result;
+    },
+    copy: function(from, to){
+        for(var prop in to){
+            if (to.hasOwnProperty(prop)){
+                var v = from[prop];
+                if (v !== null && typeof v == "object")
+                    this.copy(v, to[prop]);
+                else
+                    to[prop] = v;
+            }
+        }
+    },
+    assert: function(condition, code){
+        if (!condition)
+            throw new Error("assertion failed"
+                          + ((code !== undefined) ? " with code " + code : ""));
+    }
 };
 
 exports.Class = Class;
 exports.RTL = Class.extend({
-	init: function RTL(){
-		this.__entries = {};
-		this.__supportJS = false;
-		for(var fName in impl){
-			this[fName] = this.__makeOnDemand(fName);
-			this[fName + "Id"] = this.__makeIdOnDemand(fName);
-		}
-	},
-	supportJS: function(){this.__supportJS = true;},
-	baseClass: function(){
-		if (!this.__entries["extend"])
-			this.__entries.extend = Class.extend;
-		return "RTL$";
-	},
-	generate: function(){
-		var result = "var RTL$ = {\n";
-		var firstEntry = true;
-		for (var name in this.__entries){
-			if (!firstEntry)
-				result += ",\n";
-			else
-				firstEntry = false;
-			result += "\t" + name + ": " + this.__entries[name].toString();
-		}
-		if (!firstEntry)
-			result += "\n};\n";
-		else
-			result = "";
-		
-		if (this.__supportJS)
-			result += "var JS = function(){return this;}();\n";
-		return result;
-	},
-	__makeIdOnDemand: function(name){
-		return function(){
-			if (!this.__entries[name])
-				this.__entries[name] = impl[name];
-			return "RTL$." + name;
-		};
-	},
-	__makeOnDemand: function(name){
-		return function(){
-			var result = this[name +"Id"]() + "(";
-			if (arguments.length){
-				result += arguments[0];
-				for(var a = 1; a < arguments.length; ++a)
-					result += ", " + arguments[a];
-			}
-			result += ")";
-			return result;
-		};
-	}
+    init: function RTL(){
+        this.__entries = {};
+        this.__supportJS = false;
+        for(var fName in impl){
+            this[fName] = this.__makeOnDemand(fName);
+            this[fName + "Id"] = this.__makeIdOnDemand(fName);
+        }
+    },
+    supportJS: function(){this.__supportJS = true;},
+    baseClass: function(){
+        if (!this.__entries["extend"])
+            this.__entries.extend = Class.extend;
+        return "RTL$";
+    },
+    generate: function(){
+        var result = "var RTL$ = {\n";
+        var firstEntry = true;
+        for (var name in this.__entries){
+            if (!firstEntry)
+                result += ",\n";
+            else
+                firstEntry = false;
+            result += "\t" + name + ": " + this.__entries[name].toString();
+        }
+        if (!firstEntry)
+            result += "\n};\n";
+        else
+            result = "";
+        
+        if (this.__supportJS)
+            result += "var JS = function(){return this;}();\n";
+        return result;
+    },
+    __makeIdOnDemand: function(name){
+        return function(){
+            if (!this.__entries[name])
+                this.__entries[name] = impl[name];
+            return "RTL$." + name;
+        };
+    },
+    __makeOnDemand: function(name){
+        return function(){
+            var result = this[name +"Id"]() + "(";
+            if (arguments.length){
+                result += arguments[0];
+                for(var a = 1; a < arguments.length; ++a)
+                    result += ", " + arguments[a];
+            }
+            result += ")";
+            return result;
+        };
+    }
 
 });

+ 34 - 32
test/expected/array.js

@@ -1,42 +1,44 @@
 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;
-	},
+        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;
+    },
 	extend: function extend(methods){
-		methods.__proto__ = this.prototype; // make instanceof work
+        methods.__proto__ = this.prototype; // make instanceof work
 
-		// to see constructor name in diagnostic
-		var result = methods.init;
-		methods.constructor = result.prototype.constructor;
+        // to see constructor name in diagnostic
+        var result = methods.init;
+        methods.constructor = result.prototype.constructor;
 
-		result.prototype = methods;
-		result.extend = extend;
-		return result;
-	},
+        result.prototype = methods;
+        result.extend = extend;
+        return result;
+    },
 	copy: function (from, to){
-        for(var prop in from){
-            var v = from[prop];
-            if (typeof v == "object")
-                this.copy(v, to[prop]);
-            else if (typeof v != "function")
-                to[prop] = v;
+        for(var prop in to){
+            if (to.hasOwnProperty(prop)){
+                var v = from[prop];
+                if (v !== null && typeof v == "object")
+                    this.copy(v, to[prop]);
+                else
+                    to[prop] = v;
+            }
         }
-	}
+    }
 };
 var m = function (){
 var arraySize = 10;

+ 4 - 4
test/expected/assert.js

@@ -1,9 +1,9 @@
 var RTL$ = {
 	assert: function (condition, code){
-		if (!condition)
-			throw new Error("assertion failed"
-						  + ((code !== undefined) ? " with code " + code : ""));
-	}
+        if (!condition)
+            throw new Error("assertion failed"
+                          + ((code !== undefined) ? " with code " + code : ""));
+    }
 };
 var m = function (){
 RTL$.assert(true);

+ 14 - 14
test/expected/cast.js

@@ -1,20 +1,20 @@
 var RTL$ = {
 	extend: function extend(methods){
-		methods.__proto__ = this.prototype; // make instanceof work
+        methods.__proto__ = this.prototype; // make instanceof work
 
-		// to see constructor name in diagnostic
-		var result = methods.init;
-		methods.constructor = result.prototype.constructor;
+        // to see constructor name in diagnostic
+        var result = methods.init;
+        methods.constructor = result.prototype.constructor;
 
-		result.prototype = methods;
-		result.extend = extend;
-		return result;
-	},
+        result.prototype = methods;
+        result.extend = extend;
+        return result;
+    },
 	typeGuard: function (from, to){
-		if (!(from instanceof to))
-			throw new Error("typeguard assertion failed");
-		return from;
-	}
+        if (!(from instanceof to))
+            throw new Error("typeguard assertion failed");
+        return from;
+    }
 };
 var m = function (){
 var Base = RTL$.extend({
@@ -23,13 +23,13 @@ var Base = RTL$.extend({
 });
 var Derived1 = Base.extend({
 	init: function Derived1(){
-		Base.prototype.init.bind(this)();
+		Base.prototype.init.call(this);
 		this.field1 = 0;
 	}
 });
 var Derived2 = Derived1.extend({
 	init: function Derived2(){
-		Derived1.prototype.init.bind(this)();
+		Derived1.prototype.init.call(this);
 		this.field2 = 0;
 	}
 });

+ 10 - 10
test/expected/is.js

@@ -1,15 +1,15 @@
 var RTL$ = {
 	extend: function extend(methods){
-		methods.__proto__ = this.prototype; // make instanceof work
+        methods.__proto__ = this.prototype; // make instanceof work
 
-		// to see constructor name in diagnostic
-		var result = methods.init;
-		methods.constructor = result.prototype.constructor;
+        // to see constructor name in diagnostic
+        var result = methods.init;
+        methods.constructor = result.prototype.constructor;
 
-		result.prototype = methods;
-		result.extend = extend;
-		return result;
-	}
+        result.prototype = methods;
+        result.extend = extend;
+        return result;
+    }
 };
 var m = function (){
 var Base = RTL$.extend({
@@ -18,13 +18,13 @@ var Base = RTL$.extend({
 });
 var Derived1 = Base.extend({
 	init: function Derived1(){
-		Base.prototype.init.bind(this)();
+		Base.prototype.init.call(this);
 		this.field1 = 0;
 	}
 });
 var Derived2 = Derived1.extend({
 	init: function Derived2(){
-		Derived1.prototype.init.bind(this)();
+		Derived1.prototype.init.call(this);
 		this.field2 = 0;
 	}
 });

+ 8 - 8
test/expected/new.js

@@ -1,15 +1,15 @@
 var RTL$ = {
 	extend: function extend(methods){
-		methods.__proto__ = this.prototype; // make instanceof work
+        methods.__proto__ = this.prototype; // make instanceof work
 
-		// to see constructor name in diagnostic
-		var result = methods.init;
-		methods.constructor = result.prototype.constructor;
+        // to see constructor name in diagnostic
+        var result = methods.init;
+        methods.constructor = result.prototype.constructor;
 
-		result.prototype = methods;
-		result.extend = extend;
-		return result;
-	}
+        result.prototype = methods;
+        result.extend = extend;
+        return result;
+    }
 };
 var m = function (){
 var T1 = RTL$.extend({

+ 8 - 8
test/expected/nil.js

@@ -1,15 +1,15 @@
 var RTL$ = {
 	extend: function extend(methods){
-		methods.__proto__ = this.prototype; // make instanceof work
+        methods.__proto__ = this.prototype; // make instanceof work
 
-		// to see constructor name in diagnostic
-		var result = methods.init;
-		methods.constructor = result.prototype.constructor;
+        // to see constructor name in diagnostic
+        var result = methods.init;
+        methods.constructor = result.prototype.constructor;
 
-		result.prototype = methods;
-		result.extend = extend;
-		return result;
-	}
+        result.prototype = methods;
+        result.extend = extend;
+        return result;
+    }
 };
 var m = function (){
 var anonymous$1$base = RTL$.extend({

+ 9 - 9
test/expected/proc.js

@@ -1,15 +1,15 @@
 var RTL$ = {
 	extend: function extend(methods){
-		methods.__proto__ = this.prototype; // make instanceof work
+        methods.__proto__ = this.prototype; // make instanceof work
 
-		// to see constructor name in diagnostic
-		var result = methods.init;
-		methods.constructor = result.prototype.constructor;
+        // to see constructor name in diagnostic
+        var result = methods.init;
+        methods.constructor = result.prototype.constructor;
 
-		result.prototype = methods;
-		result.extend = extend;
-		return result;
-	}
+        result.prototype = methods;
+        result.extend = extend;
+        return result;
+    }
 };
 var m = function (){
 
@@ -21,7 +21,7 @@ function p1(arg1/*INTEGER*/){
 	});
 	var T2 = T1.extend({
 		init: function T2(){
-			T1.prototype.init.bind(this)();
+			T1.prototype.init.call(this);
 			this.field2 = false;
 		}
 	});

+ 38 - 0
test/expected/record.js

@@ -0,0 +1,38 @@
+var RTL$ = {
+	extend: function extend(methods){
+        methods.__proto__ = this.prototype; // make instanceof work
+
+        // to see constructor name in diagnostic
+        var result = methods.init;
+        methods.constructor = result.prototype.constructor;
+
+        result.prototype = methods;
+        result.extend = extend;
+        return result;
+    },
+	copy: function (from, to){
+        for(var prop in to){
+            if (to.hasOwnProperty(prop)){
+                var v = from[prop];
+                if (v !== null && typeof v == "object")
+                    this.copy(v, to[prop]);
+                else
+                    to[prop] = v;
+            }
+        }
+    }
+};
+var m = function (){
+var Base1 = RTL$.extend({
+	init: function Base1(){
+	}
+});
+var T1 = Base1.extend({
+	init: function T1(){
+		Base1.prototype.init.call(this);
+	}
+});
+var b1 = new Base1();
+var r1 = new T1();
+RTL$.copy(r1, b1);
+}();

+ 26 - 26
test/expected/set.js

@@ -1,32 +1,32 @@
 var RTL$ = {
 	makeSet: function (/*...*/){
-		var result = 0;
-		
-		function checkBit(b){
-			if (b < 0 || b > 31)
-				throw new Error("integes between 0 and 31 expected, got " + b);
-		}
+        var result = 0;
+        
+        function checkBit(b){
+            if (b < 0 || b > 31)
+                throw new Error("integes between 0 and 31 expected, got " + b);
+        }
 
-		function setBit(b){
-			checkBit(b);
-			result |= 1 << b;
-		}
-		
-		for(var i = 0; i < arguments.length; ++i){
-			var b = arguments[i];
-			if (b instanceof Array){
-				var from = b[0];
-				var to = b[1];
-				if (from < to)
-					throw new Error("invalid SET diapason: " + from + ".." + to);
-				for(var bi = from; bi <= to; ++bi)
-					setBit(bi);
-			}
-			else
-				setBit(b);
-		}
-		return result;
-	},
+        function setBit(b){
+            checkBit(b);
+            result |= 1 << b;
+        }
+        
+        for(var i = 0; i < arguments.length; ++i){
+            var b = arguments[i];
+            if (b instanceof Array){
+                var from = b[0];
+                var to = b[1];
+                if (from < to)
+                    throw new Error("invalid SET diapason: " + from + ".." + to);
+                for(var bi = from; bi <= to; ++bi)
+                    setBit(bi);
+            }
+            else
+                setBit(b);
+        }
+        return result;
+    },
 	setInclL: function (l, r){return l & r == l;},
 	setInclR: function (l, r){return l & r == r;}
 };

+ 28 - 28
test/expected/string.js

@@ -1,35 +1,35 @@
 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;
-	},
+        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;
+    },
 	assignArrayFromString: function (a, s){
-		var i;
-		for(i = 0; i < s.length; ++i)
-			a[i] = s.charCodeAt(i);
-		for(i = s.length; i < a.length; ++i)
-			a[i] = 0;
-	},
+        var i;
+        for(i = 0; i < s.length; ++i)
+            a[i] = s.charCodeAt(i);
+        for(i = s.length; i < a.length; ++i)
+            a[i] = 0;
+    },
 	strToArray: function (s){
-		var result = new Array(s.length);
-		for(i = 0; i < s.length; ++i)
-			result[i] = s.charCodeAt(i);
-		return result;
-	}
+        var result = new Array(s.length);
+        for(i = 0; i < s.length; ++i)
+            result[i] = s.charCodeAt(i);
+        return result;
+    }
 };
 var m = function (){
 var s1 = "\"";

+ 28 - 28
test/expected/var_parameter.js

@@ -1,37 +1,37 @@
 var RTL$ = {
 	extend: function extend(methods){
-		methods.__proto__ = this.prototype; // make instanceof work
+        methods.__proto__ = this.prototype; // make instanceof work
 
-		// to see constructor name in diagnostic
-		var result = methods.init;
-		methods.constructor = result.prototype.constructor;
+        // to see constructor name in diagnostic
+        var result = methods.init;
+        methods.constructor = result.prototype.constructor;
 
-		result.prototype = methods;
-		result.extend = extend;
-		return result;
-	},
+        result.prototype = methods;
+        result.extend = extend;
+        return result;
+    },
 	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;
-	},
+        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;
+    },
 	makeRef: function (obj, prop){
-	    return {set: function(v){ obj[prop] = v; },
-	            get: function(){ return obj[prop]; }};
-	}
+        return {set: function(v){ obj[prop] = v; },
+                get: function(){ return obj[prop]; }};
+    }
 };
 var m = function (){
 var R = RTL$.extend({

+ 10 - 0
test/input/record.ob

@@ -0,0 +1,10 @@
+MODULE m;
+TYPE
+	Base1 = RECORD END;
+	T1 = RECORD (Base1) END;
+VAR
+	b1: Base1;
+	r1: T1;
+BEGIN
+	b1 := r1
+END m.

+ 23 - 5
test/input/run/copy.ob

@@ -1,14 +1,32 @@
 MODULE m;
 
 TYPE
-	T1 = RECORD field: INTEGER END;
+	T1 = RECORD
+		i1: INTEGER;
+		proc1: PROCEDURE
+	END;
+
 VAR
 	a1: ARRAY 3 OF T1;
 	a2: ARRAY 3 OF T1;
+
+PROCEDURE proc1;
+END proc1;
+
+PROCEDURE proc2;
+END proc2;
+
 BEGIN
-	a1[0].field := 123;
+	a1[0].i1 := 123;
+	a1[0].proc1 := proc1;
+	a2[1].proc1 := proc1;
 	a2 := a1;
-	ASSERT(a2[0].field = 123);
-	a1[0].field := 345;
-	ASSERT(a2[0].field = 123)
+	ASSERT(a2[0].i1 = 123);
+	ASSERT(a2[0].proc1 = proc1);
+	ASSERT(a2[1].proc1 = NIL);
+
+	a1[0].i1 := 345;
+	a1[0].proc1 := proc2;
+	ASSERT(a2[0].i1 = 123);
+	ASSERT(a2[0].proc1 = proc1)
 END m.

+ 13 - 0
test/test_unit.js

@@ -787,6 +787,19 @@ procedure: function(){
 	test.expectError("intArray3 := charArray"
 				   , "type mismatch: 'intArray3' is 'ARRAY OF INTEGER' and cannot be assigned to 'ARRAY OF CHAR' expression");
 },
+"record assignment": function(){
+	var test = setupWithContext(
+		  Grammar.statement
+		, "TYPE Base1 = RECORD END;"
+			+ "T1 = RECORD (Base1) END;"
+			+ "T2 = RECORD END;"
+		+ "VAR b1: Base1; r1: T1; r2: T2;"
+		);
+	test.parse("r1 := r1");
+	test.parse("b1 := r1");
+	test.expectError("r1 := r2", "type mismatch: 'r1' is 'T1' and cannot be assigned to 'T2' expression");
+	test.expectError("r1 := b1", "type mismatch: 'r1' is 'T1' and cannot be assigned to 'Base1' expression");
+},
 "open array assignment fails": function(){
 	var test = setup(Grammar.procedureDeclaration);
 	test.expectError("PROCEDURE p(s1, s2: ARRAY OF CHAR); BEGIN s1 := s2 END p"