diff --git a/sources/zweic/Analyzer.scala b/sources/zweic/Analyzer.scala index 6c9eb91..6826852 100755 --- a/sources/zweic/Analyzer.scala +++ b/sources/zweic/Analyzer.scala @@ -75,6 +75,9 @@ case MethodDef(name, args, rtype, expr) => var myVarScope = emptyVarScope; + //XXX + tree.asInstanceOf[MethodDef].self = Name(ownerClass.name); + myVarScope = myVarScope + "this" -> VarSymbol(ownerClass.pos, "this", IClassType(ownerClass)); val paramtypes = for ( val f <- args ) yield { diff --git a/sources/zweic/Generator.scala b/sources/zweic/Generator.scala index a033e9d..9643026 100644 --- a/sources/zweic/Generator.scala +++ b/sources/zweic/Generator.scala @@ -48,14 +48,14 @@ } } + // generate class and function definitions + classes.foreach(gen); + genTmp { tmpReg => emitLoadConstant(tmpReg, offset); code.emit(SYSCALL, tmpReg, tmpReg, SYS_GC_ALLOC); } - // generate class and function definitions - classes.foreach(gen); - // generate main expression val start = code.getLabel(); code.anchorLabel(start); @@ -278,9 +278,9 @@ case Ident(name) => if ( name.name == "this" ) { - code.emit(LDW, targetReg, SP, code.getFrameSize()); + code.emit(LDW, targetReg, SP, code.getFrameSize(), name.name); } else { - code.emit(LDW, targetReg, SP, code.getFrameSize()-(name.sym.offset)); + code.emit(LDW, targetReg, SP, code.getFrameSize()-(name.sym.offset), name.name); } case New(name, args) => @@ -301,57 +301,77 @@ } case Select(prefix, selector) => - genTmp { tmpReg => - genLoad(prefix, tmpReg); - // TODO check tmpReg != null - code.emit(LDW, targetReg, tmpReg, selector.sym.offset+4); - } + genLoad(prefix, targetReg); - case Call(receiver, method, args) => - genTmp { thisReg => + val okLabel = code.getLabel(); - // put all registers on stack - val used = code.usedRegisters(); + // check prefix != null + code.emit(BNE, targetReg, okLabel); + emitLoadConstant(targetReg, 1); + code.emit(SYSCALL, targetReg, ZERO, SYS_EXIT); - for ( val i <- Iterator.range(0, used.length)) { - if ( used(i) && i != targetReg ) { - code.emit(PSH, i, SP, 4); - code.incFrameSize(4); - } + code.anchorLabel(okLabel); + + code.emit(LDW, targetReg, targetReg, selector.sym.offset+4); + + case Call(receiver, method, args) => + + // put all registers on stack + val used = code.usedRegisters(); + var freed:List[Int] = Nil; + + for ( val i <- Iterator.range(0, used.length)) { + if ( used(i) && i != targetReg ) { + code.emit(PSH, i, SP, 4); + code.incFrameSize(4); + code.freeRegister(i); + freed = i::freed; } - - // get 'this' and put it on stack - genLoad(receiver, thisReg); - code.emit(PSH, thisReg, SP, 4); - code.incFrameSize(4); - - // put args on stack - genTmp { tmpReg => - for ( val a <- args ) { - genLoad(a, tmpReg); - code.emit(PSH, tmpReg, SP, 4); - code.incFrameSize(4); - } + } + + // get 'receiver' and put it as 'this' on the stack + genLoad(receiver, targetReg); + + // check receiver != null + val okLabel = code.getLabel(); + code.emit(BNE, targetReg, okLabel); + emitLoadConstant(targetReg, 1); + code.emit(SYSCALL, targetReg, ZERO, SYS_EXIT); + code.anchorLabel(okLabel); + + code.emit(PSH, targetReg, SP, 4); + code.incFrameSize(4); + + // put args on stack + genTmp { tmpReg => + for ( val a <- args ) { + genLoad(a, tmpReg); + code.emit(PSH, tmpReg, SP, 4); + code.incFrameSize(4); } + } - //TODO check thisReg != null - code.emit(LDW, thisReg, thisReg, method.sym.offset); - //TODO check thisReg != null + code.emit(LDW, targetReg, targetReg, method.sym.offset); - code.emit(RET, thisReg); + // check receiver.method() != null + val okLabel2 = code.getLabel(); + code.emit(BNE, targetReg, okLabel2); + emitLoadConstant(targetReg, 1); + code.emit(SYSCALL, targetReg, ZERO, SYS_EXIT); + code.anchorLabel(okLabel2); + + code.emit(RET, targetReg); - code.emit(ADD, targetReg, ZERO, RES); + code.emit(ADD, targetReg, ZERO, RES); - code.decFrameSize(args.length*4+4); // fs = oldframesize - params - this - - // retrieve all registers from stack - for ( val j <- Iterator.range(0, used.length)) { - if ( used(j) && j != targetReg ) { - code.emit(POP, j, SP, 4); - code.decFrameSize(4); - } - } + code.decFrameSize(args.length*4+4); // fs = oldframesize - params - this + + // retrieve all registers from stack + for ( val j <- freed ) { + code.getRegister(j); + code.emit(POP, j, SP, 4); + code.decFrameSize(4); } case If(cond, thenp, elsep) => @@ -385,6 +405,7 @@ genLoad(left, tmpLeft); genLoad(right, tmpRight); op match { + // TODO do all this with CMP !!! case Operators.EQ => code.emit(CMP, tmpLeft, tmpLeft, tmpRight, ""); if ( when ) { @@ -410,7 +431,7 @@ } case Operators.SUB => - code.emit(SUB, tmpLeft, tmpLeft, tmpRight); + code.emit(CMP, tmpLeft, tmpLeft, tmpRight); if ( when ) { code.emit(BNE, tmpLeft, targetLabel); } else { @@ -442,7 +463,7 @@ } case Operators.LT => - code.emit(SUB, tmpLeft, tmpLeft, tmpRight); + code.emit(CMP, tmpLeft, tmpLeft, tmpRight); if ( when ) { code.emit(BLT, tmpLeft, targetLabel); } else { @@ -450,7 +471,7 @@ } case Operators.LE => - code.emit(SUB, tmpLeft, tmpLeft, tmpRight); + code.emit(CMP, tmpLeft, tmpLeft, tmpRight); if ( when ) { code.emit(BLE, tmpLeft, targetLabel); } else { @@ -458,7 +479,7 @@ } case Operators.GT => - code.emit(SUB, tmpLeft, tmpLeft, tmpRight); + code.emit(CMP, tmpLeft, tmpLeft, tmpRight); if ( when ) { code.emit(BGT, tmpLeft, targetLabel); } else { @@ -466,7 +487,7 @@ } case Operators.GE => - code.emit(SUB, tmpLeft, tmpLeft, tmpRight); + code.emit(CMP, tmpLeft, tmpLeft, tmpRight); if ( when ) { code.emit(BGE, tmpLeft, targetLabel); } else { diff --git a/sources/zweic/Tree.scala b/sources/zweic/Tree.scala index cb83d99..f997a92 100755 --- a/sources/zweic/Tree.scala +++ b/sources/zweic/Tree.scala @@ -54,7 +54,7 @@ case class MethodDef(name: Name, args: List[Formal], returntype: TypeTree, expression: Expr) extends Member { - val self: Name = Name("this"); + var self: Name = Name("this"); } /* F = Formal name T */