package xdc.services.intern.gen; | |
import java.util.*; | |
import xdc.services.global.*; | |
import xdc.services.spec.*; | |
public class ImplC { | |
private Glob glob = new Glob(); | |
// gen | |
public void gen( Unit unit, Out out ) | |
{ | |
glob.setNames(unit); | |
glob.mode = Glob.SYNMODE; | |
glob.out = out; | |
glob.genWarning(); | |
skip(); | |
genPrologue(unit); | |
skip(); | |
for (Impl.Body fb : unit.getFxnImpls()) { | |
if (!fb.getFxn().isMeta()) { | |
genFxnBody(fb); | |
} | |
} | |
} | |
// genExpr | |
private void genExpr( Expr e ) | |
{ | |
if (e == null) { | |
return; | |
} | |
glob.genAny(e, ImplC.class, this); | |
} | |
// genExpr$Addr | |
void genExpr$Addr( Expr.Addr e ) | |
{ | |
glob.out.print("&"); | |
genExpr(e.getBody()); | |
} | |
// genExpr$Call | |
void genExpr$Call( Expr.Call e ) | |
{ | |
genPath(e); | |
} | |
// genExpr$Cond | |
void genExpr$Cond( Expr.Cond e ) | |
{ | |
genExpr(e.getCond()); | |
glob.out.print(" ? "); | |
genExpr(e.getLeft()); | |
glob.out.print(" : "); | |
genExpr(e.getRight()); | |
} | |
// genExpr$Binary | |
void genExpr$Binary( Expr.Binary e ) | |
{ | |
String op = e.getOp(); | |
genExpr(e.getLeft()); | |
if (op.charAt(0) == ',') { | |
glob.out.print(", "); | |
} | |
else { | |
glob.out.printf(" %1 ", e.getOp()); | |
} | |
genExpr(e.getRight()); | |
} | |
// genExpr$Cast | |
void genExpr$Cast( Expr.Cast e ) | |
{ | |
glob.out.print("("); | |
glob.out.print("("); | |
glob.genType(e.getType(), Glob.Type$TYP, ""); | |
glob.out.print(")"); | |
glob.out.print("("); | |
genExpr(e.getBody()); | |
glob.out.print(")"); | |
glob.out.print(")"); | |
} | |
// genExpr$Const | |
void genExpr$Const( Expr.Const e ) | |
{ | |
String cs = e.getVal(); | |
if (cs.equals("null")) { | |
cs = "NULL"; | |
} | |
else if (cs.equals("true")) { | |
cs = "TRUE"; | |
} | |
else if (cs.equals("false")) { | |
cs = "FALSE"; | |
} | |
else if (cs.length() > 3 && cs.startsWith("'\"")) { | |
cs = cs.substring(1, cs.length() - 1); | |
} | |
glob.out.print(cs); | |
} | |
// genExpr$Frag | |
void genExpr$Frag( Expr.Frag e ) | |
{ | |
glob.out.print(e.getText()); | |
List<Expr> args = e.getArgs(); | |
if (args != null) { | |
glob.out.print("("); | |
genPathCallArgs(args, "", null); | |
glob.out.print(")"); | |
} | |
} | |
// genExpr$Index | |
void genExpr$Index( Expr.Index e ) | |
{ | |
genPath(e); | |
} | |
// genExpr$Paren | |
void genExpr$Paren( Expr.Paren e ) | |
{ | |
glob.out.print("("); | |
genExpr(e.getBody()); | |
glob.out.print(")"); | |
} | |
// genExpr$Size | |
void genExpr$Size( Expr.Size e ) | |
{ | |
if (e.getKeyword().getText().startsWith("a")) { | |
glob.out.printf("offsetof (struct { char c; "); | |
glob.genRef(e.getTspec().getRef()); | |
glob.out.printf(" t; }, t)"); | |
} | |
else { | |
glob.out.printf("%1 (", e.getKeyword().getText()); | |
glob.genRef(e.getTspec().getRef()); | |
String fn = e.getFieldName(); | |
if (fn != null) { | |
glob.out.printf(", %1", fn); | |
} | |
glob.out.print(")"); | |
} | |
} | |
// genExpr$Select | |
void genExpr$Select( Expr.Select e ) | |
{ | |
genPath(e); | |
} | |
// genExpr$Unary | |
void genExpr$Unary( Expr.Unary e ) | |
{ | |
if (e.isPost()) { | |
genExpr(e.getRight()); | |
glob.out.print(e.getOp()); | |
} | |
else { | |
glob.out.print(e.getOp()); | |
genExpr(e.getRight()); | |
} | |
} | |
// genExpr$Var | |
void genExpr$Var( Expr.Var e ) | |
{ | |
Decl.Arg d = e.getDecl(); | |
if (d.getInit() == null) { | |
return; | |
} | |
glob.out.print(d.getName()); | |
glob.out.print(" = "); | |
genExpr(d.getInit()); | |
} | |
// genFxnDecl | |
private void genFxnDecl( Decl.Fxn fxn, List<Decl.Arg> args ) | |
{ | |
glob.genType(fxn.getType(), Glob.Type$TYP, glob.uname + '_' + fxn.getName()); | |
glob.out.printf("("); | |
String sep = " "; | |
int k = 0; | |
if (fxn.isInst()) { | |
glob.out.printf(" %1_Object* __this", glob.uname); | |
sep = ", "; | |
} | |
for (Decl.Arg a : fxn.getArgs()) { | |
glob.out.printf(sep); | |
sep = ", "; | |
String an = args.get(k).getName(); | |
if (k == 0 && fxn.isStruct()) { | |
an = "__this"; | |
} | |
glob.genType(a.getType(), Glob.Type$TYP, an); | |
k++; | |
} | |
glob.out.printf("%1)\n", k > 0 ? " " : ""); | |
} | |
// genFxnBody | |
private void genFxnBody( Impl.Body fb ) | |
{ | |
Decl.Fxn fxn = fb.getFxn(); | |
List<Expr.Var> lcls = fb.getLocals(); | |
glob.genTitle(fxn.getName()); | |
genFxnDecl(fxn, fb.getArgs()); | |
glob.out.printf("{%+\n"); | |
for (Expr.Var e : lcls) { | |
Decl.Arg d = e.getDecl(); | |
glob.out.printf("%t"); | |
if (!e.getKeyword().equals("var")) { | |
glob.out.printf("%1 ", e.getKeyword()); | |
} | |
glob.genType(d.getType(), Glob.Type$TYP, d.getName()); | |
glob.out.printf(";\n"); | |
} | |
if (lcls.size() > 0) { | |
skip(); | |
} | |
for (Stmt st : fb.getBody().getElems()) { | |
genStmt(st); | |
} | |
glob.out.printf("%-%t}\n"); | |
} | |
// genPath | |
private void genPath( Expr.Path pex ) | |
{ | |
List<Expr.Path> chain = new ArrayList<Expr.Path>(); | |
pex.buildChain(chain); | |
genPath(pex, chain, chain.size() - 1); | |
} | |
// genPath | |
private void genPath( Expr.Path pex, List<Expr.Path> chain, int idx ) | |
{ | |
if (pex instanceof Expr.Call) { | |
genPathCall((Expr.Call)pex, chain, idx); | |
return; | |
} | |
if (pex instanceof Expr.Select) { | |
genPathSelect((Expr.Select)pex, chain, idx); | |
return; | |
} | |
if (pex instanceof Expr.Index) { | |
genPathIndex((Expr.Index)pex, chain, idx); | |
return; | |
} | |
} | |
// genPathCall | |
private void genPathCall( Expr.Call e, List<Expr.Path> chain, int idx ) | |
{ | |
// System.out.println("call " + idx + " : " + e.getCat().getCode()); | |
if (idx > 1) { | |
Cat scat = chain.get(idx - 2).getCat(); | |
Cat fcat = chain.get(idx - 1).getCat(); | |
if (scat instanceof Cat.Str && fcat.getPtrCnt() == 0) { | |
Expr.Select fxn = (Expr.Select)e.getFxn(); | |
Cat.Str strcat = (Cat.Str)scat; | |
String qn; | |
if (strcat.getAltName() != null) { | |
qn = glob.curUnit.getName() + "." + strcat.getAltName(); | |
} | |
else { | |
String tc = scat.getCode(); | |
qn = tc.substring(tc.indexOf('!') + 1); | |
} | |
String fn = qn.replace('.', '_') + "_" + fxn.getSel().getText(); | |
glob.out.printf("%1(", fn); | |
int pcnt = scat.getPtrCnt(); | |
if (pcnt == 0) { | |
glob.out.print("&"); | |
} | |
else while (pcnt-- > 1) { | |
glob.out.print("*"); | |
} | |
genPath((Expr.Path)fxn.getObj(), chain, idx - 2); | |
genPathCallArgs(e.getArgs(), ", ", fcat instanceof Cat.Fxn ? ((Cat.Fxn)fcat).getDecl() : null); | |
glob.out.print(")"); | |
return; | |
} | |
} | |
Cat cat = chain.get(idx > 0 ? idx - 1 : idx).getCat(); | |
Decl.Fxn fxn = cat instanceof Cat.Fxn ? ((Cat.Fxn)cat).getDecl() : null; | |
genPath((Expr.Path)e.getFxn(), chain, idx - 1); | |
glob.out.print("("); | |
genPathCallArgs(e.getArgs(), "", fxn); | |
glob.out.print(")"); | |
} | |
// genPathCallArgs | |
private void genPathCallArgs( List<Expr> args, String sep, Decl.Fxn fxn ) | |
{ | |
for (Expr a : args) { | |
glob.out.print(sep); | |
genExpr(a); | |
sep = ", "; | |
} | |
if (fxn == null) { | |
return; | |
} | |
List<Decl.Arg> fargs = fxn.getArgs(); | |
for (int k = fxn.isStruct() ? args.size() + 1 : args.size(); k < fargs.size(); k++) { | |
glob.out.print(sep); | |
genExpr(fargs.get(k).getInit()); | |
sep = ", "; | |
} | |
} | |
// genPathIndex | |
private void genPathIndex( Expr.Index e, List<Expr.Path> chain, int idx ) | |
{ | |
genPath((Expr.Path)e.getArr(), chain, idx - 1); | |
glob.out.print("["); | |
genExpr(e.getIdx()); | |
glob.out.print("]"); | |
} | |
// genPathSelect | |
private void genPathSelect( Expr.Select e, List<Expr.Path> chain, int idx ) | |
{ | |
// System.out.println("select " + idx + " : " + e.getCat().getCode()); | |
if (idx == 0) { | |
if (e.getUnit() != null) { | |
glob.out.printf("%1_", e.getUnit().getName()); | |
} | |
String s = e.getSel().getText(); | |
if (s.equals("this")) { | |
s = "__this"; | |
} | |
if (e.getUnit() == null && e.getCat() instanceof Cat.Uni) { | |
String code = e.getCat().getCode(); | |
s = code.substring(code.lastIndexOf('.') + 1); | |
} | |
glob.out.print(s); | |
return; | |
} | |
Cat prev = chain.get(idx - 1).getCat(); | |
if (prev instanceof Cat.Str) { | |
int k = prev.getPtrCnt(); | |
if (k > 1) { | |
glob.out.print("("); | |
for (int i = 1; i < k; i++) { | |
glob.out.print("*"); | |
} | |
} | |
genPath((Expr.Path)e.getObj(), chain, idx - 1); | |
if (k > 1) { | |
glob.out.print(")"); | |
} | |
glob.out.printf("%s", k > 0 ? "->" : "."); | |
glob.out.print(e.getSel().getText()); | |
return; | |
} | |
if (prev instanceof Cat.Uni) { | |
genPath((Expr.Path)e.getObj(), chain, idx - 1); | |
glob.out.print("_"); | |
glob.out.print(e.getSel().getText()); | |
return; | |
} | |
} | |
// genPrologue | |
private void genPrologue( Unit unit ) | |
{ | |
for (Unit u : unit.getInherits()) { | |
if (u.getQualName().equals("xdc.runtime.IModule")) { | |
break; | |
} | |
glob.out.printf("#include <%1.h>\n", glob.mkFname(u.getQualName())); | |
} | |
for (Import im : unit.getImports()) { | |
Unit u = im.getUnit(); | |
if (!u.isMeta()) { | |
glob.out.printf("#include <%1.h>\n", glob.mkFname(u.getQualName())); | |
} | |
} | |
glob.out.printf("#include \"package/internal/%1.xdc.h\"\n", unit.getName()); | |
String cf = unit.getCodeFrag(); | |
if (cf == null) { | |
return; | |
} | |
cf = cf.replaceFirst("^native\\s*\\{", ""); | |
cf = cf.replaceFirst("\\s*\\}\\s*$", ""); | |
glob.out.print("\n/* ---- begin custom prologue ---- */\n"); | |
glob.out.print(cf); | |
glob.out.print("\n\n/* ---- end custom prologue ---- */"); | |
} | |
// genStmt | |
void genStmt( Stmt st ) | |
{ | |
if (st == null) { | |
return; | |
} | |
glob.genAny(st, ImplC.class, this); | |
} | |
// genStmt$Basic | |
void genStmt$Basic( Stmt.Basic st ) | |
{ | |
Expr e = st.getExpr(); | |
if (e instanceof Expr.Var && ((Expr.Var)e).getDecl().getInit() == null) { | |
return; | |
} | |
glob.out.printf("%t"); | |
genExpr(e); | |
glob.out.printf(";\n"); | |
} | |
// genStmt$Block | |
void genStmt$Block( Stmt.Block st ) | |
{ | |
glob.out.printf("{%+\n"); | |
for (Stmt se : st.getElems()) { | |
genStmt(se); | |
} | |
glob.out.printf("%-%t}\n"); | |
} | |
// genStmt$Break | |
void genStmt$Break( Stmt.Break st ) | |
{ | |
glob.out.printf("%t%1;\n", st.getKeyword()); | |
} | |
// genStmt$For | |
void genStmt$For( Stmt.For st ) | |
{ | |
glob.out.printf("%tfor ("); | |
genExpr(st.getInit()); | |
glob.out.printf("; "); | |
genExpr(st.getCond()); | |
glob.out.printf("; "); | |
genExpr(st.getIncr()); | |
glob.out.printf(") "); | |
genStmt(st.getBody()); | |
} | |
// genStmt$If | |
void genStmt$If( Stmt.If st ) | |
{ | |
glob.out.printf("%tif ("); | |
genExpr(st.getCond()); | |
glob.out.printf(") "); | |
genStmt(st.getBodyIf()); | |
Stmt es = st.getBodyElse(); | |
if (es != null) { | |
glob.out.printf("%telse "); | |
genStmt(es); | |
} | |
} | |
// genStmt$Native | |
void genStmt$Native( Stmt.Native st ) | |
{ | |
glob.out.printf("%t"); | |
glob.out.print(st.getText()); | |
} | |
// genStmt$Return | |
void genStmt$Return( Stmt.Return st ) | |
{ | |
glob.out.printf("%treturn"); | |
if (st.getExpr() != null) { | |
glob.out.print(" "); | |
genExpr(st.getExpr()); | |
} | |
glob.out.printf(";\n"); | |
} | |
// genStmt$Switc | |
void genStmt$Switch( Stmt.Switch st ) | |
{ | |
List<Stmt.Case> csL = st.getCaseList(); | |
Stmt.Case ds = st.getDefault(); | |
glob.out.printf("%tswitch ("); | |
genExpr(st.getCond()); | |
glob.out.printf(") {\n"); | |
for (Stmt.Case cs : csL) { | |
glob.out.printf("%tcase "); | |
genExpr(cs.getCond()); | |
glob.out.printf(":\n%+"); | |
if (cs.getElems() != null) { | |
for (Stmt s : cs.getElems()) { | |
glob.out.printf("%t"); | |
genStmt(s); | |
} | |
} | |
glob.out.printf("%-"); | |
} | |
if (ds != null) { | |
glob.out.printf("%tdefault:\n%+"); | |
if (ds.getElems() != null) { | |
for (Stmt s : ds.getElems()) { | |
glob.out.printf("%t"); | |
genStmt(s); | |
} | |
} | |
glob.out.printf("%-"); | |
} | |
glob.out.printf("%t}\n"); | |
} | |
// genStmt$While | |
void genStmt$While( Stmt.While st ) | |
{ | |
if (st.getKeyword().equals("while")) { | |
glob.out.printf("%twhile ("); | |
genExpr(st.getCond()); | |
glob.out.printf(") "); | |
genStmt(st.getBody()); | |
} | |
else { | |
glob.out.printf("%tdo "); | |
genStmt(st.getBody()); | |
glob.out.printf("%twhile ("); | |
genExpr(st.getCond()); | |
glob.out.printf(");\n"); | |
} | |
} | |
// skip | |
private void skip() | |
{ | |
glob.out.print("\n"); | |
} | |
} |