فهرست منبع

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

+ 102 - 84
source/FoxSemanticChecker.Mod

@@ -328,13 +328,13 @@ TYPE
 			END;
 		END ResolvedType;
 
-		PROCEDURE VisitType(x: SyntaxTree.Type);
+		PROCEDURE VisitType*(x: SyntaxTree.Type);
 		BEGIN
 			ASSERT(x = SyntaxTree.invalidType);
 		END VisitType;
 
 		(** resolve basic type **)
-		PROCEDURE VisitBasicType(x: SyntaxTree.BasicType);
+		PROCEDURE VisitBasicType*(x: SyntaxTree.BasicType);
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 				x.SetState(SyntaxTree.Resolved);
@@ -342,66 +342,66 @@ TYPE
 			resolvedType := ResolvedType(x)
 		END VisitBasicType;
 
-		PROCEDURE VisitByteType(x: SyntaxTree.ByteType);
+		PROCEDURE VisitByteType*(x: SyntaxTree.ByteType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitByteType;
 
 		(** resolve character type **)
-		PROCEDURE VisitCharacterType(x: SyntaxTree.CharacterType);
+		PROCEDURE VisitCharacterType*(x: SyntaxTree.CharacterType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitCharacterType;
 
-		PROCEDURE VisitBooleanType(x: SyntaxTree.BooleanType);
+		PROCEDURE VisitBooleanType*(x: SyntaxTree.BooleanType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitBooleanType;
 
-		PROCEDURE VisitSetType(x: SyntaxTree.SetType);
+		PROCEDURE VisitSetType*(x: SyntaxTree.SetType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitSetType;
 
-		PROCEDURE VisitAddressType(x: SyntaxTree.AddressType);
+		PROCEDURE VisitAddressType*(x: SyntaxTree.AddressType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitAddressType;
 
-		PROCEDURE VisitSizeType(x: SyntaxTree.SizeType);
+		PROCEDURE VisitSizeType*(x: SyntaxTree.SizeType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitSizeType;
 
-		PROCEDURE VisitAnyType(x: SyntaxTree.AnyType);
+		PROCEDURE VisitAnyType*(x: SyntaxTree.AnyType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitAnyType;
 
-		PROCEDURE VisitObjectType(x: SyntaxTree.ObjectType);
+		PROCEDURE VisitObjectType*(x: SyntaxTree.ObjectType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitObjectType;
 
-		PROCEDURE VisitNilType(x: SyntaxTree.NilType);
+		PROCEDURE VisitNilType*(x: SyntaxTree.NilType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitNilType;
 
 		(** resolve integer type **)
-		PROCEDURE VisitIntegerType(x: SyntaxTree.IntegerType);
+		PROCEDURE VisitIntegerType*(x: SyntaxTree.IntegerType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitIntegerType;
 
 		(** resolve real type **)
-		PROCEDURE VisitFloatType(x: SyntaxTree.FloatType);
+		PROCEDURE VisitFloatType*(x: SyntaxTree.FloatType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitFloatType;
 
 		(** resolve complex type **)
-		PROCEDURE VisitComplexType(x: SyntaxTree.ComplexType);
+		PROCEDURE VisitComplexType*(x: SyntaxTree.ComplexType);
 		BEGIN
 			VisitBasicType(x);
 		END VisitComplexType;
@@ -409,7 +409,7 @@ TYPE
 		(**
 			resolve string type: nothing to be done
 		**)
-		PROCEDURE VisitStringType(x: SyntaxTree.StringType);
+		PROCEDURE VisitStringType*(x: SyntaxTree.StringType);
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 				x.SetState(SyntaxTree.Resolved);
@@ -454,7 +454,7 @@ TYPE
 		(**
 			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;
 			lowest, highest: LONGINT;
 		BEGIN
@@ -485,7 +485,7 @@ TYPE
 		(**
 			resolve range type: nothing to be done
 		**)
-		PROCEDURE VisitRangeType(x: SyntaxTree.RangeType);
+		PROCEDURE VisitRangeType*(x: SyntaxTree.RangeType);
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
 				x.SetState(SyntaxTree.Resolved);
@@ -497,7 +497,7 @@ TYPE
 			resolve qualified 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;
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
@@ -517,7 +517,7 @@ TYPE
 				- array of math 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;
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
@@ -599,7 +599,7 @@ TYPE
 				- math array of tensor forbidden
 				- static array of open array forbidden
 		**)
-		PROCEDURE VisitMathArrayType(x: SyntaxTree.MathArrayType);
+		PROCEDURE VisitMathArrayType*(x: SyntaxTree.MathArrayType);
 		VAR arrayBase: SyntaxTree.Type;
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
@@ -716,7 +716,7 @@ TYPE
 			resolve pointer type
 			- 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;
 		modifiers: SyntaxTree.Modifier; position: Position;
 		BEGIN
@@ -738,6 +738,7 @@ TYPE
 					recordBaseType := ResolveType(recordType.baseType);
 					recordType.SetBaseType(recordBaseType);
 					recordType.SetProtected(HasFlag(modifiers, Global.NameExclusive, position));
+					recordType.SetAbstract(HasFlag(modifiers, Global.NameAbstract, position));
 				END;
 				CheckModifiers(modifiers, TRUE);
 				typeFixes.Add(x,currentScope);
@@ -750,7 +751,7 @@ TYPE
 			resolve port type
 			- 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;
 		BEGIN
 			IF TypeNeedsResolution(x) THEN
@@ -920,7 +921,7 @@ TYPE
 			resolve procedure type
 			- 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;
 		BEGIN
 			IF TypeNeedsResolution(procedureType) THEN
@@ -959,7 +960,7 @@ TYPE
 			- check declarations
 			- 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;
 			numberMethods: LONGINT; recordBase, recordType: SyntaxTree.RecordType; procedure: SyntaxTree.Procedure;
 			symbol: SyntaxTree.Symbol; isRealtime: BOOLEAN;
@@ -986,7 +987,9 @@ TYPE
 				hasPointers := FALSE;
 				
 				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);
 				
 				IF x.baseType # NIL THEN
@@ -1068,7 +1071,7 @@ TYPE
 					IF symbol IS SyntaxTree.Procedure THEN
 						procedure := symbol(SyntaxTree.Procedure);
 						IF procedure.super # NIL THEN
-							procedure.SetMethodNumber(procedure.super.methodNumber)
+							procedure.SetMethodNumber(procedure.super.methodNumber);
 						ELSIF InMethodTable(procedure) THEN (* not a static method *)
 							procedure.SetMethodNumber(numberMethods);
 							INC(numberMethods);
@@ -1091,7 +1094,15 @@ TYPE
 				IF (x.isObject) & (x.baseType # NIL) & (x.baseType.resolved IS SyntaxTree.RecordType) THEN
 					Error(x.position,"object extends a record")
 				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.pointerType # NIL) & (x.pointerType.resolved.typeDeclaration # NIL) THEN
 						x.SetTypeDeclaration(x.pointerType.resolved.typeDeclaration);
@@ -1114,7 +1125,7 @@ TYPE
 			- check declarations
 			- 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
 			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;
@@ -1841,7 +1852,7 @@ TYPE
 		(*** values  ***)
 
 		(** check and resolve integer value **)
-		PROCEDURE VisitIntegerValue(value: SyntaxTree.IntegerValue);
+		PROCEDURE VisitIntegerValue*(value: SyntaxTree.IntegerValue);
 		VAR hugeint: HUGEINT;
 		BEGIN
 			hugeint := value(SyntaxTree.IntegerValue).hvalue;
@@ -1850,7 +1861,7 @@ TYPE
 		END VisitIntegerValue;
 
 		(** check and resolve real value **)
-		PROCEDURE VisitRealValue(value: SyntaxTree.RealValue);
+		PROCEDURE VisitRealValue*(value: SyntaxTree.RealValue);
 		VAR subtype: LONGINT; type: SyntaxTree.Type;
 		BEGIN
 			subtype := value(SyntaxTree.RealValue).subtype;
@@ -1866,7 +1877,7 @@ TYPE
 		END VisitRealValue;
 
 		(** check and resolve complex value **)
-		PROCEDURE VisitComplexValue(value: SyntaxTree.ComplexValue);
+		PROCEDURE VisitComplexValue*(value: SyntaxTree.ComplexValue);
 		VAR subtype: LONGINT; type: SyntaxTree.Type;
 		BEGIN
 			subtype := value(SyntaxTree.ComplexValue).subtype;
@@ -1882,49 +1893,49 @@ TYPE
 		END VisitComplexValue;
 
 		(** check and resolve set value **)
-		PROCEDURE VisitSetValue(value: SyntaxTree.SetValue);
+		PROCEDURE VisitSetValue*(value: SyntaxTree.SetValue);
 		BEGIN
 			value.SetType(system.setType);
 			resolvedExpression := value
 		END VisitSetValue;
 
 		(** check and resolve set value **)
-		PROCEDURE VisitMathArrayValue(value: SyntaxTree.MathArrayValue);
+		PROCEDURE VisitMathArrayValue*(value: SyntaxTree.MathArrayValue);
 		BEGIN
 			value.SetType(SyntaxTree.invalidType);
 			resolvedExpression := value
 		END VisitMathArrayValue;
 
 		(** check and resolve boolean value **)
-		PROCEDURE VisitBooleanValue(value: SyntaxTree.BooleanValue);
+		PROCEDURE VisitBooleanValue*(value: SyntaxTree.BooleanValue);
 		BEGIN
 			value.SetType(system.booleanType);
 			resolvedExpression := value
 		END VisitBooleanValue;
 
 		(** check and resolve string value **)
-		PROCEDURE VisitStringValue(value: SyntaxTree.StringValue);
+		PROCEDURE VisitStringValue*(value: SyntaxTree.StringValue);
 		BEGIN
 			value.SetType(ResolveType(SyntaxTree.NewStringType(value.position,system.characterType,value.length)));
 			resolvedExpression := value
 		END VisitStringValue;
 
 		(** check and resolve character value **)
-		PROCEDURE VisitCharacterValue(value: SyntaxTree.CharacterValue);
+		PROCEDURE VisitCharacterValue*(value: SyntaxTree.CharacterValue);
 		BEGIN
 			value.SetType(system.characterType);
 			resolvedExpression := value
 		END VisitCharacterValue;
 
 		(** check and resolve nil value **)
-		PROCEDURE VisitNilValue(value: SyntaxTree.NilValue);
+		PROCEDURE VisitNilValue*(value: SyntaxTree.NilValue);
 		BEGIN
 			value.SetType(system.nilType);
 			resolvedExpression := value
 		END VisitNilValue;
 
 		(** check and resolve enumerator value **)
-		PROCEDURE VisitEnumerationValue(value: SyntaxTree.EnumerationValue);
+		PROCEDURE VisitEnumerationValue*(value: SyntaxTree.EnumerationValue);
 		BEGIN
 			value.SetType(currentScope(SyntaxTree.EnumerationScope).ownerEnumeration);
 			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 an error occurs then report error and return invalidExpression
 		**)
-		PROCEDURE VisitSet(set: SyntaxTree.Set);
+		PROCEDURE VisitSet*(set: SyntaxTree.Set);
 		VAR
 			i: LONGINT;
 			element: SyntaxTree.Expression;
@@ -2091,7 +2102,7 @@ TYPE
 		END VisitMathArrayExpression;
 		*)
 
-		PROCEDURE VisitMathArrayExpression(x: SyntaxTree.MathArrayExpression);
+		PROCEDURE VisitMathArrayExpression*(x: SyntaxTree.MathArrayExpression);
 		VAR type: SyntaxTree.Type; isValue: BOOLEAN;
 			value: SyntaxTree.MathArrayValue; arrayType: SyntaxTree.Type;
 
@@ -2184,7 +2195,7 @@ TYPE
 		END VisitMathArrayExpression;
 
 		(** check and resolve unary expression **)
-		PROCEDURE VisitUnaryExpression(unaryExpression: SyntaxTree.UnaryExpression);
+		PROCEDURE VisitUnaryExpression*(unaryExpression: SyntaxTree.UnaryExpression);
 		VAR
 			left: SyntaxTree.Expression;
 			int: HUGEINT; real, imaginary: LONGREAL; set: SET; operator: LONGINT;
@@ -2876,7 +2887,7 @@ TYPE
 
 		(** check and resolve binary expression **)
 		(*! clean up *)
-		PROCEDURE VisitBinaryExpression(binaryExpression: SyntaxTree.BinaryExpression);
+		PROCEDURE VisitBinaryExpression*(binaryExpression: SyntaxTree.BinaryExpression);
 		VAR left,right,result: SyntaxTree.Expression;
 			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;
@@ -3407,7 +3418,7 @@ TYPE
 					- must not have step size
 		    - if error: return invalidExpression
 		**)
-		PROCEDURE VisitRangeExpression(x: SyntaxTree.RangeExpression);
+		PROCEDURE VisitRangeExpression*(x: SyntaxTree.RangeExpression);
 		VAR
 			hasError: BOOLEAN;
 			first, last, step: SyntaxTree.Expression;
@@ -3534,7 +3545,7 @@ TYPE
 			END
 		END VisitRangeExpression;
 
-		PROCEDURE VisitTensorRangeExpression(x: SyntaxTree.TensorRangeExpression);
+		PROCEDURE VisitTensorRangeExpression*(x: SyntaxTree.TensorRangeExpression);
 		BEGIN
 			x.SetType(NIL);
 			resolvedExpression := x;
@@ -3568,7 +3579,7 @@ TYPE
 			symbol designator generated in this module
 			nothing to be resolved
 		**)
-		PROCEDURE VisitSymbolDesignator(x: SyntaxTree.SymbolDesignator);
+		PROCEDURE VisitSymbolDesignator*(x: SyntaxTree.SymbolDesignator);
 		BEGIN
 			resolvedExpression := x;
 		END VisitSymbolDesignator;
@@ -3577,7 +3588,7 @@ TYPE
 			self designator generated in this module
 			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;
 		BEGIN
 			(* check if in record scope *)
@@ -3602,7 +3613,7 @@ TYPE
 			resolvedExpression := x;
 		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;
 		BEGIN
 			scope := currentScope;
@@ -3715,7 +3726,7 @@ TYPE
 			- else find symbol in current scope
 				- 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;
 		BEGIN
 			IF Trace THEN D.Str("VisitIdentifierDesignator "); D.Ln; END;
@@ -3743,7 +3754,7 @@ TYPE
 			- search symbol in computed scope
 			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
 			symbol: SyntaxTree.Symbol; left: SyntaxTree.Designator; scope: SyntaxTree.Scope;
 			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,
 			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
 			leftBracketDesignator: SyntaxTree.BracketDesignator;
 			indexDesignator: SyntaxTree.IndexDesignator;
@@ -4699,7 +4710,7 @@ TYPE
 			builtin call designator generated in VisitParameterDesignator
 			-> nothing to be resolved
 		**)
-		PROCEDURE VisitTypeGuardDesignator(x: SyntaxTree.TypeGuardDesignator);
+		PROCEDURE VisitTypeGuardDesignator*(x: SyntaxTree.TypeGuardDesignator);
 		BEGIN
 			resolvedExpression := x;
 		END VisitTypeGuardDesignator;
@@ -4708,7 +4719,7 @@ TYPE
 			builtin call designator generated in VisitParameterDesignator
 			-> nothing to be resolved
 		**)
-		PROCEDURE VisitBuiltinCallDesignator(x: SyntaxTree.BuiltinCallDesignator);
+		PROCEDURE VisitBuiltinCallDesignator*(x: SyntaxTree.BuiltinCallDesignator);
 		BEGIN
 			IF (x.returnType # NIL) & ExpressionList(x.parameters) THEN
 				resolvedExpression := NewBuiltinCallDesignator(x.position,NIL, x.parameters,NIL, ResolveType(x.returnType));
@@ -4722,7 +4733,7 @@ TYPE
 			procedure call designator generated in VisitParameterDesignator
 			-> nothing to be resolved
 		**)
-		PROCEDURE VisitProcedureCallDesignator(x: SyntaxTree.ProcedureCallDesignator);
+		PROCEDURE VisitProcedureCallDesignator*(x: SyntaxTree.ProcedureCallDesignator);
 		BEGIN
 			x.SetType(x.left.type.resolved(SyntaxTree.ProcedureType).returnType);
 			resolvedExpression := x;
@@ -5295,6 +5306,9 @@ TYPE
 								UNTIL ~CheckSizeType(actualParameter) OR (actualParameter.resolved # NIL) & ~CheckPositiveIntegerValue(actualParameter,i0,TRUE) OR (i=numberActualParameters);
 							END;
 						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));
 							IF constructor = NIL THEN
 								IF CheckArity(first,first) THEN END;
@@ -6282,7 +6296,7 @@ TYPE
 				- else return is a procedure call then return ProcedureCallDesignator
 			returns invalidDesignator = invalidExpression if error
 		**)
-		PROCEDURE VisitParameterDesignator(designator: SyntaxTree.ParameterDesignator);
+		PROCEDURE VisitParameterDesignator*(designator: SyntaxTree.ParameterDesignator);
 		VAR
 			parameters: SyntaxTree.ExpressionList;
 			left: SyntaxTree.Designator;
@@ -6437,7 +6451,7 @@ TYPE
 			returns result via global variable resolvedExpression
 			error handling deferred to procedures SupercallDesignator and DereferenceDesignator
 		**)
-		PROCEDURE VisitArrowDesignator(arrowDesignator: SyntaxTree.ArrowDesignator);
+		PROCEDURE VisitArrowDesignator*(arrowDesignator: SyntaxTree.ArrowDesignator);
 		VAR left: SyntaxTree.Designator;
 		BEGIN
 			IF Trace THEN D.Str("VisitArrowDesignator"); D.Ln; END;
@@ -6587,7 +6601,7 @@ TYPE
 				scope := scope.outerScope;
 			END;
 			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");
 					IF VerboseErrorMessage THEN
 						Printout.Info("symbol",symbol);
@@ -6624,7 +6638,7 @@ TYPE
 			- resolve and set declared type
 			- check symbol
 		**)
-		PROCEDURE VisitTypeDeclaration(typeDeclaration: SyntaxTree.TypeDeclaration);
+		PROCEDURE VisitTypeDeclaration*(typeDeclaration: SyntaxTree.TypeDeclaration);
 		VAR prevScope: SyntaxTree.Scope;
 		BEGIN
 			IF Trace THEN D.Str("VisitTypeDeclaration "); D.Str0(typeDeclaration.name);  D.Ln;  END;
@@ -6645,7 +6659,7 @@ TYPE
 			- set type and value
 			- check symbol
 		**)
