/***   routine_call.c   ***/

#include "algol.h"
#include "routine_call.h"
#include "coercion.h"
#include "standard.h"
#include "unit.h"
	   /***  ERRORS:  535,556-7,671-2,674-5,681  ***/

static void routine_call(int,int,int*);

static void routine_call(w,jold,Q) int w,jold,*Q;
{int Pold;
	adm_routine(&jold,A[w]);
	Pold=P; P=C[w];
	must(unit(Q),681); must(strong_coercion(B[w],Q),556);
	adm_close(jold); P=Pold;
}

void call_proc(Q) int *Q;
{int w,jold;
	if(C[w=B[Z]]>0){
	    adm_parameter(&jold); routine_call(w,jold,Q);
	}else{
	    must(C[w],674); standard_proc(C[w],Q);
	}
}

void execute_operator(n,w,left,right,Q) int n,w,left,right,*Q;
{int cw,jold;
	if((cw=C[w])>0){
	    adm_parameter(&jold); more_instance(left); possess(C[w+1],left);
	    if(n==2){more_instance(right); possess(C[w+2],right);}
	    routine_call(w,jold,Q);
	}else{
	    must(cw,535);
	    if(n==1){standard_monadic(cw,left);}
		else{standard_dyadic(cw,left,right);}
	}
}

void call_tail(Q) int *Q;
{int i,v,n,w,jold;
	v=Z; n=C[v];
	if(C[w=B[v]]>0){
	    adm_parameter(&jold);
	    for(i=1;i<=n;i++){
		must(unit(Q),671); must(strong_coercion(B[w+i],Q),557);
		if(*Q==G) possess(mask(C[w+i]),Z);
		must(inp(i<n?COMMA:CLOSE),672);
	    }
	    unmask(jold); routine_call(w,jold,Q);
	}else{
	    must(C[w],675); standard_proc(C[w],Q);
	}
	relax(v); MORF=TRUE;
}

