Forráskód Böngészése

support of ABSTRACT object type and ABSTRACT procedures
an object containing ABSTRACT procedures must be marked {ASBTRACT}
an object inheriting from an ABSTRACT object must be abstract or implement all ABSTRACT procedures
added check for visibility compatibility: extended methods must comply with visibility of super methods (WARNING for the time being)

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7617 8c9fc860-2736-0410-a75d-ab315db34111

felixf 7 éve
szülő
commit
c29d234643
3 módosított fájl, 267 hozzáadás és 197 törlés
  1. 91 87
      source/FoxPrintout.Mod
  2. 102 84
      source/FoxSemanticChecker.Mod
  3. 74 26
      source/FoxSyntaxTree.Mod

+ 91 - 87
source/FoxPrintout.Mod

@@ -89,7 +89,7 @@ TYPE
 			END;
 			END;
 		END Type;
 		END Type;
 
 
-		PROCEDURE VisitType(x: SyntaxTree.Type);
+		PROCEDURE VisitType*(x: SyntaxTree.Type);
 		BEGIN
 		BEGIN
 			IF x = SyntaxTree.importType THEN w.String("importType")
 			IF x = SyntaxTree.importType THEN w.String("importType")
 			ELSIF x = SyntaxTree.typeDeclarationType THEN w.String("typeDeclarationType");
 			ELSIF x = SyntaxTree.typeDeclarationType THEN w.String("typeDeclarationType");
@@ -98,7 +98,7 @@ TYPE
 			END;
 			END;
 		END VisitType;
 		END VisitType;
 
 
-		PROCEDURE VisitBasicType(x: SyntaxTree.BasicType);
+		PROCEDURE VisitBasicType*(x: SyntaxTree.BasicType);
 		BEGIN
 		BEGIN
 			IF x.typeDeclaration # NIL THEN
 			IF x.typeDeclaration # NIL THEN
 				Identifier(x.typeDeclaration.name);
 				Identifier(x.typeDeclaration.name);
@@ -107,47 +107,47 @@ TYPE
 			END
 			END
 		END VisitBasicType;
 		END VisitBasicType;
 
 
-		PROCEDURE VisitBooleanType(x: SyntaxTree.BooleanType);
+		PROCEDURE VisitBooleanType*(x: SyntaxTree.BooleanType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitBooleanType;
 		END VisitBooleanType;
 
 
-		PROCEDURE VisitSetType(x: SyntaxTree.SetType);
+		PROCEDURE VisitSetType*(x: SyntaxTree.SetType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitSetType;
 		END VisitSetType;
 
 
-		PROCEDURE VisitSizeType(x: SyntaxTree.SizeType);
+		PROCEDURE VisitSizeType*(x: SyntaxTree.SizeType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitSizeType;
 		END VisitSizeType;
 
 
-		PROCEDURE VisitCharacterType(x: SyntaxTree.CharacterType);
+		PROCEDURE VisitCharacterType*(x: SyntaxTree.CharacterType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitCharacterType;
 		END VisitCharacterType;
 
 
-		PROCEDURE VisitIntegerType(x: SyntaxTree.IntegerType);
+		PROCEDURE VisitIntegerType*(x: SyntaxTree.IntegerType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitIntegerType;
 		END VisitIntegerType;
 
 
-		PROCEDURE VisitFloatType(x: SyntaxTree.FloatType);
+		PROCEDURE VisitFloatType*(x: SyntaxTree.FloatType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitFloatType;
 		END VisitFloatType;
 
 
-		PROCEDURE VisitComplexType(x: SyntaxTree.ComplexType);
+		PROCEDURE VisitComplexType*(x: SyntaxTree.ComplexType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitComplexType;
 		END VisitComplexType;
 
 
-		PROCEDURE VisitByteType(x: SyntaxTree.ByteType);
+		PROCEDURE VisitByteType*(x: SyntaxTree.ByteType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitByteType;
 		END VisitByteType;
 
 
-		PROCEDURE VisitQualifiedType(x: SyntaxTree.QualifiedType);
+		PROCEDURE VisitQualifiedType*(x: SyntaxTree.QualifiedType);
 		BEGIN
 		BEGIN
 			IF x.resolved = SyntaxTree.invalidType THEN
 			IF x.resolved = SyntaxTree.invalidType THEN
 				AlertString("(*unresolved*)");
 				AlertString("(*unresolved*)");
@@ -165,12 +165,12 @@ TYPE
 			END;
 			END;
 		END VisitQualifiedType;
 		END VisitQualifiedType;
 
 
-		PROCEDURE VisitStringType(x: SyntaxTree.StringType);
+		PROCEDURE VisitStringType*(x: SyntaxTree.StringType);
 		BEGIN
 		BEGIN
 			w.String("STRING"); w.String("(* len = "); w.Int(x.length,1); w.String(" *)");
 			w.String("STRING"); w.String("(* len = "); w.Int(x.length,1); w.String(" *)");
 		END VisitStringType;
 		END VisitStringType;
 
 
-		PROCEDURE VisitEnumerationType(x: SyntaxTree.EnumerationType);
+		PROCEDURE VisitEnumerationType*(x: SyntaxTree.EnumerationType);
 		VAR e: SyntaxTree.Constant; first: BOOLEAN;
 		VAR e: SyntaxTree.Constant; first: BOOLEAN;
 		BEGIN
 		BEGIN
 			Keyword("ENUM ");
 			Keyword("ENUM ");
@@ -191,11 +191,11 @@ TYPE
 			Keyword(" END");
 			Keyword(" END");
 		END VisitEnumerationType;
 		END VisitEnumerationType;
 
 
-		PROCEDURE VisitRangeType(x: SyntaxTree.RangeType);
+		PROCEDURE VisitRangeType*(x: SyntaxTree.RangeType);
 		BEGIN VisitBasicType(x);
 		BEGIN VisitBasicType(x);
 		END VisitRangeType;
 		END VisitRangeType;
 
 
-		PROCEDURE VisitArrayType(x: SyntaxTree.ArrayType);
+		PROCEDURE VisitArrayType*(x: SyntaxTree.ArrayType);
 		BEGIN
 		BEGIN
 			Keyword("ARRAY " );
 			Keyword("ARRAY " );
 			IF x.length # NIL THEN Expression(x.length);
 			IF x.length # NIL THEN Expression(x.length);
@@ -204,28 +204,28 @@ TYPE
 			Type(x.arrayBase);
 			Type(x.arrayBase);
 		END VisitArrayType;
 		END VisitArrayType;
 
 
-		PROCEDURE VisitNilType(x: SyntaxTree.NilType);
+		PROCEDURE VisitNilType*(x: SyntaxTree.NilType);
 		BEGIN
 		BEGIN
 			w.String("NILTYPE");
 			w.String("NILTYPE");
 		END VisitNilType;
 		END VisitNilType;
 
 
-		PROCEDURE VisitAddressType(x: SyntaxTree.AddressType);
+		PROCEDURE VisitAddressType*(x: SyntaxTree.AddressType);
 		BEGIN
 		BEGIN
 			w.String("ADDRESSTYPE");
 			w.String("ADDRESSTYPE");
 		END VisitAddressType;
 		END VisitAddressType;
 
 
-		PROCEDURE VisitObjectType(x: SyntaxTree.ObjectType);
+		PROCEDURE VisitObjectType*(x: SyntaxTree.ObjectType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitObjectType;
 		END VisitObjectType;
 
 
-		PROCEDURE VisitAnyType(x: SyntaxTree.AnyType);
+		PROCEDURE VisitAnyType*(x: SyntaxTree.AnyType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitAnyType;
 		END VisitAnyType;
 
 
 
 
-		PROCEDURE VisitMathArrayType(x: SyntaxTree.MathArrayType);
+		PROCEDURE VisitMathArrayType*(x: SyntaxTree.MathArrayType);
 		BEGIN
 		BEGIN
 			Keyword("ARRAY " );
 			Keyword("ARRAY " );
 			IF x.form = SyntaxTree.Tensor THEN w.String("[?] ");
 			IF x.form = SyntaxTree.Tensor THEN w.String("[?] ");
@@ -273,12 +273,13 @@ TYPE
 			IF x.isRealtime THEN Flag(Global.NameRealtime,first) END;
 			IF x.isRealtime THEN Flag(Global.NameRealtime,first) END;
 			IF x.isDisposable THEN Flag(Global.NameDisposable,first) END;
 			IF x.isDisposable THEN Flag(Global.NameDisposable,first) END;
 			IF x.isPlain THEN Flag(Global.NamePlain,first) END;
 			IF x.isPlain THEN Flag(Global.NamePlain,first) END;
+			IF rec.isAbstract THEN Flag(Global.NameAbstract, first) END;
 			IF rec.IsProtected() THEN Flag(Global.NameExclusive, first) END;
 			IF rec.IsProtected() THEN Flag(Global.NameExclusive, first) END;
 			FlagEnd(first);
 			FlagEnd(first);
 		END ObjectFlags;
 		END ObjectFlags;
 		
 		
 
 
-		PROCEDURE VisitPointerType(x: SyntaxTree.PointerType);
+		PROCEDURE VisitPointerType*(x: SyntaxTree.PointerType);
 		VAR pointerBase: SyntaxTree.Type;
 		VAR pointerBase: SyntaxTree.Type;
 		BEGIN
 		BEGIN
 			IF x.pointerBase = NIL THEN
 			IF x.pointerBase = NIL THEN
@@ -295,7 +296,7 @@ TYPE
 			END;
 			END;
 		END VisitPointerType;
 		END VisitPointerType;
 
 
-		PROCEDURE VisitPortType(x: SyntaxTree.PortType);
+		PROCEDURE VisitPortType*(x: SyntaxTree.PortType);
 		BEGIN
 		BEGIN
 			Keyword("PORT");
 			Keyword("PORT");
 			IF x.direction = SyntaxTree.OutPort THEN
 			IF x.direction = SyntaxTree.OutPort THEN
@@ -309,7 +310,7 @@ TYPE
 			END;
 			END;
 		END VisitPortType;
 		END VisitPortType;
 
 
-		PROCEDURE VisitCellType(x: SyntaxTree.CellType);
+		PROCEDURE VisitCellType*(x: SyntaxTree.CellType);
 		BEGIN
 		BEGIN
 			IF x.isCellNet THEN
 			IF x.isCellNet THEN
 				Keyword("CELLNET ")
 				Keyword("CELLNET ")
@@ -330,12 +331,13 @@ TYPE
 			END;
 			END;
 		END VisitCellType;
 		END VisitCellType;
 
 
-		PROCEDURE VisitRecordType(x: SyntaxTree.RecordType);
+		PROCEDURE VisitRecordType*(x: SyntaxTree.RecordType);
 		VAR prevScope: SyntaxTree.Scope;
 		VAR prevScope: SyntaxTree.Scope;
 		BEGIN
 		BEGIN
 			IF x.isObject THEN
 			IF x.isObject THEN
 				Keyword("OBJECT ");
 				Keyword("OBJECT ");
-				IF x.pointerType # NIL THEN ObjectFlags(x, x.pointerType) END;
+				IF x.pointerType # NIL THEN ObjectFlags(x, x.pointerType) 
+				END;
 				IF info THEN
 				IF info THEN
 					BeginComment; w.String("ObjectType");
 					BeginComment; w.String("ObjectType");
 
 
@@ -407,7 +409,7 @@ TYPE
 		END Value;
 		END Value;
 
 
 
 
-		PROCEDURE VisitProcedureType(x: SyntaxTree.ProcedureType);
+		PROCEDURE VisitProcedureType*(x: SyntaxTree.ProcedureType);
 		VAR first: BOOLEAN;
 		VAR first: BOOLEAN;
 		BEGIN
 		BEGIN
 			Keyword("PROCEDURE " );
 			Keyword("PROCEDURE " );
@@ -477,22 +479,22 @@ TYPE
 			w.Update;
 			w.Update;
 		END Expression;
 		END Expression;
 
 
-		PROCEDURE VisitExpression(x: SyntaxTree.Expression);
+		PROCEDURE VisitExpression*(x: SyntaxTree.Expression);
 		BEGIN
 		BEGIN
 			AlertString("InvalidExpression");
 			AlertString("InvalidExpression");
 		END VisitExpression;
 		END VisitExpression;
 
 
-		PROCEDURE VisitSet(x: SyntaxTree.Set);
+		PROCEDURE VisitSet*(x: SyntaxTree.Set);
 		BEGIN
 		BEGIN
 			w.String( "{" );  ExpressionList(x.elements); w.String( "}" );
 			w.String( "{" );  ExpressionList(x.elements); w.String( "}" );
 		END VisitSet;
 		END VisitSet;
 
 
-		PROCEDURE VisitMathArrayExpression(x: SyntaxTree.MathArrayExpression);
+		PROCEDURE VisitMathArrayExpression*(x: SyntaxTree.MathArrayExpression);
 		BEGIN
 		BEGIN
 			w.String( "[" );  ExpressionList(x.elements); w.String( "]" );
 			w.String( "[" );  ExpressionList(x.elements); w.String( "]" );
 		END VisitMathArrayExpression;
 		END VisitMathArrayExpression;
 
 
-		PROCEDURE VisitUnaryExpression(x: SyntaxTree.UnaryExpression);
+		PROCEDURE VisitUnaryExpression*(x: SyntaxTree.UnaryExpression);
 		VAR identifier: SyntaxTree.Identifier;
 		VAR identifier: SyntaxTree.Identifier;
 		BEGIN
 		BEGIN
 			w.String(" ");
 			w.String(" ");
@@ -512,7 +514,7 @@ TYPE
 			END;
 			END;
 		END VisitUnaryExpression;
 		END VisitUnaryExpression;
 
 
-		PROCEDURE VisitBinaryExpression(x: SyntaxTree.BinaryExpression);
+		PROCEDURE VisitBinaryExpression*(x: SyntaxTree.BinaryExpression);
 		VAR identifier: SyntaxTree.Identifier;
 		VAR identifier: SyntaxTree.Identifier;
 		BEGIN
 		BEGIN
 			w.String( "(" );
 			w.String( "(" );
@@ -523,7 +525,7 @@ TYPE
 			w.String(")");
 			w.String(")");
 		END VisitBinaryExpression;
 		END VisitBinaryExpression;
 
 
-		PROCEDURE VisitRangeExpression(x: SyntaxTree.RangeExpression);
+		PROCEDURE VisitRangeExpression*(x: SyntaxTree.RangeExpression);
 		BEGIN
 		BEGIN
 			IF x.missingFirst & x.missingLast & x.missingStep THEN
 			IF x.missingFirst & x.missingLast & x.missingStep THEN
 				(* open range expression *)
 				(* open range expression *)
@@ -550,12 +552,12 @@ TYPE
 			END
 			END
 		END VisitRangeExpression;
 		END VisitRangeExpression;
 
 
-		PROCEDURE VisitTensorRangeExpression(x: SyntaxTree.TensorRangeExpression);
+		PROCEDURE VisitTensorRangeExpression*(x: SyntaxTree.TensorRangeExpression);
 		BEGIN
 		BEGIN
 			w.String(" ? ");
 			w.String(" ? ");
 		END VisitTensorRangeExpression;
 		END VisitTensorRangeExpression;
 
 
-		PROCEDURE VisitConversion(x: SyntaxTree.Conversion);
+		PROCEDURE VisitConversion*(x: SyntaxTree.Conversion);
 		BEGIN
 		BEGIN
 			IF x.typeExpression # NIL THEN Expression(x.typeExpression); w.String("(");
 			IF x.typeExpression # NIL THEN Expression(x.typeExpression); w.String("(");
 			ELSIF info THEN BeginComment; ShortType(x.type); w.String("<-"); EndComment;
 			ELSIF info THEN BeginComment; ShortType(x.type); w.String("<-"); EndComment;
@@ -564,18 +566,18 @@ TYPE
 			IF x.typeExpression # NIL THEN w.String(")") END;
 			IF x.typeExpression # NIL THEN w.String(")") END;
 		END VisitConversion;
 		END VisitConversion;
 
 
-		PROCEDURE VisitDesignator(x: SyntaxTree.Designator);
+		PROCEDURE VisitDesignator*(x: SyntaxTree.Designator);
 		BEGIN
 		BEGIN
 			AlertString("InvalidDesignator");
 			AlertString("InvalidDesignator");
 		END VisitDesignator;
 		END VisitDesignator;
 
 
-		PROCEDURE VisitIdentifierDesignator(x: SyntaxTree.IdentifierDesignator);
+		PROCEDURE VisitIdentifierDesignator*(x: SyntaxTree.IdentifierDesignator);
 		BEGIN
 		BEGIN
 			IF info THEN AlertString("(*<IdentifierDesignator>*)") END;
 			IF info THEN AlertString("(*<IdentifierDesignator>*)") END;
 			Identifier(x.identifier)
 			Identifier(x.identifier)
 		END VisitIdentifierDesignator;
 		END VisitIdentifierDesignator;
 
 
-		PROCEDURE VisitSelectorDesignator(x: SyntaxTree.SelectorDesignator);
+		PROCEDURE VisitSelectorDesignator*(x: SyntaxTree.SelectorDesignator);
 		BEGIN
 		BEGIN
 			Expression(x.left);
 			Expression(x.left);
 			w.String(".");
 			w.String(".");
@@ -583,21 +585,21 @@ TYPE
 			Identifier(x.identifier);
 			Identifier(x.identifier);
 		END VisitSelectorDesignator;
 		END VisitSelectorDesignator;
 
 
-		PROCEDURE VisitBracketDesignator(x: SyntaxTree.BracketDesignator);
+		PROCEDURE VisitBracketDesignator*(x: SyntaxTree.BracketDesignator);
 		BEGIN
 		BEGIN
 			Expression(x.left);
 			Expression(x.left);
 		 	IF info THEN AlertString("(*<BracketDesignator>*)") END;
 		 	IF info THEN AlertString("(*<BracketDesignator>*)") END;
 		 	w.String("["); ExpressionList(x.parameters); w.String("]");
 		 	w.String("["); ExpressionList(x.parameters); w.String("]");
 		END VisitBracketDesignator;
 		END VisitBracketDesignator;
 
 
-		PROCEDURE VisitParameterDesignator(x: SyntaxTree.ParameterDesignator);
+		PROCEDURE VisitParameterDesignator*(x: SyntaxTree.ParameterDesignator);
 		BEGIN
 		BEGIN
 			Expression(x.left);
 			Expression(x.left);
 			IF info THEN AlertString("(*<ParameterDesignator>*)") END;
 			IF info THEN AlertString("(*<ParameterDesignator>*)") END;
 			w.String("("); ExpressionList(x.parameters); w.String(")");
 			w.String("("); ExpressionList(x.parameters); w.String(")");
 		END VisitParameterDesignator;
 		END VisitParameterDesignator;
 
 
-		PROCEDURE VisitIndexDesignator(x: SyntaxTree.IndexDesignator);
+		PROCEDURE VisitIndexDesignator*(x: SyntaxTree.IndexDesignator);
 		BEGIN
 		BEGIN
 			Expression(x.left);
 			Expression(x.left);
 			w.String("["); ExpressionList(x.parameters); w.String("]");
 			w.String("["); ExpressionList(x.parameters); w.String("]");
@@ -610,7 +612,7 @@ TYPE
 			END;
 			END;
 		END VisitIndexDesignator;
 		END VisitIndexDesignator;
 
 
-		PROCEDURE VisitArrowDesignator(x: SyntaxTree.ArrowDesignator);
+		PROCEDURE VisitArrowDesignator*(x: SyntaxTree.ArrowDesignator);
 		BEGIN
 		BEGIN
 			Expression(x.left);
 			Expression(x.left);
 			IF info THEN AlertString("(*<ArrowDesignator>*)") END;
 			IF info THEN AlertString("(*<ArrowDesignator>*)") END;
@@ -626,7 +628,7 @@ TYPE
 			ELSE w.String("(other)") END;
 			ELSE w.String("(other)") END;
 		END ShortType;
 		END ShortType;
 
 
-		PROCEDURE VisitSymbolDesignator(x: SyntaxTree.SymbolDesignator);
+		PROCEDURE VisitSymbolDesignator*(x: SyntaxTree.SymbolDesignator);
 		BEGIN
 		BEGIN
 			IF (x.left # NIL) & ~x.left.isHidden THEN
 			IF (x.left # NIL) & ~x.left.isHidden THEN
 			Expression(x.left); w.String(".");
 			Expression(x.left); w.String(".");
@@ -650,7 +652,7 @@ TYPE
 			END;
 			END;
 		END VisitSymbolDesignator;
 		END VisitSymbolDesignator;
 
 
-		PROCEDURE VisitSupercallDesignator(x: SyntaxTree.SupercallDesignator);
+		PROCEDURE VisitSupercallDesignator*(x: SyntaxTree.SupercallDesignator);
 		BEGIN
 		BEGIN
 			Expression(x.left);
 			Expression(x.left);
 			w.String( "^" );
 			w.String( "^" );
@@ -663,7 +665,7 @@ TYPE
 			END;
 			END;
 		END VisitSupercallDesignator;
 		END VisitSupercallDesignator;
 
 
-		PROCEDURE VisitSelfDesignator(x: SyntaxTree.SelfDesignator);
+		PROCEDURE VisitSelfDesignator*(x: SyntaxTree.SelfDesignator);
 		BEGIN
 		BEGIN
 			ASSERT(x.left = NIL);
 			ASSERT(x.left = NIL);
 			IF case = Scanner.Lowercase THEN w.String("self"); ELSE w.String("SELF"); END;
 			IF case = Scanner.Lowercase THEN w.String("self"); ELSE w.String("SELF"); END;
@@ -677,7 +679,7 @@ TYPE
 
 
 		END VisitSelfDesignator;
 		END VisitSelfDesignator;
 
 
-		PROCEDURE VisitResultDesignator(x: SyntaxTree.ResultDesignator);
+		PROCEDURE VisitResultDesignator*(x: SyntaxTree.ResultDesignator);
 		BEGIN
 		BEGIN
 			ASSERT(x.left = NIL);
 			ASSERT(x.left = NIL);
 			w.String("RESULT");
 			w.String("RESULT");
@@ -690,7 +692,7 @@ TYPE
 			END;
 			END;
 		END VisitResultDesignator;
 		END VisitResultDesignator;
 
 
-		PROCEDURE VisitDereferenceDesignator(x: SyntaxTree.DereferenceDesignator);
+		PROCEDURE VisitDereferenceDesignator*(x: SyntaxTree.DereferenceDesignator);
 		BEGIN
 		BEGIN
 			Expression(x.left);
 			Expression(x.left);
 			w.String( "^" );
 			w.String( "^" );
@@ -703,7 +705,7 @@ TYPE
 			END;
 			END;
 		END VisitDereferenceDesignator;
 		END VisitDereferenceDesignator;
 
 
-		PROCEDURE VisitTypeGuardDesignator(x: SyntaxTree.TypeGuardDesignator);
+		PROCEDURE VisitTypeGuardDesignator*(x: SyntaxTree.TypeGuardDesignator);
 		BEGIN
 		BEGIN
 			Expression(x.left);
 			Expression(x.left);
 			IF info THEN
 			IF info THEN
@@ -718,7 +720,7 @@ TYPE
 			w.String(")");
 			w.String(")");
 		END VisitTypeGuardDesignator;
 		END VisitTypeGuardDesignator;
 
 
-		PROCEDURE VisitProcedureCallDesignator(x: SyntaxTree.ProcedureCallDesignator);
+		PROCEDURE VisitProcedureCallDesignator*(x: SyntaxTree.ProcedureCallDesignator);
 		BEGIN
 		BEGIN
 			Expression(x.left);
 			Expression(x.left);
 			IF info THEN
 			IF info THEN
@@ -731,7 +733,7 @@ TYPE
 			w.String("("); ExpressionList(x.parameters); w.String(")");
 			w.String("("); ExpressionList(x.parameters); w.String(")");
 		END VisitProcedureCallDesignator;
 		END VisitProcedureCallDesignator;
 
 
-		PROCEDURE VisitStatementDesignator(x: SyntaxTree.StatementDesignator);
+		PROCEDURE VisitStatementDesignator*(x: SyntaxTree.StatementDesignator);
 		BEGIN
 		BEGIN
 			Indent; Keyword("STATEMENT-DESIGNATOR ");
 			Indent; Keyword("STATEMENT-DESIGNATOR ");
 			IF x.result # NIL THEN
 			IF x.result # NIL THEN
@@ -742,7 +744,7 @@ TYPE
 		END VisitStatementDesignator;
 		END VisitStatementDesignator;
 
 
 
 
-		PROCEDURE VisitBuiltinCallDesignator(x: SyntaxTree.BuiltinCallDesignator);
+		PROCEDURE VisitBuiltinCallDesignator*(x: SyntaxTree.BuiltinCallDesignator);
 		BEGIN
 		BEGIN
 			IF x.left # NIL THEN
 			IF x.left # NIL THEN
 				Expression(x.left);
 				Expression(x.left);
@@ -761,12 +763,12 @@ TYPE
 			w.String("("); ExpressionList(x.parameters); w.String(")");
 			w.String("("); ExpressionList(x.parameters); w.String(")");
 		END VisitBuiltinCallDesignator;
 		END VisitBuiltinCallDesignator;
 
 
-		PROCEDURE VisitValue(x: SyntaxTree.Value);
+		PROCEDURE VisitValue*(x: SyntaxTree.Value);
 		BEGIN
 		BEGIN
 			AlertString("InvalidValue");
 			AlertString("InvalidValue");
 		END VisitValue;
 		END VisitValue;
 
 
-		PROCEDURE VisitBooleanValue(x: SyntaxTree.BooleanValue);
+		PROCEDURE VisitBooleanValue*(x: SyntaxTree.BooleanValue);
 		BEGIN
 		BEGIN
 			IF Scanner.Uppercase = case THEN
 			IF Scanner.Uppercase = case THEN
 				IF x.value THEN w.String("TRUE" ) ELSE w.String( "FALSE" ) END
 				IF x.value THEN w.String("TRUE" ) ELSE w.String( "FALSE" ) END
@@ -791,7 +793,7 @@ TYPE
 			REPEAT DEC( i ); w.Char( a[i] ) UNTIL i = 0
 			REPEAT DEC( i ); w.Char( a[i] ) UNTIL i = 0
 		END Hex;
 		END Hex;
 
 
-		PROCEDURE VisitIntegerValue(x: SyntaxTree.IntegerValue);
+		PROCEDURE VisitIntegerValue*(x: SyntaxTree.IntegerValue);
 
 
 			PROCEDURE InBounds(val: HUGEINT; bits: LONGINT): BOOLEAN;
 			PROCEDURE InBounds(val: HUGEINT; bits: LONGINT): BOOLEAN;
 			VAR m: HUGEINT;
 			VAR m: HUGEINT;
@@ -813,12 +815,12 @@ TYPE
 			END;
 			END;
 		END VisitIntegerValue;
 		END VisitIntegerValue;
 
 
-		PROCEDURE VisitCharacterValue(x: SyntaxTree.CharacterValue);
+		PROCEDURE VisitCharacterValue*(x: SyntaxTree.CharacterValue);
 		BEGIN
 		BEGIN
 			Hex( ORD(x.value));  w.String( "X" );
 			Hex( ORD(x.value));  w.String( "X" );
 		END VisitCharacterValue;
 		END VisitCharacterValue;
 
 
-		PROCEDURE VisitSetValue(x: SyntaxTree.SetValue);
+		PROCEDURE VisitSetValue*(x: SyntaxTree.SetValue);
 		VAR i: LONGINT;
 		VAR i: LONGINT;
 		BEGIN
 		BEGIN
 			w.String("{");
 			w.String("{");
@@ -837,7 +839,7 @@ TYPE
 			w.String("}");
 			w.String("}");
 		END VisitSetValue;
 		END VisitSetValue;
 
 
-		PROCEDURE VisitMathArrayValue(x: SyntaxTree.MathArrayValue);
+		PROCEDURE VisitMathArrayValue*(x: SyntaxTree.MathArrayValue);
 		BEGIN
 		BEGIN
 			VisitMathArrayExpression(x.array);
 			VisitMathArrayExpression(x.array);
 		END VisitMathArrayValue;
 		END VisitMathArrayValue;
@@ -866,11 +868,11 @@ TYPE
 			END;
 			END;
 		END FormatedFloat;
 		END FormatedFloat;
 
 
-		PROCEDURE VisitRealValue(x: SyntaxTree.RealValue);
+		PROCEDURE VisitRealValue*(x: SyntaxTree.RealValue);
 		BEGIN FormatedFloat(x.value, x.subtype)
 		BEGIN FormatedFloat(x.value, x.subtype)
 		END VisitRealValue;
 		END VisitRealValue;
 
 
-		PROCEDURE VisitComplexValue(x: SyntaxTree.ComplexValue);
+		PROCEDURE VisitComplexValue*(x: SyntaxTree.ComplexValue);
 		BEGIN
 		BEGIN
 			IF (x.realValue = 0) & (x.imagValue = 1) THEN
 			IF (x.realValue = 0) & (x.imagValue = 1) THEN
 				w.String("IMAG")
 				w.String("IMAG")
@@ -884,7 +886,7 @@ TYPE
 			END
 			END
 		END VisitComplexValue;
 		END VisitComplexValue;
 
 
-		PROCEDURE VisitStringValue(x: SyntaxTree.StringValue);
+		PROCEDURE VisitStringValue*(x: SyntaxTree.StringValue);
 		VAR i: LONGINT; ch: CHAR;
 		VAR i: LONGINT; ch: CHAR;
 		BEGIN
 		BEGIN
 			i := 0;
 			i := 0;
@@ -905,11 +907,11 @@ TYPE
 			w.Char('\');
 			w.Char('\');
 		END VisitStringValue;
 		END VisitStringValue;
 
 
-		PROCEDURE VisitNilValue(x: SyntaxTree.NilValue);
+		PROCEDURE VisitNilValue*(x: SyntaxTree.NilValue);
 		BEGIN IF case = Scanner.Lowercase THEN w.String( "nil" ); ELSE w.String( "NIL" ); END; IF info THEN BeginComment; Type(x.type); EndComment; END;
 		BEGIN IF case = Scanner.Lowercase THEN w.String( "nil" ); ELSE w.String( "NIL" ); END; IF info THEN BeginComment; Type(x.type); EndComment; END;
 		END VisitNilValue;
 		END VisitNilValue;
 
 
-		PROCEDURE VisitEnumerationValue(x: SyntaxTree.EnumerationValue);
+		PROCEDURE VisitEnumerationValue*(x: SyntaxTree.EnumerationValue);
 		BEGIN w.Int(x.value,1);
 		BEGIN w.Int(x.value,1);
 		END VisitEnumerationValue;
 		END VisitEnumerationValue;
 
 
@@ -924,7 +926,7 @@ TYPE
 			END
 			END
 		END Symbol;
 		END Symbol;
 
 
-		PROCEDURE VisitSymbol(x: SyntaxTree.Symbol);
+		PROCEDURE VisitSymbol*(x: SyntaxTree.Symbol);
 		BEGIN
 		BEGIN
 			AlertString("InvalidSymbol");
 			AlertString("InvalidSymbol");
 		END VisitSymbol;
 		END VisitSymbol;
@@ -971,7 +973,7 @@ TYPE
 			END;
 			END;
 		END PrintSymbol;
 		END PrintSymbol;
 
 
-		PROCEDURE VisitTypeDeclaration(x: SyntaxTree.TypeDeclaration);
+		PROCEDURE VisitTypeDeclaration*(x: SyntaxTree.TypeDeclaration);
 		BEGIN
 		BEGIN
 			IF Visible(x) THEN
 			IF Visible(x) THEN
 				IF (x.access # SyntaxTree.Hidden) OR (mode > SourceCode) THEN
 				IF (x.access # SyntaxTree.Hidden) OR (mode > SourceCode) THEN
@@ -1002,7 +1004,7 @@ TYPE
 			w.DecIndent;
 			w.DecIndent;
 		END TypeDeclarationList;
 		END TypeDeclarationList;
 
 
-		PROCEDURE VisitConstant(x: SyntaxTree.Constant);
+		PROCEDURE VisitConstant*(x: SyntaxTree.Constant);
 		BEGIN
 		BEGIN
 			IF Visible(x) THEN
 			IF Visible(x) THEN
 				IF (mode > SourceCode) OR (x.access # SyntaxTree.Hidden) THEN
 				IF (mode > SourceCode) OR (x.access # SyntaxTree.Hidden) THEN
@@ -1033,7 +1035,7 @@ TYPE
 			w.DecIndent;
 			w.DecIndent;
 		END ConstantList;
 		END ConstantList;
 
 
-		PROCEDURE VisitVariable(x: SyntaxTree.Variable);
+		PROCEDURE VisitVariable*(x: SyntaxTree.Variable);
 		BEGIN
 		BEGIN
 			IF Visible(x) THEN
 			IF Visible(x) THEN
 				IF (x.access # SyntaxTree.Hidden) THEN
 				IF (x.access # SyntaxTree.Hidden) THEN
@@ -1106,7 +1108,7 @@ TYPE
 			w.DecIndent
 			w.DecIndent
 		END VariableList;
 		END VariableList;
 
 
-		PROCEDURE VisitParameter(x: SyntaxTree.Parameter);
+		PROCEDURE VisitParameter*(x: SyntaxTree.Parameter);
 		BEGIN
 		BEGIN
 			IF (x.access # SyntaxTree.Hidden) THEN
 			IF (x.access # SyntaxTree.Hidden) THEN
 				Comments(x.comment,x,TRUE);
 				Comments(x.comment,x,TRUE);
@@ -1195,7 +1197,7 @@ TYPE
 			IF SyntaxTree.InternalRead IN access THEN w.String(" InternalRead") END;
 			IF SyntaxTree.InternalRead IN access THEN w.String(" InternalRead") END;
 		END Access;
 		END Access;
 
 
-		PROCEDURE VisitProcedure(x: SyntaxTree.Procedure);
+		PROCEDURE VisitProcedure*(x: SyntaxTree.Procedure);
 		VAR type: SyntaxTree.ProcedureType;  first: BOOLEAN; fp: SyntaxTree.FingerPrint;
 		VAR type: SyntaxTree.ProcedureType;  first: BOOLEAN; fp: SyntaxTree.FingerPrint;
 		BEGIN
 		BEGIN
 			IF Visible(x) THEN
 			IF Visible(x) THEN
@@ -1218,6 +1220,8 @@ TYPE
 				IF type.stackAlignment > 1 THEN Value(Global.NameStackAligned,type.stackAlignment,first) END;
 				IF type.stackAlignment > 1 THEN Value(Global.NameStackAligned,type.stackAlignment,first) END;
 				IF (type.isRealtime) THEN Flag(Global.NameRealtime,first) END;
 				IF (type.isRealtime) THEN Flag(Global.NameRealtime,first) END;
 				IF (type.noReturn) THEN Flag(Global.NameNoReturn,first) END;
 				IF (type.noReturn) THEN Flag(Global.NameNoReturn,first) END;
+				IF (x.isAbstract) THEN Flag(Global.NameAbstract,first) END;
+				IF (x.isFinal) THEN Flag(Global.NameFinal,first) END;
 				IF (x.fixed) THEN Value(Global.NameFixed, x.alignment,first)
 				IF (x.fixed) THEN Value(Global.NameFixed, x.alignment,first)
 				ELSIF (x.alignment >1) THEN Value(Global.NameAligned, x.alignment, first)
 				ELSIF (x.alignment >1) THEN Value(Global.NameAligned, x.alignment, first)
 				END;
 				END;
@@ -1280,7 +1284,7 @@ TYPE
 			END;
 			END;
 		END VisitProcedure;
 		END VisitProcedure;
 
 
-		PROCEDURE VisitOperator(x: SyntaxTree.Operator);
+		PROCEDURE VisitOperator*(x: SyntaxTree.Operator);
 		VAR type: SyntaxTree.ProcedureType;
 		VAR type: SyntaxTree.ProcedureType;
 			recordType: SyntaxTree.RecordType;
 			recordType: SyntaxTree.RecordType;
 			i: LONGINT;
 			i: LONGINT;
@@ -1373,7 +1377,7 @@ TYPE
 			w.DecIndent;
 			w.DecIndent;
 		END ProcedureList;
 		END ProcedureList;
 
 
-		PROCEDURE VisitImport(x: SyntaxTree.Import);
+		PROCEDURE VisitImport*(x: SyntaxTree.Import);
 		VAR context: SyntaxTree.Identifier;
 		VAR context: SyntaxTree.Identifier;
 		BEGIN
 		BEGIN
 			IF x.moduleName # x.name THEN Identifier(x.name);  w.String( " := " );  END;
 			IF x.moduleName # x.name THEN Identifier(x.name);  w.String( " := " );  END;
@@ -1399,7 +1403,7 @@ TYPE
 			IF ~first THEN w.String( ";" ); END;
 			IF ~first THEN w.String( ";" ); END;
 		END ImportList;
 		END ImportList;
 
 
-		PROCEDURE VisitBuiltin(x: SyntaxTree.Builtin);
+		PROCEDURE VisitBuiltin*(x: SyntaxTree.Builtin);
 		BEGIN
 		BEGIN
 			Indent; Keyword("BUILTIN ");
 			Indent; Keyword("BUILTIN ");
 			Identifier(x.name);
 			Identifier(x.name);
@@ -1523,20 +1527,20 @@ TYPE
 			END;
 			END;
 		END StatementSequence;
 		END StatementSequence;
 
 
-		PROCEDURE VisitStatement(x: SyntaxTree.Statement);
+		PROCEDURE VisitStatement*(x: SyntaxTree.Statement);
 		BEGIN
 		BEGIN
 			AlertString("InvalidStatement");
 			AlertString("InvalidStatement");
 		END VisitStatement;
 		END VisitStatement;
 
 
-		PROCEDURE VisitProcedureCallStatement(x: SyntaxTree.ProcedureCallStatement);
+		PROCEDURE VisitProcedureCallStatement*(x: SyntaxTree.ProcedureCallStatement);
 		BEGIN Expression(x.call) END VisitProcedureCallStatement;
 		BEGIN Expression(x.call) END VisitProcedureCallStatement;
 
 
-		PROCEDURE VisitAssignment(x: SyntaxTree.Assignment);
+		PROCEDURE VisitAssignment*(x: SyntaxTree.Assignment);
 		BEGIN
 		BEGIN
 			Expression(x.left); w.String( " := " );  Expression(x.right);
 			Expression(x.left); w.String( " := " );  Expression(x.right);
 		END VisitAssignment;
 		END VisitAssignment;
 
 
-		PROCEDURE VisitCommunicationStatement(x: SyntaxTree.CommunicationStatement);
+		PROCEDURE VisitCommunicationStatement*(x: SyntaxTree.CommunicationStatement);
 		VAR identifier: SyntaxTree.Identifier;
 		VAR identifier: SyntaxTree.Identifier;
 		BEGIN
 		BEGIN
 			Expression(x.left);
 			Expression(x.left);
@@ -1557,7 +1561,7 @@ TYPE
 			w.DecIndent;
 			w.DecIndent;
 		END IfPart;
 		END IfPart;
 
 
-		PROCEDURE VisitIfStatement(x: SyntaxTree.IfStatement);
+		PROCEDURE VisitIfStatement*(x: SyntaxTree.IfStatement);
 		VAR i: LONGINT;  elsif: SyntaxTree.IfPart;
 		VAR i: LONGINT;  elsif: SyntaxTree.IfPart;
 		BEGIN
 		BEGIN
 			IfPart(x.ifPart);
 			IfPart(x.ifPart);
@@ -1586,7 +1590,7 @@ TYPE
 			w.IncIndent;  StatementSequence(x.statements);  w.DecIndent;
 			w.IncIndent;  StatementSequence(x.statements);  w.DecIndent;
 		END WithPart;
 		END WithPart;
 
 
-		PROCEDURE VisitWithStatement(x: SyntaxTree.WithStatement);
+		PROCEDURE VisitWithStatement*(x: SyntaxTree.WithStatement);
 		VAR i: LONGINT;
 		VAR i: LONGINT;
 		BEGIN
 		BEGIN
 			Indent; Keyword("WITH " );
 			Indent; Keyword("WITH " );
@@ -1622,7 +1626,7 @@ TYPE
 			w.IncIndent; StatementSequence(x.statements);  w.DecIndent;
 			w.IncIndent; StatementSequence(x.statements);  w.DecIndent;
 		END CasePart;
 		END CasePart;
 
 
-		PROCEDURE VisitCaseStatement(x: SyntaxTree.CaseStatement);
+		PROCEDURE VisitCaseStatement*(x: SyntaxTree.CaseStatement);
 		VAR i: LONGINT;  case: SyntaxTree.CasePart;
 		VAR i: LONGINT;  case: SyntaxTree.CasePart;
 		BEGIN
 		BEGIN
 			Keyword("CASE " );
 			Keyword("CASE " );
@@ -1645,7 +1649,7 @@ TYPE
 			Keyword("END" );
 			Keyword("END" );
 		END VisitCaseStatement;
 		END VisitCaseStatement;
 
 
-		PROCEDURE VisitWhileStatement(x: SyntaxTree.WhileStatement);
+		PROCEDURE VisitWhileStatement*(x: SyntaxTree.WhileStatement);
 		BEGIN
 		BEGIN
 			Keyword("WHILE " );
 			Keyword("WHILE " );
 			Expression(x.condition);
 			Expression(x.condition);
@@ -1657,7 +1661,7 @@ TYPE
 			Keyword("END" );
 			Keyword("END" );
 		END VisitWhileStatement;
 		END VisitWhileStatement;
 
 
-		PROCEDURE VisitRepeatStatement(x: SyntaxTree.RepeatStatement);
+		PROCEDURE VisitRepeatStatement*(x: SyntaxTree.RepeatStatement);
 		BEGIN
 		BEGIN
 			Keyword("REPEAT " );
 			Keyword("REPEAT " );
 			w.IncIndent;
 			w.IncIndent;
@@ -1667,7 +1671,7 @@ TYPE
 			Expression(x.condition);
 			Expression(x.condition);
 		END VisitRepeatStatement;
 		END VisitRepeatStatement;
 
 
-		PROCEDURE VisitForStatement(x: SyntaxTree.ForStatement);
+		PROCEDURE VisitForStatement*(x: SyntaxTree.ForStatement);
 		BEGIN
 		BEGIN
 			Keyword("FOR " );
 			Keyword("FOR " );
 			Expression(x.variable);
 			Expression(x.variable);
@@ -1687,30 +1691,30 @@ TYPE
 			Keyword("END" );
 			Keyword("END" );
 		END VisitForStatement;
 		END VisitForStatement;
 
 
-		PROCEDURE VisitLoopStatement(x: SyntaxTree.LoopStatement);
+		PROCEDURE VisitLoopStatement*(x: SyntaxTree.LoopStatement);
 		BEGIN
 		BEGIN
 			Keyword("LOOP " );
 			Keyword("LOOP " );
 			w.IncIndent;  StatementSequence(x.statements);  w.DecIndent;
 			w.IncIndent;  StatementSequence(x.statements);  w.DecIndent;
 			Indent;  Keyword("END" );
 			Indent;  Keyword("END" );
 		END VisitLoopStatement;
 		END VisitLoopStatement;
 
 
-		PROCEDURE VisitExitableBlock(x: SyntaxTree.ExitableBlock);
+		PROCEDURE VisitExitableBlock*(x: SyntaxTree.ExitableBlock);
 		BEGIN
 		BEGIN
 			Keyword("EXITABLE " );
 			Keyword("EXITABLE " );
 			w.IncIndent;  StatementSequence(x.statements);  w.DecIndent;
 			w.IncIndent;  StatementSequence(x.statements);  w.DecIndent;
 			Indent;  Keyword("END " );
 			Indent;  Keyword("END " );
 		END VisitExitableBlock;
 		END VisitExitableBlock;
 
 
-		PROCEDURE VisitExitStatement(x: SyntaxTree.ExitStatement);
+		PROCEDURE VisitExitStatement*(x: SyntaxTree.ExitStatement);
 		BEGIN 	Keyword("EXIT" ) END VisitExitStatement;
 		BEGIN 	Keyword("EXIT" ) END VisitExitStatement;
 
 
-		PROCEDURE VisitReturnStatement(x: SyntaxTree.ReturnStatement);
+		PROCEDURE VisitReturnStatement*(x: SyntaxTree.ReturnStatement);
 		BEGIN
 		BEGIN
 			Keyword("RETURN " );
 			Keyword("RETURN " );
 			IF x.returnValue # NIL THEN Expression(x.returnValue) END
 			IF x.returnValue # NIL THEN Expression(x.returnValue) END
 		END VisitReturnStatement;
 		END VisitReturnStatement;
 
 
-		PROCEDURE VisitAwaitStatement(x: SyntaxTree.AwaitStatement);
+		PROCEDURE VisitAwaitStatement*(x: SyntaxTree.AwaitStatement);
 		BEGIN
 		BEGIN
 			Keyword("AWAIT (" );  Expression(x.condition);  w.String( ")" );
 			Keyword("AWAIT (" );  Expression(x.condition);  w.String( ")" );
 		END VisitAwaitStatement;
 		END VisitAwaitStatement;
@@ -1753,7 +1757,7 @@ TYPE
 		END BlockModifier;
 		END BlockModifier;
 		*)
 		*)
 
 
-		PROCEDURE VisitStatementBlock(x: SyntaxTree.StatementBlock);
+		PROCEDURE VisitStatementBlock*(x: SyntaxTree.StatementBlock);
 		BEGIN
 		BEGIN
 			Keyword("BEGIN"); Modifiers(x.blockModifiers);
 			Keyword("BEGIN"); Modifiers(x.blockModifiers);
 			w.IncIndent;
 			w.IncIndent;
@@ -1808,7 +1812,7 @@ TYPE
 			END;
 			END;
 		END Code;
 		END Code;
 
 
-		PROCEDURE VisitCode(x: SyntaxTree.Code);
+		PROCEDURE VisitCode*(x: SyntaxTree.Code);
 		VAR in, out: BOOLEAN;
 		VAR in, out: BOOLEAN;
 		BEGIN
 		BEGIN
 			Indent; Keyword("CODE");
 			Indent; Keyword("CODE");

+ 102 - 84
source/FoxSemanticChecker.Mod

@@ -328,13 +328,13 @@ TYPE
 			END;
 			END;
 		END ResolvedType;
 		END ResolvedType;
 
 
-		PROCEDURE VisitType(x: SyntaxTree.Type);
+		PROCEDURE VisitType*(x: SyntaxTree.Type);
 		BEGIN
 		BEGIN
 			ASSERT(x = SyntaxTree.invalidType);
 			ASSERT(x = SyntaxTree.invalidType);
 		END VisitType;
 		END VisitType;
 
 
 		(** resolve basic type **)
 		(** resolve basic type **)
-		PROCEDURE VisitBasicType(x: SyntaxTree.BasicType);
+		PROCEDURE VisitBasicType*(x: SyntaxTree.BasicType);
 		BEGIN
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 			IF TypeNeedsResolution(x) THEN
 				x.SetState(SyntaxTree.Resolved);
 				x.SetState(SyntaxTree.Resolved);
@@ -342,66 +342,66 @@ TYPE
 			resolvedType := ResolvedType(x)
 			resolvedType := ResolvedType(x)
 		END VisitBasicType;
 		END VisitBasicType;
 
 
-		PROCEDURE VisitByteType(x: SyntaxTree.ByteType);
+		PROCEDURE VisitByteType*(x: SyntaxTree.ByteType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitByteType;
 		END VisitByteType;
 
 
 		(** resolve character type **)
 		(** resolve character type **)
-		PROCEDURE VisitCharacterType(x: SyntaxTree.CharacterType);
+		PROCEDURE VisitCharacterType*(x: SyntaxTree.CharacterType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitCharacterType;
 		END VisitCharacterType;
 
 
-		PROCEDURE VisitBooleanType(x: SyntaxTree.BooleanType);
+		PROCEDURE VisitBooleanType*(x: SyntaxTree.BooleanType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitBooleanType;
 		END VisitBooleanType;
 
 
-		PROCEDURE VisitSetType(x: SyntaxTree.SetType);
+		PROCEDURE VisitSetType*(x: SyntaxTree.SetType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitSetType;
 		END VisitSetType;
 
 
-		PROCEDURE VisitAddressType(x: SyntaxTree.AddressType);
+		PROCEDURE VisitAddressType*(x: SyntaxTree.AddressType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitAddressType;
 		END VisitAddressType;
 
 
-		PROCEDURE VisitSizeType(x: SyntaxTree.SizeType);
+		PROCEDURE VisitSizeType*(x: SyntaxTree.SizeType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitSizeType;
 		END VisitSizeType;
 
 
-		PROCEDURE VisitAnyType(x: SyntaxTree.AnyType);
+		PROCEDURE VisitAnyType*(x: SyntaxTree.AnyType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitAnyType;
 		END VisitAnyType;
 
 
-		PROCEDURE VisitObjectType(x: SyntaxTree.ObjectType);
+		PROCEDURE VisitObjectType*(x: SyntaxTree.ObjectType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitObjectType;
 		END VisitObjectType;
 
 
-		PROCEDURE VisitNilType(x: SyntaxTree.NilType);
+		PROCEDURE VisitNilType*(x: SyntaxTree.NilType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitNilType;
 		END VisitNilType;
 
 
 		(** resolve integer type **)
 		(** resolve integer type **)
-		PROCEDURE VisitIntegerType(x: SyntaxTree.IntegerType);
+		PROCEDURE VisitIntegerType*(x: SyntaxTree.IntegerType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitIntegerType;
 		END VisitIntegerType;
 
 
 		(** resolve real type **)
 		(** resolve real type **)
-		PROCEDURE VisitFloatType(x: SyntaxTree.FloatType);
+		PROCEDURE VisitFloatType*(x: SyntaxTree.FloatType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitFloatType;
 		END VisitFloatType;
 
 
 		(** resolve complex type **)
 		(** resolve complex type **)
-		PROCEDURE VisitComplexType(x: SyntaxTree.ComplexType);
+		PROCEDURE VisitComplexType*(x: SyntaxTree.ComplexType);
 		BEGIN
 		BEGIN
 			VisitBasicType(x);
 			VisitBasicType(x);
 		END VisitComplexType;
 		END VisitComplexType;
@@ -409,7 +409,7 @@ TYPE
 		(**
 		(**
 			resolve string type: nothing to be done
 			resolve string type: nothing to be done
 		**)
 		**)
-		PROCEDURE VisitStringType(x: SyntaxTree.StringType);
+		PROCEDURE VisitStringType*(x: SyntaxTree.StringType);
 		BEGIN
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 			IF TypeNeedsResolution(x) THEN
 				x.SetState(SyntaxTree.Resolved);
 				x.SetState(SyntaxTree.Resolved);
@@ -454,7 +454,7 @@ TYPE
 		(**
 		(**
 			resolve enumeration type: check enumeration scope
 			resolve enumeration type: check enumeration scope
 		**)
 		**)
-		PROCEDURE VisitEnumerationType(x: SyntaxTree.EnumerationType);
+		PROCEDURE VisitEnumerationType*(x: SyntaxTree.EnumerationType);
 		VAR position: Position; baseScope: SyntaxTree.EnumerationScope; baseType,resolved: SyntaxTree.Type; enumerationBase: SyntaxTree.EnumerationType;
 		VAR position: Position; baseScope: SyntaxTree.EnumerationScope; baseType,resolved: SyntaxTree.Type; enumerationBase: SyntaxTree.EnumerationType;
 			lowest, highest: LONGINT;
 			lowest, highest: LONGINT;
 		BEGIN
 		BEGIN
@@ -485,7 +485,7 @@ TYPE
 		(**
 		(**
 			resolve range type: nothing to be done
 			resolve range type: nothing to be done
 		**)
 		**)
-		PROCEDURE VisitRangeType(x: SyntaxTree.RangeType);
+		PROCEDURE VisitRangeType*(x: SyntaxTree.RangeType);
 		BEGIN
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 			IF TypeNeedsResolution(x) THEN
 				x.SetState(SyntaxTree.Resolved);
 				x.SetState(SyntaxTree.Resolved);
@@ -497,7 +497,7 @@ TYPE
 			resolve qualified type
 			resolve qualified type
 			- find and resolve named type and set resolved type
 			- find and resolve named type and set resolved type
 		**)
 		**)
-		PROCEDURE VisitQualifiedType(x: SyntaxTree.QualifiedType);
+		PROCEDURE VisitQualifiedType*(x: SyntaxTree.QualifiedType);
 		VAR type: SyntaxTree.Type; typeDeclaration: SyntaxTree.TypeDeclaration;
 		VAR type: SyntaxTree.Type; typeDeclaration: SyntaxTree.TypeDeclaration;
 		BEGIN
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 			IF TypeNeedsResolution(x) THEN
@@ -517,7 +517,7 @@ TYPE
 				- array of math array  forbidden
 				- array of math array  forbidden
 				- static array of open array forbidden
 				- static array of open array forbidden
 		**)
 		**)
-		PROCEDURE VisitArrayType(x: SyntaxTree.ArrayType);
+		PROCEDURE VisitArrayType*(x: SyntaxTree.ArrayType);
 		VAR arrayBase: SyntaxTree.Type; e: SyntaxTree.Expression; pointerType: SyntaxTree.PointerType;
 		VAR arrayBase: SyntaxTree.Type; e: SyntaxTree.Expression; pointerType: SyntaxTree.PointerType;
 		BEGIN
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 			IF TypeNeedsResolution(x) THEN
@@ -599,7 +599,7 @@ TYPE
 				- math array of tensor forbidden
 				- math array of tensor forbidden
 				- static array of open array forbidden
 				- static array of open array forbidden
 		**)
 		**)
-		PROCEDURE VisitMathArrayType(x: SyntaxTree.MathArrayType);
+		PROCEDURE VisitMathArrayType*(x: SyntaxTree.MathArrayType);
 		VAR arrayBase: SyntaxTree.Type;
 		VAR arrayBase: SyntaxTree.Type;
 		BEGIN
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 			IF TypeNeedsResolution(x) THEN
@@ -716,7 +716,7 @@ TYPE
 			resolve pointer type
 			resolve pointer type
 			- enter pointer type to list of deferred fixes (to avoid infinite loops in the declaration phase)
 			- enter pointer type to list of deferred fixes (to avoid infinite loops in the declaration phase)
 		**)
 		**)
-		PROCEDURE VisitPointerType(x: SyntaxTree.PointerType);
+		PROCEDURE VisitPointerType*(x: SyntaxTree.PointerType);
 		VAR recordType: SyntaxTree.RecordType; recordBaseType: SyntaxTree.Type;
 		VAR recordType: SyntaxTree.RecordType; recordBaseType: SyntaxTree.Type;
 		modifiers: SyntaxTree.Modifier; position: Position;
 		modifiers: SyntaxTree.Modifier; position: Position;
 		BEGIN
 		BEGIN
@@ -738,6 +738,7 @@ TYPE
 					recordBaseType := ResolveType(recordType.baseType);
 					recordBaseType := ResolveType(recordType.baseType);
 					recordType.SetBaseType(recordBaseType);
 					recordType.SetBaseType(recordBaseType);
 					recordType.SetProtected(HasFlag(modifiers, Global.NameExclusive, position));
 					recordType.SetProtected(HasFlag(modifiers, Global.NameExclusive, position));
+					recordType.SetAbstract(HasFlag(modifiers, Global.NameAbstract, position));
 				END;
 				END;
 				CheckModifiers(modifiers, TRUE);
 				CheckModifiers(modifiers, TRUE);
 				typeFixes.Add(x,currentScope);
 				typeFixes.Add(x,currentScope);
@@ -750,7 +751,7 @@ TYPE
 			resolve port type
 			resolve port type
 			- enter port type to list of deferred fixes (to avoid infinite loops in the declaration phase)
 			- enter port type to list of deferred fixes (to avoid infinite loops in the declaration phase)
 		**)
 		**)
-		PROCEDURE VisitPortType(x: SyntaxTree.PortType);
+		PROCEDURE VisitPortType*(x: SyntaxTree.PortType);
 		VAR value: LONGINT;
 		VAR value: LONGINT;
 		BEGIN
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 			IF TypeNeedsResolution(x) THEN
@@ -920,7 +921,7 @@ TYPE
 			resolve procedure type
 			resolve procedure type
 			- enter procedure to list of deferred fixes (to avoid infinite loops in the declaration phase)
 			- enter procedure to list of deferred fixes (to avoid infinite loops in the declaration phase)
 		**)
 		**)
-		PROCEDURE VisitProcedureType(procedureType: SyntaxTree.ProcedureType);
+		PROCEDURE VisitProcedureType*(procedureType: SyntaxTree.ProcedureType);
 		VAR modifiers: SyntaxTree.Modifier; value: LONGINT; position: Position;
 		VAR modifiers: SyntaxTree.Modifier; value: LONGINT; position: Position;
 		BEGIN
 		BEGIN
 			IF TypeNeedsResolution(procedureType) THEN
 			IF TypeNeedsResolution(procedureType) THEN
@@ -959,7 +960,7 @@ TYPE
 			- check declarations
 			- check declarations
 			- every record type is guaranteed to have a type declaration in the module scope (anonymous or not)
 			- every record type is guaranteed to have a type declaration in the module scope (anonymous or not)
 		**)
 		**)
-		PROCEDURE VisitRecordType(x: SyntaxTree.RecordType);
+		PROCEDURE VisitRecordType*(x: SyntaxTree.RecordType);
 		VAR resolved, baseType: SyntaxTree.Type; position: Position;
 		VAR resolved, baseType: SyntaxTree.Type; position: Position;
 			numberMethods: LONGINT; recordBase, recordType: SyntaxTree.RecordType; procedure: SyntaxTree.Procedure;
 			numberMethods: LONGINT; recordBase, recordType: SyntaxTree.RecordType; procedure: SyntaxTree.Procedure;
 			symbol: SyntaxTree.Symbol; isRealtime: BOOLEAN;
 			symbol: SyntaxTree.Symbol; isRealtime: BOOLEAN;
@@ -986,7 +987,9 @@ TYPE
 				hasPointers := FALSE;
 				hasPointers := FALSE;
 				
 				
 				modifiers := x.modifiers;
 				modifiers := x.modifiers;
-				IF HasValue(modifiers,Global.NameAligned,position,value) THEN x.SetAlignmentInBits(value*system.dataUnit) END;
+				IF HasValue(modifiers,Global.NameAligned,position,value) THEN x.SetAlignmentInBits(value*system.dataUnit) 
+				END;
+				IF HasFlag(modifiers,Global.NameAbstract,position) THEN x.SetAbstract(TRUE) END;
 				CheckModifiers(modifiers, TRUE);
 				CheckModifiers(modifiers, TRUE);
 				
 				
 				IF x.baseType # NIL THEN
 				IF x.baseType # NIL THEN
@@ -1068,7 +1071,7 @@ TYPE
 					IF symbol IS SyntaxTree.Procedure THEN
 					IF symbol IS SyntaxTree.Procedure THEN
 						procedure := symbol(SyntaxTree.Procedure);
 						procedure := symbol(SyntaxTree.Procedure);
 						IF procedure.super # NIL THEN
 						IF procedure.super # NIL THEN
-							procedure.SetMethodNumber(procedure.super.methodNumber)
+							procedure.SetMethodNumber(procedure.super.methodNumber);
 						ELSIF InMethodTable(procedure) THEN (* not a static method *)
 						ELSIF InMethodTable(procedure) THEN (* not a static method *)
 							procedure.SetMethodNumber(numberMethods);
 							procedure.SetMethodNumber(numberMethods);
 							INC(numberMethods);
 							INC(numberMethods);
@@ -1091,7 +1094,15 @@ TYPE
 				IF (x.isObject) & (x.baseType # NIL) & (x.baseType.resolved IS SyntaxTree.RecordType) THEN
 				IF (x.isObject) & (x.baseType # NIL) & (x.baseType.resolved IS SyntaxTree.RecordType) THEN
 					Error(x.position,"object extends a record")
 					Error(x.position,"object extends a record")
 				END;
 				END;
-
+				IF ~x.isAbstract THEN
+					IF x.recordScope.AbstractProcedure(x.recordScope) # NIL THEN
+						Error(x.position, "non-abstract object contains abstract procedure");
+					END;
+				ELSE
+					IF x.recordScope.AbstractProcedure(x.recordScope) = NIL THEN
+						Error(x.position, "abstract object does not contain an abstract method");
+					END;
+				END;
 				IF (x.typeDeclaration = NIL) THEN
 				IF (x.typeDeclaration = NIL) THEN
 					IF (x.pointerType # NIL) & (x.pointerType.resolved.typeDeclaration # NIL) THEN
 					IF (x.pointerType # NIL) & (x.pointerType.resolved.typeDeclaration # NIL) THEN
 						x.SetTypeDeclaration(x.pointerType.resolved.typeDeclaration);
 						x.SetTypeDeclaration(x.pointerType.resolved.typeDeclaration);
@@ -1114,7 +1125,7 @@ TYPE
 			- check declarations
 			- check declarations
 			- every cell type is guaranteed to have a type declaration in the module scope (anonymous or not)
 			- every cell type is guaranteed to have a type declaration in the module scope (anonymous or not)
 		**)
 		**)
-		PROCEDURE VisitCellType(x: SyntaxTree.CellType);
+		PROCEDURE VisitCellType*(x: SyntaxTree.CellType);
 		VAR
 		VAR
 			symbol: SyntaxTree.Symbol; isRealtime: BOOLEAN; parameter: SyntaxTree.Parameter; type: SyntaxTree.Type; len: LONGINT;
 			symbol: SyntaxTree.Symbol; isRealtime: BOOLEAN; parameter: SyntaxTree.Parameter; type: SyntaxTree.Type; len: LONGINT;
 			modifier: SyntaxTree.Modifier; position: Position; value: LONGINT; isEngine: BOOLEAN; property: SyntaxTree.Property;
 			modifier: SyntaxTree.Modifier; position: Position; value: LONGINT; isEngine: BOOLEAN; property: SyntaxTree.Property;
@@ -1841,7 +1852,7 @@ TYPE
 		(*** values  ***)
 		(*** values  ***)
 
 
 		(** check and resolve integer value **)
 		(** check and resolve integer value **)
-		PROCEDURE VisitIntegerValue(value: SyntaxTree.IntegerValue);
+		PROCEDURE VisitIntegerValue*(value: SyntaxTree.IntegerValue);
 		VAR hugeint: HUGEINT;
 		VAR hugeint: HUGEINT;
 		BEGIN
 		BEGIN
 			hugeint := value(SyntaxTree.IntegerValue).hvalue;
 			hugeint := value(SyntaxTree.IntegerValue).hvalue;
@@ -1850,7 +1861,7 @@ TYPE
 		END VisitIntegerValue;
 		END VisitIntegerValue;
 
 
 		(** check and resolve real value **)
 		(** check and resolve real value **)
-		PROCEDURE VisitRealValue(value: SyntaxTree.RealValue);
+		PROCEDURE VisitRealValue*(value: SyntaxTree.RealValue);
 		VAR subtype: LONGINT; type: SyntaxTree.Type;
 		VAR subtype: LONGINT; type: SyntaxTree.Type;
 		BEGIN
 		BEGIN
 			subtype := value(SyntaxTree.RealValue).subtype;
 			subtype := value(SyntaxTree.RealValue).subtype;
@@ -1866,7 +1877,7 @@ TYPE
 		END VisitRealValue;
 		END VisitRealValue;
 
 
 		(** check and resolve complex value **)
 		(** check and resolve complex value **)
-		PROCEDURE VisitComplexValue(value: SyntaxTree.ComplexValue);
+		PROCEDURE VisitComplexValue*(value: SyntaxTree.ComplexValue);
 		VAR subtype: LONGINT; type: SyntaxTree.Type;
 		VAR subtype: LONGINT; type: SyntaxTree.Type;
 		BEGIN
 		BEGIN
 			subtype := value(SyntaxTree.ComplexValue).subtype;
 			subtype := value(SyntaxTree.ComplexValue).subtype;
@@ -1882,49 +1893,49 @@ TYPE
 		END VisitComplexValue;
 		END VisitComplexValue;
 
 
 		(** check and resolve set value **)
 		(** check and resolve set value **)
-		PROCEDURE VisitSetValue(value: SyntaxTree.SetValue);
+		PROCEDURE VisitSetValue*(value: SyntaxTree.SetValue);
 		BEGIN
 		BEGIN
 			value.SetType(system.setType);
 			value.SetType(system.setType);
 			resolvedExpression := value
 			resolvedExpression := value
 		END VisitSetValue;
 		END VisitSetValue;
 
 
 		(** check and resolve set value **)
 		(** check and resolve set value **)
-		PROCEDURE VisitMathArrayValue(value: SyntaxTree.MathArrayValue);
+		PROCEDURE VisitMathArrayValue*(value: SyntaxTree.MathArrayValue);
 		BEGIN
 		BEGIN
 			value.SetType(SyntaxTree.invalidType);
 			value.SetType(SyntaxTree.invalidType);
 			resolvedExpression := value
 			resolvedExpression := value
 		END VisitMathArrayValue;
 		END VisitMathArrayValue;
 
 
 		(** check and resolve boolean value **)
 		(** check and resolve boolean value **)
-		PROCEDURE VisitBooleanValue(value: SyntaxTree.BooleanValue);
+		PROCEDURE VisitBooleanValue*(value: SyntaxTree.BooleanValue);
 		BEGIN
 		BEGIN
 			value.SetType(system.booleanType);
 			value.SetType(system.booleanType);
 			resolvedExpression := value
 			resolvedExpression := value
 		END VisitBooleanValue;
 		END VisitBooleanValue;
 
 
 		(** check and resolve string value **)
 		(** check and resolve string value **)
-		PROCEDURE VisitStringValue(value: SyntaxTree.StringValue);
+		PROCEDURE VisitStringValue*(value: SyntaxTree.StringValue);
 		BEGIN
 		BEGIN
 			value.SetType(ResolveType(SyntaxTree.NewStringType(value.position,system.characterType,value.length)));
 			value.SetType(ResolveType(SyntaxTree.NewStringType(value.position,system.characterType,value.length)));
 			resolvedExpression := value
 			resolvedExpression := value
 		END VisitStringValue;
 		END VisitStringValue;
 
 
 		(** check and resolve character value **)
 		(** check and resolve character value **)
-		PROCEDURE VisitCharacterValue(value: SyntaxTree.CharacterValue);
+		PROCEDURE VisitCharacterValue*(value: SyntaxTree.CharacterValue);
 		BEGIN
 		BEGIN
 			value.SetType(system.characterType);
 			value.SetType(system.characterType);
 			resolvedExpression := value
 			resolvedExpression := value
 		END VisitCharacterValue;
 		END VisitCharacterValue;
 
 
 		(** check and resolve nil value **)
 		(** check and resolve nil value **)
-		PROCEDURE VisitNilValue(value: SyntaxTree.NilValue);
+		PROCEDURE VisitNilValue*(value: SyntaxTree.NilValue);
 		BEGIN
 		BEGIN
 			value.SetType(system.nilType);
 			value.SetType(system.nilType);
 			resolvedExpression := value
 			resolvedExpression := value
 		END VisitNilValue;
 		END VisitNilValue;
 
 
 		(** check and resolve enumerator value **)
 		(** check and resolve enumerator value **)
-		PROCEDURE VisitEnumerationValue(value: SyntaxTree.EnumerationValue);
+		PROCEDURE VisitEnumerationValue*(value: SyntaxTree.EnumerationValue);
 		BEGIN
 		BEGIN
 			value.SetType(currentScope(SyntaxTree.EnumerationScope).ownerEnumeration);
 			value.SetType(currentScope(SyntaxTree.EnumerationScope).ownerEnumeration);
 			ASSERT(value.type # NIL);
 			ASSERT(value.type # NIL);
@@ -1939,7 +1950,7 @@ TYPE
 			- if all elements constant then return constant set value else return set expression (via global variable resolvedExpression)
 			- if all elements constant then return constant set value else return set expression (via global variable resolvedExpression)
 			if an error occurs then report error and return invalidExpression
 			if an error occurs then report error and return invalidExpression
 		**)
 		**)
-		PROCEDURE VisitSet(set: SyntaxTree.Set);
+		PROCEDURE VisitSet*(set: SyntaxTree.Set);
 		VAR
 		VAR
 			i: LONGINT;
 			i: LONGINT;
 			element: SyntaxTree.Expression;
 			element: SyntaxTree.Expression;
@@ -2091,7 +2102,7 @@ TYPE
 		END VisitMathArrayExpression;
 		END VisitMathArrayExpression;
 		*)
 		*)
 
 
-		PROCEDURE VisitMathArrayExpression(x: SyntaxTree.MathArrayExpression);
+		PROCEDURE VisitMathArrayExpression*(x: SyntaxTree.MathArrayExpression);
 		VAR type: SyntaxTree.Type; isValue: BOOLEAN;
 		VAR type: SyntaxTree.Type; isValue: BOOLEAN;
 			value: SyntaxTree.MathArrayValue; arrayType: SyntaxTree.Type;
 			value: SyntaxTree.MathArrayValue; arrayType: SyntaxTree.Type;
 
 
@@ -2184,7 +2195,7 @@ TYPE
 		END VisitMathArrayExpression;
 		END VisitMathArrayExpression;
 
 
 		(** check and resolve unary expression **)
 		(** check and resolve unary expression **)
-		PROCEDURE VisitUnaryExpression(unaryExpression: SyntaxTree.UnaryExpression);
+		PROCEDURE VisitUnaryExpression*(unaryExpression: SyntaxTree.UnaryExpression);
 		VAR
 		VAR
 			left: SyntaxTree.Expression;
 			left: SyntaxTree.Expression;
 			int: HUGEINT; real, imaginary: LONGREAL; set: SET; operator: LONGINT;
 			int: HUGEINT; real, imaginary: LONGREAL; set: SET; operator: LONGINT;
@@ -2876,7 +2887,7 @@ TYPE
 
 
 		(** check and resolve binary expression **)
 		(** check and resolve binary expression **)
 		(*! clean up *)
 		(*! clean up *)
-		PROCEDURE VisitBinaryExpression(binaryExpression: SyntaxTree.BinaryExpression);
+		PROCEDURE VisitBinaryExpression*(binaryExpression: SyntaxTree.BinaryExpression);
 		VAR left,right,result: SyntaxTree.Expression;
 		VAR left,right,result: SyntaxTree.Expression;
 			leftType, rightType: SyntaxTree.Type;
 			leftType, rightType: SyntaxTree.Type;
 			il,ir: LONGINT; rl,rr,a,b,c,d,divisor: LONGREAL; hl,hr: HUGEINT;bl,br: BOOLEAN; sl,sr: SET;  strl,strr: Scanner.StringType;
 			il,ir: LONGINT; rl,rr,a,b,c,d,divisor: LONGREAL; hl,hr: HUGEINT;bl,br: BOOLEAN; sl,sr: SET;  strl,strr: Scanner.StringType;
@@ -3407,7 +3418,7 @@ TYPE
 					- must not have step size
 					- must not have step size
 		    - if error: return invalidExpression
 		    - if error: return invalidExpression
 		**)
 		**)
-		PROCEDURE VisitRangeExpression(x: SyntaxTree.RangeExpression);
+		PROCEDURE VisitRangeExpression*(x: SyntaxTree.RangeExpression);
 		VAR
 		VAR
 			hasError: BOOLEAN;
 			hasError: BOOLEAN;
 			first, last, step: SyntaxTree.Expression;
 			first, last, step: SyntaxTree.Expression;
@@ -3534,7 +3545,7 @@ TYPE
 			END
 			END
 		END VisitRangeExpression;
 		END VisitRangeExpression;
 
 
-		PROCEDURE VisitTensorRangeExpression(x: SyntaxTree.TensorRangeExpression);
+		PROCEDURE VisitTensorRangeExpression*(x: SyntaxTree.TensorRangeExpression);
 		BEGIN
 		BEGIN
 			x.SetType(NIL);
 			x.SetType(NIL);
 			resolvedExpression := x;
 			resolvedExpression := x;
@@ -3568,7 +3579,7 @@ TYPE
 			symbol designator generated in this module
 			symbol designator generated in this module
 			nothing to be resolved
 			nothing to be resolved
 		**)
 		**)
-		PROCEDURE VisitSymbolDesignator(x: SyntaxTree.SymbolDesignator);
+		PROCEDURE VisitSymbolDesignator*(x: SyntaxTree.SymbolDesignator);
 		BEGIN
 		BEGIN
 			resolvedExpression := x;
 			resolvedExpression := x;
 		END VisitSymbolDesignator;
 		END VisitSymbolDesignator;
@@ -3577,7 +3588,7 @@ TYPE
 			self designator generated in this module
 			self designator generated in this module
 			nothing to be resolved
 			nothing to be resolved
 		**)
 		**)
-		PROCEDURE VisitSelfDesignator(x: SyntaxTree.SelfDesignator);
+		PROCEDURE VisitSelfDesignator*(x: SyntaxTree.SelfDesignator);
 		VAR scope: SyntaxTree.Scope; record: SyntaxTree.RecordType; type: SyntaxTree.Type; cell: SyntaxTree.CellType;
 		VAR scope: SyntaxTree.Scope; record: SyntaxTree.RecordType; type: SyntaxTree.Type; cell: SyntaxTree.CellType;
 		BEGIN
 		BEGIN
 			(* check if in record scope *)
 			(* check if in record scope *)
@@ -3602,7 +3613,7 @@ TYPE
 			resolvedExpression := x;
 			resolvedExpression := x;
 		END VisitSelfDesignator;
 		END VisitSelfDesignator;
 
 
-		PROCEDURE VisitResultDesignator(x: SyntaxTree.ResultDesignator);
+		PROCEDURE VisitResultDesignator*(x: SyntaxTree.ResultDesignator);
 		VAR scope: SyntaxTree.Scope; procedure: SyntaxTree.Procedure; procedureType: SyntaxTree.ProcedureType; returnType: SyntaxTree.Type;
 		VAR scope: SyntaxTree.Scope; procedure: SyntaxTree.Procedure; procedureType: SyntaxTree.ProcedureType; returnType: SyntaxTree.Type;
 		BEGIN
 		BEGIN
 			scope := currentScope;
 			scope := currentScope;
@@ -3715,7 +3726,7 @@ TYPE
 			- else find symbol in current scope
 			- else find symbol in current scope
 				- if symbol found then return SymbolDesignator, else error message and return invalidDesignator
 				- if symbol found then return SymbolDesignator, else error message and return invalidDesignator
 		**)
 		**)
-		PROCEDURE VisitIdentifierDesignator(identifierDesignator: SyntaxTree.IdentifierDesignator);
+		PROCEDURE VisitIdentifierDesignator*(identifierDesignator: SyntaxTree.IdentifierDesignator);
 		VAR symbol: SyntaxTree.Symbol;
 		VAR symbol: SyntaxTree.Symbol;
 		BEGIN
 		BEGIN
 			IF Trace THEN D.Str("VisitIdentifierDesignator "); D.Ln; END;
 			IF Trace THEN D.Str("VisitIdentifierDesignator "); D.Ln; END;
@@ -3743,7 +3754,7 @@ TYPE
 			- search symbol in computed scope
 			- search symbol in computed scope
 			returns selector designator (via global variable resolvedExpression) if symbol found, else error message is given and invalidDesignator is returned
 			returns selector designator (via global variable resolvedExpression) if symbol found, else error message is given and invalidDesignator is returned
 		**)
 		**)
-		PROCEDURE VisitSelectorDesignator(selectorDesignator: SyntaxTree.SelectorDesignator);
+		PROCEDURE VisitSelectorDesignator*(selectorDesignator: SyntaxTree.SelectorDesignator);
 		VAR
 		VAR
 			symbol: SyntaxTree.Symbol; left: SyntaxTree.Designator; scope: SyntaxTree.Scope;
 			symbol: SyntaxTree.Symbol; left: SyntaxTree.Designator; scope: SyntaxTree.Scope;
 			module: SyntaxTree.Module; result: SyntaxTree.Expression; type: SyntaxTree.Type;
 			module: SyntaxTree.Module; result: SyntaxTree.Expression; type: SyntaxTree.Type;
@@ -4366,7 +4377,7 @@ TYPE
 			Note 3: while this compiler tries to combine multiple bracket designators into a single index designator,
 			Note 3: while this compiler tries to combine multiple bracket designators into a single index designator,
 			older Oberon compilers did this the other way around: a[x, y, z] -> A[x][y][z].
 			older Oberon compilers did this the other way around: a[x, y, z] -> A[x][y][z].
 		**)
 		**)
-		PROCEDURE VisitBracketDesignator(bracketDesignator: SyntaxTree.BracketDesignator);
+		PROCEDURE VisitBracketDesignator*(bracketDesignator: SyntaxTree.BracketDesignator);
 		VAR
 		VAR
 			leftBracketDesignator: SyntaxTree.BracketDesignator;
 			leftBracketDesignator: SyntaxTree.BracketDesignator;
 			indexDesignator: SyntaxTree.IndexDesignator;
 			indexDesignator: SyntaxTree.IndexDesignator;
@@ -4699,7 +4710,7 @@ TYPE
 			builtin call designator generated in VisitParameterDesignator
 			builtin call designator generated in VisitParameterDesignator
 			-> nothing to be resolved
 			-> nothing to be resolved
 		**)
 		**)
-		PROCEDURE VisitTypeGuardDesignator(x: SyntaxTree.TypeGuardDesignator);
+		PROCEDURE VisitTypeGuardDesignator*(x: SyntaxTree.TypeGuardDesignator);
 		BEGIN
 		BEGIN
 			resolvedExpression := x;
 			resolvedExpression := x;
 		END VisitTypeGuardDesignator;
 		END VisitTypeGuardDesignator;
@@ -4708,7 +4719,7 @@ TYPE
 			builtin call designator generated in VisitParameterDesignator
 			builtin call designator generated in VisitParameterDesignator
 			-> nothing to be resolved
 			-> nothing to be resolved
 		**)
 		**)
-		PROCEDURE VisitBuiltinCallDesignator(x: SyntaxTree.BuiltinCallDesignator);
+		PROCEDURE VisitBuiltinCallDesignator*(x: SyntaxTree.BuiltinCallDesignator);
 		BEGIN
 		BEGIN
 			IF (x.returnType # NIL) & ExpressionList(x.parameters) THEN
 			IF (x.returnType # NIL) & ExpressionList(x.parameters) THEN
 				resolvedExpression := NewBuiltinCallDesignator(x.position,NIL, x.parameters,NIL, ResolveType(x.returnType));
 				resolvedExpression := NewBuiltinCallDesignator(x.position,NIL, x.parameters,NIL, ResolveType(x.returnType));
@@ -4722,7 +4733,7 @@ TYPE
 			procedure call designator generated in VisitParameterDesignator
 			procedure call designator generated in VisitParameterDesignator
 			-> nothing to be resolved
 			-> nothing to be resolved
 		**)
 		**)
-		PROCEDURE VisitProcedureCallDesignator(x: SyntaxTree.ProcedureCallDesignator);
+		PROCEDURE VisitProcedureCallDesignator*(x: SyntaxTree.ProcedureCallDesignator);
 		BEGIN
 		BEGIN
 			x.SetType(x.left.type.resolved(SyntaxTree.ProcedureType).returnType);
 			x.SetType(x.left.type.resolved(SyntaxTree.ProcedureType).returnType);
 			resolvedExpression := x;
 			resolvedExpression := x;
@@ -5295,6 +5306,9 @@ TYPE
 								UNTIL ~CheckSizeType(actualParameter) OR (actualParameter.resolved # NIL) & ~CheckPositiveIntegerValue(actualParameter,i0,TRUE) OR (i=numberActualParameters);
 								UNTIL ~CheckSizeType(actualParameter) OR (actualParameter.resolved # NIL) & ~CheckPositiveIntegerValue(actualParameter,i0,TRUE) OR (i=numberActualParameters);
 							END;
 							END;
 						ELSIF (type0 IS SyntaxTree.RecordType) THEN
 						ELSIF (type0 IS SyntaxTree.RecordType) THEN
+							IF type0(SyntaxTree.RecordType).isAbstract THEN
+								Error(position, "forbidden new on abstract object");
+							END;
 							constructor := GetConstructor(type0(SyntaxTree.RecordType));
 							constructor := GetConstructor(type0(SyntaxTree.RecordType));
 							IF constructor = NIL THEN
 							IF constructor = NIL THEN
 								IF CheckArity(first,first) THEN END;
 								IF CheckArity(first,first) THEN END;
@@ -6282,7 +6296,7 @@ TYPE
 				- else return is a procedure call then return ProcedureCallDesignator
 				- else return is a procedure call then return ProcedureCallDesignator
 			returns invalidDesignator = invalidExpression if error
 			returns invalidDesignator = invalidExpression if error
 		**)
 		**)
-		PROCEDURE VisitParameterDesignator(designator: SyntaxTree.ParameterDesignator);
+		PROCEDURE VisitParameterDesignator*(designator: SyntaxTree.ParameterDesignator);
 		VAR
 		VAR
 			parameters: SyntaxTree.ExpressionList;
 			parameters: SyntaxTree.ExpressionList;
 			left: SyntaxTree.Designator;
 			left: SyntaxTree.Designator;
@@ -6437,7 +6451,7 @@ TYPE
 			returns result via global variable resolvedExpression
 			returns result via global variable resolvedExpression
 			error handling deferred to procedures SupercallDesignator and DereferenceDesignator
 			error handling deferred to procedures SupercallDesignator and DereferenceDesignator
 		**)
 		**)