-		PROCEDURE VisitConstant(constant: SyntaxTree.Constant);
+		PROCEDURE VisitConstant*(constant: SyntaxTree.Constant);
 		VAR
 			expression: SyntaxTree.Expression;
 			type: SyntaxTree.Type;
@@ -6718,7 +6732,7 @@ TYPE
 			- negative check on open array type
 			- check symbol
 		**)
-		PROCEDURE VisitVariable(variable: SyntaxTree.Variable);
+		PROCEDURE VisitVariable*(variable: SyntaxTree.Variable);
 		VAR modifiers: SyntaxTree.Modifier; value: LONGINT; position: Position; pointerType: SyntaxTree.PointerType;
 		BEGIN
 			IF Trace THEN D.Str("VisitVariable "); D.Str0(variable.name);  D.Ln;  END;
@@ -6786,7 +6800,7 @@ TYPE
 			END;
 		END VisitVariable;
 
-		PROCEDURE VisitProperty(property: SyntaxTree.Property);
+		PROCEDURE VisitProperty*(property: SyntaxTree.Property);
 		BEGIN
 			VisitVariable(property)
 		END VisitProperty;
@@ -6797,7 +6811,7 @@ TYPE
 			- check symbol
 			- 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;
 		BEGIN
 			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 procedure symbol
 		**)
-		PROCEDURE VisitProcedure(procedure: SyntaxTree.Procedure);
+		PROCEDURE VisitProcedure*(procedure: SyntaxTree.Procedure);
 		VAR super,proc: SyntaxTree.Procedure; record: SyntaxTree.RecordType;
 			procedureType: SyntaxTree.ProcedureType;
 			type: SyntaxTree.Type;
@@ -6942,8 +6956,6 @@ TYPE
 					Error(procedure.position,"problems during parameter offset computation");
 				END;
 
-				CheckSymbolVisibility(procedure);
-
 				IF procedure.scope IS SyntaxTree.ProcedureScope THEN
 					procedure.SetLevel(procedure.scope(SyntaxTree.ProcedureScope).ownerProcedure.level+1);
 					IF ~system.GenerateParameterOffsets(procedure,TRUE) THEN
@@ -7016,6 +7028,9 @@ TYPE
 						IF super.isFinal THEN
 							Error(procedure.position,"forbidden method extending final method");
 						END;
+						IF super.access # procedure.access THEN
+							Warning(procedure.position, "forbiden visibility mismatch of method and super method");
+						END;
 						procedure.SetSuper(super);
 						super.SetOverwritten(TRUE);
 						procedure.SetAccess(procedure.access+super.access);
@@ -7035,6 +7050,7 @@ TYPE
 				ELSIF procedure.isConstructor THEN
 					Error(procedure.position,"procedure illegaly marked as initializer - not in object scope");
 				END;
