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

Simplified

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6838 8c9fc860-2736-0410-a75d-ab315db34111
felixf 9 éve
szülő
commit
a2b77c1bc2
1 módosított fájl, 41 hozzáadás és 264 törlés
  1. 41 264
      source/FoxSemanticChecker.Mod

+ 41 - 264
source/FoxSemanticChecker.Mod

@@ -864,7 +864,7 @@ TYPE
 		VAR svalue: ARRAY 32 OF CHAR; position: LONGINT;
 		BEGIN
 			IF cellsAreObjects THEN RETURN FALSE END;
-			IF (backendName = "TRM") & x.isCellNet THEN D.TraceBack; RETURN TRUE END;
+			IF (backendName = "TRM") & x.isCellNet THEN  RETURN TRUE END;
 			IF HasStringValue(x.modifiers,Global.NameBackend,position,svalue) THEN 
 				IF svalue[0] = "~" THEN
 					Strings.TrimLeft(svalue, "~");
@@ -1023,7 +1023,7 @@ TYPE
 						Error(position,Diagnostics.Invalid,"invalid inheritance of disposable types");
 					END;
 				END;
-				Declarations(x.recordScope);
+				Declarations(x.recordScope, FALSE);
 
 				ResolveArrayStructure(x);
 
@@ -1079,136 +1079,6 @@ TYPE
 			resolvedType := ResolvedType(x);
 		END VisitRecordType;
 
