#include "rc.h"
#include "io.h"
#include "exec.h"
#include "fns.h"
#include "getflags.h"
#define	c0	t->child[0]
#define	c1	t->child[1]
#define	c2	t->child[2]
int codep, ncode;
#define	emitf(x) ((void)(codep!=ncode || morecode()), codebuf[codep].f=(x), codep++)
#define	emiti(x) ((void)(codep!=ncode || morecode()), codebuf[codep].i=(x), codep++)
#define	emits(x) ((void)(codep!=ncode || morecode()), codebuf[codep].s=(x), codep++)
void stuffdot(int);
char *fnstr(tree*);
void outcode(tree*, int);
void codeswitch(tree*, int);
int iscase(tree*);
code *codecopy(code*);
void codefree(code*);
int morecode(void){
	ncode+=100;
	codebuf=(code *)realloc((char *)codebuf, ncode*sizeof codebuf[0]);
	if(codebuf==0) panic("Can't realloc %d bytes in morecode!",
				ncode*sizeof codebuf[0]);
	return 0;
}
void stuffdot(int a){
	if(a<0 || codep<=a) panic("Bad address %d in stuffdot", a);
	codebuf[a].i=codep;
}
int compile(tree *t)
{
	ncode=100;
	codebuf=(code *)emalloc(ncode*sizeof codebuf[0]);
	codep=0;
	emiti(0);			/* reference count */
	outcode(t, flag['e']?1:0);
	if(nerror){
		efree((char *)codebuf);
		return 0;
	}
	readhere();
	emitf(Xreturn);
	emitf(0);
	return 1;
}
void cleanhere(char *f)
{
	emitf(Xdelhere);
	emits(strdup(f));
}
char *fnstr(tree *t)
{
	io *f=openstr();
	char *v;
	extern char nl;
	char svnl=nl;
	nl=';';
	pfmt(f, "%t", t);
	nl=svnl;
	v=f->strp;
	f->strp=0;
	closeio(f);
	return v;
}
void outcode(tree *t, int eflag)
{
	int p, q;
	tree *tt;
	if(t==0) return;
	if(t->type!=NOT && t->type!=';') runq->iflast=0;
	switch(t->type){
	default:
		pfmt(err, "bad type %d in outcode\n", t->type);
		break;
	case '$':
		emitf(Xmark);
		outcode(c0, eflag);
		emitf(Xdol);
		break;
	case '"':
		emitf(Xmark);
		outcode(c0, eflag);
		emitf(Xqdol);
		break;
	case SUB:
		emitf(Xmark);
		outcode(c0, eflag);
		emitf(Xmark);
		outcode(c1, eflag);
		emitf(Xsub);
		break;
	case '&':
		emitf(Xasync);
		p=emiti(0);
		outcode(c0, eflag);
		emitf(Xexit);
		stuffdot(p);
		break;
	case ';':
		outcode(c0, eflag);
		outcode(c1, eflag);
		break;
	case '^':
		emitf(Xmark);
		outcode(c1, eflag);
		emitf(Xmark);
		outcode(c0, eflag);
		emitf(Xconc);
		break;
	case '`':
		emitf(Xbackq);
		p=emiti(0);
		outcode(c0, 0);
		emitf(Xexit);
		stuffdot(p);
		break;
	case ANDAND:
		outcode(c0, 0);
		emitf(Xtrue);
		p=emiti(0);
		outcode(c1, eflag);
		stuffdot(p);
		break;
	case ARGLIST:
		outcode(c1, eflag);
		outcode(c0, eflag);
		break;
	case BANG:
		outcode(c0, eflag);
		emitf(Xbang);
		break;
	case PCMD:
	case BRACE:
		outcode(c0, eflag);
		break;
	case COUNT:
		emitf(Xmark);
		outcode(c0, eflag);
		emitf(Xcount);
		break;
	case FN:
		emitf(Xmark);
		outcode(c0, eflag);
		if(c1){
			emitf(Xfn);
			p=emiti(0);
			emits(fnstr(c1));
			outcode(c1, eflag);
			emitf(Xunlocal);	/* get rid of $* */
			emitf(Xreturn);
			stuffdot(p);
		}
		else
			emitf(Xdelfn);
		break;
	case IF:
		outcode(c0, 0);
		emitf(Xif);
		p=emiti(0);
		outcode(c1, eflag);
		emitf(Xwastrue);
		stuffdot(p);
		break;
	case NOT:
		if(!runq->iflast) yyerror("`if not' does not follow `if(...)'");
		emitf(Xifnot);
		p=emiti(0);
		outcode(c0, eflag);
		stuffdot(p);
		break;
	case OROR:
		outcode(c0, 0);
		emitf(Xfalse);
		p=emiti(0);
		outcode(c1, eflag);
		stuffdot(p);
		break;
	case PAREN:
		outcode(c0, eflag);
		break;
	case SIMPLE:
		emitf(Xmark);
		outcode(c0, eflag);
		emitf(Xsimple);
		if(eflag) emitf(Xeflag);
		break;
	case SUBSHELL:
		emitf(Xsubshell);
		p=emiti(0);
		outcode(c0, eflag);
		emitf(Xexit);
		stuffdot(p);
		if(eflag) emitf(Xeflag);
		break;
	case SWITCH:
		codeswitch(t, eflag);
		break;
	case TWIDDLE:
		emitf(Xmark);
		outcode(c1, eflag);
		emitf(Xmark);
		outcode(c0, eflag);
		emitf(Xmatch);
		if(eflag) emitf(Xeflag);
		break;
	case WHILE:
		q=codep;
		outcode(c0, 0);
		if(q==codep) emitf(Xsettrue);	/* empty condition == while(true) */
		emitf(Xtrue);
		p=emiti(0);
		outcode(c1, eflag);
		emitf(Xjump);
		emiti(q);
		stuffdot(p);
		break;
	case WORDS:
		outcode(c1, eflag);
		outcode(c0, eflag);
		break;
	case FOR:
		emitf(Xmark);
		if(c1){
			outcode(c1, eflag);
			emitf(Xglob);
		}
		else{
			emitf(Xmark);
			emitf(Xword);
			emits(strdup("*"));
			emitf(Xdol);
		}
		emitf(Xmark);		/* dummy value for Xlocal */
		emitf(Xmark);
		outcode(c0, eflag);
		emitf(Xlocal);
		p=emitf(Xfor);
		q=emiti(0);
		outcode(c2, eflag);
		emitf(Xjump);
		emiti(p);
		stuffdot(q);
		emitf(Xunlocal);
		break;
	case WORD:
		emitf(Xword);
		emits(strdup(t->str));
		break;
	case DUP:
		if(t->rtype==DUPFD){
			emitf(Xdup);
			emiti(t->fd0);
			emiti(t->fd1);
		}
		else{
			emitf(Xclose);
			emiti(t->fd0);
		}
		outcode(c1, eflag);
		emitf(Xpopredir);
		break;
	case PIPEFD:
		emitf(Xpipefd);
		emiti(t->rtype);
		p=emiti(0);
		outcode(c0, eflag);
		emitf(Xexit);
		stuffdot(p);
		break;
	case REDIR:
		emitf(Xmark);
		outcode(c0, eflag);
		emitf(Xglob);
		switch(t->rtype){
		case APPEND:
			emitf(Xappend);
			break;
		case WRITE:
			emitf(Xwrite);
			break;
		case READ:
		case HERE:
			emitf(Xread);
			break;
		}
		emiti(t->fd0);
		outcode(c1, eflag);
		emitf(Xpopredir);
		break;
	case '=':
		tt=t;
		for(;t && t->type=='=';t=c2);
		if(t){
			for(t=tt;t->type=='=';t=c2){
				emitf(Xmark);
				outcode(c1, eflag);
				emitf(Xmark);
				outcode(c0, eflag);
				emitf(Xlocal);
			}
			t=tt;
			outcode(c2, eflag);
			for(;t->type=='=';t=c2) emitf(Xunlocal);
		}
		else{
			for(t=tt;t;t=c2){
				emitf(Xmark);
				outcode(c1, eflag);
				emitf(Xmark);
				outcode(c0, eflag);
				emitf(Xassign);
			}
		}
		t=tt;	/* so tests below will work */
		break;
	case PIPE:
		emitf(Xpipe);
		emiti(t->fd0);
		emiti(t->fd1);
		p=emiti(0);
		q=emiti(0);
		outcode(c0, eflag);
		emitf(Xexit);
		stuffdot(p);
		outcode(c1, eflag);
		emitf(Xreturn);
		stuffdot(q);
		emitf(Xpipewait);
		break;
	}
	if(t->type!=NOT && t->type!=';')
		runq->iflast=t->type==IF;
	else if(c0) runq->iflast=c0->type==IF;
}
/*
 * switch code looks like this:
 *	Xmark
 *	(get switch value)
 *	Xjump	1f
 * out:	Xjump	leave
 * 1:	Xmark
 *	(get case values)
 *	Xcase	1f
 *	(commands)
 *	Xjump	out
 * 1:	Xmark
 *	(get case values)
 *	Xcase	1f
 *	(commands)
 *	Xjump	out
 * 1:
 * leave:
 *	Xpopm
 */
