home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples1.exe / MyC / Src / Asm.cs next >
Encoding:
Text File  |  2000-06-23  |  10.3 KB  |  417 lines

  1. namespace MyC
  2. {
  3. using System;
  4. using System.Text;
  5.  
  6. class Asm
  7.   {
  8.   private Io io;
  9.  
  10.   public Asm(Io ihandle)
  11.     {
  12.     io = ihandle;
  13.     }
  14.   
  15.   /*
  16.    * determine the IL static type
  17.    */
  18.   private String ilSType(int type)
  19.     {
  20.     switch (type)
  21.       {
  22.       case Tok.T_CHAR:    return "char";
  23.       case Tok.T_SHORT:    return "int16";
  24.       case Tok.T_DEFTYPE:
  25.       case Tok.T_INT:
  26.       case Tok.T_LONG:    return "int32";
  27.       case Tok.T_FLOAT:    return "float";
  28.       case Tok.T_DOUBLE:    return "double float";
  29.       case Tok.T_VOID:    return "void";
  30.       default:
  31.     Console.WriteLine("?Unhandled type " + Int32.ToString(type));
  32.     Environment.Exit(1);
  33.       }
  34.     return null;
  35.     }
  36.  
  37.   /*
  38.    * common routine to construct a signature string for a given varlist item
  39.    * requires a destination ptr, will return the updated dest ptr
  40.    */
  41.   private String genDataTypeSig(Var e)
  42.     {
  43.     if (e == null)
  44.       return null;
  45.  
  46.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  47.  
  48.     if (e.getSign() == Tok.T_UNSIGNED)    /* if var is unsigned, put it in sig */
  49.       sb.Append("unsigned ");
  50.  
  51.     sb.Append(ilSType(e.getTypeId()));    /* get the datatype */
  52.     return (sb.ToString());
  53.     }
  54.  
  55.   private String genFieldRef(Var e)
  56.     {
  57.     if (e == null)
  58.       return null;
  59.  
  60.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  61.  
  62.     if (e.getSign() == Tok.T_UNSIGNED)    /* if var is unsigned, put it in sig */
  63.       sb.Append("unsigned ");
  64.  
  65.     sb.Append(ilSType(e.getTypeId()));    /* get the datatype */
  66.     sb.Append(" ");
  67.     sb.Append(Io.GetClassname());    /* get the current classname */
  68.     sb.Append(".");
  69.     sb.Append(e.getName());    /* copy the variable name */
  70.     return (sb.ToString());
  71.     }
  72.  
  73.   public void Load(IAsm a)
  74.     {
  75.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  76.     Var e = a.getVar();
  77.     if (e == null)
  78.       {
  79.       Console.WriteLine("?Load instruction with no variable ptr");
  80.       Environment.Exit(1);
  81.       }
  82.     switch (e.getClassId())
  83.       {
  84.       case Tok.T_STATIC:
  85.     {
  86.     sb.Append("\tldsfld ");
  87.     sb.Append(genFieldRef(e));
  88.     sb.Append("\t//");
  89.     sb.Append(Int32.ToString(a.getICount()));
  90.     sb.Append(", ");
  91.     sb.Append(e.getName());
  92.     sb.Append("\n");
  93.     break;
  94.     }
  95.       case Tok.T_AUTO:
  96.       case Tok.T_DEFCLASS:
  97.     sb.Append("\tldloc ");
  98.     sb.Append(Int32.ToString(e.getIndex()));
  99.     sb.Append("\t//");
  100.     sb.Append(Int32.ToString(a.getICount()));
  101.     sb.Append(", ");
  102.     sb.Append(e.getName());
  103.     sb.Append("\n");
  104.     break;
  105.       case Tok.T_PARAM:
  106.     sb.Append("\tldarg ");
  107.     sb.Append(Int32.ToString(e.getIndex()));
  108.     sb.Append("\t//");
  109.     sb.Append(Int32.ToString(a.getICount()));
  110.     sb.Append(", ");
  111.     sb.Append(e.getName());
  112.     sb.Append("\n");
  113.     break;
  114.       default:
  115.     Console.Write("?Instruction load of unknown class (");
  116.     Console.Write(Int32.ToString(e.getClassId()));
  117.     Console.WriteLine(")");
  118.     Environment.Exit(1);
  119.       }
  120.     io.Out(sb.ToString());
  121.     }
  122.  
  123.   public void Store(IAsm a)
  124.     {
  125.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  126.     Var e = a.getVar();
  127.     if (e == null)
  128.       {
  129.       Console.WriteLine("?Store instruction with no variable ptr");
  130.       Environment.Exit(1);
  131.       }
  132.     switch (e.getClassId())
  133.       {
  134.       case Tok.T_STATIC:
  135.     sb.Append("\tstsfld ");
  136.     sb.Append(genFieldRef(e));
  137.     sb.Append("\t//");
  138.     sb.Append(Int32.ToString(a.getICount()));
  139.     sb.Append(", ");
  140.     sb.Append(e.getName());
  141.     sb.Append("\n");
  142.     break;
  143.       case Tok.T_AUTO:
  144.       case Tok.T_DEFCLASS:
  145.     sb.Append("\tstloc ");
  146.     sb.Append(Int32.ToString(e.getIndex()));
  147.     sb.Append("\t//");
  148.     sb.Append(Int32.ToString(a.getICount()));
  149.     sb.Append(", ");
  150.     sb.Append(e.getName());
  151.     sb.Append("\n");
  152.     break;
  153.       case Tok.T_PARAM:
  154.     sb.Append("\tstarg ");
  155.     sb.Append(Int32.ToString(e.getIndex()));
  156.     sb.Append("\t//");
  157.     sb.Append(Int32.ToString(a.getICount()));
  158.     sb.Append(", ");
  159.     sb.Append(e.getName());
  160.     sb.Append("\n");
  161.     break;
  162.       default:
  163.     Console.Write("?Instruction load of unknown class (");
  164.     Console.Write(Int32.ToString(e.getClassId()));
  165.     Console.WriteLine(")");
  166.     Environment.Exit(1);
  167.       }
  168.     io.Out(sb.ToString());
  169.     }
  170.  
  171.   public void FuncBegin(IAsm a)
  172.     {
  173.     Var func = a.getVar();
  174.     String funcsig = genDataTypeSig(a.getVar()); /* gen type info */
  175.  
  176.     VarList x = func.getParams(); /* get any params */
  177.     String paramsig = "";
  178.     if (x.Length() > 0)
  179.       {
  180.       int max = x.Length();
  181.       StringBuilder t = new StringBuilder(MyC.MAXSTR);
  182.       for (int i = 0; i < max; i++)
  183.     {
  184.     Var e = x.FindByIndex(i);
  185.     t.Append(genDataTypeSig(e));
  186.     if (i < max-1)
  187.       t.Append(",");
  188.     }
  189.       paramsig = t.ToString();
  190.       }
  191.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  192.     sb.Append("\t.method ");
  193.     sb.Append(funcsig);
  194.     sb.Append(" ");
  195.     sb.Append(func.getName());
  196.     sb.Append("(");
  197.     sb.Append(paramsig);
  198.     sb.Append("){\n");
  199.     io.Out(sb.ToString());
  200.  
  201.     if (func.getName().Equals("main")) /* special entry point for main */
  202.       io.Out("\t.entrypoint\n");
  203.     }
  204.   
  205.   public void Call(IAsm a)
  206.     {
  207.     Var func = a.getVar();
  208.     String funcsig = genDataTypeSig(a.getVar()); /* gen type info */
  209.  
  210.     VarList x = func.getParams(); /* get any params */
  211.     String paramsig = "";
  212.     if (x.Length() > 0)
  213.       {
  214.       int max = x.Length();
  215.       StringBuilder t = new StringBuilder(MyC.MAXSTR);
  216.       for (int i = 0; i < max; i++)
  217.     {
  218.     Var e = x.FindByIndex(i);
  219.     t.Append(genDataTypeSig(e));
  220.     if (i < max-1)
  221.       t.Append(",");
  222.     }
  223.       paramsig = t.ToString();
  224.       }
  225.  
  226.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  227.     sb.Append("\tcall ");
  228.     sb.Append(funcsig);
  229.     sb.Append("(");
  230.     sb.Append(paramsig);
  231.     sb.Append(")\t//");
  232.     sb.Append(a.getICount());
  233.     sb.Append("\n");
  234.     io.Out(sb.ToString());
  235.     }
  236.  
  237.   public void Comment(IAsm a)
  238.     {
  239.     String sp = a.getComment();    /* source ptr */
  240.     if (sp == null)
  241.       return;            // empty comment
  242.     sp.Trim();            // remove extra whitespace
  243.     if (sp == null || sp.Length == 0) /* sanity check, is there a comment? */
  244.       return;            /* no, then nothing to do */
  245.  
  246. #if DEBUG
  247.     Console.Write("Comment SP=");
  248.     for (int _debug_i=0; _debug_i<sp.Length;_debug_i++)
  249.       {
  250.       int _debug_d = sp[_debug_i];
  251.       char _debug_c = (char) (_debug_d + 96);
  252.       if (_debug_d < 32)
  253.     Console.Write("^"+Char.ToString(_debug_c));
  254.       else
  255.     Console.Write(sp[_debug_i]);
  256.       Console.Write("[");
  257.       Console.Write(Int32.ToString(_debug_d));
  258.       Console.Write("],");
  259.       }
  260.     Console.WriteLine(";");
  261. #endif
  262.     StringBuilder buf = new StringBuilder(MyC.MAXSTR); /* a buffer to work with */
  263.     buf.Append("//");
  264.     buf.Append(a.getCommentLine());
  265.     buf.Append(": ");
  266.     int i = 0;
  267.     int p = 0;
  268.     while ((i = sp.IndexOf('\n', i)) >= 0)
  269.       {
  270.       i++;            // move past the newline
  271.       String s = sp.Substring(p, i).Trim();
  272.       if (s.Length > 0)
  273.     buf.Append(s);        // copy the substr
  274.       buf.Append("\n");        // add the line seperator
  275.       if (i < sp.Length)
  276.     buf.Append("//");    // insert the comment block
  277.       p = i;
  278.       }
  279.  
  280.     buf.Append(sp.Substring(p)); // append the remaining chars
  281.     buf.Append("\n");
  282.  
  283.     io.Out(buf.ToString());    /* output the comment */
  284.     }
  285.  
  286.   public void Insn(IAsm a)
  287.     {
  288.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  289.     sb.Append("\t");
  290.     sb.Append(a.getInsn());
  291.     sb.Append("\t//");
  292.     sb.Append(a.getICount());
  293.     sb.Append("\n");
  294.     io.Out(sb.ToString());
  295.     }
  296.  
  297.   public void Label(IAsm a)
  298.     {
  299.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  300.     sb.Append(a.getLabel());
  301.     sb.Append(":\n");
  302.     io.Out(sb.ToString());
  303.     }
  304.  
  305.   public void Branch(IAsm a)
  306.     {
  307.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  308.     sb.Append("\t");
  309.     sb.Append(a.getInsn());
  310.     sb.Append(" ");
  311.     sb.Append(a.getLabel());
  312.     sb.Append("\t//");
  313.     sb.Append(a.getICount());
  314.     sb.Append("\n");
  315.     io.Out(sb.ToString());
  316.     }
  317.  
  318.   public void Ret(IAsm a)
  319.     {
  320.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  321.     sb.Append("\tret\t\t//");
  322.     sb.Append(a.getICount());
  323.     sb.Append("\n");
  324.     io.Out(sb.ToString());
  325.     }
  326.  
  327.   public void FuncEnd()
  328.     {
  329.     io.Out("\t}\n");
  330.     }
  331.  
  332.   public void LocalVars(VarList v)
  333.     {
  334.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  335.     sb.Append("\t.locals (");
  336.     int max = v.Length();
  337.  
  338.     for (int i = 0; i < max; i++)    // loop thru the local params
  339.       {
  340.       Var e = v.FindByIndex(i);    // indexed by number
  341.       String stype = "";
  342.       switch (e.getTypeId())
  343.     {
  344.     case Tok.T_CHAR:    stype = "char"; break;
  345.     case Tok.T_SHORT:    stype = "int16"; break;
  346.     case Tok.T_INT:
  347.     case Tok.T_LONG:    stype = "int32"; break;
  348.     case Tok.T_FLOAT:    stype = "float"; break;
  349.     case Tok.T_DOUBLE:    stype = "double float"; break;
  350.     default:
  351.       Console.WriteLine("?Could not find type for local\n");
  352.       Environment.Exit(1);
  353.     }
  354.       sb.Append(stype);        // append it now
  355.       if (i < max-1)
  356.     sb.Append(",");        // if not last, seperate with comma
  357.       }
  358.  
  359.     sb.Append(")\n");
  360.     io.Out(sb.ToString());
  361.     }
  362.  
  363.   public void FieldDef(IAsm a)
  364.     {
  365.     Var e = a.getVar();        /* get the field var ptr */
  366.     String prefix = "";
  367.     switch (e.getClassId())
  368.       {
  369.       case Tok.T_STATIC:
  370.     prefix = "\t.field ";
  371.     break;
  372.       case Tok.T_AUTO:
  373.       case Tok.T_DEFCLASS:
  374.     prefix = "\t.field ";
  375.     break;
  376.       default:
  377.     Console.WriteLine("?Unhandled field def type\n");
  378.     Environment.Exit(1);
  379.       }
  380.  
  381.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  382.     sb.Append(prefix);        /* copy the prefix */
  383.     sb.Append(genDataTypeSig(e)); /* gen type info, rets updated dp */
  384.     sb.Append(" ");
  385.     sb.Append(e.getName());    /* copy the variable name */
  386.     sb.Append("\n");
  387.     io.Out(sb.ToString());
  388.     }
  389.  
  390.   public void LoadConst(IAsm a)
  391.     {
  392.     StringBuilder sb = new StringBuilder(MyC.MAXSTR);
  393.     int value = Convert.ToInt32(a.getInsn());
  394.  
  395.     sb.Append("\tldc.i4");
  396.     if (value > 127 || value < -128) /* if must use long form */
  397.       {
  398.       sb.Append(" ");
  399.       }
  400.     else if (value > 8 || value < -1)    /* if must use medium form */
  401.       {
  402.       sb.Append(".s ");
  403.       }
  404.     else                /* else use short form */
  405.       {
  406.       sb.Append(".");
  407.       }
  408.     sb.Append(a.getInsn());
  409.     sb.Append("\t//");
  410.     sb.Append(a.getICount());
  411.     sb.Append("\n");
  412.  
  413.     io.Out(sb.ToString());
  414.     }
  415.   }
  416. }
  417.