Bladeren bron

bug fixes

Vladislav Folts 12 jaren geleden
bovenliggende
commit
5c0aea3aaa
6 gewijzigde bestanden met toevoegingen van 109 en 83 verwijderingen
  1. 35 32
      src/context.js
  2. 43 38
      src/procedure.js
  3. 14 5
      src/type.js
  4. 3 2
      test/expected/odd.js
  5. 2 1
      test/input/odd.ob
  6. 12 5
      test/test_unit.js

+ 35 - 32
src/context.js

@@ -205,13 +205,10 @@ exports.Designator = ChainedContext.extend({
         if ( t === undefined){
         if ( t === undefined){
             var s = getSymbol(this.parent(), id);
             var s = getSymbol(this.parent(), id);
             var info = s.info();
             var info = s.info();
-            if (s.isType() || s.isProcedure())
+            if (info instanceof Type.Type || s.isType() || s.isProcedure())
                 this.__currentType = info;
                 this.__currentType = info;
-            else if (s.isVariable() || s.isConst()){
+            else if (s.isVariable() || s.isConst())
                 this.__currentType = info.type();
                 this.__currentType = info.type();
-            }
-            else
-                throw new Errors.Error("variable, constant or procedure name expected");
             this.__info = info;
             this.__info = info;
         }
         }
         else if (t instanceof Type.Pointer){
         else if (t instanceof Type.Pointer){
@@ -308,20 +305,24 @@ exports.Designator = ChainedContext.extend({
     }
     }
 });
 });
 
 