+				CheckSymbolVisibility(procedure);
 				Declarations(procedure.procedureScope, FALSE, {0,1});
 				(* body resolution part done as late fix of the procedure type *)
 				procedure.SetState(SyntaxTree.Resolved);
@@ -7047,7 +7063,7 @@ TYPE
 			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
 		**)
-		PROCEDURE VisitBuiltin(builtinProcedure: SyntaxTree.Builtin);
+		PROCEDURE VisitBuiltin*(builtinProcedure: SyntaxTree.Builtin);
 		VAR type: SyntaxTree.Type;
 		BEGIN
 			type := ResolveType(builtinProcedure.type);
@@ -7062,7 +7078,7 @@ TYPE
 				array-structured object types and checked in 'ResolveArrayStructure')
 			- also note that inter-operator conformity is not checked here
 		**)
-		PROCEDURE VisitOperator(operator: SyntaxTree.Operator);
+		PROCEDURE VisitOperator*(operator: SyntaxTree.Operator);
 		VAR
 			procedureType: SyntaxTree.ProcedureType;
 			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)
 			- 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
 			module: SyntaxTree.Module;
 			moduleScope: SyntaxTree.ModuleScope;
@@ -7401,7 +7417,7 @@ TYPE
 			- check if procedure is callable
 			- check return type = NIL (otherwise must be assignment statement)
 		**)