-		PROCEDURE VisitArrowDesignator(arrowDesignator: SyntaxTree.ArrowDesignator);
+		PROCEDURE VisitArrowDesignator*(arrowDesignator: SyntaxTree.ArrowDesignator);
 		VAR left: SyntaxTree.Designator;
 		VAR left: SyntaxTree.Designator;
 		BEGIN
 		BEGIN
 			IF Trace THEN D.Str("VisitArrowDesignator"); D.Ln; END;
 			IF Trace THEN D.Str("VisitArrowDesignator"); D.Ln; END;
@@ -6587,7 +6601,7 @@ TYPE
 				scope := scope.outerScope;
 				scope := scope.outerScope;
 			END;
 			END;
 			IF (scope # NIL) THEN (* symbol (directly or indirectly) in procedure scope *)
 			IF (scope # NIL) THEN (* symbol (directly or indirectly) in procedure scope *)
-				IF (symbol.access * SyntaxTree.Public # {}) & (~(symbol IS SyntaxTree.Procedure) OR  ~symbol(SyntaxTree.Procedure).isBodyProcedure & ~symbol(SyntaxTree.Procedure).isConstructor & ~symbol(SyntaxTree.Procedure).isFinalizer)  THEN
+				IF (symbol.access * SyntaxTree.Public # {}) & (~(symbol IS SyntaxTree.Procedure) OR  ~symbol(SyntaxTree.Procedure).isBodyProcedure & ~symbol(SyntaxTree.Procedure).isConstructor & ~symbol(SyntaxTree.Procedure).isFinalizer) & ~((symbol(SyntaxTree.Procedure).super # NIL) & (symbol(SyntaxTree.Procedure).super.access * SyntaxTree.Public # {})) THEN
 					Error(symbol.position,"cannot be exported");
 					Error(symbol.position,"cannot be exported");
 					IF VerboseErrorMessage THEN
 					IF VerboseErrorMessage THEN
 						Printout.Info("symbol",symbol);
 						Printout.Info("symbol",symbol);
@@ -6624,7 +6638,7 @@ TYPE
 			- resolve and set declared type
 			- resolve and set declared type
 			- check symbol
 			- check symbol
 		**)
 		**)
-		PROCEDURE VisitTypeDeclaration(typeDeclaration: SyntaxTree.TypeDeclaration);
+		PROCEDURE VisitTypeDeclaration*(typeDeclaration: SyntaxTree.TypeDeclaration);
 		VAR prevScope: SyntaxTree.Scope;
 		VAR prevScope: SyntaxTree.Scope;
 		BEGIN
 		BEGIN
 			IF Trace THEN D.Str("VisitTypeDeclaration "); D.Str0(typeDeclaration.name);  D.Ln;  END;
 			IF Trace THEN D.Str("VisitTypeDeclaration "); D.Str0(typeDeclaration.name);  D.Ln;  END;
@@ -6645,7 +6659,7 @@ TYPE
 			- set type and value
 			- set type and value
 			- check symbol
 			- check symbol
 		**)
 		**)
