/*** transput.c ***/

#include <stdio.h>
#include "algol.h"
#include "transput.h"
#include "coercion.h"
#include "unit.h"
   /*** ERRORS: 811-3,825-6,831-4,841-6,851-2  ***/

static void simple_input(int);

void layout(channel,p) int channel,p;
{int ch, c;
	if(channel==stand_in){switch(p){
	    case newline_ST: case newpage_ST:
		c= p==newline_ST?'\n':12;
		while((ch=getchar())!=EOF && ch!=c);
		return;
	    case space_ST:
		ch=getchar(); return;
	    default: ERROR(811);
	}}
	if(channel==stand_out){c=0; switch(p){
	    case newline_ST:	c='\n'-12;
	    case newpage_ST:	c=c+12-' ';
	    case space_ST:	printf("%c",c+' '); return;
	    default:		ERROR(812);
	}}
	ERROR(813);
}

void simple_input(v) int v;
{int i,bv,cv; static char bf[2]; double e; inta ia;
	bv=B[v]; cv=C[v]; switch(A[v]){
	    case STRUCT:
		for(i=0;i<cv;i++)simple_input(B[bv+i]); return;
	    case ROW:
		spelling_row(bv,simple_input); return;
	    case INT:
#ifdef __TURBOC__	    
		must(scanf("%ld",&ia),841); store_int(ia,v); return;
#else
		must(scanf("%d",&ia),841); store_int(ia,v); return;
#endif		
	    case BOOL:
		must(scanf("%1s",bf),842);
		if(*bf=='1' || *bf=='t' || *bf=='T')B[v]=1;
		else{must(*bf=='0' || *bf=='f' || *bf=='F',843); B[v]=0;}
		return;
	    case REAL:
		must(scanf("%lg",&e),844); store_real(v,e); return;
	    case CHAR:
		must(scanf("%c",bf),845); B[v]=bf[0]; return;
	    case BITS:
#ifdef __TURBOC__	    
		must(scanf("%lo",&ia),846); store_bits(ia,v); return;
#else
		must(scanf("%o",&ia),846); store_bits(ia,v); return;
#endif		
	    default:
		ERROR(832);
	}
}

void general_input(u) int u;
{int Q,v,bv,cv,i;
	Q=G; Z=u; more_instance(Z); soft_coercion(&Q); must(Q==G,825);
	bv=B[v=Z]; cv=C[v]; switch(A[v]){
	    case COLL: case STRUCT:
		for(i=0;i<cv;i++)general_input(B[bv+i]); break;
	    case ROW:
		spelling_row(bv,general_input); break;
	    case UNION:
		must(cv>0,831); general_input(cv); break;
	    case REF:
		must(cv>0,833); simple_input(bv); break;
	    case PROC:
		layout(stand_in,C[bv]); break;
	    default:
		ERROR(834);
	}
	relax(v);
}

void general_output(u) int u;
{int Q,v,bv,cv,i;
	Q=G; Z=u; more_instance(Z);
	meek_coercion(&Q);
	must(Q==G,826); bv=B[v=Z]; cv=C[v]; switch(A[v]){
	    case COLL: case STRUCT:
		for(i=0;i<cv;i++)general_output(B[bv+i]); break;
	    case ROW:
		spelling_row(bv,general_output); break;
	    case UNION:
		must(cv>0,851); general_output(cv); break;
	    case PROC:
		layout(stand_out,C[bv]); break;
	    case INT:
#if INT32
                printf("%d ",bv);
#else
		printf("%ld ",
		  (unsigned long)(((((unsigned long)(unsigned)bv)<<16)|
		  ((unsigned long)(unsigned)cv))));
#endif
                break;
            case REAL:
#if INT32
		get_real(v); printf("%g ",re1); break;
#else
		get_real(v); printf("%lg ",re1); break;
#endif
	    case BOOL:
		printf("%c ",bv==1?'t':'f'); break;
	    case CHAR:
		printf("%c",bv); break;
	    case BITS:
#if INT32
                printf("%#o ",bv);
#else
                printf("%#lo ",
                  (unsigned long)(((((unsigned long)(unsigned)bv)<<16)|
                  ((unsigned long)(unsigned)cv))));
#endif
                break;
	    default:
		ERROR(852);
	}
	relax(v);
}