-		(** declaration phase:
-			check and resolve all declarations of a scope (module scope, procedure scope, record scope):
-			- import lists (for module scopes)
-			- parameter list (for procedure scopes)
-			- constant declarations
-			- type declarations
-			- variable declarations
-			- procedure declarations
-			preformed in two stages:
-				- first all symbols are entered into the symbol table (with uniqueness check),
-				- then all symbols are resolved
-			after declaration check, bodies are entered into the global list of implementations that remain to be resolved after all declarations.
-
-			Declarations depend on other declarations, this procedure is neither thread safe not would it be wise to try concurrency here
-		**)
-		PROCEDURE Declarations2(scope: SyntaxTree.Scope);
-		VAR
-			constant: SyntaxTree.Constant;
-			typeDeclaration: SyntaxTree.TypeDeclaration;
-			variable: SyntaxTree.Variable;
-			procedure: SyntaxTree.Procedure;
-			prevScope: SyntaxTree.Scope;
-			parameter: SyntaxTree.Parameter;
-			import: SyntaxTree.Import;
-			symbol: SyntaxTree.Symbol;
-			prevPhase: LONGINT;
-			prevError : BOOLEAN;
-			
-			PROCEDURE DeclareCell(type: SyntaxTree.CellType);
-			VAR baseType: SyntaxTree.Type; property, prop: SyntaxTree.Property; variable: SyntaxTree.Variable;
-			BEGIN
-				IF type.baseType # NIL THEN 
-					baseType := type.baseType.resolved;
-					IF baseType IS SyntaxTree.PointerType THEN
-						baseType := baseType(SyntaxTree.PointerType).pointerBase.resolved;
-					END;
-					IF baseType IS SyntaxTree.CellType THEN
-						DeclareCell(baseType(SyntaxTree.CellType));
-					END;
-				END;
-				parameter := type.firstParameter;
-				WHILE(parameter # NIL) DO (* duplicates forbidden *)
-					variable := SyntaxTree.NewVariable(parameter.position, parameter.name);
-					variable.SetType(parameter.type);
-					variable.SetAccess(SyntaxTree.Hidden);
-					variable.SetModifiers(parameter.modifiers);
-					currentScope.PushVariable(variable);
-					(*
-					Register(parameter,scope, FALSE); 
-					*)
-					parameter := parameter.nextParameter;
-				END;
-				
-				property := type.firstProperty;
-				WHILE (property # NIL) DO (* duplicates allowed : overwrite *)
-					variable := currentScope.FindVariable(property.name);
-					IF (variable # NIL) & (variable IS SyntaxTree.Property) THEN (* overwrite *)
-						prop := variable(SyntaxTree.Property); 
-					ELSE (* add, duplicate symbols detection later *)
-						prop := SyntaxTree.NewProperty(property.position, property.name);
-						currentScope.PushVariable(prop);
-					END;
-					prop.SetType(property.type);
-					prop.SetValue(property.value);
-					prop.SetAccess(SyntaxTree.Hidden);
-					property := property.nextProperty;
-				END;
-			END DeclareCell;
-			
-			
-		BEGIN
-			prevError := error;
-			prevPhase := phase;
-			phase := DeclarationPhase;
-			prevScope := currentScope;
-			currentScope := scope;
-			error := FALSE;
-
-			IF scope IS SyntaxTree.CellScope THEN
-				DeclareCell(scope(SyntaxTree.CellScope).ownerCell);
-			END;
-			IF error THEN RETURN END;
-
-			(* constants *)
-			constant := scope.firstConstant;
-			WHILE (constant # NIL) DO
-				Register(constant, currentScope, FALSE); constant := constant.nextConstant;
-			END;
-			(* type declarations *)
-			typeDeclaration := scope.firstTypeDeclaration;
-			WHILE (typeDeclaration # NIL) DO
-				Register(typeDeclaration, currentScope, FALSE); typeDeclaration := typeDeclaration.nextTypeDeclaration;
-			END;
-			(* variables *)
-			variable := scope.firstVariable;
-			WHILE (variable # NIL) DO
-				Register(variable, currentScope, FALSE); variable := variable.nextVariable;
-			END;
-			(* procedures *)
-			procedure := scope.firstProcedure;
-			WHILE (procedure # NIL) DO
-				Register(procedure, currentScope, procedure IS SyntaxTree.Operator); procedure := procedure.nextProcedure;
-			END;
-
-			(*
-			(* now process all symbols without any presumption on the order *)
-			symbol := scope.firstSymbol;
-			WHILE(symbol # NIL) DO
-				IF ~(symbol IS SyntaxTree.Parameter) OR (symbol(SyntaxTree.Parameter).ownerType IS SyntaxTree.CellType) THEN
-					ResolveSymbol(symbol);
-				END;
-				symbol := symbol.nextSymbol;
-			END;
-			*)
-
-
-			(*
-			IF scope.ownerModule # NIL THEN
-				IF ~(scope IS SyntaxTree.CellScope) OR ~SkipImplementation(scope(SyntaxTree.CellScope).ownerCell) THEN
-					(* add scope to global list of all scopes, very handy for code generation and for checking implementations *)
-					scope.ownerModule.AddScope(scope);
-				END;
-			END;
-			*)
-			
-			phase := prevPhase;
-			currentScope := prevScope;
-			error := error OR prevError;
-		END Declarations2;
-
 			(** check and resolve cell type
 			- check base type: must be cell
 			- check declarations
@@ -1231,70 +1101,7 @@ TYPE
 			skip: BOOLEAN;
 			svalue: ARRAY 32 OF CHAR;
 			
-			PROCEDURE DeclareCell(type: SyntaxTree.CellType);
-			VAR baseType: SyntaxTree.Type; property, prop: SyntaxTree.Property; variable: SyntaxTree.Variable;
-			BEGIN
-				IF type.baseType # NIL THEN 
-					baseType := type.baseType.resolved;
-					IF baseType IS SyntaxTree.PointerType THEN
-						baseType := baseType(SyntaxTree.PointerType).pointerBase.resolved;
-					END;
-					IF baseType IS SyntaxTree.CellType THEN
-						DeclareCell(baseType(SyntaxTree.CellType));
-					END;
-				END;
-				
-				parameter := type.firstParameter;
-				WHILE(parameter # NIL) DO (* duplicates forbidden *)
-					variable := SyntaxTree.NewVariable(parameter.position, parameter.name);
-					variable.SetType(parameter.type);
-					variable.SetAccess(SyntaxTree.Hidden);
-					variable.SetModifiers(parameter.modifiers);
-					currentScope.PushVariable(variable);
-					(*
-					Register(parameter,scope, FALSE); 
-					*)
-					parameter := parameter.nextParameter;
-				END;
-				
-				
-				(*
-				property := type.firstProperty;
-				WHILE (property # NIL) DO (* duplicates allowed : overwrite *)
-					variable := currentScope.FindVariable(property.name);
-					IF (variable # NIL) & (variable IS SyntaxTree.Property) THEN (* overwrite *)
-						prop := variable(SyntaxTree.Property); 
-					ELSE (* add, duplicate symbols detection later *)
-						prop := SyntaxTree.NewProperty(property.position, property.name);
-						currentScope.PushVariable(prop);
-					END;
-					prop.SetType(property.type);
-					prop.SetValue(property.value);
-					prop.SetAccess(SyntaxTree.Hidden);
-					(*Register(prop,currentScope,FALSE);*)
-					property := property.nextProperty;
-				END;
-				*)
-				
-							variable := currentScope.firstVariable;
-			WHILE (variable # NIL) DO
-				D.Str0(variable.name);D.Ln;
-				Register(variable, currentScope, FALSE); variable := variable.nextVariable;
-			END;
-				
-				(* now process all symbols without any presumption on the order *)
-				symbol := currentScope.firstSymbol;
-				WHILE(symbol # NIL) DO
-					IF ~(symbol IS SyntaxTree.Parameter) OR (symbol(SyntaxTree.Parameter).ownerType IS SyntaxTree.CellType) THEN
-						ResolveSymbol(symbol);
-					END;
-					symbol := symbol.nextSymbol;
-				END;
-		
-			END DeclareCell;
-
 		BEGIN
-		
 			IF TypeNeedsResolution(x) THEN
 				recordBase := NIL;
 				IF cellsAreObjects THEN
@@ -1376,40 +1183,9 @@ TYPE
 						
 						modifier := modifier.nextModifier;
 					END;
-					
-				(*ELSE
-					
-					(* no: this should not be allowed on cell net types or check against global scope ...
-					IF HasValue(modifier, Global.NameFrequencyDivider, position,value) THEN
-						IF parameter # NIL THEN Error(position, Diagnostics.Invalid,"forbiddern frequency divider in non-terminal cellnet")
-						END;
-					END
-					*)
-				
-				END;*)
 				CheckModifiers(modifier, FALSE);
 
-				IF ~SkipImplementation(x) THEN
-					Declarations(x.cellScope);
-				ELSE
-		
-					Declarations2(x.cellScope);
-					
-					(*
-					prev := currentScope;
-					currentScope := x.cellScope;
-
-					DeclareCell(x);
-					currentScope := prev;
-					
-					parameter :=x.firstParameter;
-					WHILE(parameter # NIL) DO
-						parameter.SetScope(x.cellScope);
-						parameter := parameter.nextParameter;
-					END;
-					*)
-				
-				END;
+				Declarations(x.cellScope, SkipImplementation(x));
 				
 				(* process parameters *)
 				prev := currentScope;
@@ -7137,7 +6913,7 @@ TYPE
 				ELSIF procedure.isConstructor THEN
 					Error(procedure.position,Diagnostics.Invalid,"procedure illegaly marked as initializer - not in object scope");
 				END;
-				Declarations(procedure.procedureScope);
+				Declarations(procedure.procedureScope, FALSE);
 				(* body resolution part done as late fix of the procedure type *)
 				procedure.SetState(SyntaxTree.Resolved);
 				currentIsRealtime := recentIsRealtime;
@@ -8450,7 +8226,7 @@ TYPE
 
 			Declarations depend on other declarations, this procedure is neither thread safe not would it be wise to try concurrency here
 		**)
-		PROCEDURE Declarations(scope: SyntaxTree.Scope);
+		PROCEDURE Declarations(scope: SyntaxTree.Scope; skipImplementation: BOOLEAN);
 		VAR
 			constant: SyntaxTree.Constant;
 			typeDeclaration: SyntaxTree.TypeDeclaration;
@@ -8536,16 +8312,18 @@ TYPE
 				parameter := scope(SyntaxTree.ProcedureScope).ownerProcedure.type.resolved(SyntaxTree.ProcedureType).returnParameter;
 				IF parameter # NIL THEN Register(parameter, currentScope, FALSE); END;
 			ELSIF scope IS SyntaxTree.CellScope THEN
-				import := scope(SyntaxTree.CellScope).firstImport;
-				WHILE(import # NIL) DO
-					IF import.context = SyntaxTree.invalidIdentifier THEN import.SetContext(scope.ownerModule.context) END;
-					Register(import, currentScope, FALSE);
-					import := import.nextImport;
-				END;
-				import := scope(SyntaxTree.CellScope).firstImport;
-				WHILE(import # NIL) DO (* 2nd stage to avoid duplicate symbol *)
-					ResolveSymbol(import);
-					import := import.nextImport;
+				IF~skipImplementation THEN
+					import := scope(SyntaxTree.CellScope).firstImport;
+					WHILE(import # NIL) DO
+						IF import.context = SyntaxTree.invalidIdentifier THEN import.SetContext(scope.ownerModule.context) END;
+						Register(import, currentScope, FALSE);
+						import := import.nextImport;
+					END;
+					import := scope(SyntaxTree.CellScope).firstImport;
+					WHILE(import # NIL) DO (* 2nd stage to avoid duplicate symbol *)
+						ResolveSymbol(import);
+						import := import.nextImport;
+					END;
 				END;
 				DeclareCell(scope(SyntaxTree.CellScope).ownerCell);
 			END;
@@ -8572,37 +8350,36 @@ TYPE
 				Register(procedure, currentScope, procedure IS SyntaxTree.Operator); procedure := procedure.nextProcedure;
 			END;
 
-
-			(* now process all symbols without any presumption on the order *)
-			symbol := scope.firstSymbol;
-			WHILE(symbol # NIL) DO
-				IF ~(symbol IS SyntaxTree.Parameter) OR (symbol(SyntaxTree.Parameter).ownerType IS SyntaxTree.CellType) THEN
-					ResolveSymbol(symbol);
+			IF ~skipImplementation THEN
+				(* now process all symbols without any presumption on the order *)
+				symbol := scope.firstSymbol;
+				WHILE(symbol # NIL) DO
+					IF ~(symbol IS SyntaxTree.Parameter) OR (symbol(SyntaxTree.Parameter).ownerType IS SyntaxTree.CellType) THEN
+						ResolveSymbol(symbol);
+					END;
+					symbol := symbol.nextSymbol;
 				END;
-				symbol := symbol.nextSymbol;
-			END;
 
-			IF (scope IS SyntaxTree.ProcedureScope) & scope(SyntaxTree.ProcedureScope).ownerProcedure.type.isRealtime THEN
-				symbol := scope.firstSymbol;
-				WHILE symbol # NIL DO
-					IF (symbol IS SyntaxTree.Variable) OR (symbol IS SyntaxTree.Parameter) THEN
-						IF (symbol.type IS SyntaxTree.PointerType) OR (symbol.type IS SyntaxTree.QualifiedType) THEN
-							pointerFixes.Add(symbol, currentScope);
-						END;
-						IF ~symbol.type.resolved.isRealtime THEN
-							Error(symbol.position,Diagnostics.Invalid,"symbol has no realtime type");
+				IF (scope IS SyntaxTree.ProcedureScope) & scope(SyntaxTree.ProcedureScope).ownerProcedure.type.isRealtime THEN
+					symbol := scope.firstSymbol;
+					WHILE symbol # NIL DO
+						IF (symbol IS SyntaxTree.Variable) OR (symbol IS SyntaxTree.Parameter) THEN
+							IF (symbol.type IS SyntaxTree.PointerType) OR (symbol.type IS SyntaxTree.QualifiedType) THEN
+								pointerFixes.Add(symbol, currentScope);
+							END;
+							IF ~symbol.type.resolved.isRealtime THEN
+								Error(symbol.position,Diagnostics.Invalid,"symbol has no realtime type");
+							END;
 						END;
+						symbol := symbol.nextSymbol
 					END;
-					symbol := symbol.nextSymbol
 				END;
-			END;
 
-			IF ~error & ~system.GenerateVariableOffsets(scope) THEN
-				Error(Diagnostics.Invalid,Diagnostics.Invalid,"problems during offset computation in module");
-			END;
+				IF ~error & ~system.GenerateVariableOffsets(scope) THEN
+					Error(Diagnostics.Invalid,Diagnostics.Invalid,"problems during offset computation in module");
+				END;
 
-			IF scope.ownerModule # NIL THEN
-				IF ~(scope IS SyntaxTree.CellScope) OR ~SkipImplementation(scope(SyntaxTree.CellScope).ownerCell) THEN
+				IF  (scope.ownerModule # NIL) THEN
 					(* add scope to global list of all scopes, very handy for code generation and for checking implementations *)
 					scope.ownerModule.AddScope(scope);
 				END;
@@ -8716,7 +8493,7 @@ TYPE
 			IF (x.name = Global.SystemName) OR (x.name = Global.systemName) THEN Error(x.position,Diagnostics.Invalid,"name reserved") END;
 			IF x.context = SyntaxTree.invalidIdentifier THEN x.SetContext(Global.A2Name) END;
 			RemoveModuleFromCache(importCache,x);
-			Declarations(x.moduleScope);
+			Declarations(x.moduleScope, FALSE);
 			FixTypes();
 
 			IF module.isCellNet THEN