-		PROCEDURE VisitConstant(constant: SyntaxTree.Constant);
+		PROCEDURE VisitConstant*(constant: SyntaxTree.Constant);
 		VAR
 		VAR
 			expression: SyntaxTree.Expression;
 			expression: SyntaxTree.Expression;
 			type: SyntaxTree.Type;
 			type: SyntaxTree.Type;
@@ -6718,7 +6732,7 @@ TYPE
 			- negative check on open array type
 			- negative check on open array type
 			- check symbol
 			- check symbol
 		**)
 		**)
-		PROCEDURE VisitVariable(variable: SyntaxTree.Variable);
+		PROCEDURE VisitVariable*(variable: SyntaxTree.Variable);
 		VAR modifiers: SyntaxTree.Modifier; value: LONGINT; position: Position; pointerType: SyntaxTree.PointerType;
 		VAR modifiers: SyntaxTree.Modifier; value: LONGINT; position: Position; pointerType: SyntaxTree.PointerType;
 		BEGIN
 		BEGIN
 			IF Trace THEN D.Str("VisitVariable "); D.Str0(variable.name);  D.Ln;  END;
 			IF Trace THEN D.Str("VisitVariable "); D.Str0(variable.name);  D.Ln;  END;
@@ -6786,7 +6800,7 @@ TYPE
 			END;
 			END;
 		END VisitVariable;
 		END VisitVariable;
 
 