-		PROCEDURE VisitProcedureCallStatement(procedureCall: SyntaxTree.ProcedureCallStatement);
+		PROCEDURE VisitProcedureCallStatement*(procedureCall: SyntaxTree.ProcedureCallStatement);
 		VAR call: SyntaxTree.Designator;
 		BEGIN
 			IF Trace THEN D.Str("VisitProcedureCallStatement"); D.Ln; END;
@@ -7453,7 +7469,7 @@ TYPE
 				- assignment to ASOT elements:
 					asot[indexList] := rhs; -> asot^."[]"(indexList, rhs);
 		**)
-		PROCEDURE VisitAssignment(assignment: SyntaxTree.Assignment);
+		PROCEDURE VisitAssignment*(assignment: SyntaxTree.Assignment);
 		VAR
 			left: SyntaxTree.Designator;
 			right, expression: SyntaxTree.Expression;
@@ -7521,7 +7537,7 @@ TYPE
 				- assignment to ASOT elements:
 					asot[indexList] := rhs; -> asot^."[]"(indexList, rhs);
 		**)
-		PROCEDURE VisitCommunicationStatement(communication: SyntaxTree.CommunicationStatement);
+		PROCEDURE VisitCommunicationStatement*(communication: SyntaxTree.CommunicationStatement);
 		VAR
 			left: SyntaxTree.Designator;
 			right: SyntaxTree.Expression;
