Browse Source

Allow for index operator on value types

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7127 8c9fc860-2736-0410-a75d-ab315db34111
felixf 8 years ago
parent
commit
d65ab17eb9
3 changed files with 32 additions and 5 deletions
  1. 10 0
      source/FoxGlobal.Mod
  2. 7 1
      source/FoxParser.Mod
  3. 15 4
      source/FoxSemanticChecker.Mod

+ 10 - 0
source/FoxGlobal.Mod

@@ -1537,6 +1537,16 @@ TYPE
 			WHILE toSize >= fromSize DO
 				toSize := toSize DIV 2; INC(distance);
 			END;
+		ELSIF (from IS SyntaxTree.IntegerType) & (to IS SyntaxTree.SizeType) & (toSize >= fromSize)  THEN
+			distance := 1;
+			WHILE toSize >= fromSize DO
+				toSize := toSize DIV 2; INC(distance);
+			END;
+		ELSIF (from IS SyntaxTree.SizeType) & (to IS SyntaxTree.IntegerType)  & (toSize >= fromSize) THEN
+			distance := 1;
+			WHILE toSize >= fromSize DO
+				toSize := toSize DIV 2; INC(distance);
+			END;
 		ELSIF (from IS SyntaxTree.CharacterType) & (to IS SyntaxTree.CharacterType) & (toSize >= fromSize)  OR
 			(from IS SyntaxTree.FloatType) & (to IS SyntaxTree.FloatType) & (toSize >= fromSize) 
 		THEN

+ 7 - 1
source/FoxParser.Mod

@@ -1486,7 +1486,13 @@ TYPE
 					IF Peek(Scanner.Identifier) THEN VariableDeclaration( recordScope ) END;
 				UNTIL ~Optional( Scanner.Semicolon );
 			END;
-			WHILE Optional(Scanner.Procedure) DO ProcedureDeclaration(recordScope); Ignore(Scanner.Semicolon) END; 
+			LOOP 
+				IF Optional(Scanner.Procedure) THEN ProcedureDeclaration(recordScope); Ignore(Scanner.Semicolon);
+				ELSIF Optional(Scanner.Operator) THEN OperatorDeclaration(recordScope); Ignore(Scanner.Semicolon);
+				ELSE EXIT 
+				END;
+			END;
+			(*WHILE Optional(Scanner.Procedure) DO ProcedureDeclaration(recordScope); Ignore(Scanner.Semicolon) END; *)
 			Check( Scanner.End );
 			IF Trace THEN E( "RecordType" ) END;
 			RETURN recordType

+ 15 - 4
source/FoxSemanticChecker.Mod

@@ -4225,6 +4225,7 @@ TYPE
 		PROCEDURE NewObjectOperatorCall*(position: Position; left: SyntaxTree.Expression; oper: LONGINT; parameters: SyntaxTree.ExpressionList; rhs: SyntaxTree.Expression): SyntaxTree.Designator;
 		VAR type: SyntaxTree.Type; expression: SyntaxTree.Expression; op: SyntaxTree.Operator; recordType: SyntaxTree.RecordType;
 			actualParameters: SyntaxTree.ExpressionList; i: LONGINT; result: SyntaxTree.Designator;
+			pointer: BOOLEAN; designator: SyntaxTree.Designator;
 
 			PROCEDURE FindOperator(recordType: SyntaxTree.RecordType; identifier: SyntaxTree.Identifier; actualParameters: SyntaxTree.ExpressionList): SyntaxTree.Operator;
 			VAR bestOperator: SyntaxTree.Operator; bestDistance: LONGINT; numberParameters: LONGINT; procedureType: SyntaxTree.ProcedureType;
@@ -4270,8 +4271,14 @@ TYPE
 			END FindOperator;
 		BEGIN
 			type := left.type.resolved;
-			IF ~(type IS SyntaxTree.PointerType) THEN RETURN NIL END;
-			recordType := type(SyntaxTree.PointerType).pointerBase.resolved(SyntaxTree.RecordType);
+			IF type IS SyntaxTree.RecordType THEN
+				pointer := FALSE;
+				recordType := type(SyntaxTree.RecordType);
+			ELSE
+				pointer := TRUE;
+				IF ~(type IS SyntaxTree.PointerType) THEN RETURN NIL END;
+				recordType := type(SyntaxTree.PointerType).pointerBase.resolved(SyntaxTree.RecordType);
+			END;
 
 			actualParameters := SyntaxTree.NewExpressionList();
 			IF parameters # NIL THEN
@@ -4284,7 +4291,9 @@ TYPE
 
 			op := FindOperator(recordType, SyntaxTree.NewIdentifier("[]"), actualParameters);
 			IF op # NIL THEN
-				expression := NewSymbolDesignator(position, NewDereferenceDesignator(Basic.invalidPosition, left(SyntaxTree.Designator)) , op);
+				designator := left(SyntaxTree.Designator);
+				IF pointer THEN designator := NewDereferenceDesignator(Basic.invalidPosition, designator) END;
+				expression := NewSymbolDesignator(position, designator , op);
 				ASSERT(expression IS SyntaxTree.Designator);
 				result := NewProcedureCallDesignator(position, expression(SyntaxTree.Designator), actualParameters);
 				result.SetRelatedAsot(left);
@@ -4394,7 +4403,9 @@ TYPE
 				indexDesignator := NIL;
 
 				(*!!! clean up *)
-				IF (type IS SyntaxTree.PointerType) & (type(SyntaxTree.PointerType).pointerBase.resolved IS SyntaxTree.RecordType) & ~IsArrayStructuredObjectType(type) THEN
+				IF (type IS SyntaxTree.PointerType) & (type(SyntaxTree.PointerType).pointerBase.resolved IS SyntaxTree.RecordType) & ~IsArrayStructuredObjectType(type) 
+					OR (type IS SyntaxTree.RecordType)
+				THEN
 					resolvedExpression := NewObjectOperatorCall(bracketDesignator.position, designator, 0, bracketDesignator.parameters,bracketDesignator.relatedRhs);
 					IF resolvedExpression = NIL THEN 
 						Error(bracketDesignator.position,"undefined operator");