Переглянути джерело

Implemented sending and receiving via stream operators

port designator << expression
designator << port expression

port designator <<? expression
designator <<? port expression

Stream operators >> and >>? can be parsed but are not implemented for ActiveCells3 because statements like 1+1 >> port contradict Oberon's syntax.

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6363 8c9fc860-2736-0410-a75d-ab315db34111
felixf 9 роки тому
батько
коміт
3c9373ca91

+ 68 - 27
source/FoxIntermediateBackend.Mod

@@ -3427,33 +3427,71 @@ TYPE
 					result.op := temp.op;
 					result.tag := nil; (* may be left over from calls to evaluate *)
 				END;
-			|Scanner.Questionmarks:
-				Evaluate(x.left, left);
-				Emit(Push(position,left.op));
-				ReleaseOperand(left);
-				Designate(x.right, right);
-				size := ToMemoryUnits(system,system.SizeOf(x.right.type));
-				IF ~backend.cellsAreObjects THEN
-					IF size # 1 THEN Error(x.right.position,"receive not implemented for complex data types") END;
-				END;
-				Emit(Push(position,right.op));
-				ReleaseOperand(right);
-				IF backend.cellsAreObjects THEN
-					CallThis(position,"ActiveCellsRuntime","ReceiveNonBlocking",2);
+			ELSE
+				IF (x.operator = Scanner.Questionmarks) OR (x.operator = Scanner.LessLessQ) & (x.right.type.resolved IS SyntaxTree.PortType) THEN
+					IF x.operator = Scanner.Questionmarks THEN
+						leftExpression := x.left;
+						rightExpression := x.right;
+					ELSE
+						leftExpression := x.right;
+						rightExpression := x.left;
+					END;
+					
+					Evaluate(leftExpression, left);
+					Emit(Push(position,left.op));
+					ReleaseOperand(left);
+					Designate(rightExpression, right);
+					size := ToMemoryUnits(system,system.SizeOf(x.right.type));
+					IF ~backend.cellsAreObjects THEN
+						IF size # 1 THEN Error(x.right.position,"receive not implemented for complex data types") END;
+					END;
+					Emit(Push(position,right.op));
+					ReleaseOperand(right);
+					IF backend.cellsAreObjects THEN
+						CallThis(position,"ActiveCellsRuntime","ReceiveNonBlocking",2);
+					ELSE
+						CallThis(position,ChannelModuleName,"ReceiveNonBlocking",2);
+					END;
+					InitOperand(result, ModeValue);
+					result.op := NewRegisterOperand(bool);
+					Emit(Result(position,result.op));
+					IF conditional THEN
+						IntermediateCode.InitImmediate(zero,setType,0);
+						BrneL(trueLabel,result.op,zero);
+						ReleaseOperand(result);
+						BrL(falseLabel);
+					END;
+				ELSIF (x.operator = Scanner.ExclamationMarks) OR (x.operator = Scanner.LessLessQ) & (x.left.type.resolved IS SyntaxTree.PortType) THEN
+					leftExpression := x.left;
+					rightExpression := x.right;
+
+					Evaluate(leftExpression, left);
+					Emit(Push(position,left.op));
+					ReleaseOperand(left);
+					Evaluate(rightExpression, right);
+					size := ToMemoryUnits(system,system.SizeOf(x.right.type));
+					IF ~backend.cellsAreObjects THEN
+						IF size # 1 THEN Error(x.right.position,"send not implemented for complex data types") END;
+					END;
+					Emit(Push(position,right.op));
+					ReleaseOperand(right);
+					IF backend.cellsAreObjects THEN
+						CallThis(position,"ActiveCellsRuntime","SendNonBlocking",2);
+					ELSE
+						CallThis(position,ChannelModuleName,"SendNonBlocking",2);
+					END;
+					InitOperand(result, ModeValue);
+					result.op := NewRegisterOperand(bool);
+					Emit(Result(position,result.op));
+					IF conditional THEN
+						IntermediateCode.InitImmediate(zero,setType,0);
+						BrneL(trueLabel,result.op,zero);
+						ReleaseOperand(result);
+						BrL(falseLabel);
+					END;
 				ELSE
-					CallThis(position,ChannelModuleName,"ReceiveNonBlocking",2);
+					HALT(100);
 				END;
