|
|
researchv10 Norman
#include <stdio.h>
#include "pico.h"
#include "pico2.h"
#include "y.tab.h"
extern struct SRC src[MANY];
extern short CURSCRATCH, CUROLD;
extern char faster, frameb, metheus;
extern int DEF_LL, DEF_NL;
#define NNODE 8000
Node nodearray[NNODE];
int nalloc=0;
Node *
Index(k)
Node *k;
{
switch(k->type) {
case ACOMMA: if (commacount(k) == 2)
return
new(OADD, new(OMUL, k->right, VR(&DEF_LL), Z), k->left, Z);
break;
case COMP: return new(ODIV, sumchans(k->left), NR(3), Z);
}
return k;
}
Node *
ncopy(n)
Node *n;
{
if (n == Z)
return n;
n = new(n->type, ncopy(n->left), ncopy(n->right), n->other);
if (n->type == CONDI)
n->other = ncopy(n->other);
return n;
}
int spare;
Node *
modulo(p, q)
Node *p, *q;
{ Node *tmp1, *tmp2;
if (p->type == OCOMMA || p->type == ACOMMA)
yyerror("lefthand-side of modulo is a composite");
tmp1 = new(OASS, VR(&spare), ncopy(p), Z);
tmp2 = new(OSUB, VR(&spare),
new(OMUL, new(ODIV, VR(&spare), ncopy(q), Z), ncopy(q), Z), Z);
return new(OCOMMA, tmp1, new(CONDI, tmp2, VR(&spare), q), Z);
}
Node *
divide(p, q)
Node *p, *q;
{ Node *tmp = ncopy(q);
extern Node zero;
return new(CONDI, new(ODIV, p, q, Z), &zero, tmp);
}
int fixspot;
/* encodes the assignment of a composite to a composite */
Node *
fixit(n, m)
Node *n, *m;
{ Node *tmp1 = new(OASS, VR(&fixspot), ncopy(m), Z);
Node *tmp2 = ncopy(n->left->left); /* r */
Node *tmp3 = ncopy(n->left->right->left); /* g */
Node *tmp4 = ncopy(n->left->right->right); /* b */
Node *low = new(OAND, VR(&fixspot), NR(255), Z);
Node *med = new(OLSH, notnew(OAND, VR(&fixspot), NR(255<<8)),
new(OMINUS, NR(8), Z, Z), Z);
Node *hig = new(OLSH, VR(&fixspot),
new(OMINUS, NR(16), Z, Z), Z);
Node *tmp5 = new(OASS, tmp2, low, Z);
Node *tmp6 = new(OASS, tmp3, med, Z);
Node *tmp7 = new(OASS, tmp4, hig, Z);
Node *tmp8 = new(OCOMMA, tmp5, tmp6, Z);
Node *tmp9 = new(OCOMMA, tmp7, tmp8, Z);
return new(OCOMMA, tmp1, tmp9, Z);
}
Node *
catch(what, n, m)
int what;
Node *n, *m;
{
switch (what)
{
case DIVV: return divide(n, m);
case MODU: return modulo(n, m);
case OASS: if (n->type == COMP)
{ if (m->type == CONDI)
return fixit(n, m);
else
return new(OCOMMA, par(what, n->left, m->left), Z, Z);
}
default: return new(what, n, m, Z);
}
}
Node *
new(type, left, right, oth)
Node *left, *right, *oth;
{
register Node *n;
if (nalloc >= NNODE)
yyerror("NNODE too small; recompile pico");
n = nodearray+nalloc++;
n->type = type;
n->left = left;
n->right = right;
n->other = oth;
return n;
}
Node *
sumchans(n)
Node *n;
{
if (n == Z || n->type != ACOMMA)
return n;
return new(OADD, sumchans(n->left), sumchans(n->right), Z);
}
Node *
cast(n)
Node *n;
{
if (n == Z || n->type != ACOMMA)
return n;
return new(ODIV, sumchans(n->left), NR(3), Z);
}
#define Par(side) par(what, n1->side, n2->side)
Node *
par(what, n1, n2)
int what;
Node *n1, *n2;
{
if (n1 == Z || n2 == Z)
return Z;
if (n1->type != ACOMMA || n2->type != ACOMMA)
return catch(what, ncopy(n1), ncopy(n2));
if (what == OASS)
return new(OCOMMA, Par(left), Par(right), Z);
else
return new(ACOMMA, Par(left), Par(right), Z);
}
Node *
promote(m)
Node *m;
{
Node *n;
if (m->type == CONDI)
return new(CONDI, promote(m->left), promote(m->right), m->other);
if (m->type == COMP)
return m;
n = new(ACOMMA, ncopy(m), ncopy(m), Z);
n = new(ACOMMA, ncopy(m), n, Z);
return new(COMP, n, Z, Z);
}
Node *
disp(what, n, e)
int what;
Node *n, *e;
{
if (n == Z)
return Z;
if (n->type != ACOMMA)
return catch(what, ncopy(n), ncopy(e));
return new(OCOMMA, disp(what, n->left, e), disp(what, n->right, e), Z);
}
Node *
notnew(what, n1, n2)
int what;
Node *n1, *n2;
{
int how = 0;
if (n1->type == COMP) how += 1;
if (n2->type == COMP) how += 2;
switch (how) {
case 1: n2 = promote(n2); /* fall through */
case 0: return catch(what, n1, n2);
case 2: if (what == OASS)
return catch(what, n1, new(ODIV, sumchans(n2->left), NR(3), Z));
n1 = promote(n1); /* fall through */
case 3: if (what == OASS)
return catch(what, n1, n2); /* else: */
return new(COMP, par(what, n1->left, n2->left), Z, Z);
}
}
Node *
threechans(q, r)
struct SRC *q;
Node *r;
{
Node *n;
if (q->nchan >= 3)
{ n = new(ACOMMA, DOLGRN(q, r), DOLBLU(q, r), Z);
n = new(ACOMMA, DOLRED(q, r), n, Z);
return new(COMP, n, Z, Z);
} else
return DOLRED(q, r);
}
SNode *
nsup(n, x, y, i)
Node *n, *x, *y;
char i;
{
SNode *tmp;
tmp = (SNode *) Emalloc(sizeof(SNode));
tmp->n = n;
tmp->x = x;
tmp->y = y;
tmp->i = i;
return tmp;
}
Node *
splatter(n)
SNode *n;
{
extern int ramlyank(), fblyank(), metlyank();
if (metheus)
return new(CCALL, new(ACOMMA, n->x, n->y, Z), Z, metlyank);
else if (frameb)
return new(CCALL, new(ACOMMA, n->x, n->y, Z), Z, fblyank);
}
Node *
weird(n, m)
SNode *n;
Node *m;
{
Node *tmp;
if (m == Z)
return n->n;
tmp = notnew(OASS, n->n, m);
if (n->i != CURSCRATCH
|| (!frameb && !metheus)
|| (faster && notafunc() && metheus)
|| (faster && Old->nchan==1 && notafunc() && frameb))
return tmp;
else
return new(OCOMMA, tmp, splatter(n), Z);
}
Node *
getx(n)
Node *n;
{
if (n == Z)
return AREG(XREG);
if (n->type == ACOMMA)
{ if (commacount(n) == 2)
return n->left;
else
yyerror("bad index");
}
return modulo(n, VR(&DEF_LL));
}
Node *
gety(n)
Node *n;
{
if (n == Z)
return AREG(YREG);
if (n->type == ACOMMA)
{ if (commacount(n) == 2)
return n->right;
else
yyerror("bad index");
}
return divide(n, VR(&DEF_LL));
}
SNode *
super(a, b, t)
Node *b;
{
Node *tmp;
Node *n = (b == Z)? DII: Index(b);
switch (t) {
case RGB: tmp = threechans(&src[a], n); break;
case BW: if (src[a].nchan == 1)
tmp = DOLRED((&src[a]), n);
else
tmp = cast(threechans(&src[a], n));
break;
case RCHAN: tmp = DOLRED((&src[a]), n); break;
case GCHAN: tmp = DOLGRN((&src[a]), n); break;
case BCHAN: tmp = DOLBLU((&src[a]), n); break;
}
if (b == Z)
return nsup(tmp, AREG(XREG), AREG(YREG), a);
else
return nsup(tmp, getx(b), gety(b), a);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.