Advertisement
Guest User

Untitled

a guest
May 6th, 2014
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 4.28 KB | None | 0 0
  1. import std.stdio;
  2.  
  3. enum Type {
  4.     number,
  5.     id,
  6.     add,
  7.     sub,
  8.     mul,
  9.     div,
  10.     push,
  11.     pop,
  12.     none
  13. }
  14.  
  15. enum Reg {
  16.     none,
  17.     r0,
  18.     r1
  19. }
  20.  
  21. class AST {
  22.     AST left;
  23.     AST right;
  24.     Type type;
  25.     Reg reg;
  26.     int n;
  27.  
  28.     this(AST l, AST r, Type t) {
  29.         left = l;
  30.         right = r;
  31.         type = t;
  32.         n = 0;
  33.     }
  34. }
  35.  
  36. class BinExpression : AST {
  37.     this(AST l, AST r, Type t) {
  38.         super(l, r, t);
  39.     }
  40. }
  41.  
  42. class Identifier : AST {
  43.     string name;
  44.    
  45.     this(string nm) {
  46.         super(null, null, Type.id);
  47.         name = nm;
  48.     }
  49. }
  50.  
  51. class Number : AST {
  52.     int number;
  53.    
  54.     this(int n) {
  55.         super(null, null, Type.number);
  56.         number = n;
  57.     }
  58. }
  59.  
  60.  
  61. Reg[] regs = [ Reg.r0, Reg.r1 ];
  62. const int regs_num = regs.sizeof / int.sizeof;
  63. int C = 0;
  64.  
  65. void main() {
  66.     // ((2 + 2) + (2 + 2)) + ((2 + 2) + (2 + 2))
  67.     // t1 = 2 + 2
  68.     // t2 = 2 + 2
  69.     // t3 = t1 + t2
  70.     // t4 = 2 + 2
  71.     // t5 = 2 + 2
  72.     // t6 = t4 + t5
  73.     // t7 = t3 + t6
  74.     Number a = new Number(2);
  75.     Number b = new Number(2);
  76.  
  77.     Number c = new Number(2);
  78.     Number d = new Number(2);
  79.    
  80.     Number e = new Number(2);
  81.     Number f = new Number(2);
  82.    
  83.     Number g = new Number(2);
  84.     Number h = new Number(2);
  85.    
  86.    
  87.     // t1 = 2 + 2
  88.     BinExpression t1 = new BinExpression(a, b, Type.add);
  89.     // t2 = 2 + 2
  90.     BinExpression t2 = new BinExpression(c, d, Type.add);
  91.     // t3 = t1 + t2
  92.     BinExpression t3 = new BinExpression(t1, t2, Type.add);
  93.     // t4 = 2 + 2
  94.     BinExpression t4 = new BinExpression(e, f, Type.add);
  95.     // t5 = 2 + 2
  96.     BinExpression t5 = new BinExpression(g, h, Type.add);
  97.     // t5 = t3 + t4
  98.     BinExpression t6 = new BinExpression(t4, t5,Type.add);
  99.     BinExpression t7 = new BinExpression(t3, t6, Type.add);
  100.     label(t7);
  101.     gen(t7);
  102. }
  103.  
  104. Reg get_reg() {
  105.     if(C == regs.sizeof / int.sizeof) {
  106.         //writeln("out of registers!");
  107.         C = 0;
  108.     }
  109.    
  110.     return regs[C++];
  111. }
  112.  
  113. void gen(AST ast) {
  114.     if(ast.left !is null && ast.right !is null) {
  115.         int l = ast.left.n;
  116.         int r = ast.right.n;
  117.        
  118.         if(l >= regs_num && r >= regs_num) {
  119.             gen(ast.right);
  120.             ast.n -= 1;
  121.             //Reg r2 = ast.right.reg;
  122.             emit_operation(Type.push, ast.right.reg);
  123.             gen(ast.left);
  124.             ast.reg = get_reg();
  125.             emit_operation(Type.pop, ast.right.reg);
  126.             //push_reg(r2);
  127.         } else if(l >= r) {
  128.             gen(ast.left);
  129.             gen(ast.right);
  130.             ast.n -= 1;
  131.         } else if(l < r) {
  132.             gen(ast.right);
  133.             gen(ast.left);
  134.             ast.n -= 1;
  135.         }
  136.        
  137.         ast.reg = get_reg();
  138.         Reg r1 = ast.left.reg;
  139.         Reg r2 = ast.right.reg;
  140.         emit_operation(ast.type, r1, r2);
  141.         // result is in r1, so free r2.
  142.         //push_reg(r2);
  143.     } else if(ast.type == Type.id || ast.type == Type.number) {
  144.         ast.n += 1;
  145.         ast.reg = get_reg();
  146.         emit_load(ast);
  147.     } else {
  148.         writeln("gen() error");
  149.         // error
  150.     }
  151. }
  152.  
  153. void label(AST ast) {
  154.     if(ast is null)
  155.         return;
  156.    
  157.     label(ast.left);
  158.     label(ast.right);
  159.    
  160.     if(ast.type == Type.id || ast.type == Type.number)
  161.         ast.n = 1;
  162.     // ast has two childrens
  163.     else if(ast.left !is null && ast.right !is null) {     
  164.         int l = ast.left.n;
  165.         int r = ast.right.n;
  166.        
  167.         if(l == r)
  168.             ast.n = 1 + l;
  169.         else
  170.             ast.n = max(1, l, r);
  171.     }
  172.     // ast has one child
  173.     else if(ast.left !is null && ast.right is null)
  174.         ast.n = ast.left.n;
  175.     else
  176.         writeln("label() error!");
  177. }
  178.  
  179. int max(int x, int y, int z) {
  180.     return max(x, max(y, z));
  181. }
  182.  
  183. int max(int a, int b) {
  184.     return a > b ? a : b;
  185. }
  186.  
  187. void emit_operation(Type op, Reg r1, Reg r2)
  188. {  
  189.     writefln("\t%s %s,%s",
  190.                      op_as_string(op),
  191.                      reg_as_string(r1),
  192.                      reg_as_string(r2));
  193. }
  194.  
  195. void emit_load(AST ast) {  
  196.     switch(ast.type) {
  197.         case Type.id:
  198.             writefln("\t LOAD %s,[%s]", reg_as_string(ast.reg), (cast(Identifier)ast).name);
  199.             break;
  200.         case Type.number:
  201.             writefln("\t LOAD %s,%d", reg_as_string(ast.reg), (cast(Number)ast).number);
  202.             break;
  203.         default:
  204.             writeln("emitLoad() error!");
  205.     }
  206. }
  207.  
  208. void emit_operation(Type op, Reg r)
  209. {  
  210.     writefln("\t%s %s",
  211.                      op_as_string(op),
  212.                      reg_as_string(r));
  213. }
  214.  
  215. string reg_as_string(Reg r) {
  216.     switch(r) {
  217.         case Reg.r0:   return "R0";
  218.         case Reg.r1:   return "R1";
  219.         case Reg.none: return "NONE";
  220.         default:     return "UNKNOW";
  221.     }
  222. }
  223.  
  224. string op_as_string(Type t) {
  225.     switch(t) {
  226.         case Type.add: return "ADD";
  227.         case Type.sub: return "SUB";
  228.         case Type.mul: return "MUL";
  229.         case Type.div: return "DIV";
  230.         case Type.push: return "push";
  231.         case Type.pop: return "pop";   
  232.         default:     return "UNKNOW";
  233.     }
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement