Browse Source

Interpreter can handle constructors

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6665 8c9fc860-2736-0410-a75d-ab315db34111
felixf 9 years ago
parent
commit
5062f3efbf

+ 12 - 2
source/FoxIntermediateBackend.Mod

@@ -12541,9 +12541,9 @@ TYPE
 					TypeEntry(source, parameter.type);
 					TypeEntry(source, parameter.type);
 					Info(source,"flags");
 					Info(source,"flags");
 					IF parameter.kind = SyntaxTree.VarParameter THEN
 					IF parameter.kind = SyntaxTree.VarParameter THEN
-						Set(source, {1});
+						Set(source, {SyntaxTree.FlagParameterVar});
 					ELSIF parameter.kind = SyntaxTree.ConstParameter THEN
 					ELSIF parameter.kind = SyntaxTree.ConstParameter THEN
-						Set(source,{2});
+						Set(source,{SyntaxTree.FlagParameterConst});
 					ELSE
 					ELSE
 						Set(source, {});
 						Set(source, {});
 					END;
 					END;
@@ -12882,6 +12882,7 @@ TYPE
 			PROCEDURE ProcedureArray(source: IntermediateCode.Section; procedure: SyntaxTree.Procedure);
 			PROCEDURE ProcedureArray(source: IntermediateCode.Section; procedure: SyntaxTree.Procedure);
 			VAR pc: LONGINT; size: LONGINT; 
 			VAR pc: LONGINT; size: LONGINT; 
 				segmentedName: Basic.SegmentedName;
 				segmentedName: Basic.SegmentedName;
+				flags: SET;
 			BEGIN
 			BEGIN
 				Array(source,pc,"Modules.ProcedureEntry");
 				Array(source,pc,"Modules.ProcedureEntry");
 
 
@@ -12906,6 +12907,15 @@ TYPE
 
 
 						(* return type entry *)
 						(* return type entry *)
 						TypeEntry(source, procedure.type(SyntaxTree.ProcedureType).returnType);
 						TypeEntry(source, procedure.type(SyntaxTree.ProcedureType).returnType);
+						Info(source, "flags");
+						flags := {};
+						IF procedure.type(SyntaxTree.ProcedureType).isDelegate THEN
+							INCL(flags, SyntaxTree.FlagProcedureDelegate)
+						END;
+						IF procedure.isConstructor THEN
+							INCL(flags, SyntaxTree.FlagProcedureConstructor)
+						END;
+						Set(source, flags);
 
 
 						INC(size);
 						INC(size);
 					END;
 					END;

+ 19 - 4
source/FoxInterpreter.Mod

@@ -647,6 +647,9 @@ TYPE
 			address: ADDRESS;
 			address: ADDRESS;
 			o: ANY;
 			o: ANY;
 			anyValue: InterpreterSymbols.AnyValue;
 			anyValue: InterpreterSymbols.AnyValue;
+			proc: InterpreterSymbols.ProcedureResult;
+			ignore: Result;
+			e: SyntaxTree.Expression;
 		BEGIN
 		BEGIN
 			position := x.position;
 			position := x.position;
 			p0 := NIL; p1 := NIL; p2 := NIL; 
 			p0 := NIL; p1 := NIL; p2 := NIL; 
@@ -655,9 +658,6 @@ TYPE
 			ELSE
 			ELSE
 				len := 0
 				len := 0
 			END;
 			END;
-			IF len > 0 THEN p0 := x.parameters.GetExpression(0); t0 := p0.type.resolved END;
-			IF len > 1 THEN p1 := x.parameters.GetExpression(1); t1 := p1.type.resolved END;
-			IF len > 2 THEN p2 := x.parameters.GetExpression(2); t2 := p2.type.resolved END;
 			CASE x.id OF
 			CASE x.id OF
 			(* ----- NEW -----*)
 			(* ----- NEW -----*)
 			Global.New:
 			Global.New:
