瀏覽代碼

improved statement resolution (removed another indirection)

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@8495 8c9fc860-2736-0410-a75d-ab315db34111
felixf 6 年之前
父節點
當前提交
1e3c8e46c2
共有 1 個文件被更改,包括 86 次插入92 次删除
  1. 86 92
      source/FoxSemanticChecker.Mod

+ 86 - 92
source/FoxSemanticChecker.Mod

@@ -94,7 +94,6 @@ TYPE
 			- set in AcceptXXX procedures
 			- set in AcceptXXX procedures
 			- set and read in ResolveXXX procedures
 			- set and read in ResolveXXX procedures
 		*)
 		*)
-		resolvedStatement: SyntaxTree.Statement; (** used for statement resolution **)
 		currentScope-: SyntaxTree.Scope;
 		currentScope-: SyntaxTree.Scope;
 		currentIsRealtime: BOOLEAN;
 		currentIsRealtime: BOOLEAN;
 		currentIsUnreachable: BOOLEAN;
 		currentIsUnreachable: BOOLEAN;
@@ -117,7 +116,6 @@ TYPE
 			error := FALSE;
 			error := FALSE;
 			NEW(typeFixes);
 			NEW(typeFixes);
 			NEW(pointerFixes);
 			NEW(pointerFixes);
-			resolvedStatement := NIL;
 			currentScope := NIL;
 			currentScope := NIL;
 			IF importCache = NIL THEN importCache := SyntaxTree.NewModuleScope() END;
 			IF importCache = NIL THEN importCache := SyntaxTree.NewModuleScope() END;
 			SELF.importCache := importCache;
 			SELF.importCache := importCache;
@@ -1989,7 +1987,7 @@ TYPE
 				- if expression is already of same type then return expression
 				- if expression is already of same type then return expression
 				- if incompatible conversion then report error and return invalidExpression
 				- if incompatible conversion then report error and return invalidExpression
 		**)
 		**)
-		PROCEDURE NewConversion*(position: Position; expression: SyntaxTree.Expression; type: SyntaxTree.Type; reference: SyntaxTree.Expression): SyntaxTree.Expression;
+		PROCEDURE NewConversion(position: Position; expression: SyntaxTree.Expression; type: SyntaxTree.Type; reference: SyntaxTree.Expression): SyntaxTree.Expression;
 		VAR result: SyntaxTree.Expression; value: SyntaxTree.Expression; expressionList: SyntaxTree.ExpressionList; typeDeclaration: SyntaxTree.TypeDeclaration; typeSymbol: SyntaxTree.Designator;
 		VAR result: SyntaxTree.Expression; value: SyntaxTree.Expression; expressionList: SyntaxTree.ExpressionList; typeDeclaration: SyntaxTree.TypeDeclaration; typeSymbol: SyntaxTree.Designator;
 		BEGIN
 		BEGIN
 			type := type.resolved;
 			type := type.resolved;
@@ -2116,7 +2114,7 @@ TYPE
 			- search current module scope and all (directly or indirectly) imported modules for matching operator
 			- search current module scope and all (directly or indirectly) imported modules for matching operator
 			- take operator with smalles distance, where signature distance is computed in procedure Distance
 			- take operator with smalles distance, where signature distance is computed in procedure Distance
 		**)
 		**)
-		PROCEDURE FindOperator*(system: Global.System; operator: LONGINT; actualParameters: SyntaxTree.ExpressionList; returnType: SyntaxTree.Type): SyntaxTree.Operator;
+		PROCEDURE FindOperator(system: Global.System; operator: LONGINT; actualParameters: SyntaxTree.ExpressionList; returnType: SyntaxTree.Type): SyntaxTree.Operator;
 		VAR bestOperator: SyntaxTree.Operator; bestDistance: LONGINT; import: SyntaxTree.Import; numberParameters: LONGINT; procedureType: SyntaxTree.ProcedureType;
 		VAR bestOperator: SyntaxTree.Operator; bestDistance: LONGINT; import: SyntaxTree.Import; numberParameters: LONGINT; procedureType: SyntaxTree.ProcedureType;
 			identifier: SyntaxTree.Identifier;
 			identifier: SyntaxTree.Identifier;
 
 
