Advertisement
Guest User

Untitled

a guest
Nov 20th, 2014
317
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 37.54 KB | None | 0 0
  1. /*
  2. *   CodeGenerator
  3. */
  4.  
  5. import scala.collection.mutable.StringBuilder
  6. import scala.collection.immutable.List
  7. import scala.io.Source
  8. import java.io.File
  9. import java.io.PrintWriter
  10.  
  11. class CodeGenerator(input: Program, outdir:String, emitter:Emitter) {
  12.  
  13.     val env = Checker.makeListClass(input.decl, Checker.initial)
  14.     // Don't change the prototype of this method
  15.     def run: Unit = {  
  16.         val output = generateCode(input.decl, env, List(Symbol("io",ClassType("IO"),Attribute,"IO")))
  17.         printOutput(output, outdir)      
  18.     }
  19.  
  20.     def printOutput(out:List[(String,String)], outdir: String) = {
  21.         for (i <- out) {
  22.             val dest = new PrintWriter(new File(outdir+"\\"+i._1+".j" ))
  23.             dest.print(i._2)
  24.             dest.close()
  25.         }
  26.     }
  27.    
  28.     def generateCode(lst:List[Decl],env:List[MyClassType],symTable:List[Symbol]) =
  29.         lst.map(x=>generateClass(x.asInstanceOf[ClassDecl],symTable))
  30.  
  31.     def generateClass(decl:ClassDecl,symTable:List[Symbol]) =  {
  32.         val className = decl.name.name
  33.        
  34.         val classHeader = emitter.emitPROLOG(decl)
  35.         val classCInit = emitter.emitCLINIT(decl,List())
  36.         val classInit = generateInit(decl)
  37.         val classFields = generateClassFields(decl)
  38.         val classMethods = generateMethods(decl,symTable)
  39.        
  40.  
  41.         val classBody = classHeader + "\n" +
  42.                         classFields + "\n" + classCInit + "\n" + classInit + "\n"  + classMethods
  43.         (className,classBody)
  44.     }
  45.  
  46.     def generateInit(decl:ClassDecl) = {        
  47.         val al = getArrayAttributes(decl)
  48.         emitter.emitINIT(decl,al)
  49.     }
  50.  
  51.     //Return list of attributes with array type
  52.     def getArrayAttributes(decl:ClassDecl) = List[Symbol]()
  53.  
  54.     def generateClassFields(decl:ClassDecl) = {
  55.         val al = getAttributes(decl.decl)
  56.         al.foldLeft("")((a,b) => a + emitter.emitINSTANCEFIELD(b.name,b.typ,b.kind,b.obj.get))
  57.     }
  58.  
  59.     def getAttributes(decl:List[Decl]):List[Symbol] = decl match {
  60.         case List() => List()
  61.         case head::tail => head match {
  62.             case VarDecl(i,t) => Symbol(i.name,t,Variable,Some(""))::getAttributes(tail)
  63.             case _ => getAttributes(tail)
  64.         }
  65.     }
  66.  
  67.     def generateMethods(decl:ClassDecl,sym:List[Symbol]) = {
  68.         val ml = getMethods(decl.decl)
  69.         ml.foldLeft("")((a,b) => a + generateMethod(b,decl,sym))
  70.     }
  71.  
  72.     def getMethods(decl:List[Decl]):List[MethodImpDecl] = decl match {
  73.         case List() => List()
  74.         case head::tail => head match {
  75.             case MethodImpDecl(r,n,pl,b) => MethodImpDecl(r,n,pl,b)::getMethods(tail)
  76.             case _ => getMethods(tail)
  77.         }
  78.     }
  79.  
  80.     def generateMethod(decl:MethodImpDecl,cls:ClassDecl,sym:List[Symbol]) = {
  81.         val isMain = decl.name.name == "main" && decl.param.length == 0 && cls.name.name == "Main"
  82.         val frame = new Frame(isMain)
  83.         val prolog = emitter.emitMETHOD(decl.name.name,MethodType(cls.name.name,Checker.getParamList(decl.param),decl.returnType),isMain,frame)
  84.         val params = generateParam(decl.param,sym,frame)
  85.         val startLabel = frame.getStartLabel
  86.         val endLabel = frame.getEndLabel
  87.         val label0 = emitter.emitLABEL(startLabel)
  88.         val body = generateStmt(decl.body,cls,params._2,true,frame)
  89.         val label1 = emitter.emitLABEL(endLabel)
  90.         val ret = if (isMain) emitter.emitRETURN(null,frame) else ""
  91.         val limits = emitter.emitLIMITSTACK(frame.getMaxOpStackSize) +
  92.                      emitter.emitLIMITLOCAL(frame.getMaxIndex)
  93.         val endmt = emitter.emitENDMETHOD
  94.         prolog + params._1 + label0 + body + label1 + ret + limits + endmt
  95.        
  96.     }
  97.  
  98.     def generateParam(dl:List[ParamDecl],sym:List[Symbol],frame:Frame) = {
  99.         frame.enterScope(true)
  100.         if (frame.isMain)
  101.             (emitter.emitVAR(frame.getNewIndex(),"arg","[Ljava/lang/String;",frame.getStartLabel(),frame.getEndLabel()),sym)                  
  102.         else
  103.             dl.foldLeft(("",sym))((a,b) => {
  104.                 val index = frame.getNewIndex
  105.                 (a._1 + emitter.emitVAR(index,b.id.name,b.paramType,frame.getStartLabel,frame.getEndLabel),
  106.                  Symbol(b.id.name,b.paramType,Parameter,index.toString)::a._2)
  107.                 })
  108.     }
  109.  
  110.     def generateVariable(dl:List[Decl],sym:List[Symbol],frame:Frame) = {
  111.         dl.foldLeft(("",sym))((a,b) => b match {
  112.             case VarDecl(id,t) => {
  113.                 val index = frame.getNewIndex
  114.                 (a._1 + emitter.emitVAR(index,id.name,t,frame.getStartLabel,frame.getEndLabel),
  115.                  Symbol(id.name,t,Variable,index.toString)::a._2)
  116.               }
  117.             case _ => a
  118.             })
  119.     }
  120.  
  121.     def generateStmtList(sl:List[Stmt],cls:ClassDecl,sym:List[Symbol],isBody:Boolean,frame:Frame) =
  122.         sl.foldLeft("")((a,b) => a + generateStmt(b,cls,sym,isBody,frame))
  123.  
  124.  
  125.     def generateStmt(stmt:Stmt,cls:ClassDecl,sym:List[Symbol],isBody:Boolean,frame:Frame):String = {
  126.         stmt match {
  127.             case Block(dl,sl) => {
  128.                 if (!isBody) frame.enterScope(false)
  129.                 val decl = generateVariable(dl,sym,frame)
  130.                 val startLabel = frame.getStartLabel
  131.                 val endLabel = frame.getEndLabel
  132.                 val label0 = emitter.emitLABEL(startLabel)
  133.                 val stmts = generateStmtList(sl,cls,decl._2,false,frame)
  134.                 val label1 = emitter.emitLABEL(endLabel)
  135.                 frame.exitScope()
  136.                 decl._1 + label0 + stmts + label1
  137.             }
  138.             case Assign(lhs,exp) => {
  139.                 lhs match {
  140.                     case Id(n) => {
  141.                         val expCode = generateExpression(exp,cls,sym,frame)
  142.                         val symbol = lookup(n,sym)
  143.                         val lhsCode = emitter.emitWRITEVAR(symbol,frame)
  144.                         expCode._1 + lhsCode
  145.                     }
  146.                 }
  147.             }
  148.             case Call(e,n,pl) => {
  149.                 val lhscls = generateExpression(e,cls,sym,frame)              
  150.                 val params = pl.foldLeft("")((a,b) => {val res = generateExpression(b,cls,sym,frame);a + res._1})
  151.                 val clstyp = lhscls._2.typ.asInstanceOf[ClassType]
  152.                 val mth = lookupMethod(n.name,pl.length,clstyp,env)
  153.                 val call = emitter.emitINVOKEVIRTUAL(clstyp.classType+"/"+n.name,mth.typ,frame)
  154.                 lhscls._1 + params + call
  155.             }
  156.  
  157.         }
  158.     }
  159.  
  160.     def generateExpression(exp:Expr,cls:ClassDecl,sym:List[Symbol],frame:Frame):(String,Symbol) = {
  161.         exp match {
  162.             case Id(n) => {val symbol = lookup(n,sym)
  163.                            val expCode = emitter.emitREADVAR(symbol,frame)
  164.                            (expCode,symbol)
  165.                        }
  166.  
  167.             case IntLiteral(v) => {val symbol = Symbol("",IntType,Constant,v.toString)
  168.                                     val expCode = emitter.emitICONST(v,frame)
  169.                                     (expCode,symbol)
  170.                         }
  171.             case _ => ("",Symbol("",IntType,Constant,""))
  172.         }
  173.     }
  174.  
  175.     def lookup(n:String,sym:List[Symbol]):Symbol = sym match {
  176.         case List() => throw Undeclared(Identifier,n)
  177.         case head::tail => if (n == head.name) head else lookup(n,tail)
  178.     }
  179.    
  180.  
  181.     def lookupField(n:String,cls:ClassType,env:List[MyClassType]):Symbol =
  182.         env match {
  183.             case List() => throw Undeclared(Attribute,n)
  184.             case head::tail => if (head.name == cls.classType) {
  185.                                     val res = getField(n,head.lstAtt)
  186.                                     res match {
  187.                                         case Some(s) => s
  188.                                         case None =>  if (head.parent == null||head.parent == "")
  189.                                                             throw Undeclared(Attribute,n)
  190.                                                       else lookupField(n,ClassType(head.parent),env)
  191.                                         }
  192.                                 } else lookupField(n,cls,tail)
  193.         }
  194.  
  195.     def lookupMethod(n:String,dim:Integer,cls:ClassType,env:List[MyClassType]):Symbol =
  196.         env match {
  197.             case List() => throw Undeclared(Method,n)
  198.             case head::tail => if (head.name == cls.classType) {
  199.                                     val res = getMethod(n,dim,head.lstMethod)
  200.                                     res match {
  201.                                         case Some(s) => s
  202.                                         case None =>  if (head.parent == null||head.parent == "")
  203.                                                             throw Undeclared(Method,n)
  204.                                                       else lookupMethod(n,dim,ClassType(head.parent),env)
  205.                                     }
  206.                                 } else lookupMethod(n,dim,cls,tail)
  207.         }
  208.  
  209.     def getField(n:String,lst:List[Symbol]):Option[Symbol] =
  210.         lst match {
  211.             case List() => None
  212.             case head::tail => if (n == head.name) Some(head) else getField(n,tail)
  213.         }
  214.  
  215.     def getMethod(n:String,dim:Integer,lst:List[Symbol]):Option[Symbol] =
  216.         lst match {
  217.             case List() => None
  218.             case head::tail => if (n == head.name && dim == head.typ.asInstanceOf[MethodType].params.length) Some(head) else getMethod(n,dim,tail)
  219.         }
  220. }
  221.  
  222. /**
  223. *   Emitter.scala
  224. */
  225.  
  226. import java.text.DecimalFormat
  227.  
  228. class Emitter(machine:MachineCode) {
  229.    
  230.     val END="\n"
  231.    
  232.     def emitICONST(i:Integer,frame:Frame) = {  
  233.         frame.push()
  234.         if (i == -1)
  235.             machine.emitICONST(i)  
  236.         else if (i >= 0 && i <= 5)
  237.             machine.emitICONST(i)
  238.         else if (i >= -128 && i <= 127)
  239.             machine.emitBIPUSH(i)
  240.         else if (i >= -32768 && i <= 32767)
  241.             machine.emitSIPUSH(i)
  242.         else
  243.             machine.emitLDC(i.toString)
  244.     }
  245.    
  246.     def emitICONST(in: String,frame:Frame):String = {
  247.        
  248.         if (in == "true")
  249.             emitICONST(1,frame)
  250.         else if (in == "false")
  251.             emitICONST(0,frame)
  252.         else {
  253.             try {
  254.                 emitICONST(Integer.parseInt(in),frame)
  255.             } catch  {
  256.                 case e:NumberFormatException => throw  IllegalOperandException
  257.             }
  258.         }
  259.     }
  260.        
  261.    
  262.     def emitFCONST(in: String,frame:Frame) =  {    
  263.         try {
  264.             val f = in.toFloat
  265.             val myFormatter = new DecimalFormat("###0.0###")
  266.             val rst = myFormatter.format(f)
  267.             frame.push()
  268.             machine.emitFCONST(rst)
  269.         } catch {
  270.                 case e:NumberFormatException => throw  IllegalOperandException
  271.             }
  272.     }
  273.    
  274.     def emitLDC(in: String,frame:Frame) = {
  275.         frame.push()
  276.         machine.emitLDC(in)
  277.     }
  278.    
  279.     def emitREADVAR(sym: Symbol,frame:Frame,cls: ClassType = null) = {     
  280.         if (sym.kind == Variable || sym.kind == Parameter) {
  281.             if (sym.typ == IntType || sym.typ == BoolType)
  282.                 emitILOAD(sym.obj.get.toInt,frame)
  283.             else if (sym.typ == FloatType )
  284.                 emitFLOAD(sym.obj.get.toInt,frame)
  285.             else
  286.                 emitALOAD(sym.obj.get.toInt,frame)
  287.         } else if (sym.kind == Attribute && sym.typ == ClassType("IO") && sym.name == "io") {
  288.             emitGETSTATIC(sym.name,sym.typ,frame, ClassType(sym.obj.get) )
  289.         } else
  290.             emitGETFIELD(sym.name, sym.typ,frame, ClassType(sym.obj.get) )
  291.     }
  292.    
  293.     def emitREADVAR2(sym: Symbol,frame:Frame) =
  294.         sym.typ match {
  295.             case ArrayType(dim,eT) => emitTALOAD(eT,frame)
  296.             case _ => {    
  297.             if (sym.kind == Variable || sym.kind == Parameter) {               
  298.                 if (sym.typ == IntType || sym.typ == BoolType)
  299.                     emitILOAD(sym.obj.get.toInt,frame)
  300.                 else
  301.                     emitFLOAD(sym.obj.get.toInt,frame)
  302.             } else if (sym.kind == Attribute && sym.typ == ClassType("IO") && sym.name == "io") {
  303.                 emitGETSTATIC(sym.name,sym.typ,frame,ClassType(sym.obj.get))
  304.             } else
  305.                 emitGETFIELD(sym.name,sym.typ,frame,ClassType(sym.obj.get))
  306.         }
  307.     }
  308.    
  309.     def emitWRITEVAR(sym: Symbol,frame:Frame,cls:ClassType=null) =
  310.         sym.typ match {
  311.             case ArrayType(dim,eT) => emitTASTORE(eT,frame)
  312.             case _ => {
  313.             if (sym.kind == Variable || sym.kind == Parameter) {
  314.                 if (sym.typ == IntType || sym.typ == BoolType)
  315.                     emitISTORE(sym.obj.get.toInt,frame)
  316.                 else
  317.                     emitFSTORE(sym.obj.get.toInt,frame)
  318.                
  319.             } else if (sym.kind == Attribute && sym.typ == ClassType("IO") && sym.name == "io") {
  320.                 emitPUTSTATIC(sym.name,sym.typ,frame,ClassType(sym.obj.get))
  321.             } else
  322.                 emitPUTFIELD(sym.name,sym.typ,frame,ClassType(sym.obj.get))
  323.         }
  324.     }
  325.            
  326.     def emitILOAD(in:Integer,frame:Frame) = {
  327.         frame.push()
  328.         machine.emitILOAD(in)
  329.     }
  330.    
  331.     def emitFLOAD(in: Integer,frame:Frame) = {
  332.         frame.push()
  333.         machine.emitFLOAD(in)
  334.     }  
  335.    
  336.     def emitISTORE(in: Integer,frame:Frame) = {
  337.         frame.pop()
  338.         machine.emitISTORE(in)
  339.     }
  340.    
  341.     def emitFSTORE(in: Integer,frame:Frame) =  {
  342.         frame.pop()
  343.         machine.emitFSTORE(in)
  344.     }
  345.  
  346.     def emitALOAD(in: Integer,frame:Frame) = {
  347.         frame.push()
  348.         machine.emitALOAD(in)
  349.     }  
  350.  
  351.     def emitASTORE(in: Integer,frame:Frame) = {
  352.         frame.pop()
  353.         machine.emitASTORE(in)
  354.        
  355.     }  
  356.  
  357.     def emitTALOAD(in: Type,frame:Frame) = {
  358.         frame.pop()
  359.         if (in == IntType)
  360.             machine.emitIALOAD
  361.         else if (in == FloatType)
  362.             machine.emitFALOAD
  363.         else
  364.             machine.emitBALOAD
  365.     }  
  366.  
  367.     def emitTASTORE(in: Type,frame:Frame) = {
  368.         frame.pop()
  369.         frame.pop()
  370.         frame.pop()
  371.         if (in == IntType)
  372.             machine.emitIASTORE
  373.         else if (in == FloatType)
  374.             machine.emitFASTORE
  375.         else
  376.             machine.emitBASTORE
  377.     }
  378.  
  379.     def emitADDOP(lexeme: String,in: Type,frame:Frame)=  {
  380.         frame.pop()
  381.         if (lexeme == "+") {
  382.             if (in == IntType)
  383.                 machine.emitIADD
  384.             else
  385.                 machine.emitFADD
  386.         } else
  387.             if (in == IntType)
  388.                 machine.emitISUB
  389.             else
  390.                 machine.emitFSUB
  391.     }
  392.    
  393.     def emitMULOP(lexeme: String,in: Type,frame:Frame) = {
  394.        
  395.         if (lexeme == "*") {
  396.             if (in == IntType)
  397.                 machine.emitIMUL
  398.             else
  399.                 machine.emitFMUL
  400.         } else
  401.             if (in == IntType)
  402.                 machine.emitIDIV
  403.             else
  404.                 machine.emitFDIV
  405.         frame.pop()
  406.     }
  407.  
  408.     def emitANDOP(frame:Frame) = {
  409.         frame.pop()
  410.         machine.emitIAND
  411.     }  
  412.    
  413.     def emitOROP(frame:Frame) = {
  414.         frame.pop()
  415.         machine.emitIOR
  416.     }
  417.    
  418.     def emitEQOP(lexeme: String,label:Integer,frame:Frame) = {
  419.         frame.pop()
  420.         frame.pop()
  421.         if (lexeme == "==")
  422.             machine.emitIFICMPNE(label)
  423.         else
  424.             machine.emitIFICMPEQ(label)    
  425.     }
  426.  
  427.    
  428.     def emitEQOP(lexeme: String,frame:Frame):String = {
  429.         val label = frame.getNewLabel
  430.         val label1 = frame.getNewLabel
  431.         var buff = new StringBuffer()
  432.         buff.append(emitEQOP(lexeme,label,frame))
  433.         buff.append(emitICONST(1,frame))
  434.         frame.pop()
  435.         buff.append(emitGOTO(label1,frame))
  436.         buff.append(emitLABEL(label))
  437.         buff.append(emitICONST(0,frame))
  438.         buff.append(emitLABEL(label1))
  439.         buff.toString()
  440.     }
  441.    
  442.     def emitRELOP(lexeme: String,in: Type,label:Integer,frame:Frame) = {
  443.         frame.pop()
  444.         frame.pop()
  445.         if (in == IntType)         
  446.             if (lexeme == ">=")
  447.                 machine.emitIFICMPLT(label)
  448.             else if (lexeme == ">")
  449.                 machine.emitIFICMPLE(label)
  450.             else if (lexeme == "<=")
  451.                 machine.emitIFICMPGT(label)
  452.             else
  453.                 machine.emitIFICMPGE(label)
  454.         else
  455.             ""//TODO
  456.     }
  457.  
  458.     def emitRELOP(lexeme: String,in: Type, frame: Frame):String = {
  459.        
  460.         val label = frame.getNewLabel
  461.         val label1 = frame.getNewLabel
  462.         var buff = new StringBuffer()
  463.         buff.append(emitRELOP(lexeme,in,label,frame))
  464.         buff.append(emitICONST(1,frame))
  465.         frame.pop()
  466.         buff.append(emitGOTO(label1,frame))
  467.         buff.append(emitLABEL(label))
  468.         buff.append(emitICONST(0,frame))
  469.         buff.append(emitLABEL(label1))
  470.         buff.toString()
  471.     }
  472.    
  473.     def emitIFTRUE(label: Integer,frame:Frame) = {
  474.         frame.pop()
  475.         machine.emitIFGT(label)
  476.     }
  477.    
  478.     def emitIFFALSE(label: Integer,frame:Frame) = {
  479.         frame.pop()
  480.         machine.emitIFLE(label)
  481.     }
  482.        
  483.     def emitNEGOP(lexeme: String,in: Type,frame:Frame) = {
  484.         if (lexeme == "!" || lexeme == "-") {
  485.             if (in == IntType || in == BoolType)
  486.                 machine.emitINEG
  487.             else
  488.                 machine.emitFNEG
  489.         }
  490.         else
  491.             ""
  492.     }
  493.    
  494.     def emitGETSTATIC(lexeme: String, in: Type,frame:Frame,cls: ClassType) = {
  495.         frame.push()
  496.         machine.emitGETSTATIC(cls.classType+"."+lexeme,in.genCode)
  497.     }
  498.    
  499.     def emitPUTSTATIC(lexeme: String, in: Type,frame:Frame,cls: ClassType) = {
  500.         frame.pop()
  501.         machine.emitPUTSTATIC(cls.classType+"."+lexeme,in.genCode)
  502.     }  
  503.    
  504.  
  505.     def emitGETFIELD(lexeme: String, in: Type,frame:Frame, cls: ClassType) = {
  506.         frame.push()
  507.         machine.emitGETFIELD(cls.classType+"."+lexeme,in.genCode)
  508.     }
  509.      
  510.     def emitPUTFIELD(lexeme: String, in: Type,frame:Frame,cls: ClassType) = {
  511.         frame.pop()
  512.         machine.emitPUTFIELD(cls.classType+"."+lexeme,in.genCode)
  513.     }
  514.     def emitGOTO(label: Integer,frame:Frame) = {
  515.         machine.emitGOTO(label)
  516.     }
  517.    
  518.     def emitDUP(frame:Frame) = {
  519.         frame.push()
  520.         machine.emitDUP
  521.     }
  522.  
  523.     def emitDUPX2(frame:Frame) = {
  524.         frame.push()
  525.         machine.emitDUPX2
  526.     }  
  527.     def emitPOP(frame:Frame) = {
  528.         frame.pop()
  529.         machine.emitPOP
  530.     }
  531.    
  532.     def emitI2F(frame:Frame) =
  533.         machine.emitI2F
  534.    
  535.    
  536.     def emitNEWARRAY(in: Type,frame:Frame) =
  537.         machine.emitNEWARRAY(in.genCode)
  538.    
  539.    
  540.     def emitINVOKESTATIC(lexeme: String,in: Type,frame:Frame) = {
  541.         val ft = in.asInstanceOf[MethodType]
  542.  
  543.         (1 to ft.params.length).foreach( _ => frame.pop)
  544.        
  545.         if (ft.returnType != null && ft.returnType != VoidType)
  546.             frame.push()       
  547.         machine.emitINVOKESTATIC(lexeme,in.genCode)
  548.     }
  549.    
  550.     def emitINVOKEVIRTUAL(lexeme: String,in: Type,frame:Frame) = {
  551.         val ft = in.asInstanceOf[MethodType]
  552.        
  553.         (0 to ft.params.length).foreach( _ => frame.pop)
  554.        
  555.         if (ft.returnType != null && ft.returnType != VoidType)
  556.             frame.push()
  557.         machine.emitINVOKEVIRTUAL(lexeme,in.genCode)
  558.     }
  559.  
  560.     def emitINVOKESPECIAL(frame:Frame) =
  561.         machine.emitINVOKESPECIAL
  562.    
  563.    
  564.     def emitRETURN(in: Type,frame:Frame) = {
  565.         if (in == null){
  566.             machine.emitRETURN
  567.         } else {
  568.             frame.pop()
  569.             if (in == IntType || in == BoolType)
  570.                 machine.emitIRETURN
  571.             else
  572.                 machine.emitFRETURN
  573.         }
  574.     }
  575.    
  576.     def emitLIMITSTACK(in: Integer) =
  577.         machine.emitLIMITSTACK(in)
  578.    
  579.    
  580.     def emitLIMITLOCAL(in: Integer) =
  581.         machine.emitLIMITLOCAL(in)
  582.    
  583.  
  584.     def emitVAR(in: Integer,varName: String, inType: Type, fromLabel: Integer, toLabel: Integer) =
  585.         machine.emitVAR(in, varName,inType.genCode,fromLabel,toLabel)
  586.    
  587.     def emitVAR(in: Integer,varName: String, inType: String, fromLabel: Integer, toLabel: Integer) =
  588.         machine.emitVAR(in,varName,inType,fromLabel,toLabel)
  589.        
  590.     def emitVAR(in: Integer, varname: String, inType: Type) =
  591.         machine.emitVAR(in,varname,inType.genCode)
  592.    
  593.    
  594.     def emitMETHOD(lexeme: String, in: String, isStatic: Boolean,frame:Frame) =
  595.         machine.emitMETHOD(lexeme,in,isStatic)
  596.    
  597.  
  598.     def emitMETHOD(lexeme: String, in: Type, isStatic: Boolean,frame:Frame):String = {     
  599.         if (frame.isMain)
  600.             emitMETHOD(lexeme,"([Ljava/lang/String;)V",true ,frame)
  601.         else
  602.             emitMETHOD(lexeme,in.genCode ,isStatic,frame)
  603.     }  
  604.  
  605.     def emitENDMETHOD() =
  606.         machine.emitENDMETHOD
  607.    
  608.    
  609.     def emitLABEL(in: Integer) =
  610.         machine.emitLABEL(in)
  611.    
  612.    
  613.     def emitPROLOG(decl:ClassDecl) = {
  614.         val cls = machine.emitCLASS(decl.name.name)
  615.         val parent = machine.emitSUPER(if (decl.parent != null) decl.parent.name else "java/lang/Object")
  616.         //val sour = ".source " + source + END
  617.         cls + parent //+ sour
  618.     }
  619.    
  620.     def emitSTATICFIELD(lexeme: String, in: Type, kind: Kind, value: String = "") = {
  621.         machine.emitSTATICFIELD(lexeme,in.genCode,kind == Constant,value)
  622.     }
  623.    
  624.     def emitINSTANCEFIELD(lexeme: String, in: Type, kind: Kind, value: String = "") = {
  625.         machine.emitINSTANCEFIELD(lexeme,in.genCode,kind == Constant,value)
  626.     }
  627.    
  628.     def emitCLINIT(decl:ClassDecl, in:List[Symbol]) = {
  629.         var result = new StringBuffer()
  630.         val prs:List[Type] = List()
  631.         val tmp = MethodType(decl.name.name,prs,VoidType)
  632.         val frame = new Frame(false)
  633.         frame.enterScope(true)
  634.         result.append(emitMETHOD("<clinit>",tmp,true,frame))
  635.         result.append(emitLIMITSTACK(1))
  636.         result.append(emitLIMITLOCAL(0))
  637.         //if (CodeGenerator.DEBUG) System.out.println(in.size())
  638.         in.foreach(sym => {
  639.             val at = sym.typ.asInstanceOf[ArrayType]
  640.             result.append(emitICONST(at.dimen.value,frame))
  641.             result.append(emitNEWARRAY(at.eleType,frame))
  642.             result.append(emitPUTSTATIC(sym.name,sym.typ,frame,ClassType(decl.name.name)))
  643.         })
  644.         result.append(emitRETURN(null,frame))
  645.         result.append(emitENDMETHOD())
  646.         frame.exitScope()
  647.         //in.clear()
  648.         result.toString()
  649.     }      
  650.        
  651.     def emitINIT(decl:ClassDecl,in:List[Symbol]) = {
  652.         var result = new StringBuffer()
  653.        
  654.         val tmp = MethodType(decl.name.name,List(),VoidType)
  655.         val frame = new Frame(false)
  656.         frame.enterScope(true)
  657.         result.append(emitMETHOD("<init>",tmp,false,frame))
  658.         result.append(emitLIMITSTACK(3))
  659.         result.append(emitLIMITLOCAL(1))
  660.         result.append(emitVAR(0,"this",ClassType(decl.name.name),0,1))
  661.         result.append(emitLABEL(0))
  662.         result.append(emitALOAD(0,frame))
  663.         result.append(emitINVOKESPECIAL(frame))
  664.         for (sym <- in) {
  665.             val at = sym.typ.asInstanceOf[ArrayType]
  666.             result.append(emitALOAD(0,frame))
  667.             result.append(emitICONST(at.dimen.value,frame))
  668.             result.append(emitNEWARRAY(at.eleType,frame))
  669.             result.append(emitPUTFIELD(sym.name,sym.typ,frame,ClassType(decl.name.name)))
  670.         }
  671.         result.append(emitLABEL(1))
  672.         result.append(emitRETURN(null,frame))
  673.         result.append(emitENDMETHOD())
  674.         frame.exitScope()
  675.         result.toString()
  676.     }
  677.    
  678.     def emitINITARRAY(index:Integer, in: Type,frame:Frame) =  {
  679.         var buff = new StringBuffer()
  680.         val at = in.asInstanceOf[ArrayType]
  681.         buff.append(emitICONST(at.dimen.value,frame))
  682.         buff.append(emitNEWARRAY(at.eleType,frame))
  683.         buff.append(emitASTORE(index,frame))
  684.         buff.toString()
  685.     }
  686.    
  687.     def emitLISTARRAY(in:List[Symbol],frame:Frame) = {
  688.         var result = new StringBuffer()
  689.         for (it <- in) {
  690.             //val at = it.typ.asInstanceOf[ArrayType]
  691.             result.append(emitINITARRAY(it.obj.get.toInt,it.typ,frame))
  692.         }
  693.         result.toString()
  694.     }
  695.    
  696.    
  697. }
  698.  
  699.  
  700.  
  701. /**
  702. *   Frame.scala
  703. */
  704. import scala.collection.mutable.Stack
  705.  
  706. class Frame(val isMain:Boolean) {
  707.    
  708.     var currentLabel = 0
  709.     var currOpStackSize = 0
  710.     var maxOpStackSize = 0
  711.     var currIndex = 0
  712.     var maxIndex = 0
  713.     val startLabel = new Stack[Int]()
  714.     val endLabel = new Stack[Int]()
  715.     val indexLocal = new Stack[Int]()
  716.     val conLabel = new Stack[Int]()
  717.     val brkLabel = new Stack[Int]()
  718.  
  719.     def getCurrIndex(): Int = {
  720.         currIndex
  721.     }
  722.  
  723.  
  724.  
  725.     def setCurrIndex(index: Int) = {
  726.         currIndex = index
  727.     }
  728.    
  729.     /**
  730.     *   return a new label in the method.
  731.     *   @return an integer representing the label.
  732.     */
  733.     def getNewLabel(): Int = {
  734.         val tmp = currentLabel
  735.         currentLabel += 1;
  736.         tmp
  737.     }
  738.    
  739.     /**
  740.     *   simulate an instruction that pushes a value onto operand stack.
  741.     */
  742.     def push() {
  743.         currOpStackSize += 1;
  744.         if (maxOpStackSize < currOpStackSize)
  745.             maxOpStackSize = currOpStackSize
  746.     }
  747.    
  748.     /**
  749.     *   simulate an instruction that pops a value out of operand stack.
  750.     */
  751.    
  752.     def pop() {
  753.         currOpStackSize -= 1;
  754.         if (currOpStackSize < 0)
  755.             throw IllegalRuntimeException("Pop an empty stack(")
  756.     }
  757.    
  758.     /**
  759.     *   return the maximum size of the operand stack that the method needs to use.
  760.     *   @return an integer that represent the maximum stack size
  761.     */
  762.     def getMaxOpStackSize(): Int = {
  763.         maxOpStackSize
  764.     }
  765.    
  766.     /**
  767.     *   check if the operand stack is empty or not.
  768.     *   @throws IllegalRuntimeException if the operand stack is not empty.
  769.     */
  770.    
  771.     def checkOpStack() = {
  772.         if ( currOpStackSize != 0)
  773.             throw  IllegalRuntimeException("Operand Stack is not empty")
  774.     }
  775.    
  776.     /**
  777.     *   invoked when parsing into a new scope inside a method.<p>
  778.     *   This method will create 2 new labels that represent the starting and ending points of the scope.<p>
  779.     *   Then, these labels are pushed onto corresponding stacks.<p>
  780.     *   These labels can be retrieved by getStartLabel() and getEndLabel().<p>
  781.     *   In addition, this method also saves the current index of local variable.
  782.     */
  783.    
  784.     def enterScope(isProc: Boolean) {
  785.         val start = getNewLabel()
  786.         val end = getNewLabel()
  787.        
  788.         startLabel.push(start)
  789.         endLabel.push(end)
  790.         indexLocal.push(currIndex)
  791.        
  792.         if (isProc) {
  793.             maxOpStackSize = 0
  794.             maxIndex = 0
  795.         }
  796.     }
  797.    
  798.     /**
  799.     *   invoked when parsing out of a scope in a method.<p>
  800.     *   This method will pop the starting and ending labels of this scope
  801.     *   and restore the current index
  802.     */
  803.    
  804.     def exitScope() = {
  805.         if (startLabel.isEmpty || endLabel.isEmpty || indexLocal.isEmpty)
  806.             throw IllegalRuntimeException("Exit scope but startLabel or endLabel or indexLocal is empty")      
  807.        
  808.         startLabel.pop()
  809.         endLabel.pop()
  810.         currIndex = indexLocal.pop
  811.     }
  812.    
  813.     /**
  814.     *   return the starting label of the current scope.
  815.     *   @return an integer representing the starting label
  816.     */
  817.    
  818.     def getStartLabel(): Int = {
  819.         if (startLabel.isEmpty)
  820.             throw IllegalRuntimeException("Start label is empty ")
  821.            
  822.         startLabel.top
  823.     }
  824.    
  825.     /**
  826.     *   return the ending label of the current scope.
  827.     *   @return an integer representing the ending label
  828.     */
  829.    
  830.     def getEndLabel(): Int = {
  831.         if (endLabel.isEmpty)
  832.             throw IllegalRuntimeException("End Label is empty ")
  833.            
  834.         endLabel.top
  835.     }
  836.    
  837.     /**
  838.     *   return a new index for a local variable declared in a scope.
  839.     *   @return an integer that represents the index of the local variable
  840.     */
  841.     def getNewIndex(): Int = {
  842.         val tmp = currIndex
  843.        
  844.         currIndex += 1;
  845.         if (currIndex > maxIndex)
  846.             maxIndex = currIndex
  847.            
  848.         tmp
  849.     }
  850.    
  851.     /**
  852.     *   return the maximum index used in generating code for the current method
  853.     *   @return an integer representing the maximum index
  854.     */
  855.     def getMaxIndex(): Int = {
  856.         maxIndex
  857.     }
  858.    
  859.     /**
  860.     *   invoked when parsing into a loop statement.<p>
  861.     *   This method creates 2 new labels that represent the starting and ending label of the loop.<p>
  862.     *   These labels are pushed onto corresponding stacks and are retrieved by getBeginLoopLabel() and getEndLoopLabel().
  863.     */
  864.     def enterLoop() {
  865.         val con = getNewLabel()
  866.         val brk = getNewLabel()
  867.         conLabel.push(con)
  868.         brkLabel.push(brk)
  869.     }
  870.    
  871.     /**
  872.     *   invoked when parsing out of a loop statement.
  873.     *   This method will take 2 labels representing the starting and ending labels of the current loop out of its stacks.
  874.     */
  875.    
  876.     def exitLoop() = {
  877.         if (conLabel.isEmpty || brkLabel.isEmpty)
  878.             throw IllegalRuntimeException("Continue or Break label is empty ")
  879.            
  880.         conLabel.pop
  881.         brkLabel.pop
  882.     }
  883.    
  884.     /**
  885.     *   return the label of the innest enclosing loop to which continue statement would jump
  886.     *   @return an integer representing the continue label
  887.     */
  888.    
  889.     def getContinueLabel(): Int = {
  890.         if (conLabel.isEmpty)
  891.             throw IllegalRuntimeException("Continue label is empty ")
  892.        
  893.         conLabel.top
  894.     }
  895.    
  896.     /**
  897.     *   return the label of the innest enclosing loop to which break statement would jump
  898.     *   @return an integer representing the break label
  899.     */
  900.    
  901.     def getBreakLabel(): Int = {
  902.         if (brkLabel.isEmpty)
  903.             throw IllegalRuntimeException("Break label is empty ")
  904.            
  905.         brkLabel.top
  906.     }
  907. }
  908.  
  909.  
  910. /**
  911. *   MachineCode.scala
  912. */
  913.  
  914. trait MachineCode {
  915.     def emitNULLCONST: String
  916.     def emitICONST(i: Int): String
  917.     def emitBIPUSH(i: Int): String
  918.     def emitSIPUSH(i: Int): String
  919.     def emitLDC(in: String): String
  920.     def emitFCONST(in: String): String
  921.     def emitILOAD(in: Int): String
  922.     def emitFLOAD(in: Int): String
  923.     def emitISTORE(in: Int): String
  924.     def emitFSTORE(in: Int): String
  925.     def emitALOAD(in: Int): String
  926.     def emitASTORE(in: Int): String
  927.     def emitIASTORE(): String  
  928.     def emitFASTORE(): String  
  929.     def emitBASTORE(): String  
  930.     def emitAASTORE(): String  
  931.     def emitIALOAD(): String    
  932.     def emitFALOAD(): String    
  933.     def emitBALOAD(): String    
  934.     def emitAALOAD(): String    
  935.     def emitGETSTATIC(lexeme: String, typ: String): String  
  936.     def emitPUTSTATIC(lexeme: String, typ: String): String  
  937.     def emitGETFIELD(lexeme: String, typ: String): String  
  938.     def emitPUTFIELD(lexeme: String, typ: String): String  
  939.     def emitIADD(): String  
  940.     def emitFADD(): String  
  941.     def emitISUB(): String  
  942.     def emitFSUB(): String  
  943.     def emitIMUL(): String  
  944.     def emitFMUL(): String  
  945.     def emitIDIV(): String  
  946.     def emitFDIV(): String  
  947.     def emitIAND(): String  
  948.     def emitIOR(): String  
  949.     def emitIREM(): String  
  950.     def emitIFICMPEQ(label: Int): String    
  951.     def emitIFICMPNE(label: Int): String    
  952.     def emitIFICMPLT(label: Int): String    
  953.     def emitIFICMPLE(label: Int): String   
  954.     def emitIFICMPGT(label: Int): String   
  955.     def emitIFICMPGE(label: Int): String   
  956.     def emitIFEQ(label: Int): String   
  957.     def emitIFNE(label: Int): String   
  958.     def emitIFLT(label: Int): String   
  959.     def emitIFLE(label: Int): String   
  960.     def emitIFGT(label: Int): String   
  961.     def emitIFGE(label: Int): String   
  962.     def emitLABEL(label: Int): String  
  963.     def emitGOTO(label: Int): String   
  964.     def emitINEG(): String  
  965.     def emitFNEG(): String  
  966.     def emitDUP(): String
  967.     def emitDUPX2(): String    
  968.     def emitPOP(): String  
  969.     def emitI2F(): String  
  970.     def emitNEW(lexeme: String): String    
  971.     def emitNEWARRAY(lexeme: String): String    
  972.     def emitMULTIANEWARRAY (typ: String, dimensions: Int): String  
  973.     def emitINVOKESTATIC(lexeme: String, typ: String): String  
  974.     def emitINVOKESPECIAL(lexeme: String, typ: String): String  
  975.     def emitINVOKESPECIAL(): String
  976.     def emitINVOKEVIRTUAL(lexeme: String, typ: String): String  
  977.     def emitIRETURN(): String
  978.     def emitARETURN(): String  
  979.     def emitFRETURN(): String  
  980.     def emitRETURN(): String    
  981.     def emitLIMITSTACK(in: Int): String    
  982.     def emitFCMPL(): String    
  983.     def emitLIMITLOCAL(in: Int): String    
  984.     def emitVAR(in: Int, varName: String, intyp: String, fromLabel: Int, toLabel: Int): String  
  985.     def emitVAR(in: Int, varName: String, intyp: String): String
  986.     def emitMETHOD(lexeme: String, typ: String, isStatic: Boolean): String
  987.     def emitENDMETHOD(): String
  988.     def emitSOURCE(lexeme: String): String  
  989.     def emitCLASS(lexeme: String): String  
  990.     def emitSUPER(lexeme: String): String  
  991.     def emitSTATICFIELD(lexeme: String, typ: String, isFinal: Boolean,value:String): String
  992.     def emitINSTANCEFIELD(lexeme: String, typ: String, isFinal: Boolean,value:String): String
  993. }
  994.  
  995. object JasminCode extends MachineCode {
  996.     val END = "\n"
  997.     val INDENT = "\t"
  998.    
  999.     def emitNULLCONST(): String = {    
  1000.         INDENT + "aconst_null" + END   
  1001.     }
  1002.        
  1003.     def emitICONST(i: Int): String = {     
  1004.         if (i == -1) {
  1005.             INDENT + "iconst_m1" + END     
  1006.         } else if (i >= 0 && i <= 5){
  1007.             INDENT + "iconst_" + i + END                   
  1008.         } else throw IllegalOperandException
  1009.     }
  1010.    
  1011.    
  1012.     def emitBIPUSH(i: Int): String = {
  1013.         if ((i >= -128 && i < -1) || (i > 5 && i <= 127))
  1014.             INDENT + "bipush " + i + END
  1015.         else
  1016.             throw IllegalOperandException
  1017.     }
  1018.    
  1019.    
  1020.     def emitSIPUSH(i: Int): String = {
  1021.         if ((i >= -32768 && i < -128) || (i > 127 && i <= 32767))
  1022.             INDENT + "sipush " + i + END
  1023.         else
  1024.             throw IllegalOperandException
  1025.     }
  1026.    
  1027.    
  1028.     def emitLDC(in: String): String = {
  1029.         INDENT + "ldc " + in + END
  1030.     }
  1031.    
  1032.    
  1033.     def emitFCONST(in: String): String = {
  1034.         if (in.equals("0.0")) {
  1035.             INDENT + "fconst_0" + END
  1036.         } else if (in.equals("1.0")) {
  1037.             INDENT + "fconst_1" + END
  1038.         } else if (in.equals("2.0")) {
  1039.             INDENT + "fconst_2" + END
  1040.         } else
  1041.             throw IllegalOperandException
  1042.     }
  1043.    
  1044.    
  1045.     def emitILOAD(in: Int): String = {
  1046.         if (in >= 0 && in <= 3)
  1047.             INDENT + "iload_" + in + END
  1048.         else
  1049.             INDENT + "iload " + in + END
  1050.     }
  1051.    
  1052.    
  1053.     def emitFLOAD(in: Int): String = {
  1054.         if (in >= 0 && in <= 3)
  1055.             INDENT + "fload_" + in + END
  1056.         else
  1057.             INDENT + "fload " + in + END
  1058.     }  
  1059.    
  1060.    
  1061.     def emitISTORE(in: Int): String = {
  1062.         if (in >= 0 && in <= 3)
  1063.             INDENT + "istore_" + in + END
  1064.         else
  1065.             INDENT + "istore " + in + END
  1066.     }
  1067.    
  1068.    
  1069.     def emitFSTORE(in: Int): String =  {
  1070.         if (in >= 0 && in <= 3)
  1071.             INDENT + "fstore_" + in + END
  1072.         else
  1073.             INDENT + "fstore " + in + END
  1074.     }
  1075.  
  1076.    
  1077.     def emitALOAD(in: Int): String = {
  1078.         if (in >= 0 && in <= 3)
  1079.             INDENT + "aload_" + in + END
  1080.         else
  1081.             INDENT + "aload " + in + END
  1082.     }  
  1083.  
  1084.    
  1085.     def emitASTORE(in: Int): String = {
  1086.         if (in >= 0 && in <= 3)
  1087.             INDENT + "astore_" + in + END
  1088.         else
  1089.             INDENT + "astore " + in + END
  1090.     }  
  1091.  
  1092.    
  1093.     def emitIASTORE(): String = {
  1094.         INDENT + "iastore" + END
  1095.     }
  1096.    
  1097.    
  1098.     def emitFASTORE(): String = {
  1099.         INDENT + "fastore" + END
  1100.     }
  1101.    
  1102.    
  1103.     def emitBASTORE(): String = {
  1104.         INDENT + "bastore" + END
  1105.     }
  1106.    
  1107.    
  1108.     def emitAASTORE(): String = {
  1109.         INDENT + "aastore" + END
  1110.     }
  1111.    
  1112.    
  1113.     def emitIALOAD(): String = {
  1114.         INDENT + "iaload" + END
  1115.     }
  1116.    
  1117.    
  1118.     def emitFALOAD(): String = {
  1119.         INDENT + "faload" + END
  1120.     }
  1121.    
  1122.    
  1123.     def emitBALOAD(): String = {
  1124.         INDENT + "baload" + END
  1125.     }
  1126.    
  1127.    
  1128.     def emitAALOAD(): String = {
  1129.         INDENT + "aaload" + END
  1130.     }
  1131.    
  1132.    
  1133.     def emitGETSTATIC(lexeme: String, typ: String): String = {
  1134.         INDENT + "getstatic " + lexeme + " " + typ + END
  1135.     }
  1136.    
  1137.    
  1138.     def emitPUTSTATIC(lexeme: String, typ: String): String = {
  1139.         INDENT + "putfield " + lexeme + " " + typ + END
  1140.     }  
  1141.    
  1142.    
  1143.     def emitGETFIELD(lexeme: String, typ: String): String = {
  1144.         INDENT + "getfield " + lexeme + " " + typ + END
  1145.     }
  1146.    
  1147.    
  1148.     def emitPUTFIELD(lexeme: String, typ: String): String = {
  1149.         INDENT + "putfield " + lexeme + " " + typ + END
  1150.     }  
  1151.    
  1152.    
  1153.     def emitIADD(): String = {
  1154.         INDENT + "iadd" + END
  1155.     }
  1156.    
  1157.    
  1158.     def emitFADD(): String = {
  1159.         INDENT + "fadd" + END
  1160.     }
  1161.    
  1162.    
  1163.     def emitISUB(): String = {
  1164.         INDENT + "isub" + END
  1165.     }
  1166.    
  1167.    
  1168.     def emitFSUB(): String = {
  1169.         INDENT + "fsub" + END
  1170.     }
  1171.    
  1172.    
  1173.     def emitIMUL(): String = {
  1174.         INDENT + "imul" + END
  1175.     }
  1176.    
  1177.    
  1178.     def emitFMUL(): String = {
  1179.         INDENT + "fmul" + END
  1180.     }
  1181.    
  1182.    
  1183.     def emitIDIV(): String = {
  1184.         INDENT + "idiv" + END
  1185.     }
  1186.    
  1187.    
  1188.     def emitFDIV(): String = {
  1189.         INDENT + "fdiv" + END
  1190.     }
  1191.    
  1192.    
  1193.     def emitIAND(): String = {
  1194.         INDENT + "iand" + END
  1195.     }
  1196.    
  1197.    
  1198.     def emitIOR(): String = {
  1199.         INDENT + "ior" + END
  1200.     }
  1201.    
  1202.    
  1203.     def emitIREM(): String = {
  1204.         INDENT + "irem" + END
  1205.     }
  1206.    
  1207.    
  1208.     def emitIFICMPEQ(label: Int): String = {
  1209.         INDENT + "if_icmpeq Label" + label + END
  1210.     }
  1211.    
  1212.    
  1213.     def emitIFICMPNE(label: Int): String = {
  1214.         INDENT + "if_icmpne Label" + label + END
  1215.     }
  1216.    
  1217.    
  1218.     def emitIFICMPLT(label: Int): String = {
  1219.         INDENT + "if_icmplt Label" + label + END
  1220.     }
  1221.    
  1222.    
  1223.     def emitIFICMPLE(label: Int): String  = {
  1224.         INDENT + "if_icmple Label" + label + END
  1225.     }
  1226.    
  1227.    
  1228.     def emitIFICMPGT(label: Int): String  = {
  1229.         INDENT + "if_icmpgt Label" + label + END
  1230.     }
  1231.    
  1232.    
  1233.     def emitIFICMPGE(label: Int): String  = {
  1234.         INDENT + "if_icmpge Label" + label + END
  1235.     }
  1236.    
  1237.    
  1238.     def emitIFEQ(label: Int): String  = {
  1239.         INDENT + "ifeq Label" + label + END
  1240.     }
  1241.    
  1242.    
  1243.     def emitIFNE(label: Int): String  = {
  1244.         INDENT + "ifne Label" + label + END
  1245.     }
  1246.    
  1247.    
  1248.     def emitIFLT(label: Int): String  = {
  1249.         INDENT + "iflt Label" + label + END
  1250.     }
  1251.    
  1252.    
  1253.     def emitIFLE(label: Int): String  = {
  1254.         INDENT + "ifle Label" + label + END
  1255.     }
  1256.    
  1257.    
  1258.     def emitIFGT(label: Int): String  = {
  1259.         INDENT + "ifgt Label" + label + END
  1260.     }
  1261.    
  1262.    
  1263.     def emitIFGE(label: Int): String  = {
  1264.         INDENT + "ifge Label" + label + END
  1265.     }
  1266.    
  1267.    
  1268.     def emitLABEL(label: Int): String = {
  1269.         "Label" + label + ":" + END
  1270.     }
  1271.    
  1272.    
  1273.     def emitGOTO(label: Int): String  = {
  1274.         INDENT + "goto Label" + label + END
  1275.     }
  1276.    
  1277.    
  1278.     def emitINEG(): String = {
  1279.         INDENT + "ineg" + END
  1280.     }
  1281.    
  1282.    
  1283.     def emitFNEG(): String = {
  1284.         INDENT + "fneg" + END
  1285.     }
  1286.    
  1287.    
  1288.     def emitDUP(): String = {
  1289.         INDENT + "dup" + END
  1290.     }
  1291.  
  1292.    
  1293.     def emitDUPX2(): String = {
  1294.         INDENT + "dup_x2" + END
  1295.     }
  1296.    
  1297.    
  1298.     def emitPOP(): String = {
  1299.         INDENT + "pop" + END
  1300.     }
  1301.    
  1302.    
  1303.     def emitI2F(): String = {
  1304.         INDENT + "i2f" + END
  1305.     }
  1306.    
  1307.    
  1308.     def emitNEW(lexeme: String): String = {
  1309.         INDENT + "new " + lexeme + END
  1310.     }
  1311.    
  1312.    
  1313.     def emitNEWARRAY(lexeme: String): String = {
  1314.         INDENT + "newarray " + lexeme + END
  1315.     }
  1316.    
  1317.    
  1318.     def emitMULTIANEWARRAY (typ: String, dimensions: Int): String = {
  1319.         INDENT + "multianewarray " + typ + " " + dimensions + END
  1320.     }
  1321.    
  1322.    
  1323.     def emitINVOKESTATIC(lexeme: String, typ: String): String = {      
  1324.         INDENT + "invokestatic " + lexeme + typ + END
  1325.     }
  1326.    
  1327.     def emitINVOKESPECIAL(lexeme: String, typ: String): String = {     
  1328.         INDENT + "invokespecial " + lexeme + typ + END
  1329.     }
  1330.    
  1331.     def emitINVOKESPECIAL(): String = {
  1332.         INDENT + "invokespecial java/lang/Object/<init>()V" + END
  1333.     }
  1334.    
  1335.    
  1336.     def emitINVOKEVIRTUAL(lexeme: String, typ: String): String = {
  1337.         INDENT + "invokevirtual " + lexeme + typ + END
  1338.     }
  1339.    
  1340.    
  1341.     def emitIRETURN(): String = {
  1342.         INDENT + "ireturn" + END
  1343.     }
  1344.    
  1345.    
  1346.     def emitARETURN(): String = {
  1347.         INDENT + "areturn" + END
  1348.     }
  1349.    
  1350.    
  1351.     def emitFRETURN(): String = {
  1352.         INDENT + "freturn" + END
  1353.     }
  1354.    
  1355.    
  1356.     def emitRETURN(): String = {
  1357.         INDENT + "return" + END
  1358.     }
  1359.    
  1360.     def emitLIMITSTACK(in: Int): String = {
  1361.         ".limit stack " + in + END
  1362.     }
  1363.    
  1364.     def emitFCMPL(): String = {
  1365.         INDENT + "fcmpl" + END
  1366.     }
  1367.    
  1368.     def emitLIMITLOCAL(in: Int): String = {
  1369.         ".limit locals " + in + END
  1370.     }
  1371.    
  1372.     def emitVAR(in: Int, varName: String, intyp: String, fromLabel: Int, toLabel: Int): String = {
  1373.         ".var " + in + " is " + varName + " " + intyp + " from Label" + fromLabel + " to Label" + toLabel + END
  1374.     }
  1375.  
  1376.     def emitVAR(in: Int, varName: String, intyp: String): String = {
  1377.         ".var " + in + " is " + varName + " " + intyp + END
  1378.     }
  1379.    
  1380.     def emitMETHOD(lexeme: String, typ: String, isStatic: Boolean): String = {
  1381.         if (isStatic)
  1382.             END + ".method public static " + lexeme + typ + END
  1383.         else
  1384.             END + ".method public " + lexeme + typ + END
  1385.     }
  1386.    
  1387.     def emitENDMETHOD(): String = {
  1388.         ".end method" + END
  1389.     }
  1390.  
  1391.    
  1392.     def emitSOURCE(lexeme: String): String = {
  1393.         ".source " + lexeme + END
  1394.     }
  1395.    
  1396.    
  1397.     def emitCLASS(lexeme: String): String = {
  1398.         ".class " + lexeme + END
  1399.     }
  1400.    
  1401.    
  1402.     def emitSUPER(lexeme: String): String = {
  1403.         ".super " + lexeme + END
  1404.     }
  1405.    
  1406.     def emitSTATICFIELD(lexeme: String, typ: String, isFinal: Boolean,value:String): String = {
  1407.         val init = if (value.length > 0) " = "+value else ""
  1408.         if (isFinal)
  1409.             ".field static final " + lexeme + " " + typ + init + END
  1410.         else
  1411.             ".field static " + lexeme + " " + typ + init + END 
  1412.     }
  1413.    
  1414.     def emitINSTANCEFIELD(lexeme: String, typ: String, isFinal: Boolean,value:String): String = {
  1415.         val init = if (value.length > 0) " = "+value else ""
  1416.         if (isFinal)
  1417.             ".field protected final " + lexeme + " " + typ + init + END
  1418.         else
  1419.             ".field protected " + lexeme + " " + typ + init + END
  1420.     }
  1421. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement