blob: 499497a1f8fd8efbe2d79d3f5629a32c9da180f4 [file] [log] [blame]
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");
}
}