-		PROCEDURE VisitProperty(property: SyntaxTree.Property);
+		PROCEDURE VisitProperty*(property: SyntaxTree.Property);
 		BEGIN
 		BEGIN
 			VisitVariable(property)
 			VisitVariable(property)
 		END VisitProperty;
 		END VisitProperty;
@@ -6797,7 +6811,7 @@ TYPE
 			- check symbol
 			- check symbol
 			- check parameter kind and set read-only flags if appropriate
 			- check parameter kind and set read-only flags if appropriate
 		**)
 		**)
-		PROCEDURE VisitParameter(parameter: SyntaxTree.Parameter);
+		PROCEDURE VisitParameter*(parameter: SyntaxTree.Parameter);
 		VAR modifiers: SyntaxTree.Modifier; expression: SyntaxTree.Expression; position: Position;
 		VAR modifiers: SyntaxTree.Modifier; expression: SyntaxTree.Expression; position: Position;
 		BEGIN
 		BEGIN
 			IF Trace THEN D.Str("VisitParameter "); D.Str0(parameter.name);  D.Ln;  END;
 			IF Trace THEN D.Str("VisitParameter "); D.Str0(parameter.name);  D.Ln;  END;
@@ -6854,7 +6868,7 @@ TYPE
 			- check declarations (including a delayed implementation check, cf procedure Declarations)
 			- check declarations (including a delayed implementation check, cf procedure Declarations)
 			- check procedure symbol
 			- check procedure symbol
 		**)
 		**)