-				InitOperand(result, ModeValue);
-				result.op := NewRegisterOperand(bool);
-				Emit(Result(position,result.op));
-				IF conditional THEN
-					IntermediateCode.InitImmediate(zero,setType,0);
-					BrneL(trueLabel,result.op,zero);
-					ReleaseOperand(result);
-					BrL(falseLabel);
-				END;
-			ELSE
-				HALT(100);
 			END;
 			destination := dest;
 			IF Trace THEN TraceExit("VisitBinaryExpression") END;
@@ -9491,10 +9529,10 @@ TYPE
 		END EmitCooperativeSwitch;
 
 		PROCEDURE VisitCommunicationStatement(communication: SyntaxTree.CommunicationStatement);
-		VAR p0,p1: SyntaxTree.Expression; s0,s1: Operand; size: LONGINT;
+		VAR p0,p1,tmp: SyntaxTree.Expression; s0,s1: Operand; size: LONGINT;
 		BEGIN
 			p0 := communication.left; p1 := communication.right;
-			IF communication.send THEN
+			IF (communication.op = Scanner.ExclamationMark) OR (communication.op = Scanner.LessLess) & (communication.left.type.resolved IS SyntaxTree.PortType) THEN
 				Evaluate(p0,s0);
 				Evaluate(p1,s1);
 				size := ToMemoryUnits(system,system.SizeOf(p1.type));
@@ -9515,6 +9553,9 @@ TYPE
 				END;
 			(* ----- RECEIVE ------*)
 			ELSE
+				IF (communication.op = Scanner.LessLess) & (communication.right.type.resolved IS SyntaxTree.PortType) THEN
+					tmp := p0; p0 := p1; p1 := tmp;
+				END;
 				Evaluate(p0,s0);
 				Emit(Push(position,s0.op));
 				Designate(p1,s1);

+ 6 - 10
source/FoxParser.Mod

@@ -100,6 +100,7 @@ CONST
 
 		RelationOp           = '=' | '.=' | '#' | '.#'
 		                     | '<' | '.<' | '<=' | '.<=' | '>' | '.>' | '>=' | '.>='
+		                     | '??' | '!!' | '<<?' | '>>?'		                     
 		                     | 'in' | 'is'
 
 		RangeExpression  = SimpleExpression | [SimpleExpression] '..' [SimpleExpression] ['by' SimpleExpression] | '*'.
@@ -757,15 +758,12 @@ TYPE
 					factor := SyntaxTree.NewUnaryExpression(position,factor,Scanner.Transpose);
 				END;
 			END;
-			IF Optional(Scanner.Questionmarks) THEN
-				factor := SyntaxTree.NewBinaryExpression(position, factor, Factor(), Scanner.Questionmarks)
-			END;
 			IF Trace THEN E( "Factor" ) END;
 			RETURN factor
 		END Factor;
 
 		(** Term = Factor {MulOp Factor}.
-		   MulOp = '*' | '**' | '.*' | '+*' | '/' | './' | 'div' | 'mod' | '&'.
+		   MulOp = '*' | '**' | '.*' | '+*' | '/' | './' | 'div' | 'mod' | '&' | '<<?' | '>>?' || '!'.
 		**)
 		PROCEDURE Term( ): SyntaxTree.Expression;
 		VAR term, factor: SyntaxTree.Expression;  operator: LONGINT; position: LONGINT;
@@ -813,6 +811,7 @@ TYPE
 			Expression           = RangeExpression [RelationOp RangeExpression].
 			RelationOp           = '=' | '.=' | '#' | '.#'
 			                     | '<' | '.<' | '<=' | '.<=' | '>' | '.>' | '>=' | '.>='
+			                     | '??' | '!!' | '<<?' | '>>?'
 			                     | 'in' | 'is'
 		**)
 		PROCEDURE Expression*( ): SyntaxTree.Expression;
@@ -890,13 +889,10 @@ TYPE
 						expression := Expression();
 						statement := SyntaxTree.NewAssignment( position, designator, expression,outer );
 						CommentStatement(statement);
-					ELSIF Optional(Scanner.ExclamationMark) THEN
-						expression := Expression();
-						statement := SyntaxTree.NewCommunicationStatement(position, TRUE, designator, expression, outer);
-						CommentStatement(statement);
-					ELSIF Optional(Scanner.Questionmark) THEN
+					ELSIF Peek(Scanner.ExclamationMark) OR Peek(Scanner.Questionmark) OR Peek(Scanner.LessLess) OR Peek(Scanner.GreaterGreater) THEN
 						expression := Expression();