+function unwrapType(type){
+    if (!(type instanceof Type.TypeId))
+        throw new Errors.Error("type name expected");
+    return type.type();
+}
+
 exports.Type = ChainedContext.extend({
 exports.Type = ChainedContext.extend({
     init: function TypeContext(context){ChainedContext.prototype.init.bind(this)(context);},
     init: function TypeContext(context){ChainedContext.prototype.init.bind(this)(context);},
     setIdent: function(id){
     setIdent: function(id){
         var s = this.findSymbol(id);
         var s = this.findSymbol(id);
         if (!s)
         if (!s)
             throw new Errors.Error("undeclared type: '" + id + "'");
             throw new Errors.Error("undeclared type: '" + id + "'");
-        if (s instanceof Type.Type)
-            throw new Errors.Error("type name expected");
-        this.setType(s.info());
+        this.setType(unwrapType(s.info()));
     }
     }
 });
 });
 
 
 exports.FormalType = exports.Type.extend({
 exports.FormalType = exports.Type.extend({
-    init: function FormatlTypeContext(context){
+    init: function FormalType(context){
         exports.Type.prototype.init.bind(this)(context);
         exports.Type.prototype.init.bind(this)(context);
         this.__arrayDimension = 0;
         this.__arrayDimension = 0;
     },
     },
@@ -365,9 +366,7 @@ exports.FormalParameters = ChainedContext.extend({
     setIdent: function(id){
     setIdent: function(id){
         var parent = this.parent();
         var parent = this.parent();
         var s = getSymbol(parent, id);
         var s = getSymbol(parent, id);
-        if (!s.isType())
-            throw new Errors.Error("type name expected");
-        this.__result = s.info();
+        this.__result = unwrapType(s.info());
     },
     },
     endParse: function(){
     endParse: function(){
         this.__type.define(this.__arguments, this.__result);
         this.__type.define(this.__arguments, this.__result);
@@ -498,7 +497,7 @@ exports.ProcParams = ChainedContext.extend({
 });
 });
 
 
 exports.PointerDecl = ChainedContext.extend({
 exports.PointerDecl = ChainedContext.extend({
-    init: function PointerDeclContext(context){
+    init: function PointerDecl(context){
         ChainedContext.prototype.init.bind(this)(context);
         ChainedContext.prototype.init.bind(this)(context);
         this.__base = undefined;
         this.__base = undefined;
         this.__name = this.parent().genTypeName();
         this.__name = this.parent().genTypeName();
@@ -514,8 +513,9 @@ exports.PointerDecl = ChainedContext.extend({
         if (existing)
         if (existing)
             return existing;
             return existing;
 
 
-        var resolve = function(){return getSymbol(this.__parent, id).info();};
-        return new Symbol(id, new Type.ForwardRecord(resolve.bind(this)));
+        var resolve = function(){return getSymbol(this.__parent, id).info().type();};
+        var type = new Type.ForwardRecord(resolve.bind(this));
+        return new Symbol(id, new Type.TypeId(type));
     },
     },
     genTypeName: function(){
     genTypeName: function(){
         return this.__name + "$base";
         return this.__name + "$base";
@@ -944,14 +944,13 @@ exports.Expression = ChainedContext.extend({
         else if (this.__relation == "IS"){
         else if (this.__relation == "IS"){
             if (!(leftType instanceof Type.Pointer))
             if (!(leftType instanceof Type.Pointer))
                 throw new Errors.Error("POINTER to type expected before 'IS'");
                 throw new Errors.Error("POINTER to type expected before 'IS'");
-            else if (!(rightType instanceof Type.Record))
+
+            rightType = unwrapType(rightType);
+            if (!(rightType instanceof Type.Record))
                 throw new Errors.Error("RECORD type expected after 'IS'");
                 throw new Errors.Error("RECORD type expected after 'IS'");
-            else
-                checkTypeCast(leftType, rightType, "invalid type test");
 
 
-            var designator = e.designator();
-            if (!designator || !(designator.info() instanceof Type.Type))
-                throw new Errors.Error("type name expected");
+            checkTypeCast(leftType, rightType, "invalid type test");
+
             code = leftCode + " instanceof " + rightCode;
             code = leftCode + " instanceof " + rightCode;
         }
         }
         else {
         else {
@@ -1385,7 +1384,7 @@ exports.StatementProcedureCall = ProcedureCall.extend({
 });
 });
 
 
 exports.ExpressionProcedureCall = ProcedureCall.extend({
 exports.ExpressionProcedureCall = ProcedureCall.extend({
-    init: function ExpressionProcedureCallContext(context){
+    init: function ExpressionProcedureCall(context){
         ProcedureCall.prototype.init.bind(this)(context);
         ProcedureCall.prototype.init.bind(this)(context);
         this.__designator = undefined;
         this.__designator = undefined;
         this.__hasActualParameters = false;
         this.__hasActualParameters = false;
@@ -1398,12 +1397,18 @@ exports.ExpressionProcedureCall = ProcedureCall.extend({
         this.__hasActualParameters = true;
         this.__hasActualParameters = true;
     },
     },
     endParse: function(){
     endParse: function(){
+        var parent = this.parent();
         if (this.__hasActualParameters){
         if (this.__hasActualParameters){
             ProcedureCall.prototype.endParse.call(this);
             ProcedureCall.prototype.endParse.call(this);
-            this.parent().handleFactor(this.callExpression());
+            parent.handleFactor(this.callExpression());
+        }
+        else{
+            var d = this.__designator;
+            var info = d.info();
+            if (info instanceof Procedure.Std)
+                throw new Errors.Error(info.description() + " cannot be referenced");
+            parent.setDesignator(d);
         }
         }
-        else
-            this.parent().setDesignator(this.__designator);
     }
     }
 });
 });
 
 
@@ -1418,9 +1423,7 @@ exports.RecordDecl = ChainedContext.extend({
     addField: function(name, type) {this.__type.addField(name, type);},
     addField: function(name, type) {this.__type.addField(name, type);},
     setBaseType: function(id){
     setBaseType: function(id){
         var s = getSymbol(this.parent(), id);
         var s = getSymbol(this.parent(), id);
-        if (!s.isType())
-            throw new Errors.Error("type name expected");
-        this.__type.setBaseType(s.info());
+        this.__type.setBaseType(unwrapType(s.info()));
     },
     },
     endParse: function(){
     endParse: function(){
         var type = this.__type;
         var type = this.__type;
@@ -1449,7 +1452,7 @@ exports.TypeDeclaration = ChainedContext.extend({
     },
     },
     setIdent: function(id){this.__ident = id;},
     setIdent: function(id){this.__ident = id;},
     setType: function(type){
     setType: function(type){
-        this.addSymbol(new Symbol(this.__ident, type));
+        this.addSymbol(new Symbol(this.__ident, new Type.TypeId(type)));
     },
     },
     typeName: function(){return this.__ident;},
     typeName: function(){return this.__ident;},
     genTypeName: function(){return this.__ident;},
     genTypeName: function(){return this.__ident;},
@@ -1465,7 +1468,7 @@ exports.TypeCast = ChainedContext.extend({
         var s = getSymbol(this.parent(), id);
         var s = getSymbol(this.parent(), id);
         if (!s.isType())
         if (!s.isType())
             return; // this is not a type cast, may be procedure call
             return; // this is not a type cast, may be procedure call
-        this.__type = s.info();
+        this.__type = s.info().type();
     },
     },
     endParse: function(){
     endParse: function(){
         if (this.__type === undefined)
         if (this.__type === undefined)
@@ -1523,9 +1526,9 @@ var Scope = Class.extend({
         var symbols = {};
         var symbols = {};
         for(var t in basicTypes){
         for(var t in basicTypes){
             var type = basicTypes[t];
             var type = basicTypes[t];
-            symbols[type.name()] = new Symbol(type.name(), type);
+            symbols[type.name()] = new Symbol(type.name(), new Type.TypeId(type));
         }
         }
-        symbols["LONGREAL"] = new Symbol("LONGREAL", basicTypes.real);
+        symbols["LONGREAL"] = new Symbol("LONGREAL", new Type.TypeId(basicTypes.real));
         
         
         var predefined = Procedure.predefined;
         var predefined = Procedure.predefined;
         for(var i = 0; i < predefined.length; ++i){
         for(var i = 0; i < predefined.length; ++i){

+ 43 - 38
src/procedure.js

@@ -141,13 +141,14 @@ var DefinedProc = Type.Procedure.extend({
     }
     }
 });
 });
 
 
-var ProcType = Type.Procedure.extend({
-    init: function ProcType(name, args, result, callGeneratorFactory){
+var Std = Type.Procedure.extend({
+    init: function Std(name, args, result, callGeneratorFactory){
         Type.Procedure.prototype.init.call(this, name);
         Type.Procedure.prototype.init.call(this, name);
         this.__arguments = args;
         this.__arguments = args;
         this.__result = result;
         this.__result = result;
         this.__callGeneratorFactory = callGeneratorFactory;
         this.__callGeneratorFactory = callGeneratorFactory;
     },
     },
+    description: function(){return "standard procedure " + this.name();},
     arguments: function(){return this.__arguments;},
     arguments: function(){return this.__arguments;},
     result: function(){return this.__result;},
     result: function(){return this.__result;},
     callGenerator: function(context, id){
     callGenerator: function(context, id){
@@ -193,8 +194,8 @@ function setBitImpl(name, op){
         var valueCode = value + "/*" + comment + "*/";
         var valueCode = value + "/*" + comment + "*/";
         return op(Code.adjustPrecedence(x, precedence.assignment), valueCode);
         return op(Code.adjustPrecedence(x, precedence.assignment), valueCode);
     }
     }
-    var proc = new ProcType(
-        "predefined procedure " + name,
+    var proc = new Std(
+        name,
         args,
         args,
         undefined,
         undefined,
         function(context, id, type){
         function(context, id, type){
@@ -226,8 +227,8 @@ function incImpl(name, unary, op){
             checkVariableArgumentsCount(1, 2, count);
             checkVariableArgumentsCount(1, 2, count);
         }
         }
     });
     });
-    var proc = new ProcType(
-        "predefined procedure " + name,
+    var proc = new Std(
+        name,
         args,
         args,
         undefined,
         undefined,
         function(context, id, type){
         function(context, id, type){
@@ -251,8 +252,8 @@ function bitShiftImpl(name, op){
     var args = [new Arg(Type.basic.int, false),
     var args = [new Arg(Type.basic.int, false),
                 new Arg(Type.basic.int, false)
                 new Arg(Type.basic.int, false)
                ];
                ];
-    var proc = new ProcType(
-        "predefined procedure " + name,
+    var proc = new Std(
+        name,
         args,
         args,
         Type.basic.int,
         Type.basic.int,
         function(context, id, type){
         function(context, id, type){
@@ -270,8 +271,8 @@ function longShort(name){
         callExpression: function(){return this.args()[0];}
         callExpression: function(){return this.args()[0];}
     });
     });
     var args = [new Arg(Type.basic.real, false)];
     var args = [new Arg(Type.basic.real, false)];
-    var proc = new ProcType(
-        "predefined procedure " + name,
+    var proc = new Std(
+        name,
         args,
         args,
         Type.basic.real,
         Type.basic.real,
         function(context, id, type){
         function(context, id, type){
@@ -311,8 +312,8 @@ exports.predefined = [
 
 
         var name = "NEW";
         var name = "NEW";
         var args = [new Arg(undefined, true)];
         var args = [new Arg(undefined, true)];
-        var type = new ProcType(
-            "predefined procedure NEW",
+        var type = new Std(
+            "NEW",
             args,
             args,
             undefined,
             undefined,
             function(context, id, type){
             function(context, id, type){
@@ -340,8 +341,8 @@ exports.predefined = [
 
 
         var name = "LEN";
         var name = "LEN";
         var args = [new Arg(new Type.Array("ARRAY OF any type"), false)];
         var args = [new Arg(new Type.Array("ARRAY OF any type"), false)];
-        var type = new ProcType(
-            "predefined procedure LEN",
+        var type = new Std(
+            "LEN",
             args,
             args,
             Type.basic.int,
             Type.basic.int,
             function(context, id, type){
             function(context, id, type){
@@ -351,17 +352,20 @@ exports.predefined = [
         return symbol;
         return symbol;
     }(),
     }(),
     function(){
     function(){
-        var CallGenerator = ProcCallGenerator.extend({
+        var CallGenerator = ExpCallGenerator.extend({
             init: function OddProcCallGenerator(context, id, type){
             init: function OddProcCallGenerator(context, id, type){
-                ProcCallGenerator.prototype.init.call(this, context, id, type);
+                ExpCallGenerator.prototype.init.call(this, context, id, type);
             },
             },
-            prolog: function(){return "(";},
-            epilog: function(){return " & 1)";}
+            callExpression: function(){
+                var e = this.args()[0];
+                var code = Code.adjustPrecedence(e, precedence.bitAnd);
+                return new Code.Expression(code + " & 1", Type.basic.bool, undefined, e.constValue(), precedence.bitAnd);
+            }
         });
         });
         var name = "ODD";
         var name = "ODD";
         var args = [new Arg(Type.basic.int, false)];
         var args = [new Arg(Type.basic.int, false)];
-        var type = new ProcType(
-            "predefined procedure ODD",
+        var type = new Std(
+            "ODD",
             args,
             args,
             Type.basic.bool,
             Type.basic.bool,
             function(context, id, type){
             function(context, id, type){
@@ -382,8 +386,8 @@ exports.predefined = [
         });
         });
 
 
         var args = [new Arg(Type.basic.bool), new Arg(Type.basic.int)];
         var args = [new Arg(Type.basic.bool), new Arg(Type.basic.int)];
-        var proc = new ProcType(
-            "predefined procedure ASSERT",
+        var proc = new Std(
+            "ASSERT",
             args,
             args,
             undefined,
             undefined,
             function(context, id, type){
             function(context, id, type){
@@ -414,8 +418,8 @@ exports.predefined = [
             resultType: function(){return this.__argType;}
             resultType: function(){return this.__argType;}
         });
         });
         var args = [new Arg(undefined, false)];
         var args = [new Arg(undefined, false)];
-        var proc = new ProcType(
-            "predefined procedure ABS",
+        var proc = new Std(
+            "ABS",
             args,
             args,
             undefined,
             undefined,
             function(context, id, type){
             function(context, id, type){
@@ -432,8 +436,8 @@ exports.predefined = [
             prolog: function(){return "Math.floor(";},
             prolog: function(){return "Math.floor(";},
         });
         });
         var args = [new Arg(Type.basic.real, false)];
         var args = [new Arg(Type.basic.real, false)];
-        var proc = new ProcType(
-            "predefined procedure FLOOR",
+        var proc = new Std(
+            "FLOOR",
             args,
             args,
             Type.basic.int,
             Type.basic.int,
             function(context, id, type){
             function(context, id, type){
@@ -453,8 +457,8 @@ exports.predefined = [
             }
             }
         });
         });
         var args = [new Arg(Type.basic.int, false)];
         var args = [new Arg(Type.basic.int, false)];
-        var proc = new ProcType(
-            "predefined procedure FLT",
+        var proc = new Std(
+            "FLT",
             args,
             args,
             Type.basic.real,
             Type.basic.real,
             function(context, id, type){
             function(context, id, type){
@@ -504,8 +508,8 @@ exports.predefined = [
         var name = "ORD";
         var name = "ORD";
         var argType = new Type.Basic("CHAR or BOOLEAN or SET");
         var argType = new Type.Basic("CHAR or BOOLEAN or SET");
         var args = [new Arg(argType, false)];
         var args = [new Arg(argType, false)];
-        var type = new ProcType(
-            "predefined procedure " + name,
+        var type = new Std(
+            name,
             args,
             args,
             Type.basic.int,
             Type.basic.int,
             function(context, id, type){
             function(context, id, type){
@@ -524,8 +528,8 @@ exports.predefined = [
             }
             }
         });
         });
         var name = "CHR";
         var name = "CHR";
-        var type = new ProcType(
-            "predefined procedure " + name,
+        var type = new Std(
+            name,
             [new Arg(Type.basic.int, false)],
             [new Arg(Type.basic.int, false)],
             Type.basic.char,
             Type.basic.char,
             function(context, id, type){
             function(context, id, type){
@@ -545,8 +549,8 @@ exports.predefined = [
             }
             }
         });
         });
         var name = "COPY";
         var name = "COPY";
-        var type = new ProcType(
-            "predefined procedure " + name,
+        var type = new Std(
+            name,
             [new Arg(undefined, false),
             [new Arg(undefined, false),
              new Arg(new Type.Array("ARRAY OF CHAR", undefined, Type.basic.char), true)],
              new Arg(new Type.Array("ARRAY OF CHAR", undefined, Type.basic.char), true)],
             undefined,
             undefined,
@@ -563,8 +567,8 @@ exports.predefined = [
             return op.mulInplace(x, op.pow2(y));
             return op.mulInplace(x, op.pow2(y));
         }
         }
         var name = "PACK";
         var name = "PACK";
-        var proc = new ProcType(
-            "predefined procedure " + name,
+        var proc = new Std(
+            name,
             args,
             args,
             undefined,
             undefined,
             function(context, id, type){
             function(context, id, type){
@@ -583,8 +587,8 @@ exports.predefined = [
                    op.divInplace(x, op.pow2(y));
                    op.divInplace(x, op.pow2(y));
         }
         }
         var name = "UNPACK";
         var name = "UNPACK";
-        var proc = new ProcType(
-            "predefined procedure " + name,
+        var proc = new Std(
+            name,
             args,
             args,
             undefined,
             undefined,
             function(context, id, type){
             function(context, id, type){
@@ -598,3 +602,4 @@ exports.predefined = [
 
 
 exports.CallGenerator = ProcCallGenerator;
 exports.CallGenerator = ProcCallGenerator;
 exports.Type = DefinedProc;
 exports.Type = DefinedProc;
+exports.Std = Std;

+ 14 - 5
src/type.js

@@ -10,11 +10,17 @@ var Id = Class.extend({
 var Type = Id.extend({
 var Type = Id.extend({
 	init: function Type(){
 	init: function Type(){
 		Id.prototype.init.call(this);
 		Id.prototype.init.call(this);
-	},
-	idType: function(){return "type";},
+	}
 });
 });
 
 
-exports.Type = Type;
+var TypeId = Id.extend({
+	init: function TypeId(type){
+		Id.prototype.init.call(this);
+		this.__type = type;
+	},
+	type: function(){return this.__type;},
+	description: function(){return 'type ' + this.__type.description();}
+});
 
 
 exports.String = Type.extend({
 exports.String = Type.extend({
 	init: function TypeString(s){
 	init: function TypeString(s){
@@ -34,6 +40,7 @@ var BasicType = Type.extend({
 		this.__name = name;
 		this.__name = name;
 		this.__initValue = initValue;
 		this.__initValue = initValue;
 	},
 	},
+	idType: function(){return "type";},
 	name: function() {return this.__name;},
 	name: function() {return this.__name;},
 	description: function(){return this.name();},
 	description: function(){return this.name();},
 	initializer: function() {return this.__initValue;}
 	initializer: function() {return this.__initValue;}
@@ -70,7 +77,7 @@ exports.Pointer = BasicType.extend({
 });
 });
 
 
 exports.ForwardRecord = Type.extend({
 exports.ForwardRecord = Type.extend({
-	init: function(resolve){
+	init: function ForwardRecord(resolve){
 		Type.prototype.init.bind(this)();
 		Type.prototype.init.bind(this)();
 		this.__resolve = resolve;
 		this.__resolve = resolve;
 	},
 	},
@@ -167,8 +174,10 @@ var Symbol = Class.extend({
 	info: function(){return this.__info;},
 	info: function(){return this.__info;},
 	isVariable: function(){return this.__info instanceof exports.Variable;},
 	isVariable: function(){return this.__info instanceof exports.Variable;},
 	isConst: function(){return this.__info instanceof exports.Const;},
 	isConst: function(){return this.__info instanceof exports.Const;},
-	isType: function(){return this.__info instanceof Type;},
+	isType: function(){return this.__info instanceof TypeId;},
 	isProcedure: function(){return this.__info instanceof exports.Procedure;},
 	isProcedure: function(){return this.__info instanceof exports.Procedure;},
 });
 });
 
 
 exports.Symbol = Symbol;
 exports.Symbol = Symbol;
+exports.Type = Type;
+exports.TypeId = TypeId;

+ 3 - 2
test/expected/odd.js

@@ -7,8 +7,9 @@ var RTL$ = {
 };
 };
 var m = function (){
 var m = function (){
 var i = 0;
 var i = 0;
-RTL$.assert((1 & 1));
+RTL$.assert(1 & 1);
 i = 4;
 i = 4;
-RTL$.assert((1 + i & 1));
+RTL$.assert(1 + i & 1);
 RTL$.assert(!(2 & 1));
 RTL$.assert(!(2 & 1));
+RTL$.assert((true || false ? 1 : 0) & 1);
 }();
 }();

+ 2 - 1
test/input/odd.ob

@@ -6,5 +6,6 @@ BEGIN
 	ASSERT(ODD(1));
 	ASSERT(ODD(1));
 	i := 4;
 	i := 4;
 	ASSERT(ODD(1 + i));
 	ASSERT(ODD(1 + i));
-	ASSERT(~ODD(2))
+	ASSERT(~ODD(2));
+	ASSERT(ODD(ORD(TRUE OR FALSE)));
 END m.
 END m.

+ 12 - 5
test/test_unit.js

@@ -25,7 +25,7 @@ function parseUsingGrammar(grammar, s, cxFactory, handlerError){
     }
     }
     catch (x){
     catch (x){
         if (!(x instanceof Errors.Error))
         if (!(x instanceof Errors.Error))
-            throw x;//console.log(x.stack);
+            throw new Error("'" + s + '":\n' + x.stack);
         
         
         if (handlerError)
         if (handlerError)
             handlerError(x);
             handlerError(x);
@@ -342,8 +342,8 @@ identifier: function(){
         + "VAR p: POINTER TO RECORD END; pBase: POINTER TO Base; pDerived: POINTER TO Derived; vDerived: Derived; i: INTEGER;");
         + "VAR p: POINTER TO RECORD END; pBase: POINTER TO Base; pDerived: POINTER TO Derived; vDerived: Derived; i: INTEGER;");
 
 
     test.parse("pBase IS Derived");
     test.parse("pBase IS Derived");
-    test.expectError("pBase IS pDerived", "RECORD type expected after 'IS'");
-    test.expectError("pBase IS TRUE", "RECORD type expected after 'IS'");
+    test.expectError("pBase IS pDerived", "type name expected");
+    test.expectError("pBase IS TRUE", "type name expected");
     test.expectError("pBase IS vDerived", "type name expected");
     test.expectError("pBase IS vDerived", "type name expected");
     test.expectError("Derived IS Derived", "POINTER to type expected before 'IS'");
     test.expectError("Derived IS Derived", "POINTER to type expected before 'IS'");
     test.expectError("i IS Derived", "POINTER to type expected before 'IS'");
     test.expectError("i IS Derived", "POINTER to type expected before 'IS'");
@@ -364,7 +364,7 @@ identifier: function(){
         );
         );
 
 
     test.parse("NEW(p)");
     test.parse("NEW(p)");
-    test.expectError("NEW.NEW(p)", "cannot designate 'predefined procedure NEW'");
+    test.expectError("NEW.NEW(p)", "cannot designate 'standard procedure NEW'");
     test.expectError("NEW(i)", "POINTER variable expected, got 'INTEGER'");
     test.expectError("NEW(i)", "POINTER variable expected, got 'INTEGER'");
     test.expectError("NEW()", "1 argument(s) expected, got 0");
     test.expectError("NEW()", "1 argument(s) expected, got 0");
     test.expectError("NEW(p, p)", "1 argument(s) expected, got 2");
     test.expectError("NEW(p, p)", "1 argument(s) expected, got 2");
@@ -522,6 +522,11 @@ identifier: function(){
          ["UNPACK(123.456, i)", "expression cannot be used as VAR parameter"]
          ["UNPACK(123.456, i)", "expression cannot be used as VAR parameter"]
          )
          )
 ),
 ),
+"standard procedure cannot be referenced" : testWithContext(
+    context(Grammar.expression, "VAR chr: PROCEDURE(c: CHAR): INTEGER;"),
+    pass(),
+    fail(["CHR", "standard procedure CHR cannot be referenced"])
+    ),
 "assignment statement": function(){
 "assignment statement": function(){
     var test = setupWithContext(
     var test = setupWithContext(
           Grammar.statement
           Grammar.statement
@@ -544,6 +549,8 @@ identifier: function(){
     test.expectError("c := i", "cannot assign to constant");
     test.expectError("c := i", "cannot assign to constant");
     test.expectError("ch := \"AB\""
     test.expectError("ch := \"AB\""
                    , "type mismatch: 'ch' is 'CHAR' and cannot be assigned to 'multi-character string' expression");
                    , "type mismatch: 'ch' is 'CHAR' and cannot be assigned to 'multi-character string' expression");
+    test.expectError("ch := CHAR"
+                   , "type mismatch: 'ch' is 'CHAR' and cannot be assigned to 'type CHAR' expression");
     test.expectError("i := .1", "expression expected");
     test.expectError("i := .1", "expression expected");
     test.expectError("proc1 := proc2"
     test.expectError("proc1 := proc2"
                    , "type mismatch: 'proc1' is 'PROCEDURE' and cannot be assigned to 'PROCEDURE(): INTEGER' expression");
                    , "type mismatch: 'proc1' is 'PROCEDURE' and cannot be assigned to 'PROCEDURE(): INTEGER' expression");
@@ -980,7 +987,7 @@ procedure: function(){
         , "type mismatch: 'v3' is 'PROCEDURE(INTEGER): ProcType1' and cannot be assigned to 'PROCEDURE(BOOLEAN): ProcType1' expression");
         , "type mismatch: 'v3' is 'PROCEDURE(INTEGER): ProcType1' and cannot be assigned to 'PROCEDURE(BOOLEAN): ProcType1' expression");
     test.expectError(
     test.expectError(
           "v10 := NEW"
           "v10 := NEW"
-        , "type mismatch: 'v10' is 'ProcType6' and cannot be assigned to 'predefined procedure NEW' expression");
+        , "standard procedure NEW cannot be referenced");
     test.expectError("v10 := v11", "type mismatch: 'v10' is 'ProcType6' and cannot be assigned to 'ProcType7' expression" );
     test.expectError("v10 := v11", "type mismatch: 'v10' is 'ProcType6' and cannot be assigned to 'ProcType7' expression" );
     test.expectError("v8 := v8VAR", "type mismatch: 'v8' is 'ProcType4' and cannot be assigned to 'ProcType4VAR' expression" );
     test.expectError("v8 := v8VAR", "type mismatch: 'v8' is 'ProcType4' and cannot be assigned to 'ProcType4VAR' expression" );
 },
 },