-		PROCEDURE VisitProcedure(procedure: SyntaxTree.Procedure);
+		PROCEDURE VisitProcedure*(procedure: SyntaxTree.Procedure);
 		VAR super,proc: SyntaxTree.Procedure; record: SyntaxTree.RecordType;
 		VAR super,proc: SyntaxTree.Procedure; record: SyntaxTree.RecordType;
 			procedureType: SyntaxTree.ProcedureType;
 			procedureType: SyntaxTree.ProcedureType;
 			type: SyntaxTree.Type;
 			type: SyntaxTree.Type;
@@ -6942,8 +6956,6 @@ TYPE
 					Error(procedure.position,"problems during parameter offset computation");
 					Error(procedure.position,"problems during parameter offset computation");
 				END;
 				END;
 
 
-				CheckSymbolVisibility(procedure);
-
 				IF procedure.scope IS SyntaxTree.ProcedureScope THEN
 				IF procedure.scope IS SyntaxTree.ProcedureScope THEN
 					procedure.SetLevel(procedure.scope(SyntaxTree.ProcedureScope).ownerProcedure.level+1);
 					procedure.SetLevel(procedure.scope(SyntaxTree.ProcedureScope).ownerProcedure.level+1);
 					IF ~system.GenerateParameterOffsets(procedure,TRUE) THEN
 					IF ~system.GenerateParameterOffsets(procedure,TRUE) THEN
@@ -7016,6 +7028,9 @@ TYPE
 						IF super.isFinal THEN
 						IF super.isFinal THEN
 							Error(procedure.position,"forbidden method extending final method");
 							Error(procedure.position,"forbidden method extending final method");
 						END;
 						END;
+						IF super.access # procedure.access THEN
+							Warning(procedure.position, "forbiden visibility mismatch of method and super method");
+						END;
 						procedure.SetSuper(super);
 						procedure.SetSuper(super);
 						super.SetOverwritten(TRUE);
 						super.SetOverwritten(TRUE);
 						procedure.SetAccess(procedure.access+super.access);
 						procedure.SetAccess(procedure.access+super.access);
@@ -7035,6 +7050,7 @@ TYPE
 				ELSIF procedure.isConstructor THEN
 				ELSIF procedure.isConstructor THEN
 					Error(procedure.position,"procedure illegaly marked as initializer - not in object scope");
 					Error(procedure.position,"procedure illegaly marked as initializer - not in object scope");
 				END;
 				END;
+				CheckSymbolVisibility(procedure);
 				Declarations(procedure.procedureScope, FALSE, {0,1});
 				Declarations(procedure.procedureScope, FALSE, {0,1});
 				(* body resolution part done as late fix of the procedure type *)
 				(* body resolution part done as late fix of the procedure type *)
 				procedure.SetState(SyntaxTree.Resolved);
 				procedure.SetState(SyntaxTree.Resolved);
@@ -7047,7 +7063,7 @@ TYPE
 			a builtin procedure is a global item that may not be modified locally
 			a builtin procedure is a global item that may not be modified locally
 			instead the resolving of builtin procedure calls are done in the esignator
 			instead the resolving of builtin procedure calls are done in the esignator
 		**)
 		**)
-		PROCEDURE VisitBuiltin(builtinProcedure: SyntaxTree.Builtin);
+		PROCEDURE VisitBuiltin*(builtinProcedure: SyntaxTree.Builtin);
 		VAR type: SyntaxTree.Type;
 		VAR type: SyntaxTree.Type;
 		BEGIN
 		BEGIN
 			type := ResolveType(builtinProcedure.type);
 			type := ResolveType(builtinProcedure.type);
@@ -7062,7 +7078,7 @@ TYPE
 				array-structured object types and checked in 'ResolveArrayStructure')
 				array-structured object types and checked in 'ResolveArrayStructure')
 			- also note that inter-operator conformity is not checked here
 			- also note that inter-operator conformity is not checked here
 		**)
 		**)
-		PROCEDURE VisitOperator(operator: SyntaxTree.Operator);
+		PROCEDURE VisitOperator*(operator: SyntaxTree.Operator);
 		VAR
 		VAR
 			procedureType: SyntaxTree.ProcedureType;
 			procedureType: SyntaxTree.ProcedureType;
 			leftType, rightType: SyntaxTree.Type;
 			leftType, rightType: SyntaxTree.Type;
@@ -7254,7 +7270,7 @@ TYPE
 			- enter re-imports into list of imported modules as non-direct import (if not in direct import list)
 			- enter re-imports into list of imported modules as non-direct import (if not in direct import list)
 			- after this import this direct import and all indirect imports are stored in the current module's import list
 			- after this import this direct import and all indirect imports are stored in the current module's import list
 		**)
 		**)
-		PROCEDURE VisitImport(x: SyntaxTree.Import);
+		PROCEDURE VisitImport*(x: SyntaxTree.Import);
 		VAR
 		VAR
 			module: SyntaxTree.Module;
 			module: SyntaxTree.Module;
 			moduleScope: SyntaxTree.ModuleScope;
 			moduleScope: SyntaxTree.ModuleScope;
@@ -7401,7 +7417,7 @@ TYPE
 			- check if procedure is callable
 			- check if procedure is callable
 			- check return type = NIL (otherwise must be assignment statement)
 			- check return type = NIL (otherwise must be assignment statement)
 		**)
 		**)