-						statement := SyntaxTree.NewCommunicationStatement(position, FALSE, designator, expression, outer);
+						statement := SyntaxTree.NewCommunicationStatement(position, symbol.token, designator, expression, outer);
+						NextSymbol;
 						CommentStatement(statement);
 					ELSE
 						caller := SyntaxTree.NewProcedureCallStatement(designator.position, designator,outer);

+ 3 - 6
source/FoxPrintout.Mod

@@ -1525,17 +1525,14 @@ TYPE
 		END VisitAssignment;
 
 		PROCEDURE VisitCommunicationStatement(x: SyntaxTree.CommunicationStatement);
+		VAR identifier: SyntaxTree.Identifier;
 		BEGIN
 			Expression(x.left);
-			IF x.send THEN
-				w.String(" ! ");
-			ELSE
-				w.String(" ? ");
-			END;
+			identifier := Global.GetIdentifier(x.op,case);
+			w.String(" "); Identifier(identifier); w.String(" ");
 			 Expression(x.right);
 		END VisitCommunicationStatement;
 
-
 		PROCEDURE IfPart(x: SyntaxTree.IfPart);
 		BEGIN
 			Comments(x.comment, x, FALSE);

+ 63 - 43
source/FoxScanner.Mod

@@ -34,69 +34,71 @@ CONST
 	(* RelationOps: Equal ... Is *)
     	Equal DotEqual Unequal DotUnequal
     	Less DotLess  LessEqual DotLessEqual Greater DotGreater GreaterEqual DotGreaterEqual
+    	LessLessQ GreaterGreaterQ Questionmarks ExclamationMarks 
     	In Is
     	(* MulOps: Times ... And *)
     	Times TimesTimes DotTimes PlusTimes Slash Backslash DotSlash Div Mod And
     	(* AddOps: Or ... Minus *)
     	Or Plus Minus
     	(* Prefix Unary Operators Plus ... Not *)
-	Not
+		Not
     	(* expressions may start with Plus ... Identifier *)
-	LeftParenthesis LeftBracket LeftBrace Number Character String Nil Imag True False Self Result Identifier
-	(* statementy may start with Self ... Begin *)
-	If Case While Repeat For Loop With Exit Await Return Begin
-	(* symbols, expressions and statements cannot start with *)
-	Semicolon Transpose RightBrace RightBracket RightParenthesis Questionmark Questionmarks ExclamationMark ExclamationMarks Upto
-    	Arrow Period Comma Colon Of Then Do To By Becomes Bar End Else Elsif Until Finally
-	(* declaration elements *)
-	Code Const Type Var Out Procedure Operator Import Definition Module Cell CellNet Extern
-	(* composite type symbols *)
-	Array Object Record Pointer Enum Port Address Size Alias
-	(* assembler constants *)
-	Ln PC PCOffset
-	(* number types *)
-	Shortint Integer Longint Hugeint Real Longreal
-	Comment EndOfText
-	~
+		LeftParenthesis LeftBracket LeftBrace Number Character String Nil Imag True False Self Result Identifier
+		(* statementy may start with Self ... Begin *)
+		If Case While Repeat For Loop With Exit Await Return Begin
+		(* symbols, expressions and statements cannot start with *)
+		Semicolon Transpose RightBrace RightBracket RightParenthesis 
+		Questionmark ExclamationMark
+		LessLess GreaterGreater 
+		Upto Arrow Period Comma Colon Of Then Do To By Becomes Bar End Else Elsif Until Finally
+		(* declaration elements *)
+		Code Const Type Var Out Procedure Operator Import Definition Module Cell CellNet Extern
+		(* composite type symbols *)
+		Array Object Record Pointer Enum Port Address Size Alias
+		(* assembler constants *)
+		Ln PC PCOffset
+		(* number types *)
+		Shortint Integer Longint Hugeint Real Longreal
+		Comment EndOfText
+		~
 	*)
-
 	None*= 0; 
 	(* RelationOps: Equal ... Is *)
 	Equal*= 1; DotEqual*= 2; Unequal*= 3; DotUnequal*= 4; Less*= 5; DotLess*= 6; 
 	LessEqual*= 7; DotLessEqual*= 8; Greater*= 9; DotGreater*= 10; GreaterEqual*= 11; DotGreaterEqual*= 12; 