@@ -3097,7 +3095,7 @@ TYPE
 		PROCEDURE ResolveIdentifierDesignator(identifierDesignator: SyntaxTree.IdentifierDesignator): SyntaxTree.Expression;
 		PROCEDURE ResolveIdentifierDesignator(identifierDesignator: SyntaxTree.IdentifierDesignator): SyntaxTree.Expression;
 		VAR symbol: SyntaxTree.Symbol;
 		VAR symbol: SyntaxTree.Symbol;
 		BEGIN
 		BEGIN
-			IF Trace THEN D.Str("VisitIdentifierDesignator "); D.Ln; END;
+			IF Trace THEN D.Str("ResolveIdentifierDesignator "); D.Ln; END;
 			symbol := Find(currentScope,identifierDesignator.identifier,TRUE);
 			symbol := Find(currentScope,identifierDesignator.identifier,TRUE);
 			IF symbol # NIL THEN
 			IF symbol # NIL THEN
 				ResolveSymbol(symbol);
 				ResolveSymbol(symbol);
@@ -3127,7 +3125,7 @@ TYPE
 			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;
 		BEGIN
 		BEGIN
-			IF Trace THEN D.Str("VisitSelectorDesignator"); D.Ln; END;
+			IF Trace THEN D.Str("ResolveSelectorDesignator"); D.Ln; END;
 			left := ResolveDesignator(selectorDesignator.left);
 			left := ResolveDesignator(selectorDesignator.left);
 
 
 			result := SyntaxTree.invalidDesignator;
 			result := SyntaxTree.invalidDesignator;
@@ -3533,7 +3531,7 @@ TYPE
 
 
 
 
 		BEGIN
 		BEGIN
-			IF Trace THEN D.Str("VisitBracketDesignator"); D.Ln; END;
+			IF Trace THEN D.Str("ResolveBracketDesignator"); D.Ln; END;
 
 
 			IF bracketDesignator.left IS SyntaxTree.BracketDesignator THEN
 			IF bracketDesignator.left IS SyntaxTree.BracketDesignator THEN
 				leftBracketDesignator := bracketDesignator.left(SyntaxTree.BracketDesignator);
 				leftBracketDesignator := bracketDesignator.left(SyntaxTree.BracketDesignator);
@@ -3686,7 +3684,7 @@ TYPE
 		BEGIN
 		BEGIN
 			IF Trace THEN D.Str("ProcedureCallDesignator"); D.Ln; END;
 			IF Trace THEN D.Str("ProcedureCallDesignator"); D.Ln; END;
 			result := SyntaxTree.invalidDesignator;
 			result := SyntaxTree.invalidDesignator;
-			formalType := left.type.resolved(SyntaxTree.ProcedureType); (* type checked in VisitParameterDesignator *)
+			formalType := left.type.resolved(SyntaxTree.ProcedureType); (* type checked in ResolveParameterDesignator *)
 			numberFormalParameters := formalType.numberParameters;
 			numberFormalParameters := formalType.numberParameters;
 			numberActualParameters := actualParameters.Length();
 			numberActualParameters := actualParameters.Length();
 
 
@@ -3744,7 +3742,7 @@ TYPE
 
 
 
 
 		(**
 		(**
-			builtin call designator generated in VisitParameterDesignator
+			builtin call designator generated in ResolveParameterDesignator
 			-> nothing to be resolved
 			-> nothing to be resolved
 		**)
 		**)
 		PROCEDURE ResolveBuiltinCallDesignator(x: SyntaxTree.BuiltinCallDesignator): SyntaxTree.Expression;
 		PROCEDURE ResolveBuiltinCallDesignator(x: SyntaxTree.BuiltinCallDesignator): SyntaxTree.Expression;
@@ -5352,7 +5350,7 @@ TYPE
 			END BaseType;
 			END BaseType;
 
 
 		BEGIN
 		BEGIN
-			IF Trace THEN D.Str("VisitParameterDesignator"); D.Ln; END;
+			IF Trace THEN D.Str("ResolveParameterDesignator"); D.Ln; END;
 			result := SyntaxTree.invalidDesignator;
 			result := SyntaxTree.invalidDesignator;
 			left := ResolveDesignator(designator.left);
 			left := ResolveDesignator(designator.left);
 			IF left # SyntaxTree.invalidDesignator THEN
 			IF left # SyntaxTree.invalidDesignator THEN
