DIRECTORY
  ParseDefs USING [Value, Value2],
  TreesDefs USING [MakeNode];

ParseExpr1Impl: PROGRAM IMPORTS TreesDefs EXPORTS ParseDefs = {

  -- the interpretation rules
  

  ParseExpr1: PUBLIC PROCEDURE [rule: CARDINAL, top: CARDINAL,
  	v: LONG DESCRIPTOR FOR ARRAY OF ParseDefs.Value,
	v2: LONG DESCRIPTOR FOR ARRAY OF ParseDefs.Value2] = {
	
    temp: ParseDefs.Value;
    temp2: ParseDefs.Value2;
    atemp: LONG POINTER TO ParseDefs.Value ← @temp;
    avtop: LONG POINTER TO ParseDefs.Value ← @v[top];

      SELECT rule FROM

        	--	EXPRESSIONS	--

        98  =>  -- eL1		::=	eL2
                -- eL2		::=C	eL3
                -- eL3		::=	eL4
                -- eL4		::=C	eL5
                -- eL5		::=	eL6
                -- eL6		::=C	eL7
                -- eL7		::=	eL8
                -- eL8		::=C	eL9
                -- eL9		::=	eL10
                -- eL10		::=C	eL11
                -- eL11		::=	eL12
                -- eL12		::=C	eL13
                -- eL13		::=	eL14
                -- eL14		::=C	eL15
          NULL;

        99  =>  -- EOrEmpty	::=
          {
	  v2[top] ← NIL;
	  };
       100  =>  -- EOrEmpty  ::=	e
	  NULL;
       101  =>  -- elist  ::=		e
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← eList;
	  v2[top].lastInList ← v2[top];
	  };
       102  =>  -- elist  ::=		elist  ,  e
          {
	  temp2 ← TreesDefs.MakeNode[left: v2[top + 2], right: NIL,
	      string: NIL, nodeType: operation];
	  temp2.operationType ← eList;
	  v2[top].lastInList.right ← temp2;
	  v2[top].lastInList ← temp2;
          };
       103  =>  -- e  ::=C		eL1
	  NULL;

        --124 => e ::= e , eL1
        -- {
        -- };
	
			--	OP ASSIGNS	--
			
       104  =>  -- eL1  ::=		eL2  "*="  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← multiplyAssign;
          };
       105  =>  -- eL1  ::=		eL2  "/="  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← divideAssign;
          };
       106  =>  -- eL1  ::=		eL2  "%="  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← modulusAssign;
          };
       107  =>  -- eL1  ::=		eL2  "+="  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← plusAssign;
          };
       108  =>  -- eL1  ::=		eL2  "-="  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← minusAssign;
          };
       109  =>  -- eL1  ::=		eL2  "<<="  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← shiftLeftAssign;
          };
       110  =>  -- eL1  ::=		eL2  ">>="  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← shiftRightAssign;
          };
       111  =>  -- eL1  ::=		eL2  "&="  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← bitAndAssign;
          };
       112  =>  -- eL1  ::=		eL2  "|="  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← bitOrAssign;
          };
       113  =>  -- eL1  ::=		eL2  "↑="  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← bitXorAssign;
          };
	  
	  		--	ASSIGNMENT	--
			
       114  =>  -- eL1  ::=		eL2  =  eL1
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← assignOp;
          };
	  
	  		--	IF / THEN / ELSE EXPRESSION	--
			
       115  =>  -- eL2  ::=		eL3  '?  eL3  :  eL2
          {
	  temp2 ← TreesDefs.MakeNode[left: v2[top + 2], right: v2[top + 4],
	      string: NIL, nodeType: operation];
	  temp2.operationType ← thenElseExpression;
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: temp2,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← ifExpression;
          };
	  
	  		--	LOGICAL OPERATORS	--
			
       116  =>  -- eL3  ::=		eL3  "||"  eL4
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← logicalOr;
          };
       117  =>  -- eL4  ::=		eL4  "&&"  eL5
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← logicalAnd;
          };
	  
	  		--	BITWISE LOGICAL OPERATORS	--
			
       118  =>  -- eL5 ::=		eL5  '|  eL6
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← bitOr;
          };
       119  =>  -- eL6  ::=		eL6  ↑  eL7
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← bitXor;
          };
       120  =>  -- eL7 ::=		eL7  &  eL8
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← bitAnd;
          };
	  
	  		--	EQUALITY OPERATORS	--
			
       121  =>  -- eL8  ::=		eL8  "=="  eL9
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← equals;
          };
       122  =>  -- eL8  ::=		eL8  "!="  eL9
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← notEquals;
          };
	  
	  		--	RELATIONAL OPERATORS	--
			
       123  =>  -- eL9  ::=		eL9  <  eL10
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← lessThan;
          };
       124  =>  -- eL9  ::=		eL9  >  eL10
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← greaterThan;
          };
       125  =>  -- eL9  ::=		eL9  "<="  eL10
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← lessThanOrEqual;
          };
       126  =>  -- eL9  ::=		eL9  ">="  eL10
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← greaterThanOrEqual;
          };
	  
	  		--	BIT SHIFT OPERATORS	--
			
       127  =>  -- eL10  ::=		eL10  "<<"  eL11
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← shiftLeft;
          };
       128  =>  -- eL10  ::=		eL10  ">>"  eL11
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← shiftRight;
          };

        ENDCASE => ERROR;
    };

  }.