int sub(int n; int a[]) {
int remain; remain = 1;
while(remain) {
remain = 0; int i; i = 1;
while(i < n) {
if(a[i-1]>a[i]) { int z; z=a[i-1]; a[i-1]=a[i]; a[i]=z; remain=1; }
i = i + 1; } } }
Package samc1;
Helpers
digit = ['0'..'9'] ;
lcase = ['a'..'z'] ;
ucase = ['A'..'Z'] ;
letter = lcase | ucase ;
Tokens
iconst = digit+ ;
blank = (' '|13|10)+ ;
int = 'int' ;
if = 'if' ;
while = 'while' ;
semi = ';' ;
assign = '=' ;
add = '+' ;
sub = '-' ;
aster = '*' ;
slash = '/' ;
lt = '<' ;
gt = '>' ;
lbra = '{' ;
rbra = '}' ;
lpar = '(' ;
rpar = ')' ;
lsbr = '[' ;
rsbr = ']' ;
ident = letter (letter|digit)* ;
Ignored Tokens
blank;
Productions
prog = {main} int ident lpar dcls rpar stat
;
dcls = {lst} dcls semi dcl
| {one} dcl
;
dcl = {idcl} int ident
| {adcl} int ident lsbr rsbr
;
stlist = {stat} stlist stat
| {empty}
;
stat = {idcl} int ident semi
| {assign} ident assign expr semi
| {aassign} ident lsbr [idx]:expr rsbr assign expr semi
| {if} if lpar expr rpar stat
| {while} while lpar expr rpar stat
| {block} lbra stlist rbra
;
expr = {gt} [left]:nexp gt [right]:nexp
| {lt} [left]:nexp lt [right]:nexp
| {one} nexp
;
nexp = {add} nexp add term
| {sub} nexp sub term
| {one} term
;
term = {mul} term aster fact
| {div} term slash fact
| {one} fact
;
fact = {iconst} iconst
| {ident} ident
| {aref} ident lsbr expr rsbr
| {one} lpar expr rpar
;
package samc1;
import java.util.*;
public class IntCode {
List<Block> code = new ArrayList<Block>();
Block cb;
int lblno = 1000;
public IntCode() {
cb = new Block("L1000", code.size()); code.add(cb);
}
public List<Block> getBlocks() { return code; }
public void gLabel(int l) {
if(cb.getTmp() && cb.getSize()==0) { cb.setLabel("L"+l); }
else { cb = new Block("L"+l, code.size()); code.add(cb); }
}
public void gMovereg(int t1, String r) { cb.add(new Movereg(t1, r)); }
public void gMoveint(int t1, int v) { cb.add(new Moveint(t1, v)); }
public void gMove(int t1, int t2) { cb.add(new Move(t1, t2)); }
public void gAdef(int t1, int t2, int t3) { cb.add(new Adef(t1, t2, t3)); }
public void gAref(int t1, int t2, int t3) { cb.add(new Aref(t1, t2, t3)); }
public void gAdd(int t1, int t2, int t3) { cb.add(new Add(t1, t2, t3)); }
public void gSub(int t1, int t2, int t3) { cb.add(new Sub(t1, t2, t3)); }
public void gMul(int t1, int t2, int t3) { cb.add(new Mul(t1, t2, t3)); }
public void gDiv(int t1, int t2, int t3) { cb.add(new Div(t1, t2, t3)); }
public void gJump(int l) { cb.add(new Jump(l)); eb(); }
public void gIfz(int t1, int l) { cb.add(new Ifz(t1, l)); eb(); }
public void gIfnz(int t1, int l) { cb.add(new Ifnz(t1, l)); eb(); }
public void gIfne(int t1, int t2, int l) { cb.add(new Ifne(t1,t2,l)); eb(); }
public void gIfeq(int t1, int t2, int l) { cb.add(new Ifeq(t1,t2,l)); eb(); }
public void gIfgt(int t1, int t2, int l) { cb.add(new Ifgt(t1,t2,l)); eb(); }
public void gIflt(int t1, int t2, int l) { cb.add(new Iflt(t1,t2,l)); eb(); }
public void gIfge(int t1, int t2, int l) { cb.add(new Ifge(t1,t2,l)); eb(); }
public void gIfle(int t1, int t2, int l) { cb.add(new Ifle(t1,t2,l)); eb(); }
private void eb() { gLabel(++lblno); cb.setTmp(true); }
public void show() { for(Block b: code) { b.show(); } }
public void calcconnect() {
Map<String,Block> map = new HashMap<String,Block>();
for(Block b: code) { map.put(b.getLabel(), b); }
for(int i = 0; i < code.size(); ++i) {
Block b1 = code.get(i);
for(int j: b1.getJdsts()) {
if(j < 0 && i < code.size()-1) { b1.connect(code.get(i+1)); }
if(j >= 0) { b1.connect(map.get("L"+j)); }
}
}
}
public void showconnect() { for(Block b: code) { b.showconnect(); } }
public static class Block {
String label;
List<Inst> body = new ArrayList<Inst>();
Set<Integer> prev = new TreeSet<Integer>();
Set<Integer> succ = new TreeSet<Integer>();
Set<Integer> ref = null;
Set<Integer> def = null;
int bid = 0;
boolean tmp = false;
public Block(String l, int i) { label = l; bid = i; }
public int getId() { return bid; }
public String getLabel() { return label; }
public void setLabel(String lbl) { label = lbl; }
public boolean getTmp() { return tmp; }
public void setTmp(boolean t) { tmp = t; }
public int getSize() { return body.size(); }
public void add(Inst i) { body.add(i); }
public List<Inst> getBody() { return body; }
public Set<Integer> getPrev() { return prev; }
public Set<Integer> getSucc() { return succ; }
public Set<Integer> getRef() { if(ref==null) { calcDR(); } return ref; }
public Set<Integer> getDef() { if(def==null) { calcDR(); } return def; }
private void calcDR() {
def = new TreeSet<Integer>(); ref = new TreeSet<Integer>();
for(Inst op: body) {
for(Integer i: op.getRefs()) { if(!def.contains(i)) { ref.add(i); }}
for(Integer i: op.getDefs()) { def.add(i); }
}
}
public void connect(Block b1) { succ.add(b1.getId()); b1.prev.add(bid); }
public int[] getJdsts() {
if(body.size() == 0) { return new int[]{ -1 }; }
Inst last = body.get(body.size()-1);
int dst = last.getJdst();
if(last instanceof Jump || dst < 0) { return new int[]{ dst }; }
return new int[]{ dst, -1 };
}
public void show() {
System.out.println(label + ": // B" + bid);
for(Inst i: body) { System.out.println(" "+i); }
}
public void showconnect() {
System.out.print("B" + bid);
System.out.print(" prev(");
for(int i: prev) { System.out.printf(" B%d", i); }
System.out.print(" ) succ(");
for(int i: succ) { System.out.printf(" B%d", i); }
System.out.println(" )");
}
}
public static class Inst {
int[] defs = {};
int[] refs = {};
String s;
int jdst = -1, val;
protected void sd(int... a) { defs = a; }
protected void sr(int... a) { refs = a; }
public int[] getDefs() { return defs; }
public int[] getRefs() { return refs; }
public int getJdst() { return jdst; }
public String toString() { return s; }
public int assDest() { return -1; }
public int refNum() { return 0; }
public String refExp() { return null; }
public String refExp(String v1) { return null; }
public String refExp(String v1, String v2) { return null; }
public Inst renew() { return this; }
public Inst renew(int t1) { return this; }
public Inst renew(int t1, int t2) { return this; }
}
static class Movereg extends Inst {
public Movereg(int t1, String reg) {
s = String.format("t%d = %s", t1, reg); sd(t1);
}
}
static class Move extends Inst {
public Move(int t1, int t2) {
s = String.format("t%d = t%d", t1, t2); sd(t1); sr(t2);
}
public int assDest() { return defs[0]; }
public int refNum() { return 1; }
public String refExp(String v1) { return v1; }
}
static class Moveint extends Inst {
public Moveint(int t1, int v) {
val = v; s = String.format("t%d = %d", t1, val); sd(t1);
}
public int assDest() { return defs[0]; }
public int refNum() { return 0; }
public String refExp() { return val+""; }
}
static class Adef extends Inst {
public Adef(int t1, int t2, int t3) {
s = String.format("t%d[t%d] = t%d", t1, t2, t3); sd(t1); sr(t2, t3);
}
public int refNum() { return 2; }
public Inst renew(int t1, int t2) { return new Adef(defs[0], t1, t2); }
}
static class Aref extends Inst {
public Aref(int t1, int t2, int t3) {
s = String.format("t%d = t%d[t%d]", t1, t2, t3); sd(t1); sr(t2, t3);
}
public int assDest() { return defs[0]; }
public int refNum() { return 2; }
public String refExp(String v1, String v2) { return v1+"["+v2+"]"; }
public Inst renew(int t1, int t2) { return new Aref(defs[0], t1, t2); }
}
static class Add extends Inst {
public Add(int t1, int t2, int t3) {
s = String.format("t%d = t%d + t%d", t1, t2, t3); sd(t1); sr(t2, t3);
}
public int assDest() { return defs[0]; }
public int refNum() { return 2; }
public String refExp(String v1, String v2) { return v1+"+"+v2; }
public Inst renew(int t1, int t2) { return new Add(defs[0], t1, t2); }
}
static class Sub extends Inst {
public Sub(int t1, int t2, int t3) {
s = String.format("t%d = t%d - t%d", t1, t2, t3); sd(t1); sr(t2, t3);
}
public int assDest() { return defs[0]; }
public int refNum() { return 2; }
public String refExp(String v1, String v2) { return v1+"-"+v2; }
public Inst renew(int t1, int t2) { return new Sub(defs[0], t1, t2); }
}
static class Mul extends Inst {
public Mul(int t1, int t2, int t3) {
s = String.format("t%d = t%d * t%d", t1, t2, t3); sd(t1); sr(t2, t3);
}
public int assDest() { return defs[0]; }
public int refNum() { return 2; }
public String refExp(String v1, String v2) { return v1+"*"+v2; }
public Inst renew(int t1, int t2) { return new Mul(defs[0], t1, t2); }
}
static class Div extends Inst {
public Div(int t1, int t2, int t3) {
s = String.format("t%d = t%d / t%d", t1, t2, t3); sd(t1); sr(t2, t3);
}
public int assDest() { return defs[0]; }
public int refNum() { return 2; }
public String refExp(String v1, String v2) { return v1+"/"+v2; }
public Inst renew(int t1, int t2) { return new Div(defs[0], t1, t2); }
}
static class Jump extends Inst {
public Jump(int lbl) {
s = String.format("jmp L%d", lbl); jdst = lbl;
}
}
static class Ifz extends Inst {
public Ifz(int t1, int lbl) {
s = String.format("ifz t%d then L%d", t1, lbl); sr(t1); jdst = lbl;
}
public int refNum() { return 1; }
public Inst renew(int t1) { return new Ifz(t1, jdst); }
}
static class Ifnz extends Inst {
public Ifnz(int t1, int lbl) {
s = String.format("ifnz t%d then L%d", t1, lbl); sr(t1); jdst = lbl;
}
public int refNum() { return 1; }
public Inst renew(int t1) { return new Ifnz(t1, jdst); }
}
static class Ifeq extends Inst {
public Ifeq(int t1, int t2, int lbl) {
s = String.format("if t%d == t%d then L%d", t1, t2, lbl); sr(t1, t2);
jdst = lbl;
}
public int refNum() { return 2; }
public Inst renew(int t1, int t2) { return new Ifeq(t1, t2, jdst); }
}
static class Ifne extends Inst {
public Ifne(int t1, int t2, int lbl) {
s = String.format("if t%d != t%d then L%d", t1, t2, lbl); sr(t1, t2);
jdst = lbl;
}
public int refNum() { return 2; }
public Inst renew(int t1, int t2) { return new Ifne(t1, t2, jdst); }
}
static class Ifgt extends Inst {
public Ifgt(int t1, int t2, int lbl) {
s = String.format("if t%d > t%d then L%d", t1, t2, lbl); sr(t1, t2);
jdst = lbl;
}
public int refNum() { return 2; }
public Inst renew(int t1, int t2) { return new Ifgt(t1, t2, jdst); }
}
static class Iflt extends Inst {
public Iflt(int t1, int t2, int lbl) {
s = String.format("if t%d < t%d then L%d", t1, t2, lbl); sr(t1, t2);
jdst = lbl;
}
public int refNum() { return 2; }
public Inst renew(int t1, int t2) { return new Iflt(t1, t2, jdst); }
}
static class Ifge extends Inst {
public Ifge(int t1, int t2, int lbl) {
s = String.format("if t%d >= t%d then L%d", t1, t2, lbl); sr(t1, t2);
jdst = lbl;
}
public int refNum() { return 2; }
public Inst renew(int t1, int t2) { return new Ifge(t1, t2, jdst); }
}
static class Ifle extends Inst {
public Ifle(int t1, int t2, int lbl) {
s = String.format("if t%d <= t%d then L%d", t1, t2, lbl); sr(t1, t2);
jdst = lbl;
}
public int refNum() { return 2; }
public Inst renew(int t1, int t2) { return new Ifle(t1, t2, jdst); }
}
}
package samc1;
import samc1.analysis.*;
import samc1.node.*;
import java.io.*;
import java.util.*;
class GenIntcode extends DepthFirstAdapter {
HashMap<Node,Integer> pos;
Symtab st;
IntCode ic;
int pcnt = 0, lcnt = 0;
static String preg[] = {"%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9"};
private int ti(Object o) { return (Integer)o; }
public GenIntcode(Symtab s, HashMap<Node,Integer> p, IntCode i) {
st = s; pos = p; ic = i;
}
@Override
public void outAIdclDcl(AIdclDcl node) {
ic.gMovereg(pos.get(node), preg[pcnt++]);
}
@Override
public void outAAdclDcl(AAdclDcl node) {
ic.gMovereg(pos.get(node), preg[pcnt++]);
}
@Override
public void outAAssignStat(AAssignStat node) {
ic.gMove(pos.get(node), ti(getOut(node.getExpr())));
}
@Override
public void outAAassignStat(AAassignStat node) {
ic.gAdef(pos.get(node), ti(getOut(node.getIdx())), ti(getOut(node.getExpr())));
}
@Override
public void caseAIfStat(AIfStat node) {
int lbl = lcnt; lcnt += 1;
node.getExpr().apply(this);
ic.gIfnz(ti(getOut(node.getExpr())), lbl);
node.getStat().apply(this);
ic.gLabel(lbl);
}
@Override
public void caseAWhileStat(AWhileStat node) {
int lbl = lcnt; lcnt += 2;
ic.gLabel(lbl);
node.getExpr().apply(this);
ic.gIfz(ti(getOut(node.getExpr())), lbl+1);
node.getStat().apply(this);
ic.gJump(lbl);
ic.gLabel(lbl+1);
}
@Override
public void outAGtExpr(AGtExpr node) {
Symtab.Ent f = st.addDef(".t" + pcnt++, Symtab.ITYPE);
ic.gIfgt(ti(getOut(node.getLeft())), ti(getOut(node.getRight())), lcnt);
ic.gMoveint(f.pos, 0);
ic.gJump(lcnt+1);
ic.gLabel(lcnt++);
ic.gMoveint(f.pos, 1);
ic.gLabel(lcnt++);
setOut(node, new Integer(f.pos));
}
@Override
public void outALtExpr(ALtExpr node) {
Symtab.Ent f = st.addDef(".t" + pcnt++, Symtab.ITYPE);
ic.gIflt(ti(getOut(node.getLeft())), ti(getOut(node.getRight())), lcnt);
ic.gMoveint(f.pos, 0);
ic.gJump(lcnt+1);
ic.gLabel(lcnt++);
ic.gMoveint(f.pos, 1);
ic.gLabel(lcnt++);
setOut(node, new Integer(f.pos));
}
@Override
public void outAOneExpr(AOneExpr node) { setOut(node, getOut(node.getNexp())); }
@Override
public void outAAddNexp(AAddNexp node) {
Symtab.Ent f = st.addDef(".t" + pcnt++, Symtab.ITYPE);
ic.gAdd(f.pos, ti(getOut(node.getNexp())), ti(getOut(node.getTerm())));
setOut(node, new Integer(f.pos));
}
@Override
public void outASubNexp(ASubNexp node) {
Symtab.Ent f = st.addDef(".t" + pcnt++, Symtab.ITYPE);
ic.gSub(f.pos, ti(getOut(node.getNexp())), ti(getOut(node.getTerm())));
setOut(node, new Integer(f.pos));
}
@Override
public void outAOneNexp(AOneNexp node) { setOut(node, getOut(node.getTerm())); }
@Override
public void outAMulTerm(AMulTerm node) {
Symtab.Ent f = st.addDef(".t" + pcnt++, Symtab.ITYPE);
ic.gMul(f.pos, ti(getOut(node.getTerm())), ti(getOut(node.getFact())));
setOut(node, new Integer(f.pos));
}
@Override
public void outADivTerm(ADivTerm node) {
Symtab.Ent f = st.addDef(".t" + pcnt++, Symtab.ITYPE);
ic.gDiv(f.pos, ti(getOut(node.getTerm())), ti(getOut(node.getFact())));
setOut(node, new Integer(f.pos));
}
@Override
public void outAOneTerm(AOneTerm node) { setOut(node, getOut(node.getFact())); }
@Override
public void outAIconstFact(AIconstFact node) {
Symtab.Ent e = st.addDef(".t" + pcnt++, Symtab.ITYPE);
ic.gMoveint(e.pos, new Integer(node.getIconst().getText()));
setOut(node, new Integer(e.pos));
}
@Override
public void outAIdentFact(AIdentFact node) {
setOut(node, new Integer(pos.get(node)));
}
@Override
public void outAArefFact(AArefFact node) {
Symtab.Ent f = st.addDef(".t" + pcnt++, Symtab.ITYPE);
ic.gAref(f.pos, pos.get(node), ti(getOut(node.getExpr())));
setOut(node, new Integer(f.pos));
}
@Override
public void outAOneFact(AOneFact node) { setOut(node, getOut(node.getExpr())); }
}
package samc1;
import samc1.parser.*;
import samc1.lexer.*;
import samc1.node.*;
import java.io.*;
import java.util.*;
public class SamC1 {
public static void main(String[] args) throws Exception {
if(args.length == 0) { showoptions(); return; }
Parser p = new Parser(new Lexer(new PushbackReader(
new InputStreamReader(new FileInputStream(args[0]), "JISAutoDetect"),
1024)));
Start tree = p.parse();
Symtab st = new Symtab();
HashMap<Node,Integer> vtbl = new HashMap<Node,Integer>();
TypeChecker tck = new TypeChecker(st, vtbl); tree.apply(tck);
if(Log.getError() > 0) { return; }
IntCode ic = new IntCode();
GenIntcode gen = new GenIntcode(st, vtbl, ic); tree.apply(gen);
ic.calcconnect();
// Dataflow df = new Dataflow(ic.getBlocks());
for(int i = 1; i < args.length; ++i) {
if(args[i].equals("pt")) { st.show(); }
else if(args[i].equals("pi")) { ic.show(); }
else if(args[i].equals("pc")) { ic.showconnect(); }
// else if(args[i].equals("vn")) { ValNumber.run(ic, false); }
// else if(args[i].equals("pvn")) { ValNumber.run(ic, true); }
// else if(args[i].equals("clio")) { df.calcLiveInOut(); }
// else if(args[i].equals("plio")) { df.showLiveInOut(); }
else { System.err.println("unknown command: "+args[i]); }
}
}
private static void showoptions() {
String[] msg = {
"pt: print table",
"pi: print intcode",
"pc: print block-connection",
// "vn: value numbering",
// "pvn: value numvering with printout",
// "clio: calculate LiveIn/LIveOut",
// "plio: print LiveIn/LiveOut",
};
System.out.println("usage: java samc1/SamC1 <source> <option>...");
for(String s: msg) { System.out.println(" " + s); }
}
}
class Log {
public static int err = 0;
public static void pError(String s) { System.out.println(s); ++err; }
public static int getError() { return err; }
}
class Symtab {
public static final int ITYPE = 1, ATYPE = 2, UNDEF = -1;
List<Ent> tbl = new ArrayList<Ent>();
Stack<Integer> stk = new Stack<Integer>();
int mark;
private boolean duplCheck(String n) {
for(int i = mark; i < tbl.size(); ++i) {
Ent e = tbl.get(i);
if(e.alive && e.name.equals(n)) { return true; }
}
return false;
}
public Ent addDef(String n, int t) {
if(duplCheck(n)) {
Log.pError("dublicate: "+n); return new Ent(n, UNDEF, 0);
}
Ent e = new Ent(n, t, tbl.size()); tbl.add(e); return e;
}
public void enterScope() { stk.push(mark); mark = tbl.size(); }
public void exitScope() {
for(int i = mark; i < tbl.size(); ++i) { tbl.get(i).alive = false; }
mark = stk.pop();
}
public Ent lookup(String n) {
for(int i = tbl.size()-1; i >= 0; --i) {
Ent e = tbl.get(i);
if(e.alive && e.name.equals(n)) { return e; }
}
return new Ent(n, UNDEF, 0);
}
public int getGsize() { return tbl.size(); }
public void show() { for(Ent e: tbl) { System.out.println(" " + e); } }
public static class Ent {
public String name;
public boolean alive = true;
public int type, pos = 0;
public Ent(String n, int t, int p) { name = n; type = t; pos = p; }
public String toString() {
return String.format("%s%s[%d %d]", name, alive?"_":"!", type, pos);
}
}
}
package samc1;
import samc1.analysis.*;
import samc1.node.*;
import java.io.*;
import java.util.*;
class TypeChecker extends DepthFirstAdapter {
Symtab st;
HashMap vtbl;
public TypeChecker(Symtab tb, HashMap vt) { st = tb; vtbl = vt; }
private void ckv(Node n, int t, int l, String s) {
if(getOut(n) instanceof Integer && (Integer)getOut(n) == t) { return; }
Log.pError(l+": "+s);
}
private int cki(String i, int t, int l) {
Symtab.Ent e = st.lookup(i);
if(e.type != t) { Log.pError(l+": identyfier is not of expexted type: "+i); }
return e.pos;
}
@Override
public void inAMainProg(AMainProg node) {
st.addDef("$dummy$", Symtab.ITYPE);
st.addDef(node.getIdent().getText(), Symtab.ITYPE);
}
@Override
public void outAIdclDcl(AIdclDcl node) {
Symtab.Ent e = st.addDef(node.getIdent().getText(), Symtab.ITYPE);
vtbl.put(node, e.pos);
}
@Override
public void outAAdclDcl(AAdclDcl node) {
Symtab.Ent e = st.addDef(node.getIdent().getText(), Symtab.ATYPE);
vtbl.put(node, e.pos);
}
@Override
public void outAIdclStat(AIdclStat node) {
st.addDef(node.getIdent().getText(), Symtab.ITYPE);
}
@Override
public void outAAssignStat(AAssignStat node) {
int p = cki(node.getIdent().getText(), Symtab.ITYPE, node.getIdent().getLine());
ckv(node.getExpr(), Symtab.ITYPE, node.getAssign().getLine(), "non-int val");
vtbl.put(node, p);
}
@Override
public void outAAassignStat(AAassignStat node) {
int p = cki(node.getIdent().getText(), Symtab.ATYPE, node.getIdent().getLine());
ckv(node.getIdx(), Symtab.ITYPE, node.getLsbr().getLine(), "non-int index");
ckv(node.getExpr(), Symtab.ITYPE, node.getAssign().getLine(), "non-int val");
vtbl.put(node, p);
}
@Override
public void outAIfStat(AIfStat node) {
ckv(node.getExpr(), Symtab.ITYPE, node.getLpar().getLine(), "non-int cond");
}
@Override
public void outAWhileStat(AWhileStat node) {
ckv(node.getExpr(), Symtab.ITYPE, node.getLpar().getLine(), "non-int cond");
}
@Override
public void inABlockStat(ABlockStat node) { st.enterScope(); }
@Override
public void outABlockStat(ABlockStat node) { st.exitScope(); }
@Override
public void outAGtExpr(AGtExpr node) {
ckv(node.getLeft(), Symtab.ITYPE, node.getGt().getLine(), "non-int val");
ckv(node.getRight(), Symtab.ITYPE, node.getGt().getLine(), "non-int val");
setOut(node, new Integer(Symtab.ITYPE));
}
@Override
public void outALtExpr(ALtExpr node) {
ckv(node.getLeft(), Symtab.ITYPE, node.getLt().getLine(), "non-int val");
ckv(node.getRight(), Symtab.ITYPE, node.getLt().getLine(), "non-int val");
setOut(node, new Integer(Symtab.ITYPE));
}
@Override
public void outAOneExpr(AOneExpr node) { setOut(node, getOut(node.getNexp())); }
@Override
public void outAAddNexp(AAddNexp node) {
ckv(node.getNexp(), Symtab.ITYPE, node.getAdd().getLine(), "non-int val");
ckv(node.getTerm(), Symtab.ITYPE, node.getAdd().getLine(), "non-int val");
setOut(node, new Integer(Symtab.ITYPE));
}
@Override
public void outASubNexp(ASubNexp node) {
ckv(node.getNexp(), Symtab.ITYPE, node.getSub().getLine(), "non-int val");
ckv(node.getTerm(), Symtab.ITYPE, node.getSub().getLine(), "non-int val");
setOut(node, new Integer(Symtab.ITYPE));
}
@Override
public void outAOneNexp(AOneNexp node) { setOut(node, getOut(node.getTerm())); }
@Override
public void outAMulTerm(AMulTerm node) {
ckv(node.getTerm(), Symtab.ITYPE, node.getAster().getLine(), "non-int val");
ckv(node.getFact(), Symtab.ITYPE, node.getAster().getLine(), "non-int val");
setOut(node, new Integer(Symtab.ITYPE));
}
@Override
public void outADivTerm(ADivTerm node) {
ckv(node.getTerm(), Symtab.ITYPE, node.getSlash().getLine(), "non-int val");
ckv(node.getFact(), Symtab.ITYPE, node.getSlash().getLine(), "non-int val");
setOut(node, new Integer(Symtab.ITYPE));
}
@Override
public void outAOneTerm(AOneTerm node) { setOut(node, getOut(node.getFact())); }
@Override
public void outAIconstFact(AIconstFact node) {
setOut(node, new Integer(Symtab.ITYPE));
}
@Override
public void outAIdentFact(AIdentFact node) {
Symtab.Ent e = st.lookup(node.getIdent().getText());
setOut(node, new Integer(e.type)); vtbl.put(node, e.pos);
}
@Override
public void outAArefFact(AArefFact node) {
int p = cki(node.getIdent().getText(), Symtab.ATYPE, node.getIdent().getLine());
ckv(node.getExpr(), Symtab.ITYPE, node.getLsbr().getLine(), "non-int index");
setOut(node, new Integer(Symtab.ITYPE)); vtbl.put(node, p);
}
@Override
public void outAOneFact(AOneFact node) { setOut(node, getOut(node.getExpr())); }
}
package samc1;
import java.util.*;
public class ValNumber {
Map<Integer, String> tmpval = new HashMap<Integer,String>();
Map<String, Integer> valtmp = new HashMap<String,Integer>();
Map<String, String> expval = new HashMap<String,String>();
int vcnt = 1;
public void exec(List<IntCode.Inst> lst, boolean pr) {
for(int k = 0; k < lst.size(); ++k) {
IntCode.Inst op = lst.get(k), op1 = op; insttmp(op);
int d = op.assDest();
if(d < 0) {
op1 = renew(op);
} else {
String exp = newexp(op), v = exp2val(exp);
if(!valtmp.containsKey(v)) {
op1 = renew(op);
tmpval.put(d, v); valtmp.put(v, d);
if(pr) { System.out.printf(" t%d:%s = %s\n", d, v, exp); }
} else {
int t = valtmp.get(v);
if(tmpval.get(t).equals(v)) {
op1 = new IntCode.Move(d, t);
tmpval.put(d, v);
if(pr) { System.out.printf(" t%d:%s = t%d\n", d, v, t); }
} else {
op1 = renew(op);
tmpval.put(d, v); valtmp.put(v, t);
if(pr) { System.out.printf(" t%d:%s = %s\n", d, v, exp); }
}
}
}
if(pr) { System.out.println(" " + op + " ==> " + op1); }
lst.set(k, op1);
}
if(!pr) { return; }
System.out.println("--------");
for(Integer i: tmpval.keySet()) { pl(" t"+i+" = "+tmpval.get(i)); }
System.out.println("--------");
for(String e: valtmp.keySet()) { pl(" "+e+" = t"+valtmp.get(e)); }
System.out.println("--------");
for(String e: expval.keySet()) { pl(" "+e+" = "+expval.get(e)); }
System.out.println("--------");
}
private void pl(String s) { System.out.println(s); }
private boolean alldigit(String s) { return s.matches("^[0-9]+$"); }
private String exp2val(String e) {
if(expval.containsKey(e)) { return expval.get(e); }
if(alldigit(e)) { return e; }
if(e.charAt(0) == 'v' && alldigit(e.substring(1))) { return e; }
String v = "v"+vcnt++; expval.put(e, v); return v;
}
private void insttmp(IntCode.Inst op) {
for(int i = 0; i < op.refNum(); ++i) {
int t = op.getRefs()[i];
if(!tmpval.containsKey(t)) {
String v = "v"+vcnt++; tmpval.put(t, v); valtmp.put(v, t);
}
}
}
private String newexp(IntCode.Inst op) {
String e = "?";
int[] ref = op.getRefs();
if(op.refNum() == 0) {
e = op.refExp();
} else if(op.refNum() == 1) {
e = op.refExp(tmpval.get(ref[0]));
} else {
e = op.refExp(tmpval.get(ref[0]), tmpval.get(ref[1]));
}
return e;
}
private IntCode.Inst renew(IntCode.Inst op) {
int[] r = op.getRefs();
if(op.refNum() == 0) {
return op.renew();
} else if(op.refNum() == 1) {
Integer i1 = valtmp.get(tmpval.get(r[0]));
return i1 == null ? op : op.renew(i1);
} else {
Integer i1 = valtmp.get(tmpval.get(r[0]));
Integer i2 = valtmp.get(tmpval.get(r[1]));
return i1 == null || i2 == null ? op : op.renew(i1, i2);
}
}
public static void run(IntCode ic, boolean pr) {
for(IntCode.Block b: ic.getBlocks()) {
if(pr) { System.out.println(b.getLabel()); }
new ValNumber().exec(b.getBody(), pr);
}
}
}
package samc1;
import java.util.*;
public class Dataflow {
List<IntCode.Block> blocks;
public Dataflow(List<IntCode.Block> b) { blocks = b; }
private List<Set<Integer>> newListSet() {
List<Set<Integer>> lst = new ArrayList<Set<Integer>>();
for(IntCode.Block b: blocks) { lst.add(new TreeSet<Integer>()); }
return lst;
}
private static Set<Integer> add(Set<Integer> s1, Set<Integer> s2) {
Set<Integer> s3 = new TreeSet<Integer>();
for(Integer i: s1) { s3.add(i); }
for(Integer i: s2) { s3.add(i); }
return s3;
}
private static Set<Integer> sub(Set<Integer> s1, Set<Integer> s2) {
Set<Integer> s3 = new TreeSet<Integer>();
for(Integer i: s1) { if(!s2.contains(i)) { s3.add(i); } }
return s3;
}
List<Set<Integer>> liveIn, liveOut;
List<Set<Integer>> blkRef, blkDef;
public List<Set<Integer>> getLiveIn() { return liveIn; }
public List<Set<Integer>> getLiveOut() { return liveOut; }
public void calcLiveInOut() {
liveIn = newListSet(); liveOut = newListSet();
boolean chg = true;
while(chg) {
chg = false;
for(IntCode.Block b: blocks) {
Set<Integer> li1, lo1 = new TreeSet<Integer>();
for(Integer i: b.getSucc()) { lo1 = add(lo1, liveIn.get(i)); }
li1 = add(b.getRef(), sub(lo1, b.getDef()));
int i = b.getId();
if(!(liveIn.get(i).equals(li1))) { liveIn.set(i, li1); chg = true; }
if(!(liveOut.get(i).equals(lo1))) { liveOut.set(i, lo1); chg = true; }
}
}
}
public void showLiveInOut() {
for(IntCode.Block b: blocks) {
int id = b.getId();
System.out.printf("LiveIn/Out[B%d] = {", id);
for(Integer i: liveIn.get(id)) { System.out.print(" "+i); }
System.out.print(" } {");
for(Integer i: liveOut.get(id)) { System.out.print(" "+i); }
System.out.println(" }");
}
}
}