@@ -7618,7 +7634,7 @@ TYPE
 		(** check and resolve if statement
 			- 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;
 		BEGIN
 			prevUnreachable := currentIsUnreachable;
@@ -7697,7 +7713,7 @@ TYPE
 			- create if statement:
 				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;
 		BEGIN
 			prevScope := currentScope; symbol := NIL;
@@ -7806,7 +7822,7 @@ TYPE
 			- check variable
 			- 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;
 			ch: CHAR; l: LONGINT; min,max: LONGINT; msg: ARRAY 64 OF CHAR;
 		BEGIN
@@ -7857,7 +7873,7 @@ TYPE
 			- check condition
 			- check statement sequence
 		**)
-		PROCEDURE VisitWhileStatement(whileStatement: SyntaxTree.WhileStatement);
+		PROCEDURE VisitWhileStatement*(whileStatement: SyntaxTree.WhileStatement);
 		VAR prevIsUnreachable,b: BOOLEAN;
 		BEGIN
 			prevIsUnreachable := currentIsUnreachable;
@@ -7875,7 +7891,7 @@ TYPE
 			- check condition
 			- check statement sequence
 		**)
-		PROCEDURE VisitRepeatStatement(repeatStatement: SyntaxTree.RepeatStatement);
+		PROCEDURE VisitRepeatStatement*(repeatStatement: SyntaxTree.RepeatStatement);
 		BEGIN
 			repeatStatement.SetCondition(ResolveCondition(repeatStatement.condition));
 			StatementSequence(repeatStatement.statements);
