home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 June (DVD) / DPPRO0605DVD.iso / dotNETSDK / SETUP.EXE / netfxsd1.cab / FL_CodeGen_cs________.3643236F_FC70_11D3_A536_0090278A1BB8 < prev    next >
Encoding:
Text File  |  2001-06-29  |  8.9 KB  |  379 lines

  1.  
  2. using System;
  3. using System.Reflection;
  4. using System.Reflection.Emit;
  5. using System.Collections;
  6. using System.Threading;
  7. using Absyn;
  8.  
  9.  
  10. class CodeGen : IExpVisitor
  11. {
  12.     ExpList expr;
  13.     TypeBuilder tb;
  14.     MethodBuilder methodb;
  15.     Hashtable Functions;
  16.     Hashtable GlobalVars;
  17.     Hashtable DoVars;
  18.     
  19.     ILGenerator il;
  20.     
  21.     public CodeGen(ExpList ex, Hashtable f, Hashtable g)
  22.     {
  23.     expr = ex;
  24.     Functions = new Hashtable();
  25.     GlobalVars = new Hashtable();
  26.     DoVars = new Hashtable();
  27.     }
  28.     
  29.     void Init()
  30.     {
  31.     
  32.     }
  33.  
  34.     public void IntExp(IntExp e)
  35.     {
  36.         switch(e.Value){
  37.         case 0:
  38.         il.Emit(OpCodes.Ldc_I4_0);
  39.         break;
  40.         case 1:
  41.             il.Emit(OpCodes.Ldc_I4_1);
  42.             break;
  43.         case 2:
  44.             il.Emit(OpCodes.Ldc_I4_2);
  45.             break;
  46.         case 3:
  47.             il.Emit(OpCodes.Ldc_I4_3);
  48.             break;
  49.         case 4:
  50.             il.Emit(OpCodes.Ldc_I4_4);
  51.             break;
  52.         case 5:
  53.             il.Emit(OpCodes.Ldc_I4_5);
  54.             break;
  55.         case 6:
  56.             il.Emit(OpCodes.Ldc_I4_6);
  57.             break;
  58.         case 7:
  59.             il.Emit(OpCodes.Ldc_I4_7);
  60.             break;
  61.         case 8:
  62.             il.Emit(OpCodes.Ldc_I4_8);
  63.             break;
  64.         default:
  65.             if (e.Value > -128 && e.Value < 127)
  66.             il.Emit(OpCodes.Ldc_I4_S, (byte)e.Value);
  67.             else if (e.Value > Int32.MinValue && e.Value < Int32.MaxValue)
  68.             il.Emit(OpCodes.Ldc_I4, (int)e.Value);
  69.             else 
  70.             il.Emit(OpCodes.Ldc_I8, e.Value);
  71.             break;
  72.         }
  73.     }
  74.     
  75.     public void BinopExp(BinopExp e)
  76.     {
  77.     e.Left.Visit(this);
  78.     e.Right.Visit(this);
  79.     switch(e.Oper){
  80.     case Operator.ADD:
  81.         il.Emit(OpCodes.Add);
  82.         break;
  83.     case Operator.SUB:
  84.         il.Emit(OpCodes.Sub);
  85.         break;
  86.     case Operator.MUL:
  87.         il.Emit(OpCodes.Mul);
  88.         break;
  89.     case Operator.DIVIDE:
  90.         il.Emit(OpCodes.Div);
  91.         break;
  92.     }
  93.     }
  94.  
  95.     public void CompareExp(CompareExp e)
  96.     {
  97.     Label TrueLabel = il.DefineLabel();
  98.     Label EndLabel = il.DefineLabel();
  99.     e.Left.Visit(this);
  100.     e.Right.Visit(this);
  101.     switch(e.Oper){
  102.     case Operator.LT:
  103.         il.Emit(OpCodes.Blt, TrueLabel);
  104.         break;
  105.     case Operator.GT:
  106.         il.Emit(OpCodes.Bgt, TrueLabel);
  107.         break;
  108.     case Operator.EQ:
  109.         il.Emit(OpCodes.Beq, TrueLabel);
  110.         break;
  111.     case Operator.LE:
  112.         il.Emit(OpCodes.Ble, TrueLabel);
  113.         break;
  114.     case Operator.GE:
  115.         il.Emit(OpCodes.Bge, TrueLabel);
  116.         break;
  117.  
  118.     }
  119.     il.Emit(OpCodes.Ldc_I4_0);
  120.     il.Emit(OpCodes.Br, EndLabel);
  121.     il.MarkLabel(TrueLabel);
  122.     il.Emit(OpCodes.Ldc_I4_1);
  123.     il.MarkLabel(EndLabel);
  124.     
  125.     }
  126.     
  127.  
  128.     public void CallExp(CallExp e)
  129.     {
  130.     for(int i = 0; i < e.Params.Length; i++){
  131.         e.Params[i].Visit(this);
  132.     }
  133.     if(e.System){
  134.         il.Emit(OpCodes.Call, ((typeof(LispRuntime)).GetMethod(e.FunctionName)));
  135.     }
  136.     else{
  137.         il.Emit(OpCodes.Call, (MethodInfo)Functions[e.FunctionName]);
  138.     }
  139.     
  140.     }
  141.     
  142.     public void CarExp(CarExp e)
  143.     {
  144.     e.Left.Visit(this);
  145.     il.Emit(OpCodes.Call, ((typeof(LispRuntime)).GetMethod("Car")));
  146.     }
  147.     
  148.     public void IsNullExp(IsNullExp e)
  149.     {
  150.     }
  151.  
  152.     public void ToIntExp(ToIntExp e)
  153.     {
  154.     e.Value.Visit(this);
  155.     il.Emit(OpCodes.Call, ((typeof(LispRuntime)).GetMethod("ToInt")));
  156.     }
  157.  
  158.     public void ToListExp(ToListExp e)
  159.     {
  160.     e.Value.Visit(this);
  161.     il.Emit(OpCodes.Call, ((typeof(LispRuntime)).GetMethod("ToList")));
  162.     }
  163.     
  164.     
  165.     public void StringExp(StringExp e)
  166.     {
  167.     il.Emit(OpCodes.Ldstr, (e.Value));
  168.     il.Emit(OpCodes.Call, ((typeof(LispRuntime)).GetMethod("Init")));
  169.     }
  170.     
  171.     public void VarExp(VarExp e)
  172.     {
  173.     switch(e.Pos){
  174.     case 0:
  175.         il.Emit(OpCodes.Ldarg_0);
  176.         break;
  177.     case 1:
  178.         il.Emit(OpCodes.Ldarg_1);
  179.         break;
  180.     case 2:
  181.         il.Emit(OpCodes.Ldarg_2);
  182.         break;
  183.     case 3:
  184.         il.Emit(OpCodes.Ldarg_3);
  185.         break;
  186.     default:
  187.         if(e.Pos > -128 && e.Pos < 127)
  188.         il.Emit(OpCodes.Ldarg_S, e.Pos);
  189.         else 
  190.         il.Emit(OpCodes.Ldarg, e.Pos);
  191.         break;
  192.     }
  193.     }
  194.     
  195.     public void GlobalVarExp(GlobalVarExp e)
  196.     {
  197.         il.Emit(OpCodes.Ldsfld, (FieldInfo)GlobalVars[e.Name]);    
  198.     }
  199.     
  200.     public void IfExp(IfExp e)
  201.     {
  202.     Label FalseLabel, EndLabel;
  203.     FalseLabel = il.DefineLabel();
  204.     EndLabel = il.DefineLabel();
  205.     e.EvalExp.Visit(this);
  206.     il.Emit(OpCodes.Brfalse, FalseLabel);
  207.     e.ThenExp.Visit(this);
  208.     il.Emit(OpCodes.Br, EndLabel);
  209.     il.MarkLabel(FalseLabel);
  210.     e.ElseExp.Visit(this);
  211.     il.MarkLabel(EndLabel);
  212.     
  213.     }
  214.  
  215.     public void DoExp(DoExp e)
  216.     {
  217.     Label l1 = il.DefineLabel();
  218.     Label l2 = il.DefineLabel();
  219.     Label EndLabel = il.DefineLabel();
  220.     
  221.     for (ExpList el = e.Vars; el != null; el = el.Tail){
  222.         el.Head.Visit(this);
  223.     }
  224.     il.Emit(OpCodes.Br, l1);
  225.     il.MarkLabel(l2);
  226.     for (ExpList el = e.Vars; el != null; el = el.Tail){
  227.         DoVarIter((DoVarDef)el.Head);
  228.     }
  229.     il.MarkLabel(l1);
  230.     
  231.     for (ExpList el = e.Conds; el != null; el = el.Tail){
  232.         ((DoCondExp)el.Head).EndLabel = EndLabel;
  233.         el.Head.Visit(this);
  234.     }
  235.     il.Emit(OpCodes.Br, l2);
  236.     
  237.     il.MarkLabel(EndLabel);
  238.     
  239.     }
  240.  
  241.     public void DoVarIter(DoVarDef e)
  242.     {
  243.     e.Iter.Visit(this);
  244.     il.Emit(OpCodes.Stloc, (LocalBuilder)DoVars[e.Pos]);
  245.     }
  246.     
  247.  
  248.     public void DoVarExp(DoVarExp e)
  249.     {
  250.         il.Emit(OpCodes.Ldloc, (LocalBuilder)DoVars[e.Pos]);
  251.     }
  252.     
  253.     public void DoCondExp(DoCondExp e)
  254.     {
  255.     Label FalseLabel;
  256.     FalseLabel = il.DefineLabel();
  257.  
  258.     e.Cond.Visit(this);
  259.     il.Emit(OpCodes.Brfalse, FalseLabel);
  260.     e.Ret.Visit(this);
  261.     il.Emit(OpCodes.Br, e.EndLabel);
  262.     
  263.     il.MarkLabel(FalseLabel);
  264.     
  265.     }
  266.     
  267.     public void DoVarDef(DoVarDef e)
  268.     {
  269.     LocalBuilder lt = il.DeclareLocal(e.Init.ExpType);
  270.     DoVars.Add(e.Pos, lt);
  271.     e.Init.Visit(this);
  272.     il.Emit(OpCodes.Stloc, lt);
  273.     }
  274.     
  275.     
  276.     public void FunctionDef(FunctionDef e)
  277.     {
  278.     Type[] param = new Type[e.Count];
  279.     DoVars = new Hashtable();
  280.     
  281.     for (int i = 0; i < e.Count; i++){
  282.         param[i] = (Type)e.Params[i];
  283.     }
  284.     
  285.     //DescriptorInfo di = new DescriptorInfo(param);
  286.     //di.SetReturnType(e.ExpType);
  287.     //di.MethodAttributes = MethodAttributes.Static | MethodAttributes.Public;
  288.     methodb = tb.DefineMethod(e.Name, MethodAttributes.Static | MethodAttributes.Public, e.ExpType, param);
  289.     Functions.Add(e.Name, methodb);
  290.     ILGenerator ilmain = il;
  291.     il = methodb.GetILGenerator();
  292.  
  293.     e.Body.Visit(this);
  294.     
  295.     il.Emit(OpCodes.Ret);
  296.     il = ilmain;
  297.     }
  298.     
  299.     public void GlobalVarDef(GlobalVarDef e)
  300.     {
  301.     FieldInfo fi = tb.DefineField(e.Name, e.ExpType, FieldAttributes.Static);
  302.     GlobalVars.Add(e.Name, fi);
  303.  
  304.     e.Value.Visit(this);
  305.     il.Emit(OpCodes.Stsfld, fi);
  306.     }
  307.     
  308.     public void Generate(String filename)
  309.     {
  310.     AppDomain ad = Thread.GetDomain(); //AppDomain.CreateDomain("First", null, null);
  311.     AssemblyName an = new AssemblyName();
  312.     an.Name = filename + ".exe"; //AssemblyName.CreateSimpleName(filename + ".exe", "LispExe", "Lisp Executable", "default_alias");
  313.     AssemblyBuilder ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
  314.     ModuleBuilder mb = ab.DefineDynamicModule(filename + ".exe", filename + ".exe");
  315.     MethodBuilder methodb;
  316.     //DescriptorInfo di = new DescriptorInfo(0);
  317.     tb = mb.DefineType(filename);
  318.     
  319.     //di.SetReturnType(typeof(void));
  320.     //di.MethodAttributes = MethodAttributes.Static | MethodAttributes.Public;
  321.     methodb = tb.DefineMethod("Main", MethodAttributes.Static | MethodAttributes.Public, typeof(void), null);
  322.     il = methodb.GetILGenerator();
  323.  
  324.     do{
  325.         expr.Head.Visit(this);
  326.             if (expr.Head is FunctionDef)
  327.             GenerateDefStub(((FunctionDef)expr.Head).Name);
  328.              else if (expr.Head is GlobalVarDef)
  329.             GenerateDefStub(((GlobalVarDef)expr.Head).Name);
  330.          else if (expr.Head.ExpType == typeof(int))
  331.           GenerateNumericExpStub();
  332.             else if (expr.Head.ExpType == typeof(bool))
  333.         GenerateBoolExpStub();
  334.             else if (expr.Head.ExpType == typeof(CList)) 
  335.             GenerateListExpStub();
  336.         
  337.         expr = expr.Tail;
  338.     }while(expr != null);
  339.     
  340.     il.Emit(OpCodes.Ret);
  341.     tb.CreateType();
  342.     
  343.     ab.SetEntryPoint((mb.GetType(filename)).GetMethod("Main"));
  344.     ab.Save(filename + ".exe");
  345.     }
  346.  
  347.     void GenerateNumericExpStub()
  348.     {
  349.       Type[] type = new Type[1];
  350.       type[0] = typeof(System.Int32);
  351.       il.Emit(OpCodes.Call, ((typeof(System.Console)).GetMethod("WriteLine", type)));
  352.     }
  353.  
  354.     void GenerateListExpStub()
  355.     {
  356.       il.Emit(OpCodes.Call, ((typeof(LispRuntime)).GetMethod("Print")));
  357.       Type[] type = new Type[1];
  358.       type[0] = typeof(System.String);
  359.     il.Emit(OpCodes.Ldstr, "");                //This is just to do a WriteLine after the Print.
  360.       il.Emit(OpCodes.Call, ((typeof(System.Console)).GetMethod("WriteLine", type)));
  361.     
  362.     }
  363.  
  364.     void GenerateDefStub(String Name)
  365.     {
  366.       Type[] type = new Type[1];
  367.       type[0] = typeof(System.String);
  368.     il.Emit(OpCodes.Ldstr, Name);
  369.       il.Emit(OpCodes.Call, ((typeof(System.Console)).GetMethod("WriteLine", type)));
  370.     
  371.     }
  372.  
  373.     void GenerateBoolExpStub()
  374.     {
  375.     il.Emit(OpCodes.Call, ((typeof(LispRuntime)).GetMethod("PrintBool")));
  376.     }
  377.     
  378. }
  379.