-		PROCEDURE VisitProcedureCallStatement(procedureCall: SyntaxTree.ProcedureCallStatement);
+		PROCEDURE VisitProcedureCallStatement*(procedureCall: SyntaxTree.ProcedureCallStatement);
 		VAR call: SyntaxTree.Designator;
 		VAR call: SyntaxTree.Designator;
 		BEGIN
 		BEGIN
 			IF Trace THEN D.Str("VisitProcedureCallStatement"); D.Ln; END;
 			IF Trace THEN D.Str("VisitProcedureCallStatement"); D.Ln; END;
@@ -7453,7 +7469,7 @@ TYPE
 				- assignment to ASOT elements:
 				- assignment to ASOT elements:
 					asot[indexList] := rhs; -> asot^."[]"(indexList, rhs);
 					asot[indexList] := rhs; -> asot^."[]"(indexList, rhs);
 		**)
 		**)
-		PROCEDURE VisitAssignment(assignment: SyntaxTree.Assignment);
+		PROCEDURE VisitAssignment*(assignment: SyntaxTree.Assignment);
 		VAR
 		VAR
 			left: SyntaxTree.Designator;
 			left: SyntaxTree.Designator;
 			right, expression: SyntaxTree.Expression;
 			right, expression: SyntaxTree.Expression;
@@ -7521,7 +7537,7 @@ TYPE
 				- assignment to ASOT elements:
 				- assignment to ASOT elements:
 					asot[indexList] := rhs; -> asot^."[]"(indexList, rhs);
 					asot[indexList] := rhs; -> asot^."[]"(indexList, rhs);
 		**)
 		**)
-		PROCEDURE VisitCommunicationStatement(communication: SyntaxTree.CommunicationStatement);
+		PROCEDURE VisitCommunicationStatement*(communication: SyntaxTree.CommunicationStatement);
 		VAR
 		VAR
 			left: SyntaxTree.Designator;
 			left: SyntaxTree.Designator;
 			right: SyntaxTree.Expression;
 			right: SyntaxTree.Expression;
@@ -7618,7 +7634,7 @@ TYPE
 		(** check and resolve if statement
 		(** check and resolve if statement
 			- check if parts and else part statement sequence
 			- check if parts and else part statement sequence
 		**)
 		**)
-		PROCEDURE VisitIfStatement(ifStatement: SyntaxTree.IfStatement);
+		PROCEDURE VisitIfStatement*(ifStatement: SyntaxTree.IfStatement);
 		VAR elsif: SyntaxTree.IfPart; i: LONGINT; ifPartTrue, prevUnreachable: BOOLEAN;
 		VAR elsif: SyntaxTree.IfPart; i: LONGINT; ifPartTrue, prevUnreachable: BOOLEAN;
 		BEGIN
 		BEGIN
 			prevUnreachable := currentIsUnreachable;
 			prevUnreachable := currentIsUnreachable;
@@ -7697,7 +7713,7 @@ TYPE
 			- create if statement:
 			- create if statement:
 				WITH variable: type DO ... END; 	--> IF ~(variable IS type) THEN HALT(withTrap) ELSE ... END;
 				WITH variable: type DO ... END; 	--> IF ~(variable IS type) THEN HALT(withTrap) ELSE ... END;
 		**)
 		**)
-		PROCEDURE VisitWithStatement(withStatement: SyntaxTree.WithStatement);
+		PROCEDURE VisitWithStatement*(withStatement: SyntaxTree.WithStatement);
 		VAR i: LONGINT; prevScope: SyntaxTree.Scope; symbol: SyntaxTree.Symbol;
 		VAR i: LONGINT; prevScope: SyntaxTree.Scope; symbol: SyntaxTree.Symbol;
 		BEGIN
 		BEGIN
 			prevScope := currentScope; symbol := NIL;
 			prevScope := currentScope; symbol := NIL;
@@ -7806,7 +7822,7 @@ TYPE
 			- check variable
 			- check variable
 			- check case parts
 			- check case parts
 		**)
 		**)
-		PROCEDURE VisitCaseStatement(caseStatement: SyntaxTree.CaseStatement);
+		PROCEDURE VisitCaseStatement*(caseStatement: SyntaxTree.CaseStatement);
 		VAR expression: SyntaxTree.Expression; i: LONGINT; type: SyntaxTree.Type; caseList: SyntaxTree.CaseConstant;
 		VAR expression: SyntaxTree.Expression; i: LONGINT; type: SyntaxTree.Type; caseList: SyntaxTree.CaseConstant;
 			ch: CHAR; l: LONGINT; min,max: LONGINT; msg: ARRAY 64 OF CHAR;
 			ch: CHAR; l: LONGINT; min,max: LONGINT; msg: ARRAY 64 OF CHAR;
 		BEGIN
 		BEGIN
@@ -7857,7 +7873,7 @@ TYPE
 			- check condition
 			- check condition
 			- check statement sequence
 			- check statement sequence
 		**)
 		**)
-		PROCEDURE VisitWhileStatement(whileStatement: SyntaxTree.WhileStatement);
+		PROCEDURE VisitWhileStatement*(whileStatement: SyntaxTree.WhileStatement);
 		VAR prevIsUnreachable,b: BOOLEAN;
 		VAR prevIsUnreachable,b: BOOLEAN;
 		BEGIN
 		BEGIN
 			prevIsUnreachable := currentIsUnreachable;
 			prevIsUnreachable := currentIsUnreachable;
@@ -7875,7 +7891,7 @@ TYPE
 			- check condition
 			- check condition
 			- check statement sequence
 			- check statement sequence
 		**)
 		**)
-		PROCEDURE VisitRepeatStatement(repeatStatement: SyntaxTree.RepeatStatement);
+		PROCEDURE VisitRepeatStatement*(repeatStatement: SyntaxTree.RepeatStatement);
 		BEGIN
 		BEGIN
 			repeatStatement.SetCondition(ResolveCondition(repeatStatement.condition));
 			repeatStatement.SetCondition(ResolveCondition(repeatStatement.condition));
 			StatementSequence(repeatStatement.statements);
 			StatementSequence(repeatStatement.statements);
@@ -7902,7 +7918,7 @@ TYPE
 			- check that to has compatible type
 			- check that to has compatible type
 			- check that by is constant integer with compatible type
 			- check that by is constant integer with compatible type
 		**)
 		**)
-		PROCEDURE VisitForStatement(forStatement: SyntaxTree.ForStatement);
+		PROCEDURE VisitForStatement*(forStatement: SyntaxTree.ForStatement);
 		VAR expression: SyntaxTree.Expression; designator: SyntaxTree.Designator; type: SyntaxTree.Type;
 		VAR expression: SyntaxTree.Expression; designator: SyntaxTree.Designator; type: SyntaxTree.Type;
 		BEGIN
 		BEGIN
 			designator := ResolveDesignator(forStatement.variable);
 			designator := ResolveDesignator(forStatement.variable);
@@ -7960,12 +7976,12 @@ TYPE
 		(** check and resolve loop statement LOOP StatementSequence END
 		(** check and resolve loop statement LOOP StatementSequence END
 			- check statement sequence
 			- check statement sequence
 		**)
 		**)
-		PROCEDURE VisitLoopStatement(loopStatement: SyntaxTree.LoopStatement);
+		PROCEDURE VisitLoopStatement*(loopStatement: SyntaxTree.LoopStatement);
 		BEGIN
 		BEGIN
 			StatementSequence(loopStatement.statements)
 			StatementSequence(loopStatement.statements)
 		END VisitLoopStatement;
 		END VisitLoopStatement;
 
 
-		PROCEDURE VisitExitableBlock(exitableBlock: SyntaxTree.ExitableBlock);
+		PROCEDURE VisitExitableBlock*(exitableBlock: SyntaxTree.ExitableBlock);
 		BEGIN
 		BEGIN
 			StatementSequence(exitableBlock.statements);
 			StatementSequence(exitableBlock.statements);
 		END VisitExitableBlock;
 		END VisitExitableBlock;
@@ -7974,7 +7990,7 @@ TYPE
 		(** check and resolve exit statement EXIT
 		(** check and resolve exit statement EXIT
 			- check that exit is within LOOP statement block
 			- check that exit is within LOOP statement block
 		**)
 		**)
-		PROCEDURE VisitExitStatement(exitStatement: SyntaxTree.ExitStatement);
+		PROCEDURE VisitExitStatement*(exitStatement: SyntaxTree.ExitStatement);
 		VAR outer: SyntaxTree.Statement;
 		VAR outer: SyntaxTree.Statement;
 		BEGIN
 		BEGIN
 			outer := exitStatement.outer;
 			outer := exitStatement.outer;
@@ -7992,7 +8008,7 @@ TYPE
 				- if in procedure scope then check expression compatibility
 				- if in procedure scope then check expression compatibility
 				- if not in procecdure scope then check on return without expression
 				- if not in procecdure scope then check on return without expression
 		**)
 		**)
-		PROCEDURE VisitReturnStatement(returnStatement: SyntaxTree.ReturnStatement);
+		PROCEDURE VisitReturnStatement*(returnStatement: SyntaxTree.ReturnStatement);
 		VAR expression: SyntaxTree.Expression; position: Position; procedure: SyntaxTree.Procedure;
 		VAR expression: SyntaxTree.Expression; position: Position; procedure: SyntaxTree.Procedure;
 			returnType: SyntaxTree.Type; outer: SyntaxTree.Statement; scope: SyntaxTree.Scope;
 			returnType: SyntaxTree.Type; outer: SyntaxTree.Statement; scope: SyntaxTree.Scope;
 		BEGIN
 		BEGIN
@@ -8044,7 +8060,7 @@ TYPE
 		(** check and resolve await statement AWAIT(condition: Expression)
 		(** check and resolve await statement AWAIT(condition: Expression)
 			- check await condition
 			- check await condition
 		**)
 		**)
-		PROCEDURE VisitAwaitStatement(awaitStatement: SyntaxTree.AwaitStatement);
+		PROCEDURE VisitAwaitStatement*(awaitStatement: SyntaxTree.AwaitStatement);
 		VAR condition: SyntaxTree.Expression;
 		VAR condition: SyntaxTree.Expression;
 		BEGIN
 		BEGIN
 			condition := ResolveCondition(awaitStatement.condition);
 			condition := ResolveCondition(awaitStatement.condition);
@@ -8072,7 +8088,7 @@ TYPE
 
 
 		(** check and resolve code statement: do nothing, must be done by assembler
 		(** check and resolve code statement: do nothing, must be done by assembler
 		**)
 		**)
-		PROCEDURE VisitCode(code: SyntaxTree.Code);
+		PROCEDURE VisitCode*(code: SyntaxTree.Code);
 		VAR i: LONGINT; statement: SyntaxTree.Statement;
 		VAR i: LONGINT; statement: SyntaxTree.Statement;
 		BEGIN
 		BEGIN
 			CheckSystemImport(code.position);
 			CheckSystemImport(code.position);
@@ -8205,7 +8221,7 @@ TYPE
 			- check flags (exclusive)
 			- check flags (exclusive)
 			- check statement sequence
 			- check statement sequence
 		**)
 		**)
-		PROCEDURE VisitStatementBlock(statementBlock: SyntaxTree.StatementBlock);
+		PROCEDURE VisitStatementBlock*(statementBlock: SyntaxTree.StatementBlock);
 		VAR recentExclusive, recentUnreachable, recentRealtime: BOOLEAN;
 		VAR recentExclusive, recentUnreachable, recentRealtime: BOOLEAN;
 		BEGIN
 		BEGIN
 			BlockFlags(statementBlock);
 			BlockFlags(statementBlock);
@@ -8718,7 +8734,7 @@ TYPE
 			SELF.diagnostics := diagnostics
 			SELF.diagnostics := diagnostics
 		END InitWarnings;
 		END InitWarnings;
 
 
-		PROCEDURE VisitPortType(x: SyntaxTree.PortType);
+		PROCEDURE VisitPortType*(x: SyntaxTree.PortType);
 		BEGIN	END VisitPortType;
 		BEGIN	END VisitPortType;
 
 
 		(** types *)
 		(** types *)