void codeswitch(tree *t, int eflag)
{
	int leave;		/* patch jump address to leave switch */
	int out;		/* jump here to leave switch */
	int nextcase;	/* patch jump address to next case */
	tree *tt;
	if(c1->child[0]==nil
	|| c1->child[0]->type!=';'
	|| !iscase(c1->child[0]->child[0])){
		yyerror("case missing in switch");
		return;
	}
	emitf(Xmark);
	outcode(c0, eflag);
	emitf(Xjump);
	nextcase=emiti(0);
	out=emitf(Xjump);
	leave=emiti(0);
	stuffdot(nextcase);
	t=c1->child[0];
	while(t->type==';'){
		tt=c1;
		emitf(Xmark);
		for(t=c0->child[0];t->type==ARGLIST;t=c0) outcode(c1, eflag);
		emitf(Xcase);
		nextcase=emiti(0);
		t=tt;
		for(;;){
			if(t->type==';'){
				if(iscase(c0)) break;
				outcode(c0, eflag);
				t=c1;
			}
			else{
				if(!iscase(t)) outcode(t, eflag);
				break;
			}
		}
		emitf(Xjump);
		emiti(out);
		stuffdot(nextcase);
	}
	stuffdot(leave);
	emitf(Xpopm);
}
int iscase(tree *t)
{
	if(t->type!=SIMPLE) return 0;
	do t=c0; while(t->type==ARGLIST);
	return t->type==WORD && !t->quoted && strcmp(t->str, "case")==0;
}
code *codecopy(code *cp)
{
	cp[0].i++;
	return cp;
}
void codefree(code *cp)
{
	code *p;
	if(--cp[0].i!=0) return;
	for(p=cp+1;p->f;p++){
		if(p->f==Xappend || p->f==Xclose || p->f==Xread || p->f==Xwrite
		|| p->f==Xasync || p->f==Xbackq || p->f==Xcase || p->f==Xfalse
		|| p->f==Xfor || p->f==Xjump
		|| p->f==Xsubshell || p->f==Xtrue) p++;
		else if(p->f==Xdup || p->f==Xpipefd) p+=2;
		else if(p->f==Xpipe) p+=4;
		else if(p->f==Xword || p->f==Xdelhere) efree((++p)->s);
		else if(p->f==Xfn){
			efree(p[2].s);
			p+=2;
		}
	}
	efree((char *)cp);
}