-	In*= 13; Is*= 14; 
+	LessLessQ*= 13; GreaterGreaterQ*= 14; Questionmarks*= 15; ExclamationMarks*= 16; In*= 17; Is*= 18; 
 	(* MulOps: Times ... And *)
-	Times*= 15; TimesTimes*= 16; DotTimes*= 17; PlusTimes*= 18; Slash*= 19; Backslash*= 20; 
-	DotSlash*= 21; Div*= 22; Mod*= 23; And*= 24; 
+	Times*= 19; TimesTimes*= 20; DotTimes*= 21; PlusTimes*= 22; Slash*= 23; Backslash*= 24; 
+	DotSlash*= 25; Div*= 26; Mod*= 27; And*= 28; 
 	(* AddOps: Or ... Minus *)
-	Or*= 25; Plus*= 26; Minus*= 27; 
+	Or*= 29; Plus*= 30; Minus*= 31; 
 	(* Prefix Unary Operators Plus ... Not *)
-	Not*= 28; 
+	Not*= 32; 
 	(* expressions may start with Plus ... Identifier *)
-	LeftParenthesis*= 29; LeftBracket*= 30; LeftBrace*= 31; Number*= 32; Character*= 33; String*= 34; 
-	Nil*= 35; Imag*= 36; True*= 37; False*= 38; Self*= 39; Result*= 40; 
-	Identifier*= 41; 
+	LeftParenthesis*= 33; LeftBracket*= 34; LeftBrace*= 35; Number*= 36; Character*= 37; String*= 38; 
+	Nil*= 39; Imag*= 40; True*= 41; False*= 42; Self*= 43; Result*= 44; 
+	Identifier*= 45; 
 	(* statementy may start with Self ... Begin *)
-	If*= 42; Case*= 43; While*= 44; Repeat*= 45; For*= 46; Loop*= 47; 
-	With*= 48; Exit*= 49; Await*= 50; Return*= 51; Begin*= 52; 
+	If*= 46; Case*= 47; While*= 48; Repeat*= 49; For*= 50; Loop*= 51; 
+	With*= 52; Exit*= 53; Await*= 54; Return*= 55; Begin*= 56; 
 	(* symbols, expressions and statements cannot start with *)
-	Semicolon*= 53; Transpose*= 54; RightBrace*= 55; RightBracket*= 56; RightParenthesis*= 57; Questionmark*= 58; 
-	Questionmarks*= 59; ExclamationMark*= 60; ExclamationMarks*= 61; Upto*= 62; Arrow*= 63; Period*= 64; 
-	Comma*= 65; Colon*= 66; Of*= 67; Then*= 68; Do*= 69; To*= 70; 
-	By*= 71; Becomes*= 72; Bar*= 73; End*= 74; Else*= 75; Elsif*= 76; 
-	Until*= 77; Finally*= 78; 
+	Semicolon*= 57; Transpose*= 58; RightBrace*= 59; RightBracket*= 60; RightParenthesis*= 61; Questionmark*= 62; 
+	ExclamationMark*= 63; LessLess*= 64; GreaterGreater*= 65; Upto*= 66; Arrow*= 67; Period*= 68; 
+	Comma*= 69; Colon*= 70; Of*= 71; Then*= 72; Do*= 73; To*= 74; 
+	By*= 75; Becomes*= 76; Bar*= 77; End*= 78; Else*= 79; Elsif*= 80; 
+	Until*= 81; Finally*= 82; 
 	(* declaration elements *)
-	Code*= 79; Const*= 80; Type*= 81; Var*= 82; Out*= 83; Procedure*= 84; 
-	Operator*= 85; Import*= 86; Definition*= 87; Module*= 88; Cell*= 89; CellNet*= 90; 
-	Extern*= 91; 
+	Code*= 83; Const*= 84; Type*= 85; Var*= 86; Out*= 87; Procedure*= 88; 
+	Operator*= 89; Import*= 90; Definition*= 91; Module*= 92; Cell*= 93; CellNet*= 94; 
+	Extern*= 95; 
 	(* composite type symbols *)
-	Array*= 92; Object*= 93; Record*= 94; Pointer*= 95; Enum*= 96; Port*= 97; 
-	Address*= 98; Size*= 99; Alias*= 100; 
+	Array*= 96; Object*= 97; Record*= 98; Pointer*= 99; Enum*= 100; Port*= 101; 
+	Address*= 102; Size*= 103; Alias*= 104; 
 	(* assembler constants *)