@@ -666,6 +666,18 @@ TYPE
 					address := result.Address();
 					address := result.Address();
 					Heaps.NewRec(o, address, FALSE);
 					Heaps.NewRec(o, address, FALSE);
 					NEW(anyValue, o);
 					NEW(anyValue, o);
+					
+					proc := result(InterpreterSymbols.TypeResult).Constructor();
+					IF proc # NIL THEN
+						proc.Pars();
+						proc.PushAddress(o);
+						FOR i := 0 TO x.parameters.Length()-1 DO
+							e := x.parameters.GetExpression(i);
+							IF ~proc.Push(Designate(e)) THEN Error("wrong parameter"); item.object := NIL; RETURN END;
+						END;
+						IF ~proc.Check() THEN Error("non-matching parameter number"); item.object := NIL; RETURN END; 
+						ignore := proc.Evaluate();
+					END;
 					item.object := anyValue;
 					item.object := anyValue;
 				ELSE
 				ELSE
 					Error("No Type");
 					Error("No Type");
@@ -937,8 +949,11 @@ TYPE
 		BEGIN
 		BEGIN
 			IF error THEN RETURN FALSE END;
 			IF error THEN RETURN FALSE END;
 			Expression(x);
 			Expression(x);
+			IF error THEN RETURN FALSE END;
 			LoadValue();
 			LoadValue();
-			w := item.object(Value);
+			IF item.object # NIL THEN 
+				w := item.object(Value);
+			END;
 			RETURN ~error
 			RETURN ~error
 		END GetValue;
 		END GetValue;
 		
 		

+ 33 - 2
source/FoxInterpreterSymbols.Mod

@@ -1,6 +1,6 @@
 MODULE FoxInterpreterSymbols; (** AUTHOR ""; PURPOSE ""; *)
 MODULE FoxInterpreterSymbols; (** AUTHOR ""; PURPOSE ""; *)
 
 
-IMPORT Strings, Basic := FoxBasic, StringPool, Streams, Commands, PersistentObjects, Modules, Machine, SYSTEM;
+IMPORT Strings, Basic := FoxBasic, StringPool, Streams, Commands, PersistentObjects, Modules, Machine, SyntaxTree := FoxSyntaxTree, SYSTEM;
 
 
 CONST
 CONST
 	TAB = 09X;
 	TAB = 09X;
@@ -112,6 +112,11 @@ TYPE
 		BEGIN
 		BEGIN
 			RETURN NIL;
 			RETURN NIL;
 		END Evaluate;
 		END Evaluate;
+		
+		PROCEDURE Constructor*(): ProcedureResult;
+		BEGIN
+			RETURN FindConstructor(SELF, type);
+		END Constructor;
 
 
 	END TypeResult;
 	END TypeResult;
 
 
@@ -146,7 +151,6 @@ TYPE
 					RETURN field;
 					RETURN field;
 				ELSE 
 				ELSE 
 					type := FindType(mod.typeInfo, name);
 					type := FindType(mod.typeInfo, name);
-					TRACE(name, type);
 					IF type # NIL THEN
 					IF type # NIL THEN
 						NEW(typeResult, name, type);
 						NEW(typeResult, name, type);
 					END;
 					END;
@@ -371,6 +375,7 @@ TYPE
 			set: SET;
 			set: SET;
 			var: BOOLEAN;
 			var: BOOLEAN;
 			v:Value;
 			v:Value;
+			a: ADDRESS;
 		BEGIN
 		BEGIN
 			IF (proc.parameters = NIL) OR (index >= LEN(proc.parameters)) THEN RETURN FALSE END; 
 			IF (proc.parameters = NIL) OR (index >= LEN(proc.parameters)) THEN RETURN FALSE END; 
 			type := proc.parameters[index].type;
 			type := proc.parameters[index].type;
@@ -442,6 +447,12 @@ TYPE
 						stack.PushSet(set);
 						stack.PushSet(set);
 						RETURN TRUE
 						RETURN TRUE
 					END;
 					END;