@@ -5492,7 +5490,7 @@ TYPE
 		PROCEDURE ResolveArrowDesignator(arrowDesignator: SyntaxTree.ArrowDesignator): SyntaxTree.Expression;
 		PROCEDURE ResolveArrowDesignator(arrowDesignator: SyntaxTree.ArrowDesignator): SyntaxTree.Expression;
 		VAR left: SyntaxTree.Designator;
 		VAR left: SyntaxTree.Designator;
 		BEGIN
 		BEGIN
-			IF Trace THEN D.Str("VisitArrowDesignator"); D.Ln; END;
+			IF Trace THEN D.Str("ResolveArrowDesignator"); D.Ln; END;
 			left := ResolveDesignator(arrowDesignator.left);
 			left := ResolveDesignator(arrowDesignator.left);
 			IF left # NIL THEN
 			IF left # NIL THEN
 				IF (left.type = NIL) THEN
 				IF (left.type = NIL) THEN
@@ -6483,44 +6481,31 @@ TYPE
 
 
 		(*** statements ***)
 		(*** statements ***)
 
 
-		PROCEDURE VStatement*(x: SyntaxTree.Statement);
-		BEGIN
-			WITH x: 
-			SyntaxTree.ProcedureCallStatement DO VisitProcedureCallStatement(x)
-			| SyntaxTree.Assignment DO VisitAssignment(x)
-			| SyntaxTree.CommunicationStatement DO VisitCommunicationStatement(x)
-			| SyntaxTree.IfStatement DO VisitIfStatement(x)
-			| SyntaxTree.WithStatement DO VisitWithStatement(x)
-			| SyntaxTree.CaseStatement DO VisitCaseStatement(x)
-			| SyntaxTree.WhileStatement DO VisitWhileStatement(x)
-			| SyntaxTree.RepeatStatement DO VisitRepeatStatement(x)
-			| SyntaxTree.ForStatement DO VisitForStatement(x)
-			| SyntaxTree.LoopStatement DO VisitLoopStatement(x)
-			| SyntaxTree.ExitableBlock DO VisitExitableBlock(x)
-			| SyntaxTree.ExitStatement DO VisitExitStatement(x)
-			| SyntaxTree.ReturnStatement DO VisitReturnStatement(x)
-			| SyntaxTree.AwaitStatement DO VisitAwaitStatement(x)
-			| SyntaxTree.StatementBlock DO VisitStatementBlock(x)
-			| SyntaxTree.Code DO VisitCode(x)
-			END;
-		END VStatement;
-
 		PROCEDURE ResolveStatement*(x: SyntaxTree.Statement): SyntaxTree.Statement;
 		PROCEDURE ResolveStatement*(x: SyntaxTree.Statement): SyntaxTree.Statement;
-		VAR prev,resolved: SyntaxTree.Statement;
-		BEGIN
-			prev := resolvedStatement;
-			resolvedStatement := x;
+		VAR result: SyntaxTree.Statement;
+		BEGIN			
 			IF currentIsUnreachable THEN x.SetUnreachable(TRUE) END;
 			IF currentIsUnreachable THEN x.SetUnreachable(TRUE) END;
 			activeCellsStatement := FALSE;
 			activeCellsStatement := FALSE;
