فهرست منبع

Enabled separate imports / separate compilation of cells within a module (TRM / ARM / AMD separation)

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6836 8c9fc860-2736-0410-a75d-ab315db34111
felixf 9 سال پیش
والد
کامیت
3c00209322

+ 1 - 0
source/FoxAMDBackend.Mod

@@ -3140,6 +3140,7 @@ TYPE
 			cRegisters[4] := R8 - RAX;
 			cRegisters[5] := R9 - RAX; 
 			
+			SetName("AMD");
 		END InitBackendAMD64;
 
 		PROCEDURE Initialize(diagnostics: Diagnostics.Diagnostics; log: Streams.Writer; flags: SET; checker: SemanticChecker.Checker; system: Global.System);

+ 1 - 0
source/FoxARMBackend.Mod

@@ -3337,6 +3337,7 @@ TYPE
 			system := NIL;
 			initLocals := TRUE;
 			SetHasLinkRegister;
+			SetName("ARM");
 		END InitBackendARM;
 
 		PROCEDURE Initialize(diagnostics: Diagnostics.Diagnostics; log: Streams.Writer; flags: SET; checker: SemanticChecker.Checker; system: Global.System);

+ 6 - 0
source/FoxBackend.Mod

@@ -23,6 +23,7 @@ TYPE
 		oberon07-: BOOLEAN;
 		instructionWidth -: LONGINT;
 		hasLinkRegister-: BOOLEAN;
+		name-: ARRAY 32 OF CHAR;
 
 		(* constructor *)
 		PROCEDURE & InitBackend *;
@@ -77,6 +78,11 @@ TYPE
 			SELF.checker := checker;
 			SELF.system := system;
 		END Initialize;
+		
+		PROCEDURE SetName*(CONST name: ARRAY OF CHAR);
+		BEGIN
+			COPY(name, SELF.name);
+		END SetName;
 
 		(* Get the system used by this backend (singleton) *)
 		PROCEDURE GetSystem*():Global.System;

+ 1 - 1
source/FoxBinarySymbolFile.Mod

@@ -246,7 +246,7 @@ TYPE
 		BEGIN
 			typeList := NIL; SELF.system := system; NEW(typeFixes);
 			NEW(streamDiagnostics, D.Log);
-			checker := SemanticChecker.NewChecker(streamDiagnostics,FALSE,FALSE,TRUE,system,symbolFile,importCache);
+			checker := SemanticChecker.NewChecker(streamDiagnostics,FALSE,FALSE,TRUE,system,symbolFile,importCache,"");
 		END Init;
 
 		(* types that do not refer to other types *)

+ 7 - 1
source/FoxCompiler.Mod

@@ -97,6 +97,7 @@ TYPE
 		split: Strings.StringArray;
 		sectionOffset: LONGINT;
 		flags: SET;
+		backendName: ARRAY 32 OF CHAR;
 
 		PROCEDURE FinalMessage(error: BOOLEAN; CONST msg: ARRAY OF CHAR);
 		VAR message,name: ARRAY 256 OF CHAR;