@@ -10177,6 +10193,8 @@ TYPE
 	BEGIN
 	BEGIN
 		RETURN (procedureType # NIL) & (procedureType.callingConvention=SyntaxTree.OberonCallingConvention) & ReturnedAsParameter(procedureType.returnType);
 		RETURN (procedureType # NIL) & (procedureType.callingConvention=SyntaxTree.OberonCallingConvention) & ReturnedAsParameter(procedureType.returnType);
 	END StructuredReturnType;
 	END StructuredReturnType;
+	
+	
 
 
 
 
 
 

+ 74 - 26
source/FoxSyntaxTree.Mod

@@ -575,7 +575,7 @@ TYPE
 		BEGIN position := SELF.position.start; v.VisitObjectType(SELF)
 		BEGIN position := SELF.position.start; v.VisitObjectType(SELF)
 		END Accept;
 		END Accept;
 
 
-		PROCEDURE IsPointer(): BOOLEAN;
+		PROCEDURE IsPointer*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsPointer;
 		END IsPointer;
 
 
@@ -601,7 +601,7 @@ TYPE
 		BEGIN RETURN (to IS NilType) OR (to IS ObjectType) OR (to IS AnyType) OR (to IS PointerType) OR (to IS ProcedureType) OR (to IS AddressType)
 		BEGIN RETURN (to IS NilType) OR (to IS ObjectType) OR (to IS AnyType) OR (to IS PointerType) OR (to IS ProcedureType) OR (to IS AddressType)
 		END CompatibleTo;
 		END CompatibleTo;
 
 
-		PROCEDURE IsPointer(): BOOLEAN;
+		PROCEDURE IsPointer*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsPointer;
 		END IsPointer;
 
 
@@ -630,7 +630,7 @@ TYPE
 		BEGIN RETURN (to IS AnyType)
 		BEGIN RETURN (to IS AnyType)
 		END CompatibleTo;
 		END CompatibleTo;
 
 
-		PROCEDURE IsPointer(): BOOLEAN;
+		PROCEDURE IsPointer*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsPointer;
 		END IsPointer;
 
 
@@ -813,7 +813,7 @@ TYPE
 		BEGIN RETURN SameType(to)
 		BEGIN RETURN SameType(to)
 		END CompatibleTo;
 		END CompatibleTo;
 
 
-		PROCEDURE IsComposite(): BOOLEAN;
+		PROCEDURE IsComposite*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsComposite;
 		END IsComposite;
 
 
@@ -915,7 +915,7 @@ TYPE
 		BEGIN RETURN (to IS ComplexType) & (componentType.CompatibleTo(to(ComplexType).componentType))
 		BEGIN RETURN (to IS ComplexType) & (componentType.CompatibleTo(to(ComplexType).componentType))
 		END CompatibleTo;
 		END CompatibleTo;
 
 
-		PROCEDURE IsComposite(): BOOLEAN;
+		PROCEDURE IsComposite*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsComposite;
 		END IsComposite;
 
 
@@ -954,11 +954,11 @@ TYPE
 		BEGIN RETURN (resolved # NIL) & resolved.CompatibleTo(to)
 		BEGIN RETURN (resolved # NIL) & resolved.CompatibleTo(to)
 		END CompatibleTo;
 		END CompatibleTo;
 
 
-		PROCEDURE IsPointer(): BOOLEAN;
+		PROCEDURE IsPointer*(): BOOLEAN;
 		BEGIN RETURN (resolved # NIL) & resolved.IsPointer()
 		BEGIN RETURN (resolved # NIL) & resolved.IsPointer()
 		END IsPointer;
 		END IsPointer;
 
 
-		PROCEDURE IsComposite(): BOOLEAN;
+		PROCEDURE IsComposite*(): BOOLEAN;
 		BEGIN RETURN (resolved # NIL) & resolved.IsComposite()
 		BEGIN RETURN (resolved # NIL) & resolved.IsComposite()
 		END IsComposite;
 		END IsComposite;
 
 
@@ -971,7 +971,7 @@ TYPE
 		BEGIN RETURN (resolved # NIL) & (resolved.NeedsTrace());
 		BEGIN RETURN (resolved # NIL) & (resolved.NeedsTrace());
 		END NeedsTrace;
 		END NeedsTrace;
 		
 		
-		PROCEDURE IsRecordType(): BOOLEAN;
+		PROCEDURE IsRecordType*(): BOOLEAN;
 		BEGIN
 		BEGIN
 			RETURN (resolved # NIL) & (resolved.IsRecordType());
 			RETURN (resolved # NIL) & (resolved.IsRecordType());
 		END IsRecordType;
 		END IsRecordType;
@@ -1013,7 +1013,7 @@ TYPE
 			END;
 			END;
 		END CompatibleTo;
 		END CompatibleTo;
 
 
-		PROCEDURE IsComposite(): BOOLEAN;
+		PROCEDURE IsComposite*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsComposite;
 		END IsComposite;
 
 
@@ -1136,7 +1136,7 @@ TYPE
 			RETURN (form = Static) & SameType(to)
 			RETURN (form = Static) & SameType(to)
 		END CompatibleTo;
 		END CompatibleTo;
 
 
-		PROCEDURE IsComposite(): BOOLEAN;
+		PROCEDURE IsComposite*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsComposite;
 		END IsComposite;
 
 
@@ -1280,7 +1280,7 @@ TYPE
 		BEGIN RETURN hasPointers OR (arrayBase # NIL) & (arrayBase.resolved.NeedsTrace());
 		BEGIN RETURN hasPointers OR (arrayBase # NIL) & (arrayBase.resolved.NeedsTrace());
 		END NeedsTrace;
 		END NeedsTrace;
 		
 		
-		PROCEDURE IsComposite(): BOOLEAN;
+		PROCEDURE IsComposite*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsComposite;
 		END IsComposite;
 
 
@@ -1378,7 +1378,7 @@ TYPE
 		BEGIN	RETURN SameType(to) OR ~(to IS RecordType) & SELF.Extends(to)
 		BEGIN	RETURN SameType(to) OR ~(to IS RecordType) & SELF.Extends(to)
 		END CompatibleTo;
 		END CompatibleTo;
 
 
-		PROCEDURE IsPointer(): BOOLEAN;
+		PROCEDURE IsPointer*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsPointer;
 		END IsPointer;
 		
 		
@@ -1432,7 +1432,7 @@ TYPE
 		BEGIN	RETURN SameType(to)
 		BEGIN	RETURN SameType(to)
 		END CompatibleTo;
 		END CompatibleTo;
 		
 		
-		PROCEDURE IsPointer(): BOOLEAN;
+		PROCEDURE IsPointer*(): BOOLEAN;
 		BEGIN RETURN cellsAreObjects;
 		BEGIN RETURN cellsAreObjects;
 		END IsPointer;
 		END IsPointer;
 
 
@@ -1454,6 +1454,7 @@ TYPE
 			pointerType-: PointerType; (* for support of A = POINTER TO RECORD ... END and B = POINTER TO RECORD (A) END; *)
 			pointerType-: PointerType; (* for support of A = POINTER TO RECORD ... END and B = POINTER TO RECORD (A) END; *)
 			modifiers-: Modifier;
 			modifiers-: Modifier;
 			isObject-,isProtected: BOOLEAN;
 			isObject-,isProtected: BOOLEAN;
+			isAbstract-: BOOLEAN;
 
 
 			(* a math array type describing an object's array structure; NIL if the type does not exhibit an array structure *)
 			(* a math array type describing an object's array structure; NIL if the type does not exhibit an array structure *)
 			arrayStructure-: MathArrayType;
 			arrayStructure-: MathArrayType;
@@ -1473,7 +1474,13 @@ TYPE
 			isObject := FALSE; isProtected := FALSE;
 			isObject := FALSE; isProtected := FALSE;
 			arrayStructure := NIL;
 			arrayStructure := NIL;
 			modifiers := NIL;
 			modifiers := NIL;
+			isAbstract := FALSE;
 		END InitRecordType;
 		END InitRecordType;
+		
+		PROCEDURE SetAbstract*(abstract: BOOLEAN);
+		BEGIN
+			isAbstract := abstract;
+		END SetAbstract;
 
 
 		PROCEDURE SetModifiers*(flag: Modifier);
 		PROCEDURE SetModifiers*(flag: Modifier);
 		BEGIN SELF.modifiers := flag;
 		BEGIN SELF.modifiers := flag;
@@ -1577,7 +1584,7 @@ TYPE
 		BEGIN RETURN (arrayStructure # NIL)
 		BEGIN RETURN (arrayStructure # NIL)
 		END HasArrayStructure
 		END HasArrayStructure
 		;
 		;
-		PROCEDURE IsComposite(): BOOLEAN;
+		PROCEDURE IsComposite*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsComposite;
 		END IsComposite;
 
 
@@ -1590,7 +1597,7 @@ TYPE
 		BEGIN position := SELF.position.start; v.VisitRecordType(SELF)
 		BEGIN position := SELF.position.start; v.VisitRecordType(SELF)
 		END Accept;
 		END Accept;
 		
 		
-		PROCEDURE IsRecordType(): BOOLEAN;
+		PROCEDURE IsRecordType*(): BOOLEAN;
 		BEGIN
 		BEGIN
 			RETURN TRUE;
 			RETURN TRUE;
 		END IsRecordType;
 		END IsRecordType;
@@ -1707,7 +1714,7 @@ TYPE
 		BEGIN RETURN SameType(to)
 		BEGIN RETURN SameType(to)
 		END CompatibleTo;
 		END CompatibleTo;
 
 
-		PROCEDURE IsComposite(): BOOLEAN;
+		PROCEDURE IsComposite*(): BOOLEAN;
 		BEGIN RETURN TRUE
 		BEGIN RETURN TRUE
 		END IsComposite;
 		END IsComposite;
 
 
@@ -1880,7 +1887,7 @@ TYPE
 			RETURN SameType(to) & (~isDelegate OR to(ProcedureType).isDelegate) & (~to.isRealtime OR isRealtime);
 			RETURN SameType(to) & (~isDelegate OR to(ProcedureType).isDelegate) & (~to.isRealtime OR isRealtime);
 		END CompatibleTo;
 		END CompatibleTo;
 
 
-		PROCEDURE IsComposite(): BOOLEAN;
+		PROCEDURE IsComposite*(): BOOLEAN;
 		BEGIN RETURN isDelegate
 		BEGIN RETURN isDelegate
 		END IsComposite;
 		END IsComposite;
 
 
@@ -3490,7 +3497,7 @@ TYPE
 		BEGIN SELF.methodNumber := methodNumber
 		BEGIN SELF.methodNumber := methodNumber
 		END SetMethodNumber;
 		END SetMethodNumber;
 
 
-		PROCEDURE NeedsSection(): BOOLEAN;
+		PROCEDURE NeedsSection*(): BOOLEAN;
 		BEGIN
 		BEGIN
 			RETURN (access * Public # {}) OR (methodNumber >= 0);
 			RETURN (access * Public # {}) OR (methodNumber >= 0);
 		END NeedsSection;
 		END NeedsSection;
@@ -4506,7 +4513,7 @@ TYPE
 		END SetCode;
 		END SetCode;
 
 
 	END Body;
 	END Body;
-
+		
 	(** (* comment *)  *)
 	(** (* comment *)  *)
 	Comment*=OBJECT
 	Comment*=OBJECT
 	VAR position-: Position;
 	VAR position-: Position;
@@ -4541,6 +4548,7 @@ TYPE
 	Scope*=OBJECT
 	Scope*=OBJECT
 		VAR
 		VAR
 		firstSymbol-: Symbol; numberSymbols-: LONGINT; (* all symbols in scope (sorted) *)
 		firstSymbol-: Symbol; numberSymbols-: LONGINT; (* all symbols in scope (sorted) *)
+		symbolTable: Basic.HashTableInt;
 
 
 		firstConstant-,lastConstant-: Constant;  numberConstants-: LONGINT; (* constants *)
 		firstConstant-,lastConstant-: Constant;  numberConstants-: LONGINT; (* constants *)
 		firstTypeDeclaration-,lastTypeDeclaration-: TypeDeclaration; numberTypeDeclarations-: LONGINT; (* type declarations *)
 		firstTypeDeclaration-,lastTypeDeclaration-: TypeDeclaration; numberTypeDeclarations-: LONGINT; (* type declarations *)
@@ -4568,6 +4576,7 @@ TYPE
 				ownerModule := NIL;
 				ownerModule := NIL;
 			END;
 			END;
 			nextScope := NIL;
 			nextScope := NIL;
+			NEW(symbolTable,11);
 		END InitScope;
 		END InitScope;
 		
 		
 		PROCEDURE Clear*;
 		PROCEDURE Clear*;
@@ -4596,17 +4605,24 @@ TYPE
 			symbol.nextSymbol := p;
 			symbol.nextSymbol := p;
 			IF q = NIL THEN firstSymbol := symbol ELSE q.nextSymbol := symbol END;
 			IF q = NIL THEN firstSymbol := symbol ELSE q.nextSymbol := symbol END;
 			symbol.SetScope(SELF);
 			symbol.SetScope(SELF);
+			symbolTable.Put(symbol.name,symbol);
 
 
 			INC(numberSymbols);
 			INC(numberSymbols);
 		END EnterSymbol;
 		END EnterSymbol;
 
 
 		(** Find symbol by name *)
 		(** Find symbol by name *)
 		PROCEDURE FindSymbol*(identifier: Identifier): Symbol;
 		PROCEDURE FindSymbol*(identifier: Identifier): Symbol;
-		VAR p: Symbol;
+		VAR p: Symbol; a: ANY;
 		BEGIN
 		BEGIN
 			IF identifier # invalidIdentifier THEN
 			IF identifier # invalidIdentifier THEN
+				a := symbolTable.Get(identifier);
+				IF (a # NIL) & ~(a IS Operator) THEN
+					p := a(Symbol);
+				END;
+				(*
 				p := firstSymbol;
 				p := firstSymbol;
 				WHILE(p#NIL) & ((p.name # identifier) OR (p IS Operator)) DO p := p.nextSymbol END;
 				WHILE(p#NIL) & ((p.name # identifier) OR (p IS Operator)) DO p := p.nextSymbol END;
+				*)
 			END;
 			END;
 			RETURN p;
 			RETURN p;
 		END FindSymbol;
 		END FindSymbol;
@@ -4692,7 +4708,6 @@ TYPE
 			procedures.AddProcedure(p);
 			procedures.AddProcedure(p);
 		END AddProcedureDeclaration;
 		END AddProcedureDeclaration;
 		
 		
-
 		PROCEDURE FindProcedure*(identifier: Identifier): Procedure;
 		PROCEDURE FindProcedure*(identifier: Identifier): Procedure;
 		VAR p: Procedure;
 		VAR p: Procedure;
 		BEGIN
 		BEGIN
@@ -4700,7 +4715,7 @@ TYPE
 			WHILE (p#NIL) & ((p.name # identifier) OR (p IS Operator)) DO p := p.nextProcedure END;
 			WHILE (p#NIL) & ((p.name # identifier) OR (p IS Operator)) DO p := p.nextProcedure END;
 			RETURN p;
 			RETURN p;
 		END FindProcedure;
 		END FindProcedure;
-
+		
 		PROCEDURE FindMethod*(number: LONGINT): Procedure;
 		PROCEDURE FindMethod*(number: LONGINT): Procedure;
 		VAR p: Procedure;
 		VAR p: Procedure;
 		BEGIN
 		BEGIN
@@ -4711,7 +4726,6 @@ TYPE
 			RETURN p;
 			RETURN p;
 		END FindMethod;
 		END FindMethod;
 
 
-
 		PROCEDURE Level*(): LONGINT;
 		PROCEDURE Level*(): LONGINT;
 		VAR scope: Scope; level: LONGINT;
 		VAR scope: Scope; level: LONGINT;
 		BEGIN
 		BEGIN
@@ -4803,7 +4817,7 @@ TYPE
 			numberMethods-: LONGINT;
 			numberMethods-: LONGINT;
 			firstParameter-,lastParameter-: Parameter; numberParameters-: LONGINT;  (* parameters for Active Cells programming*)
 			firstParameter-,lastParameter-: Parameter; numberParameters-: LONGINT;  (* parameters for Active Cells programming*)
 			firstOperator-, lastOperator-: Operator; numberOperators: LONGINT; (* defined operators *)
 			firstOperator-, lastOperator-: Operator; numberOperators: LONGINT; (* defined operators *)
-
+			
 		PROCEDURE & InitRecordScope(outer: Scope);
 		PROCEDURE & InitRecordScope(outer: Scope);
 		BEGIN
 		BEGIN
 			InitScope(outer);
 			InitScope(outer);
@@ -4853,6 +4867,34 @@ TYPE
 			RETURN p;
 			RETURN p;
 		END FindSymbol;
 		END FindSymbol;
 
 
+		(* if there is an abstract procedure in the scope, return it. Otherwise return nil *)		
+		PROCEDURE AbstractProcedure*(inScope: Scope): Procedure;
+		VAR p: Procedure; s: Symbol; base: RecordType;
+		BEGIN
+			p := firstProcedure;
+			WHILE p # NIL DO
+				IF p.isAbstract THEN
+					IF inScope # SELF THEN  (* elevate to mother scope, if necesary *)
+						s := inScope.FindSymbol(p.name); 
+						IF s = p THEN (* procedure is not overwritten *)
+							RETURN p
+						ELSE
+							ASSERT(s # NIL);
+							ASSERT(s IS Procedure);							
+						END;
+					ELSE
+						RETURN p
+					END;
+				END;
+				p := p.nextProcedure;
+			END;
+			base := ownerRecord.GetBaseRecord();
+			IF (base # NIL) THEN
+				RETURN base.recordScope.AbstractProcedure(inScope);
+			END;
+			RETURN NIL;
+		END AbstractProcedure;
+
 		PROCEDURE FindConstant*(identifier: Identifier): Constant;
 		PROCEDURE FindConstant*(identifier: Identifier): Constant;
 		VAR p: Constant; base: RecordType;
 		VAR p: Constant; base: RecordType;
 		BEGIN
 		BEGIN
@@ -5297,11 +5339,17 @@ TYPE
 		PROCEDURE GetProcedure*( index: LONGINT ): Procedure;
 		PROCEDURE GetProcedure*( index: LONGINT ): Procedure;
 		VAR p: ANY;
 		VAR p: ANY;
 		BEGIN
 		BEGIN
-			p := list.Get(index); RETURN p(Procedure);
+			IF index >= list.Length() THEN RETURN NIL END;
+			p := list.Get(index); 
+			IF p = NIL THEN 
+				RETURN NIL 
+			ELSE 
+				RETURN p(Procedure);
+			END;
 		END GetProcedure;
 		END GetProcedure;
 
 
 		PROCEDURE SetProcedure*(index: LONGINT; expression: Procedure);
 		PROCEDURE SetProcedure*(index: LONGINT; expression: Procedure);
-		BEGIN list.Set(index,expression)
+		BEGIN list.GrowAndSet(index,expression)
 		END SetProcedure;
 		END SetProcedure;
 
 
 		PROCEDURE RemoveProcedure*(i: LONGINT);
 		PROCEDURE RemoveProcedure*(i: LONGINT);