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

ParseExpr2Impl: PROGRAM IMPORTS TreesDefs EXPORTS ParseDefs = {

  -- the interpretation rules
  

  ParseExpr2: 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

	  		--	ARITHMETIC OPERATORS	--
			
       129  =>  -- eL11  ::=		eL11  +  eL12
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← plusOp;
          };
       130  =>  -- eL11  ::=		eL11  -  eL12
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← minusOp;
          };
       131  =>  -- eL12 ::=		eL12  *  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← multiplyOp;
          };
       132  =>  -- eL12  ::=		eL12  /  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← divideOp;
          };
       133  =>  -- eL12  ::=		eL12  %  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← modulusOp;
          };
	  
	  		--	UNARY OPERATORS	--
			
       134  =>  -- eL13  ::=		"++"  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← preIncrement;
          };
       135  =>  -- eL13  ::=		"!!"  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← preDecrement;
          };
       136  =>  -- eL13  ::=		*  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← dereference;
          };
       137  =>  -- eL13  ::=		&  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← addressOf;
          };
       138  =>  -- eL13  ::=		-  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← unaryMinus;
          };
       139  =>  -- eL13  ::=		!  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← logicalNot;
          };
       140  =>  -- eL13  ::=		~  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← bitNot;
          };
       141  =>  -- eL13  ::=		sizeof  eL13
          {
	  -- not legal in Mesa (what to do?)
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← sizeOf;
          };
       142  =>  -- eL13  ::=		(  CastType  )  eL13
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 3], right: v2[top + 1],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← castOp;
          };
       143  =>  -- eL13  ::=		sizeof  (  CastType  )
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 2], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← sizeOf;
          };
	  		--	RIGHT ASSOCIATIVE UNARY		--
	  
       144  =>  -- eL14  ::=		eL14  "++"
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← postIncrement;
          };
       145  =>  -- eL14  ::=		eL14  "!!"
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← postDecrement;
          };
	  		--	BASIC EXPRESSIONS	--
			
       146  =>  -- eL15  ::=		eL15  [  e  ]
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← arrayReference;
          };
       147  =>  -- eL15  ::=		NAME (  )
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top], nodeType: operation];
	  v2[top].operationType ← procedureCall;
	  };
       148  =>  -- eL15  ::=		NAME ( elist  )
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: v2[top + 2],
	      string: v[top], nodeType: operation];
	  v2[top].operationType ← procedureCall;
          };
       149  =>  -- eL15  ::=		NAME 
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top], nodeType: operation];
	  v2[top].operationType ← nameValue;
          };
       150  =>  -- eL15  ::=		ICON 
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top], nodeType: operation];
	  v2[top].operationType ← iconValue;
          };
       151  =>  -- eL15  ::=		FCON 
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top], nodeType: operation];
	  v2[top].operationType ← fconValue;
          };
       152  =>  -- eL15  ::=		STRING 
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top], nodeType: operation];
	  v2[top].operationType ← stringValue;
          };
       153  =>  -- eL15  ::=		(  e  )
          {
          v2[top] ← v2[top + 1];
          };
	  
	  		--	STRUCTURE REFERENCING OPERATORS	--
			
       154  =>  -- eL15  ::=		eL15  "->"  NAME
          {
	  temp2 ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top + 2], nodeType: operation];
	  temp2.operationType ← nameValue;
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: temp2,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← structReference;
          };
       155  =>  -- eL15  ::=		eL15  .  NAME
          {
	  temp2 ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top + 2], nodeType: operation];
	  temp2.operationType ← nameValue;
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: temp2,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← structReference;
          };
	  
	  		--	ABSTRACT DECLARATORS	--

       156  =>  -- CastType  ::=	Type  NullDeclarator
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 1],
	      string: NIL, nodeType: castType];
          };
       157  =>  -- NullDeclarator  ::=	*  NullDeclarator
          {
	  temp2 ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: declarator];
	  temp2.declaratorType ← pointerTo;
	  v2[top] ← v2[top + 1];
	  v2[top].lastInList.right ← temp2;
	  v2[top].lastInList ← temp2;
          };
       158  =>  -- NullDeclarator  ::=	(  NullDeclarator )  (  )
          {
	  temp2 ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: declarator];
	  temp2.declaratorType ← functionOf;
	  v2[top] ← v2[top + 1];
	  v2[top].lastInList.right ← temp2;
	  v2[top].lastInList ← temp2;
          };
       159  =>  -- NullDeclarator  ::=	NullDeclarator  [  ]
          {
	  temp2 ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: declarator];
	  temp2.declaratorType ← arrayOf;
	  v2[top].lastInList.right ← temp2;
	  v2[top].lastInList ← temp2;
          };
       160  =>  -- NullDeclarator  ::=	NullDeclarator  [  e  ]
          {
	  temp2 ← TreesDefs.MakeNode[left: v2[top + 2], right: NIL,
	      string: NIL, nodeType: declarator];
	  temp2.declaratorType ← arrayOf;
	  v2[top].lastInList.right ← temp2;
	  v2[top].lastInList ← temp2;
          };
       161  =>  -- NullDeclarator  ::=	(  )
          {
	  -- phony NAME holder (NAME in abstract declarators is empty)
	  temp2 ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: declarator];
	  temp2.declaratorType ← functionOf;
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: temp2,
	      string: NIL, nodeType: declarator];
	  v2[top].declaratorType ← simpleName;
	  v2[top].lastInList ← temp2;
          };
       162  =>  -- NullDeclarator  ::=	
          {
	  -- phony NAME holder (NAME in abstract declarators is empty)
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: declarator];
	  v2[top].declaratorType ← simpleName;
	  v2[top].lastInList ← v2[top];
          };
       163  =>  -- NullDeclarator  ::=	(  NullDeclarator  )
          {
          v2[top] ← v2[top + 1]; -- parens just for grouping
	  v2[top + 1] ← NIL;
          };

        ENDCASE => ERROR;
    };
  }.