@@ -174,7 +175,12 @@ TYPE
 				IF (options.symbolFile # NIL) THEN
 					options.symbolFile.Initialize(diagnostics,system,options.destPath);
 				END;
-				checker := SemanticChecker.NewChecker(diagnostics,Info IN flags,UseDarwinCCalls IN flags,Cooperative IN flags,system,options.symbolFile,importCache);
+				IF options.backend # NIL THEN
+					COPY(options.backend.name, backendName);
+				ELSE
+					backendName := "";
+				END;
+				checker := SemanticChecker.NewChecker(diagnostics,Info IN flags,UseDarwinCCalls IN flags,Cooperative IN flags,system,options.symbolFile,importCache,backendName);
 				checker.replacements := options.replacements;
 				checker.Module(module);
 				IF checker.error THEN

+ 3 - 1
source/FoxGlobal.Mod

@@ -59,6 +59,7 @@ CONST
 	StringEngine*="Engine";
 	StringTRM*="TRM";
 	StringTRMS*="TRMS";
+	StringBackend*="Backend";
 
 	(* traps *)
 	WithTrap* = 1;
@@ -188,7 +189,7 @@ VAR
 	NameWinAPI-,NameC-,NameMovable-,NameUntraced-,NameDelegate-,NameInterrupt-, NamePcOffset-, NameNoPAF-,NameEntry-, NameExit-, NameFixed-,NameFictive-, NameAligned-,NameStackAligned-,
 	NameExclusive-,NameActive-,NamePriority-,NameSafe-,NameRealtime-, NameDynamic-, NameDataMemorySize-, NameCodeMemorySize-
 	, NameChannelWidth-, NameChannelDepth-, NameChannelModule-, NameVector-, NameFloatingPoint-, NameNoMul-,NameNonBlockingIO-, NameTRM-, NameTRMS-, NameEngine-, NameFinal-, NameAbstract-,
-	NameFrequencyDivider-, NameRegister-,NameNoReturn-,NamePlain-,NameUnsafe-,NameDisposable-,NameUnchecked-,NameUncooperative-: SyntaxTree.Identifier;
+	NameBackend-, NameFrequencyDivider-, NameRegister-,NameNoReturn-,NamePlain-,NameUnsafe-,NameDisposable-,NameUnchecked-,NameUncooperative-: SyntaxTree.Identifier;
 
 	identifiers: ARRAY 2 OF ARRAY end OF SyntaxTree.Identifier;
 
@@ -1651,6 +1652,7 @@ TYPE
 		NameNonBlockingIO:=SyntaxTree.NewIdentifier(StringNonBlockingIO);
 		NameTRM := SyntaxTree.NewIdentifier(StringTRM);
 		NameTRMS := SyntaxTree.NewIdentifier(StringTRMS);
+		NameBackend := SyntaxTree.NewIdentifier(StringBackend);
 		NameEngine := SyntaxTree.NewIdentifier(StringEngine);
 		NameFinal := SyntaxTree.NewIdentifier(StringFinal);
 		NameAbstract := SyntaxTree.NewIdentifier(StringAbstract);

+ 6 - 1
source/FoxIntermediateBackend.Mod

@@ -324,7 +324,12 @@ TYPE
 			IF HasFlag(x.modifiers, Global.StringFloatingPoint) THEN INCL(capabilities, Global.FloatingPointCapability) END;
 			IF HasFlag(x.modifiers, Global.StringVector) THEN INCL(capabilities, Global.VectorCapability) END;
 			backend.SetCapabilities(capabilities);
-			Scope(x.cellScope);
+			
+			IF ~implementationVisitor.checker.SkipImplementation(x) THEN
+				Scope(x.cellScope);
+			END;
+			
+			
 		END VisitCellType;
 
 		PROCEDURE VisitProcedureType(x: SyntaxTree.ProcedureType);

+ 8 - 2
source/FoxParser.Mod

@@ -1424,6 +1424,8 @@ TYPE
 
 			IF Optional( Scanner.Semicolon ) THEN END;
 
+			
+			IF Optional(Scanner.Import) THEN ImportList(cellScope) END;
 			DeclarationSequence( cellScope);
 			IF Peek(Scanner.Begin) OR Peek(Scanner.Code) THEN
 				cellScope.SetBodyProcedure(BodyProcedure(cellScope));
@@ -2133,7 +2135,7 @@ TYPE
 			ImportList = 'import' Import { ',' Import } ';'.
 			Import     = Identifier [':=' Identifier] ['in' Identifier].
 		**)
-		PROCEDURE ImportList( moduleScope: SyntaxTree.ModuleScope );
+		PROCEDURE ImportList( scope: SyntaxTree.Scope );
 		VAR alias, name, context: SyntaxTree.Identifier;  import: SyntaxTree.Import; position,idPosition: LONGINT;
 		BEGIN
 			IF Trace THEN S( "ImportList" ) END;