-	Ln*= 101; PC*= 102; PCOffset*= 103; 
+	Ln*= 105; PC*= 106; PCOffset*= 107; 
 	(* number types *)
-	Shortint*= 104; Integer*= 105; Longint*= 106; Hugeint*= 107; Real*= 108; Longreal*= 109; 
-	Comment*= 110; EndOfText*= 111; 
+	Shortint*= 108; Integer*= 109; Longint*= 110; Hugeint*= 111; Real*= 112; Longreal*= 113; 
+	Comment*= 114; EndOfText*= 115; 
 
 	SingleQuote = 27X;  DoubleQuote* = 22X;
 	Ellipsis = 7FX;   (* used in Scanner.GetNumber to return with ".." when reading an interval like 3..5 *)
@@ -881,10 +883,21 @@ TYPE
 					IF ch = '=' THEN GetNextCharacter;  s := Becomes  ELSE s := Colon END
 			| ';':     s := Semicolon;  GetNextCharacter
 			| '<':     GetNextCharacter;
-					IF ch = '=' THEN GetNextCharacter;  s := LessEqual ELSE s := Less;  END
+					IF ch = '=' THEN GetNextCharacter;  s := LessEqual 
+					ELSIF ch ='<' THEN GetNextCharacter; 
+						IF ch ='?' THEN GetNextCharacter; s := LessLessQ
+						ELSE s := LessLess
+						END;
+					ELSE s := Less;  
+					END
 			| '=':     s := Equal;  GetNextCharacter
 			| '>':     GetNextCharacter;
-					IF ch = '=' THEN GetNextCharacter;  s := GreaterEqual ELSE s := Greater;  END
+					IF ch = '=' THEN GetNextCharacter;  s := GreaterEqual 
+					ELSIF ch ='>' THEN GetNextCharacter; 
+						IF ch ='?' THEN GetNextCharacter; s := GreaterGreaterQ
+						ELSE s := GreaterGreater
+						END;
+					ELSE s := Greater;  END
 			| '[':     s := LeftBracket;  GetNextCharacter
 			| ']':     s := RightBracket;  GetNextCharacter
 			| '^':     s := Arrow;  GetNextCharacter