-			VStatement(x);
-			(* removed this, implementation restriction should be resolved by backend
-			IF (inCellNetBody) & (activeCellsStatement = FALSE) THEN
-				Error(x.position, "non-activeCells statement in activeCells block - not yet implemented");
+			result := x; 
+			WITH x: 
+			SyntaxTree.ProcedureCallStatement DO result := ResolveProcedureCallStatement(x)
+			| SyntaxTree.Assignment DO result := ResolveAssignment(x)
+			| SyntaxTree.CommunicationStatement DO result := ResolveCommunicationStatement(x)
+			| SyntaxTree.IfStatement DO result := ResolveIfStatement(x)
+			| SyntaxTree.WithStatement DO result := ResolveWithStatement(x)
+			| SyntaxTree.CaseStatement DO result := ResolveCaseStatement(x)
+			| SyntaxTree.WhileStatement DO result := ResolveWhileStatement(x)
+			| SyntaxTree.RepeatStatement DO result := ResolveRepeatStatement(x)
+			| SyntaxTree.ForStatement DO result := ResolveForStatement(x)
+			| SyntaxTree.LoopStatement DO result := ResolveLoopStatement(x)
+			| SyntaxTree.ExitableBlock DO result := ResolveExitableBlock(x)
+			| SyntaxTree.ExitStatement DO result := ResolveExitStatement(x)
+			| SyntaxTree.ReturnStatement DO result := ResolveReturnStatement(x)
+			| SyntaxTree.AwaitStatement DO result := ResolveAwaitStatement(x)
+			| SyntaxTree.StatementBlock DO ResolveStatementBlock(x)
+			| SyntaxTree.Code DO ResolveCode(x)
 			END;
 			END;
-			*)
-			resolved := resolvedStatement;
-			resolvedStatement := prev;
-			RETURN resolved
+			RETURN result;
 		END ResolveStatement;
 		END ResolveStatement;
 
 
 		(** check and resolve statement sequence
 		(** check and resolve statement sequence
@@ -6540,17 +6525,15 @@ TYPE
 			END;
 			END;
 		END StatementSequence;
 		END StatementSequence;
 
 
-
-
 		(** check and resolve procedure call statement procedureCall() or procedureCall;
 		(** check and resolve procedure call statement procedureCall() or procedureCall;
 			- check if call is a procedure call designator, if not (procedure type symbol) try to make one out of it
 			- check if call is a procedure call designator, if not (procedure type symbol) try to make one out of it
 			- 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 ResolveProcedureCallStatement(procedureCall: SyntaxTree.ProcedureCallStatement): SyntaxTree.Statement;
 		VAR call: SyntaxTree.Designator;
 		VAR call: SyntaxTree.Designator;
 		BEGIN
 		BEGIN
-			IF Trace THEN D.Str("VisitProcedureCallStatement"); D.Ln; END;
+			IF Trace THEN D.Str("ResolveProcedureCallStatement"); D.Ln; END;
 			call := procedureCall.call;
 			call := procedureCall.call;
 			IF (call # NIL) &  ~(call IS SyntaxTree.ParameterDesignator) & ~(call IS SyntaxTree.ProcedureCallDesignator) & ~(call IS SyntaxTree.BuiltinCallDesignator)  THEN
 			IF (call # NIL) &  ~(call IS SyntaxTree.ParameterDesignator) & ~(call IS SyntaxTree.ProcedureCallDesignator) & ~(call IS SyntaxTree.BuiltinCallDesignator)  THEN
 				IF procedureCall.ignore THEN Error(procedureCall.position, "ignoring non-procedure call") END;
 				IF procedureCall.ignore THEN Error(procedureCall.position, "ignoring non-procedure call") END;
@@ -6559,7 +6542,6 @@ TYPE
 
 
 			call := ResolveDesignator(call);
 			call := ResolveDesignator(call);
 
 
-
 			IF call = SyntaxTree.invalidDesignator THEN
 			IF call = SyntaxTree.invalidDesignator THEN
 				(* error already handled *)
 				(* error already handled *)
 			ELSIF call IS SyntaxTree.StatementDesignator THEN
 			ELSIF call IS SyntaxTree.StatementDesignator THEN
@@ -6575,7 +6557,8 @@ TYPE
 				Error(procedureCall.position,"ignoring procedure call without return value");
 				Error(procedureCall.position,"ignoring procedure call without return value");
 			END;
 			END;
 			procedureCall.SetCall(call);
 			procedureCall.SetCall(call);
-		END VisitProcedureCallStatement;
+			RETURN procedureCall;
+		END ResolveProcedureCallStatement;
 
 
 		(** check and resolve assignment LHS := RHS
 		(** check and resolve assignment LHS := RHS
 			- resolve LHS and RHS
 			- resolve LHS and RHS
@@ -6584,7 +6567,7 @@ TYPE
 			- check if LHS is variable (i.e. assignable)
 			- check if LHS is variable (i.e. assignable)
 			- convert RHS if necessary
 			- convert RHS if necessary
 		**)
 		**)
-		PROCEDURE VisitAssignment*(assignment: SyntaxTree.Assignment);
+		PROCEDURE ResolveAssignment(assignment: SyntaxTree.Assignment): SyntaxTree.Statement;
 		VAR
 		VAR
 			left: SyntaxTree.Designator;
 			left: SyntaxTree.Designator;
 			right, expression: SyntaxTree.Expression;
 			right, expression: SyntaxTree.Expression;
@@ -6599,24 +6582,24 @@ TYPE
 			ELSIF IsIndexOperator(left) & left.assignable THEN
 			ELSIF IsIndexOperator(left) & left.assignable THEN
 				(* LHS is index write operator call *)
 				(* LHS is index write operator call *)
 				procedureCallDesignator :=  left(SyntaxTree.ProcedureCallDesignator);
 				procedureCallDesignator :=  left(SyntaxTree.ProcedureCallDesignator);
-				resolvedStatement := SyntaxTree.NewProcedureCallStatement(assignment.position, FALSE, procedureCallDesignator, assignment.outer);
+				RETURN SyntaxTree.NewProcedureCallStatement(assignment.position, FALSE, procedureCallDesignator, assignment.outer);
 			ELSIF CheckVariable(left) THEN
 			ELSIF CheckVariable(left) THEN
 				expression := NewOperatorCall(assignment.position, Scanner.Becomes, left, right, NIL);
 				expression := NewOperatorCall(assignment.position, Scanner.Becomes, left, right, NIL);
 				IF (expression # NIL) & (expression IS SyntaxTree.ProcedureCallDesignator) THEN
 				IF (expression # NIL) & (expression IS SyntaxTree.ProcedureCallDesignator) THEN
 					procedureCallDesignator := expression(SyntaxTree.ProcedureCallDesignator);
 					procedureCallDesignator := expression(SyntaxTree.ProcedureCallDesignator);
-					resolvedStatement := SyntaxTree.NewProcedureCallStatement(assignment.position, FALSE, procedureCallDesignator, assignment.outer);
+					RETURN SyntaxTree.NewProcedureCallStatement(assignment.position, FALSE, procedureCallDesignator, assignment.outer);
 				ELSIF (expression # NIL) & (expression IS SyntaxTree.StatementDesignator) THEN
 				ELSIF (expression # NIL) & (expression IS SyntaxTree.StatementDesignator) THEN
-					resolvedStatement := expression(SyntaxTree.StatementDesignator).statement;
+					RETURN expression(SyntaxTree.StatementDesignator).statement;
 				ELSIF AssignmentCompatible(left, right) THEN
 				ELSIF AssignmentCompatible(left, right) THEN
 					right := NewConversion(right.position, right, left.type.resolved, NIL);
 					right := NewConversion(right.position, right, left.type.resolved, NIL);
 					assignment.SetLeft(left);
 					assignment.SetLeft(left);
 					assignment.SetRight(right);
 					assignment.SetRight(right);
-					resolvedStatement := assignment
 				END
 				END
-			END
-		END VisitAssignment;
+			END;
+			RETURN assignment;
+		END ResolveAssignment;
 
 
-		PROCEDURE VisitCommunicationStatement*(communication: SyntaxTree.CommunicationStatement);
+		PROCEDURE ResolveCommunicationStatement(communication: SyntaxTree.CommunicationStatement): SyntaxTree.Statement;
 		VAR
 		VAR
 			left: SyntaxTree.Designator;
 			left: SyntaxTree.Designator;
 			right: SyntaxTree.Expression;
 			right: SyntaxTree.Expression;
@@ -6632,7 +6615,7 @@ TYPE
 			expression := NewOperatorCall(communication.position, communication.op, left, right, NIL);
 			expression := NewOperatorCall(communication.position, communication.op, left, right, NIL);
 			IF (expression # NIL) & (expression IS SyntaxTree.ProcedureCallDesignator) THEN
 			IF (expression # NIL) & (expression IS SyntaxTree.ProcedureCallDesignator) THEN
 				procedureCallDesignator := expression(SyntaxTree.ProcedureCallDesignator);
 				procedureCallDesignator := expression(SyntaxTree.ProcedureCallDesignator);
-				resolvedStatement := SyntaxTree.NewProcedureCallStatement(communication.position, FALSE, procedureCallDesignator, communication.outer);
+				RETURN SyntaxTree.NewProcedureCallStatement(communication.position, FALSE, procedureCallDesignator, communication.outer);
 			ELSE
 			ELSE
 
 
 				IF ~cellsAreObjects THEN ImportModule(Global.NameChannelModule,communication.position) END;
 				IF ~cellsAreObjects THEN ImportModule(Global.NameChannelModule,communication.position) END;
@@ -6681,7 +6664,8 @@ TYPE
 					Error(communication.position, "unsupported operation");
 					Error(communication.position, "unsupported operation");
 				END;
 				END;
 			END;
 			END;
-		END VisitCommunicationStatement;
+			RETURN communication;
+		END ResolveCommunicationStatement;
 
 
 		(** check and resolve if/eslif part
 		(** check and resolve if/eslif part
 			- check condition
 			- check condition
@@ -6706,7 +6690,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 ResolveIfStatement(ifStatement: SyntaxTree.IfStatement): SyntaxTree.Statement;
 		VAR elsif: SyntaxTree.IfPart; i: LONGINT; ifPartTrue, prevUnreachable: BOOLEAN;
 		VAR elsif: SyntaxTree.IfPart; i: LONGINT; ifPartTrue, prevUnreachable: BOOLEAN;
 		BEGIN
 		BEGIN
 			prevUnreachable := currentIsUnreachable;
 			prevUnreachable := currentIsUnreachable;
@@ -6723,7 +6707,8 @@ TYPE
 				StatementSequence(ifStatement.elsePart)
 				StatementSequence(ifStatement.elsePart)
 			END;
 			END;
 			currentIsUnreachable := prevUnreachable;
 			currentIsUnreachable := prevUnreachable;
-		END VisitIfStatement;
+			RETURN ifStatement;
+		END ResolveIfStatement;
 
 
 		PROCEDURE WithPart(withPart: SyntaxTree.WithPart; variable: SyntaxTree.Designator);
 		PROCEDURE WithPart(withPart: SyntaxTree.WithPart; variable: SyntaxTree.Designator);
 		VAR 
 		VAR 
@@ -6784,7 +6769,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 ResolveWithStatement(withStatement: SyntaxTree.WithStatement): SyntaxTree.Statement;
 		VAR i,j: LONGINT; prevScope: SyntaxTree.Scope; variable: SyntaxTree.Designator;
 		VAR i,j: LONGINT; prevScope: SyntaxTree.Scope; variable: SyntaxTree.Designator;
 		BEGIN
 		BEGIN
 			prevScope := currentScope;
 			prevScope := currentScope;
@@ -6809,7 +6794,8 @@ TYPE
 				StatementSequence(withStatement.elsePart)
 				StatementSequence(withStatement.elsePart)
 			END;
 			END;
 			currentScope := prevScope;
 			currentScope := prevScope;
-		END VisitWithStatement;
+			RETURN withStatement;
+		END ResolveWithStatement;
 
 
 		(** check and resolve case part <<a, b, c..d: StatementSequence>>
 		(** check and resolve case part <<a, b, c..d: StatementSequence>>
 			- check expression to be constant or case range expression <<first .. last>> with constants 'first' and 'last' and compatible to type
 			- check expression to be constant or case range expression <<first .. last>> with constants 'first' and 'last' and compatible to type
@@ -6846,7 +6832,7 @@ TYPE
 					(* read out 'first' and 'last' *)
 					(* read out 'first' and 'last' *)
 					left := expression(SyntaxTree.RangeExpression).first;
 					left := expression(SyntaxTree.RangeExpression).first;
 					right := expression(SyntaxTree.RangeExpression).last;
 					right := expression(SyntaxTree.RangeExpression).last;
-					(* guaranteed by VisitRangeExpression: *)
+					(* guaranteed by ResolveRangeExpression: *)
 					ASSERT((left # NIL) & (right # NIL));
 					ASSERT((left # NIL) & (right # NIL));
 					ASSERT(left.type.resolved = right.type.resolved);
 					ASSERT(left.type.resolved = right.type.resolved);
 					left := CompatibleConversion(left.position, left, type);
 					left := CompatibleConversion(left.position, left, type);
@@ -6907,7 +6893,7 @@ TYPE
 			- check variable
 			- check variable
 			- check case parts
 			- check case parts
 		**)
 		**)
-		PROCEDURE VisitCaseStatement*(caseStatement: SyntaxTree.CaseStatement);
+		PROCEDURE ResolveCaseStatement(caseStatement: SyntaxTree.CaseStatement): SyntaxTree.Statement;
 		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: Basic.Integer; min,max: Basic.Integer;
 			ch: CHAR; l: Basic.Integer; min,max: Basic.Integer;
 		BEGIN
 		BEGIN
@@ -6944,14 +6930,14 @@ TYPE
 				END;
 				END;
 				IF EnterCase(caseList,l,l) & (caseStatement.elsePart = NIL) THEN Error(caseStatement.position,"no matching case label") END;
 				IF EnterCase(caseList,l,l) & (caseStatement.elsePart = NIL) THEN Error(caseStatement.position,"no matching case label") END;
 			END;
 			END;
-
-		END VisitCaseStatement;
+			RETURN caseStatement;
+		END ResolveCaseStatement;
 
 
 		(** check and resolve while statement
 		(** check and resolve while statement
 			- check condition
 			- check condition
 			- check statement sequence
 			- check statement sequence
 		**)
 		**)
-		PROCEDURE VisitWhileStatement*(whileStatement: SyntaxTree.WhileStatement);
+		PROCEDURE ResolveWhileStatement(whileStatement: SyntaxTree.WhileStatement): SyntaxTree.Statement;
 		VAR prevIsUnreachable,b: BOOLEAN;
 		VAR prevIsUnreachable,b: BOOLEAN;
 		BEGIN
 		BEGIN
 			prevIsUnreachable := currentIsUnreachable;
 			prevIsUnreachable := currentIsUnreachable;
@@ -6962,18 +6948,20 @@ TYPE
 				END;
 				END;
 			END;
 			END;
 			StatementSequence(whileStatement.statements);
 			StatementSequence(whileStatement.statements);
-			currentIsUnreachable := prevIsUnreachable
-		END VisitWhileStatement;
+			currentIsUnreachable := prevIsUnreachable;
+			RETURN whileStatement;
+		END ResolveWhileStatement;
 
 
 		(** check and resolve repeat statement
 		(** check and resolve repeat statement
 			- check condition
 			- check condition
 			- check statement sequence
 			- check statement sequence
 		**)
 		**)
-		PROCEDURE VisitRepeatStatement*(repeatStatement: SyntaxTree.RepeatStatement);
+		PROCEDURE ResolveRepeatStatement(repeatStatement: SyntaxTree.RepeatStatement): SyntaxTree.Statement;
 		BEGIN
 		BEGIN
 			repeatStatement.SetCondition(ResolveCondition(repeatStatement.condition));
 			repeatStatement.SetCondition(ResolveCondition(repeatStatement.condition));
 			StatementSequence(repeatStatement.statements);
 			StatementSequence(repeatStatement.statements);
-		 END VisitRepeatStatement;
+			RETURN repeatStatement;
+		 END ResolveRepeatStatement;
 
 
 
 
 		PROCEDURE GetGuard(symbol: SyntaxTree.Symbol; VAR type: SyntaxTree.Type): BOOLEAN;
 		PROCEDURE GetGuard(symbol: SyntaxTree.Symbol; VAR type: SyntaxTree.Type): BOOLEAN;
@@ -6996,7 +6984,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 ResolveForStatement(forStatement: SyntaxTree.ForStatement): SyntaxTree.Statement;
 		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);
@@ -7049,26 +7037,29 @@ TYPE
 			forStatement.SetBy(expression);
 			forStatement.SetBy(expression);
 
 
 			StatementSequence(forStatement.statements);
 			StatementSequence(forStatement.statements);
-		END VisitForStatement;
+			RETURN forStatement;
+		END ResolveForStatement;
 
 
 		(** 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 ResolveLoopStatement(loopStatement: SyntaxTree.LoopStatement): SyntaxTree.Statement;
 		BEGIN
 		BEGIN
-			StatementSequence(loopStatement.statements)
-		END VisitLoopStatement;
+			StatementSequence(loopStatement.statements);
+			RETURN loopStatement;
+		END ResolveLoopStatement;
 
 
-		PROCEDURE VisitExitableBlock*(exitableBlock: SyntaxTree.ExitableBlock);
+		PROCEDURE ResolveExitableBlock(exitableBlock: SyntaxTree.ExitableBlock): SyntaxTree.Statement;
 		BEGIN
 		BEGIN
 			StatementSequence(exitableBlock.statements);
 			StatementSequence(exitableBlock.statements);
-		END VisitExitableBlock;
+			RETURN exitableBlock;
+		END ResolveExitableBlock;
 
 
 
 
 		(** 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 ResolveExitStatement(exitStatement: SyntaxTree.ExitStatement): SyntaxTree.Statement;
 		VAR outer: SyntaxTree.Statement;
 		VAR outer: SyntaxTree.Statement;
 		BEGIN
 		BEGIN
 			outer := exitStatement.outer;
 			outer := exitStatement.outer;
@@ -7078,7 +7069,8 @@ TYPE
 			IF outer = NIL THEN
 			IF outer = NIL THEN
 				Error(exitStatement.position,"exit statement not within loop statement");
 				Error(exitStatement.position,"exit statement not within loop statement");
 			END;
 			END;
-		 END VisitExitStatement;
+			RETURN exitStatement;
+		 END ResolveExitStatement;
 
 
 		(** check and resolve return statement RETURN [expression]
 		(** check and resolve return statement RETURN [expression]
 			- check expression (if any)
 			- check expression (if any)
@@ -7086,7 +7078,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 ResolveReturnStatement(returnStatement: SyntaxTree.ReturnStatement): SyntaxTree.Statement;
 		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
@@ -7133,12 +7125,13 @@ TYPE
 					END;
 					END;
 				END;
 				END;
 			END;
 			END;
-		 END VisitReturnStatement;
+			RETURN returnStatement;
+		 END ResolveReturnStatement;
 
 
 		(** 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 ResolveAwaitStatement(awaitStatement: SyntaxTree.AwaitStatement): SyntaxTree.Statement;
 		VAR condition: SyntaxTree.Expression;
 		VAR condition: SyntaxTree.Expression;
 		BEGIN
 		BEGIN
 			condition := ResolveCondition(awaitStatement.condition);
 			condition := ResolveCondition(awaitStatement.condition);
@@ -7149,7 +7142,8 @@ TYPE
 				Error(awaitStatement.position,"senseless await statement with constant condition");
 				Error(awaitStatement.position,"senseless await statement with constant condition");
 			END;
 			END;
 			awaitStatement.SetCondition(condition);
 			awaitStatement.SetCondition(condition);
-		END VisitAwaitStatement;
+			RETURN awaitStatement;
+		END ResolveAwaitStatement;
 
 
 		PROCEDURE CheckSystemImport(position: Position);
 		PROCEDURE CheckSystemImport(position: Position);
 		VAR import: SyntaxTree.Import;
 		VAR import: SyntaxTree.Import;
@@ -7166,7 +7160,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 ResolveCode(code: SyntaxTree.Code);
 		VAR i: LONGINT; statement: SyntaxTree.Statement;
 		VAR i: LONGINT; statement: SyntaxTree.Statement;
 		BEGIN
 		BEGIN
 			CheckSystemImport(code.position);
 			CheckSystemImport(code.position);
@@ -7194,7 +7188,7 @@ TYPE
 					Error(statement.position, "(out) can only be assignment")
 					Error(statement.position, "(out) can only be assignment")
 				END;
 				END;
 			END;
 			END;
-		END VisitCode;
+		END ResolveCode;
 
 
 
 
 		(** check and set flags of a statement block
 		(** check and set flags of a statement block
@@ -7299,7 +7293,7 @@ TYPE
 			- check flags (exclusive)
 			- check flags (exclusive)
 			- check statement sequence
 			- check statement sequence
 		**)
 		**)
-		PROCEDURE VisitStatementBlock*(statementBlock: SyntaxTree.StatementBlock);
+		PROCEDURE ResolveStatementBlock(statementBlock: SyntaxTree.StatementBlock);
 		VAR recentExclusive, recentUnreachable, recentRealtime: BOOLEAN; recentScope: SyntaxTree.Scope;
 		VAR recentExclusive, recentUnreachable, recentRealtime: BOOLEAN; recentScope: SyntaxTree.Scope;
 		BEGIN
 		BEGIN
 			recentScope := currentScope;
 			recentScope := currentScope;
@@ -7324,7 +7318,7 @@ TYPE
 			currentIsExclusive := recentExclusive;
 			currentIsExclusive := recentExclusive;
 			currentIsUnreachable := recentUnreachable;
 			currentIsUnreachable := recentUnreachable;
 			currentScope := recentScope;
 			currentScope := recentScope;
-		END VisitStatementBlock;
+		END ResolveStatementBlock;
 
 
 		(** check and resolve body
 		(** check and resolve body
 			- check flags (active, priority, safe)
 			- check flags (active, priority, safe)
@@ -7332,7 +7326,7 @@ TYPE
 		 **)
 		 **)
 		PROCEDURE Body(body: SyntaxTree.Body);
 		PROCEDURE Body(body: SyntaxTree.Body);
 		BEGIN
 		BEGIN
-			VisitStatementBlock(body);
+			ResolveStatementBlock(body);
 			IF body.isActive THEN
 			IF body.isActive THEN
 				IF  ~currentIsBodyProcedure THEN
 				IF  ~currentIsBodyProcedure THEN
 					Error(body.position,"active flag not in object body");
 					Error(body.position,"active flag not in object body");