@@ -7902,7 +7918,7 @@ TYPE
 			- check that to has 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;
 		BEGIN
 			designator := ResolveDesignator(forStatement.variable);
@@ -7960,12 +7976,12 @@ TYPE
 		(** check and resolve loop statement LOOP StatementSequence END
 			- check statement sequence
 		**)
-		PROCEDURE VisitLoopStatement(loopStatement: SyntaxTree.LoopStatement);
+		PROCEDURE VisitLoopStatement*(loopStatement: SyntaxTree.LoopStatement);
 		BEGIN
 			StatementSequence(loopStatement.statements)
 		END VisitLoopStatement;
 
-		PROCEDURE VisitExitableBlock(exitableBlock: SyntaxTree.ExitableBlock);
+		PROCEDURE VisitExitableBlock*(exitableBlock: SyntaxTree.ExitableBlock);
 		BEGIN
 			StatementSequence(exitableBlock.statements);
 		END VisitExitableBlock;
@@ -7974,7 +7990,7 @@ TYPE
 		(** check and resolve exit statement EXIT
 			- check that exit is within LOOP statement block
 		**)
-		PROCEDURE VisitExitStatement(exitStatement: SyntaxTree.ExitStatement);
+		PROCEDURE VisitExitStatement*(exitStatement: SyntaxTree.ExitStatement);
 		VAR outer: SyntaxTree.Statement;
 		BEGIN
 			outer := exitStatement.outer;
@@ -7992,7 +8008,7 @@ TYPE
 				- if in procedure scope then check expression compatibility
 				- 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;
 			returnType: SyntaxTree.Type; outer: SyntaxTree.Statement; scope: SyntaxTree.Scope;
 		BEGIN
@@ -8044,7 +8060,7 @@ TYPE
 		(** check and resolve await statement AWAIT(condition: Expression)
 			- check await condition
 		**)
-		PROCEDURE VisitAwaitStatement(awaitStatement: SyntaxTree.AwaitStatement);
+		PROCEDURE VisitAwaitStatement*(awaitStatement: SyntaxTree.AwaitStatement);
 		VAR condition: SyntaxTree.Expression;
 		BEGIN
 			condition := ResolveCondition(awaitStatement.condition);
@@ -8072,7 +8088,7 @@ TYPE
 
 		(** 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;
 		BEGIN
 			CheckSystemImport(code.position);
@@ -8205,7 +8221,7 @@ TYPE
 			- check flags (exclusive)
 			- check statement sequence
 		**)
-		PROCEDURE VisitStatementBlock(statementBlock: SyntaxTree.StatementBlock);
+		PROCEDURE VisitStatementBlock*(statementBlock: SyntaxTree.StatementBlock);
 		VAR recentExclusive, recentUnreachable, recentRealtime: BOOLEAN;
 		BEGIN
 			BlockFlags(statementBlock);
@@ -8718,7 +8734,7 @@ TYPE
 			SELF.diagnostics := diagnostics
 		END InitWarnings;
 
-		PROCEDURE VisitPortType(x: SyntaxTree.PortType);
+		PROCEDURE VisitPortType*(x: SyntaxTree.PortType);
 		BEGIN	END VisitPortType;
 
 		(** types *)
@@ -10177,6 +10193,8 @@ TYPE
 	BEGIN
 		RETURN (procedureType # NIL) & (procedureType.callingConvention=SyntaxTree.OberonCallingConvention) & ReturnedAsParameter(procedureType.returnType);
 	END StructuredReturnType;
+	
+	
 
 
 

+ 74 - 26
source/FoxSyntaxTree.Mod

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