+				|sfTypePointerToRecord:
+					IF v.GetAddress(a) THEN
+						stack.PushA(a);
+						RETURN TRUE
+					END;
+				ELSE TRACE(ORD(type.class)); HALT(100);
 				END;
 				END;
 			ELSIF type.subclass = sfTypeOpenArray THEN
 			ELSIF type.subclass = sfTypeOpenArray THEN
 				CASE type.class OF
 				CASE type.class OF
@@ -682,6 +693,26 @@ TYPE
 		RETURN NIL; 
 		RETURN NIL; 
 	END FindInType;
 	END FindInType;
 	
 	
+	PROCEDURE FindConstructor(scope: Result; type: ADDRESS): ProcedureResult;
+	VAR tag: ADDRESS; typeInfo: Modules.TypeDesc; i, num: LONGINT; 
+			proc: ProcedureResult; f: FieldResult;	
+	BEGIN
+		FOR i := 15 TO 0 BY -1 DO
+			SYSTEM.GET(type-(2+i)*SIZEOF(ADDRESS), tag); 
+			IF tag # NIL THEN
+				SYSTEM.GET(tag-SIZEOF(ADDRESS), typeInfo); 
+				FOR num := 0 TO LEN(typeInfo.procedures)-1 DO
+					IF SyntaxTree.FlagProcedureConstructor IN typeInfo.procedures[num].flags THEN
+						NEW(proc, scope, typeInfo.procedures[num].name^, typeInfo.procedures[num]);
+						proc.address := typeInfo.procedures[num].address;
+						RETURN proc
+					END;
+				END;
+			END;
+		END;
+		RETURN NIL; 
+	END FindConstructor;
+	
 TYPE
 TYPE
 	Value*= OBJECT(Result)
 	Value*= OBJECT(Result)
 
 

+ 7 - 0
source/FoxSyntaxTree.Mod

@@ -54,6 +54,13 @@ CONST
 	ArrayIndex* = 0;
 	ArrayIndex* = 0;
 	SetElement* = 1;
 	SetElement* = 1;
 	CaseGuard* = 2;
 	CaseGuard* = 2;
+	
+	(* reflection flags *)
+	FlagProcedureDelegate*=0;
+	FlagProcedureConstructor*=1;
+	
+	FlagParameterVar*=1;
+	FlagParameterConst*=2;
 
 
 TYPE
 TYPE
 	SourceCode*= Scanner.StringType;
 	SourceCode*= Scanner.StringType;

+ 1 - 0
source/Generic.Modules.Mod

@@ -83,6 +83,7 @@ TYPE
 		variables*: FieldEntries;
 		variables*: FieldEntries;
 		procedures*: ProcedureEntries;
 		procedures*: ProcedureEntries;
 		returnType*: EntryType;
 		returnType*: EntryType;
+		flags*: SET;
 	END;
 	END;
 
 
 	TypeDesc* = POINTER TO RECORD 
 	TypeDesc* = POINTER TO RECORD 

+ 2 - 1
source/InterpreterShell.Mod

@@ -838,6 +838,7 @@ TYPE
 					context.out.Ln;
 					context.out.Ln;
 					context.out.String(">");
 					context.out.String(">");
 					context.out.Update;
 					context.out.Update;
+					IF interpreter.error THEN interpreter.Reset END;
 					WHILE parser.Optional(Scanner.Escape) OR parser.Optional(Scanner.Semicolon) DO 
 					WHILE parser.Optional(Scanner.Escape) OR parser.Optional(Scanner.Semicolon) DO 
 						(*TRACE(parser.Token());*)
 						(*TRACE(parser.Token());*)
 					END;
 					END;
@@ -964,6 +965,6 @@ TYPE
 
 
 END InterpreterShell.
 END InterpreterShell.
 
 
-SystemTools.Free WMInterpreterShell InterpreterShell FoxInterpreter FoxInterpreterSymbols ~
+SystemTools.Free WMInterpreterShell InterpreterShell FoxInterpreter FoxInterpreterSymbols Test ~
 
 
 WMInterpreterShell.Open ~
 WMInterpreterShell.Open ~