@@ -2150,7 +2152,11 @@ TYPE
 						context := Identifier(idPosition);
 						IF context # SyntaxTree.invalidIdentifier THEN  import.SetContext(context) END;
 					END;
-					moduleScope.AddImport( import );
+					WITH scope: SyntaxTree.ModuleScope DO
+						scope.AddImport( import );
+					| scope: SyntaxTree.CellScope DO
+						scope.AddImport( import );
+					END;
 				END;
 			UNTIL ~Optional( Scanner.Comma );
 			IF Lax THEN Ignore(Scanner.Semicolon) ELSE Check( Scanner.Semicolon ) END;

+ 83 - 8
source/FoxSemanticChecker.Mod

@@ -86,6 +86,8 @@ TYPE
 		phase: LONGINT;
 		system-: Global.System;
 		symbolFileFormat-: Formats.SymbolFileFormat;
+		backendName-: ARRAY 32 OF CHAR;
+
 
 		(* temporary variables for the visitors
 		    they replace variables on a stack during use of the visitor pattern and may only be
@@ -108,7 +110,7 @@ TYPE
 		cellsAreObjects: BOOLEAN;
 		variableAccessed: BOOLEAN;
 
-		PROCEDURE &InitChecker*(diagnostics: Diagnostics.Diagnostics; verboseErrorMessage,useDarwinCCalls,cooperative: BOOLEAN; system: Global.System; symbolFileFormat: Formats.SymbolFileFormat; VAR importCache: SyntaxTree.ModuleScope);
+		PROCEDURE &InitChecker*(diagnostics: Diagnostics.Diagnostics; verboseErrorMessage,useDarwinCCalls,cooperative: BOOLEAN; system: Global.System; symbolFileFormat: Formats.SymbolFileFormat; VAR importCache: SyntaxTree.ModuleScope; CONST backend: ARRAY OF CHAR);
 		BEGIN
 			SELF.diagnostics := diagnostics;
 			SELF.useDarwinCCalls := useDarwinCCalls;
@@ -135,6 +137,7 @@ TYPE
 			currentIsExclusive := FALSE;
 			withEntries := NIL;
 			SELF.cellsAreObjects := system.cellsAreObjects;
+			COPY(backend, backendName);
 		END InitChecker;
 
 		(** report error **)
@@ -201,6 +204,8 @@ TYPE
 				s := NIL;
 				IF (symbol # NIL) & (symbol.access * SyntaxTree.Public = {}) & (symbol.scope IS SyntaxTree.CellScope) (* hidden copies of parameters *) THEN
 					s := symbol.scope(SyntaxTree.CellScope).ownerCell.FindParameter(name);
+				ELSIF (symbol = NIL) & (scope IS SyntaxTree.CellScope) THEN
+					symbol := scope(SyntaxTree.CellScope).ownerCell.FindParameter(name);
 				END;
 
 				IF (symbol # NIL) & (symbol IS SyntaxTree.Parameter) & (symbol.scope IS SyntaxTree.CellScope) THEN (* ok, symbol auto-export in scope *)
@@ -834,6 +839,48 @@ TYPE
 			END;
 		END HasValue;
 
+		PROCEDURE HasStringValue(modifiers: SyntaxTree.Modifier; name: SyntaxTree.Identifier; VAR position: LONGINT; VAR value: ARRAY OF CHAR): BOOLEAN;
+		VAR prev,this: SyntaxTree.Modifier;
+		BEGIN
+			this := modifiers;prev := NIL;
+			WHILE (this # NIL) & (this.identifier # name) DO
+				prev := this; this := this.nextModifier;
+			END;
+			IF this # NIL THEN
+				IF this.expression = NIL THEN
+					Error(this.position,Diagnostics.Invalid,"expected expression value");
+				ELSE
+					this.SetExpression(ConstantExpression(this.expression));
+					IF CheckStringValue(this.expression,value) THEN END;
+				END;
+				this.Resolved;
+				position := this.position;
+				RETURN TRUE
+			ELSE RETURN FALSE
+			END;
+		END HasStringValue;
+
+		PROCEDURE SkipImplementation*(x: SyntaxTree.CellType): BOOLEAN;
+		VAR svalue: ARRAY 32 OF CHAR; position: LONGINT;
+		BEGIN
+			IF cellsAreObjects THEN RETURN FALSE 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, "~");
+					IF svalue = backendName THEN
+						RETURN TRUE;
+					END;
+				ELSIF svalue # backendName THEN
+					RETURN TRUE;
+				END;
+			END;
+			IF x.baseType # NIL THEN
+				RETURN SkipImplementation(x.baseType.resolved(SyntaxTree.CellType));
+			END;
+			RETURN FALSE;
+		END SkipImplementation;
+
 		PROCEDURE CheckModifiers(modifiers: SyntaxTree.Modifier; checkUse: BOOLEAN);
 		VAR this: SyntaxTree.Modifier;
 		BEGIN
@@ -1051,6 +1098,8 @@ TYPE
 			str: Scanner.StringType;
 			atype: SyntaxTree.ArrayType;
 			prev: SyntaxTree.Scope;
+			skip: BOOLEAN;
+			svalue: ARRAY 32 OF CHAR;
 		BEGIN
 		
 			IF TypeNeedsResolution(x) THEN
@@ -1119,6 +1168,7 @@ TYPE
 								atype.SetArrayBase(modifier.expression.type(SyntaxTree.StringType).baseType);
 								atype.SetLength(Global.NewIntegerValue(system,-1, (* type(SyntaxTree.StringType).length *) 256 (*! check if this is a good idea *) ));
 								property.SetType(atype);
+								
 							ELSE
 								Error(modifier.position, Diagnostics.Invalid, "unsupported property type");
 							END;
@@ -1146,9 +1196,16 @@ TYPE
 				END;*)
 				CheckModifiers(modifier, FALSE);
 
-
-				Declarations(x.cellScope);
-
+				IF ~SkipImplementation(x) THEN
+					Declarations(x.cellScope);
+				ELSE
+					parameter :=x.firstParameter;
+					WHILE(parameter # NIL) DO
+						parameter.SetScope(x.cellScope);
+						parameter := parameter.nextParameter;
+					END;
+				END;
+				
 				(* process parameters *)
 				prev := currentScope;
 				currentScope := x.cellScope;
@@ -4867,6 +4924,20 @@ TYPE
 			RETURN result;
 		END CheckIntegerValue;
 
+		PROCEDURE CheckStringValue(x: SyntaxTree.Expression; VAR value: ARRAY OF CHAR): BOOLEAN;
+		VAR result: BOOLEAN;
+		BEGIN
+			result := FALSE;
+			IF x = SyntaxTree.invalidExpression THEN
+			ELSIF (x.resolved # NIL) & (x.resolved IS SyntaxTree.StringValue) THEN
+				result := TRUE;
+				COPY(x.resolved(SyntaxTree.StringValue).value^, value);
+			ELSE
+				Error(x.position,Diagnostics.Invalid,"expression is not an integer constant");
+			END;
+			RETURN result;
+		END CheckStringValue;
+
 		PROCEDURE IsUnsignedValue(x: SyntaxTree.Expression; maxSizeInBits: LONGINT): BOOLEAN;
 		BEGIN
 			IF (x.resolved # NIL) & (x.resolved IS SyntaxTree.IntegerValue) THEN
@@ -8315,8 +8386,10 @@ TYPE
 			END;
 
 			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);
+				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;
@@ -9730,10 +9803,10 @@ TYPE
 	END EnterCase;
 
 	(** generate and return a new checker object, errors are entered into diagnostics **)
-	PROCEDURE NewChecker*(diagnostics: Diagnostics.Diagnostics; verboseErrorMessage,useDarwinCCalls,cooperative: BOOLEAN; system: Global.System; symbolFileFormat: Formats.SymbolFileFormat; VAR importCache: SyntaxTree.ModuleScope): Checker;
+	PROCEDURE NewChecker*(diagnostics: Diagnostics.Diagnostics; verboseErrorMessage,useDarwinCCalls,cooperative: BOOLEAN; system: Global.System; symbolFileFormat: Formats.SymbolFileFormat; VAR importCache: SyntaxTree.ModuleScope; CONST backend: ARRAY OF CHAR): Checker;
 	VAR checker: Checker;
 	BEGIN
-		NEW(checker, diagnostics,verboseErrorMessage,useDarwinCCalls,cooperative,system,symbolFileFormat,importCache);
+		NEW(checker, diagnostics,verboseErrorMessage,useDarwinCCalls,cooperative,system,symbolFileFormat,importCache,backend);
 		RETURN checker
 	END NewChecker;
 
@@ -9890,5 +9963,7 @@ TYPE
 	BEGIN
 		RETURN ~OptimizeMethodTable OR IsStaticProcedure(procedure)
 	END InMethodTable;
+	
+
 
 END FoxSemanticChecker.

+ 30 - 1
source/FoxSyntaxTree.Mod

@@ -4839,6 +4839,7 @@ TYPE
 		ownerCell-: CellType;
 		bodyProcedure-: Procedure;
 		constructor-: Procedure;
+		firstImport-,lastImport-: Import; numberImports: LONGINT; (* imported modules *)
 
 		PROCEDURE & InitCellScope(outer: Scope);
 		BEGIN
@@ -4861,7 +4862,35 @@ TYPE
 		PROCEDURE SetConstructor*(p: Procedure);
 		BEGIN constructor := p
 		END SetConstructor;
-		
+
+		PROCEDURE AddImport*(i: Import);
+		BEGIN
+			ASSERT(i # NIL);
+			ASSERT(i.nextImport = NIL);
+			IF lastImport= NIL THEN firstImport:= i ELSE lastImport.nextImport := i END;
+			lastImport := i;
+			INC(numberImports);
+		END AddImport;
+
+		PROCEDURE FindImport*(identifier: Identifier): Import;
+		VAR p: Import;
+		BEGIN
+			p := firstImport;
+			WHILE(p#NIL) & (p.name # identifier) DO p := p.nextImport END; (* finds imports and re-imports! *)
+			RETURN p;
+		END FindImport;
+
+		PROCEDURE GetImport*( index: LONGINT ): Import;
+		VAR import: Import;
+		BEGIN
+			import := firstImport;
+			WHILE(import # NIL) & (index > 0) DO
+				import := import.nextImport;
+				DEC(index);
+			END;
+			RETURN import;
+		END GetImport;
+				
 		PROCEDURE FindSymbol*(identifier: Identifier): Symbol;
 		VAR p: Symbol; base: Type;
 		BEGIN

+ 1 - 0
source/FoxTRMBackend.Mod

@@ -2183,6 +2183,7 @@ TYPE
 			myInstructionSet:=defaultInstructionSet;
 			SetHasLinkRegister;
 			recentInstructionWidth := Sections.UnknownSize;
+			SetName("TRM");
 		END InitBackendTRM;
 
 		PROCEDURE Initialize(diagnostics: Diagnostics.Diagnostics; log: Streams.Writer; flags: SET; checker: SemanticChecker.Checker; system: Global.System);

+ 1 - 1
source/FoxTextualSymbolFile.Mod

@@ -27,7 +27,7 @@ TYPE
 
 			IF (module # NIL) & ~(SyntaxTree.Resolved IN module.state) THEN
 				(*! should rather be done by importer *)
-				checker := SemanticChecker.NewChecker(NIL,FALSE,FALSE,TRUE,system,SELF,importCache);
+				checker := SemanticChecker.NewChecker(NIL,FALSE,FALSE,TRUE,system,SELF,importCache,"");
 				checker.Module(module); (* semantic check *)
 				IF checker.error THEN module := NIL END;
 			END;