瀏覽代碼

Patched compatibility problem
Added alias for inline scopes

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

felixf 6 年之前
父節點
當前提交
e72d61944b
共有 3 個文件被更改,包括 64 次插入4 次删除
  1. 9 0
      source/FoxIntermediateBackend.Mod
  2. 12 1
      source/FoxSemanticChecker.Mod
  3. 43 3
      source/FoxSyntaxTree.Mod

+ 9 - 0
source/FoxIntermediateBackend.Mod

@@ -10599,6 +10599,9 @@ TYPE
 		PROCEDURE GetBaseRegister(VAR result: IntermediateCode.Operand; scope,baseScope: SyntaxTree.Scope);
 		VAR left,right: IntermediateCode.Operand;level: LONGINT;
 		BEGIN
+			WHILE (scope # NIL) & (scope IS SyntaxTree.BlockScope) DO
+				scope := scope.outerScope;
+			END;
 			IF scope # baseScope THEN
 				(* left := [fp+8] *)
 				IntermediateCode.InitMemory(right,addressType,fp,ToMemoryUnits(system,2*addressType.sizeInBits));
@@ -10958,6 +10961,12 @@ TYPE
 		BEGIN
 			VisitProcedure(x);
 		END VisitOperator;
+		
+		PROCEDURE VisitAlias(x: SyntaxTree.Alias);
+		BEGIN
+			VExpression(x.expression);
+		END VisitAlias;
+		
 
 		(** statements *)
 

+ 12 - 1
source/FoxSemanticChecker.Mod

@@ -3833,6 +3833,7 @@ TYPE
 			returnType: SyntaxTree.Type;
 			const: SyntaxTree.Constant;
 			var: SyntaxTree.Variable;
+			alias: SyntaxTree.Alias;
 		BEGIN
 			IF Trace THEN D.Str("ProcedureCallDesignator"); D.Ln; END;
 			result := SyntaxTree.invalidDesignator;
@@ -3897,7 +3898,7 @@ TYPE
 			END;
 
 			IF InliningSupport & (procedure # NIL) & IsOberonInline(procedure) THEN
-				NEW(inlineScope, currentScope); 
+				inlineScope := SyntaxTree.NewBlockScope(currentScope);
 				procedureType := procedure.type(SyntaxTree.ProcedureType);
 
 				formalParameter := procedureType.firstParameter;
@@ -3917,6 +3918,10 @@ TYPE
 						const.SetType(actualParameter.type);
 						inlineScope.AddConstant(const);
 						inlineScope.EnterSymbol(const, duplicate);
+					ELSIF (formalParameter.kind IN {SyntaxTree.ConstParameter, SyntaxTree.VarParameter}) & SimpleExpression(actualParameter) THEN
+						alias := SyntaxTree.NewAlias(actualParameter.position, formalParameter.name, actualParameter);
+						alias.SetType(actualParameter.type);
+						inlineScope.EnterSymbol(alias, duplicate);
 					ELSE
 						var := SyntaxTree.NewVariable(actualParameter.position, formalParameter.name); 
 						(* copy expression to var *)
@@ -5897,6 +5902,7 @@ TYPE
 			| SyntaxTree.Variable DO ResolveVariable(x)
 			| SyntaxTree.Operator DO ResolveOperator(x)
 			| SyntaxTree.Procedure DO ResolveProcedure(x)
+			| SyntaxTree.Alias DO ResolveAlias(x)
 			| SyntaxTree.Builtin DO ResolveBuiltin(x)
 			| SyntaxTree.Import DO ResolveImport(x)
 			END;
@@ -6377,6 +6383,11 @@ TYPE
 				currentIsBodyProcedure := recentIsBodyProcedure;
 			END;
 		END ResolveProcedure;
+		
+		PROCEDURE ResolveAlias(x: SyntaxTree.Alias);
+		BEGIN
+			x.SetExpression(ResolveExpression(x.expression));
+		END ResolveAlias;
 
 		(**
 			a builtin procedure is a global item that may not be modified locally

+ 43 - 3
source/FoxSyntaxTree.Mod

@@ -361,6 +361,9 @@ TYPE
 		PROCEDURE VisitProcedure*(x: Procedure);
 		BEGIN HALT(100) (* abstract *) END VisitProcedure;
 
+		PROCEDURE VisitAlias*(x: Alias);
+		BEGIN HALT(100) (* abstract *) END VisitAlias;
+
 		PROCEDURE VisitBuiltin*(x: Builtin);
 		BEGIN HALT(100) (* abstract *) END VisitBuiltin;
 
@@ -381,6 +384,7 @@ TYPE
 			| Variable DO VisitVariable(x)
 			| Operator DO VisitOperator(x)
 			| Procedure DO VisitProcedure(x)
+			| Alias DO VisitAlias(x)
 			| Builtin DO VisitBuiltin(x)
 			| Import DO VisitImport(x)
 			ELSE 
@@ -2445,6 +2449,7 @@ TYPE
 	VAR
 		procedureCall-: ProcedureCallDesignator;
 		block-: StatementBlock; (* contains scope *)
+		result-: Expression;
 		
 		PROCEDURE & InitInlineCall*(position: Position; o: ProcedureCallDesignator; b: StatementBlock);
 		BEGIN
@@ -2453,6 +2458,11 @@ TYPE
 			block := b;
 		END InitInlineCall;
 		
+		PROCEDURE SetResult*(e: Expression);
+		BEGIN
+			result := e;
+		END SetResult;
+
 	END InlineCallDesignator;
 
 	(** <<procedure(parameters)>>
@@ -3210,6 +3220,23 @@ TYPE
 		END SetValue;
 
 	END Property;
+	
+	Alias* = OBJECT (Symbol)
+	VAR
+		expression-: Expression;
+		
+		PROCEDURE & InitAlias*(position: Position; name: Identifier; e: Expression);
+		BEGIN
+			InitSymbol(position, name); 
+			expression := e;
+		END InitAlias;
+		
+		PROCEDURE SetExpression*(e: Expression);
+		BEGIN
+			expression := e;
+		END SetExpression;
+		
+	END Alias;
 
 
 	(** Procedure declaration symbol. Represents a procedure being defined in the form PROCEDURE name(parameters): returnType;
@@ -4219,7 +4246,7 @@ TYPE
 
 		PROCEDURE & InitBody(position: Position; scope: ProcedureScope);
 		BEGIN
-			InitStatementBlock(position,NIL,scope); finally := NIL; priority := NIL; inScope := scope; code := NIL;
+			InitStatementBlock(position,NIL,NIL); finally := NIL; priority := NIL; inScope := scope; code := NIL;
 			isActive := FALSE; isSafe := FALSE; isRealtime := FALSE;
 		END InitBody;
 
@@ -4293,7 +4320,7 @@ TYPE
 		ownerModule-: Module;
 
 
-		PROCEDURE & InitScope*(outer: Scope);
+		PROCEDURE & InitScope(outer: Scope);
 		BEGIN
 			firstSymbol := NIL; numberSymbols := 0;
 			firstConstant := NIL; lastConstant := NIL; numberConstants := 0;
@@ -4511,7 +4538,9 @@ TYPE
 		END NeedsTrace;
 
 	END ProcedureScope;
-
+		
+	BlockScope* = OBJECT(Scope)
+	END BlockScope; 
 
 	EnumerationScope*= OBJECT(Scope)
 	VAR
@@ -5153,6 +5182,12 @@ VAR
 		NEW( procedure, position, name, scope);  RETURN procedure
 	END NewProcedure;
 
+	PROCEDURE NewAlias*( position: Position;  name: Identifier; expression: Expression): Alias;
+	VAR alias: Alias;
+	BEGIN
+		NEW( alias, position, name, expression);  RETURN alias
+	END NewAlias;
+
 	PROCEDURE NewBuiltin*(position: Position; name: Identifier; id: LONGINT): Builtin;
 	VAR builtin: Builtin;
 	BEGIN
@@ -5768,6 +5803,11 @@ VAR
 	BEGIN	NEW(scope,outer); RETURN scope
 	END NewProcedureScope;
 
+	PROCEDURE NewBlockScope*(outer: Scope): BlockScope;
+	VAR scope: BlockScope;
+	BEGIN	NEW(scope,outer); RETURN scope
+	END NewBlockScope;
+
 	PROCEDURE NewModuleScope*(): ModuleScope;
 	VAR scope: ModuleScope;
 	BEGIN	NEW(scope); RETURN scope