@@ -1471,6 +1484,13 @@ TYPE
 		EnterSymbol( "\", Backslash);
 		EnterSymbol( "`", Transpose);
 		EnterSymbol( "?",Questionmark);
+		EnterSymbol( "??",Questionmarks);
+		EnterSymbol( "!",ExclamationMark);
+		EnterSymbol( "!!",ExclamationMarks);
+		EnterSymbol( "<<",LessLess);
+		EnterSymbol( "<<?",LessLessQ);
+		EnterSymbol( ">>",GreaterGreater);
+		EnterSymbol( ">>?",GreaterGreaterQ);
 
 		Basic.SetErrorMessage(Number,"missing number");
 		Basic.SetErrorMessage(String,"missing string");

+ 28 - 3
source/FoxSemanticChecker.Mod

@@ -2967,7 +2967,9 @@ TYPE
 				ELSE
 					Error(binaryExpression.position,Diagnostics.Invalid,"operator not applicable between different enumerators");
 				END;
-			ELSIF (leftType IS SyntaxTree.PortType) & (operator = Scanner.Questionmarks) THEN
+			ELSIF (leftType IS SyntaxTree.PortType) & ((operator = Scanner.Questionmarks) OR (operator = Scanner.ExclamationMarks) OR (operator = Scanner.LessLessQ)) THEN
+				type := system.booleanType;
+			ELSIF (rightType IS SyntaxTree.PortType) & (operator = Scanner.LessLessQ) THEN
 				type := system.booleanType;
 			ELSIF (leftType IS SyntaxTree.BasicType) & (rightType IS SyntaxTree.BasicType)
 				OR IsCharacterType(leftType) & IsCharacterType(rightType)
@@ -7222,7 +7224,28 @@ TYPE
 
 			IF (left = SyntaxTree.invalidDesignator) OR (right = SyntaxTree.invalidExpression) THEN
 				(* error already handled *)
-			ELSIF communication.send & CheckPortType(left,outPort)  THEN
+			ELSIF communication.op = Scanner.LessLess THEN (* left is dest *)
+				IF (left.type.resolved IS SyntaxTree.PortType) & CheckPortType(left, outPort) THEN (* send *)
+					IF outPort.direction # SyntaxTree.OutPort THEN
+						Error(left.position,Diagnostics.Invalid,"not an out-port")
+					ELSIF outPort.sizeInBits # system.SizeOf(right.type) THEN
+						Error(left.position,Diagnostics.Invalid,"incompatible to port type");
+					ELSE
+						right := NewConversion(communication.position,right,left.type.resolved,NIL);
+						communication.SetRight(right)
+					END;
+				ELSIF (right.type.resolved IS SyntaxTree.PortType) & CheckPortType(right, inPort) THEN (* receive *)
+					IF CheckVariable(left) THEN
+						IF inPort.direction # SyntaxTree.InPort THEN
+							Error(left.position,Diagnostics.Invalid,"not an in-port")
+						ELSIF inPort.sizeInBits # system.SizeOf(right.type) THEN
+							Error(right.position,Diagnostics.Invalid,"incompatible to port type");
+						END;
+					END;
+				ELSE
+					Error(communication.position, -1, "unsupported stream operation");
+				END;
+			ELSIF (communication.op = Scanner.Questionmark)  & CheckPortType(left,outPort)  THEN
 				IF outPort.direction # SyntaxTree.OutPort THEN
 					Error(left.position,Diagnostics.Invalid,"not an out-port")
 				ELSIF outPort.sizeInBits # system.SizeOf(right.type) THEN
@@ -7231,7 +7254,7 @@ TYPE
 					right := NewConversion(communication.position,right,left.type.resolved,NIL);
 					communication.SetRight(right)
 				END;
-			ELSIF ~communication.send & CheckPortType(left,inPort) THEN
+			ELSIF (communication.op = Scanner.ExclamationMark) & CheckPortType(left,inPort) THEN
 				IF CheckVariable(right) THEN
 					IF inPort.direction # SyntaxTree.InPort THEN
 						Error(left.position,Diagnostics.Invalid,"not an in-port")
@@ -7239,6 +7262,8 @@ TYPE
 						Error(right.position,Diagnostics.Invalid,"incompatible to port type");
 					END;
 				END;
+			ELSE
+				Error(communication.position, -1, "unsupported operation");
 			END
 		END VisitCommunicationStatement;
 

+ 7 - 6
source/FoxSyntaxTree.Mod

@@ -3644,13 +3644,14 @@ TYPE
 
 	END Assignment;
 
-	(** << left ('!' | '?') right >> **)
+	(** << left ('!' | '?' | '<<' | '>>') right >> **)
 	CommunicationStatement* = OBJECT (Statement)
-	VAR left-: Designator; right-: Expression; send-: BOOLEAN;
+	VAR 
+		left-: Designator; right-: Expression; op-: LONGINT;
 
-		PROCEDURE & InitAssignment*( position: LONGINT;  send: BOOLEAN; left: Designator;  right: Expression; outer: Statement );
+		PROCEDURE & InitAssignment*( position: LONGINT; op: LONGINT; left: Designator;  right: Expression; outer: Statement );
 		BEGIN
-			InitStatement( position,outer );  SELF.send := send; SELF.left := left;  SELF.right := right;
+			InitStatement( position,outer );  SELF.op := op; SELF.left := left;  SELF.right := right;
 		END InitAssignment;
 
 		PROCEDURE SetLeft*(left: Designator);
@@ -5637,10 +5638,10 @@ VAR
 		NEW( assignment, position, left, right,outer );  RETURN assignment
 	END NewAssignment;
 
-	PROCEDURE NewCommunicationStatement*( position: LONGINT;  send: BOOLEAN; left: Designator; right: Expression; outer: Statement): CommunicationStatement;
+	PROCEDURE NewCommunicationStatement*( position: LONGINT;  op: LONGINT; left: Designator; right: Expression; outer: Statement): CommunicationStatement;
 	VAR communication: CommunicationStatement;
 	BEGIN
-		NEW( communication, position, send, left, right,outer );  RETURN communication
+		NEW( communication, position, op, left, right,outer );  RETURN communication
 	END NewCommunicationStatement;
 
 	PROCEDURE NewProcedureCallStatement*(position: LONGINT; call: Designator; outer: Statement): ProcedureCallStatement;