diff --git a/sources/zweic/Generator.scala b/sources/zweic/Generator.scala index 5ec3991..b48b210 100644 --- a/sources/zweic/Generator.scala +++ b/sources/zweic/Generator.scala @@ -39,9 +39,22 @@ // go initialize the VMTs // ... � compl�ter ... + val tmpLabel = code.getLabel(); + code.anchorLabel(tmpLabel); + var offset = tmpLabel.getAnchor(); + for ( val c <- classes ) { + c.name.sym.offset = offset; + offset = offset + c.name.sym.asInstanceOf[ClassSymbol].allMethods.length*4; + //XXX: no +4 for empty top entry + } + + genTmp { tmpReg => + emitLoadConstant(tmpReg, offset); + code.emit(SYSCALL, tmpReg, tmpReg, SYS_GC_ALLOC); + } // generate class and function definitions - // ... � compl�ter ... + classes.foreach(gen); // generate main expression val start = code.getLabel(); @@ -75,19 +88,53 @@ code.freeRegister(r1); // populate VMTs - // ... � compl�ter ... + genTmp { classHeader => + genTmp { methodAddr => + for ( val ClassDef(cname, _, members) <- classes ) { + emitLoadConstant(classHeader, cname.sym.offset); + for ( val m <- cname.sym.asInstanceOf[ClassSymbol].allMethods ) { + emitLoadConstant(methodAddr, m.address); + code.emit(STW, methodAddr, classHeader, m.offset); + } + } + } + } // jump to main expression code.emit(BEQ, ZERO, start); case ClassDef(_, _, members) => - + members.foreach(gen); //TODO: case FieldDecl(_, _) => ; case FieldDecl(_) => ; case method @ MethodDef(name, params, _, body) => + // TODO ? // ... � compl�ter ... + val tmpLabel = code.getLabel(); + code.anchorLabel(tmpLabel); + name.sym.asInstanceOf[MethodSymbol].address = tmpLabel.getAnchor(); + + //TODO generato method code + code.emit(PSH, LNK, SP, 4); + //(emitLoadConstant(tmpReg, params.length*4); + + //var regList = Nil; + //var offset = 0; + + //for ( val Formal(name, _) <- params ) { + // code.getRegister()::regList; + // code.emit(POP, regList.head, SP, 4); + // name.sym.offset = offset; + // offset += 4; + //} + gen(body); + + //regList.foreach(code.freeRegister); + code.emit(POP, LNK, SP, 4); + code.emit(RET, LNK); + case While(cond, stats) => genTmp { tmpReg => @@ -151,6 +198,7 @@ tree match { case NullLit() => + // TODO // ... � compl�ter ... case IntLit(value) => @@ -218,18 +266,27 @@ code.decFrameSize(code.getFrameSize()); case Ident(name) => - code.emit(LDW, targetReg, SP, code.getFrameSize()-name.sym.offset); + if ( name.name == "this" ) { + //TODO + //code.emit(LDW, targetReg, SP, code.getFrameSize()-name.sym.offset); + } else { + code.emit(LDW, targetReg, SP, code.getFrameSize()-name.sym.offset); + } case New(name, args) => val af = name.sym.asInstanceOf[ClassSymbol].allFields; genTmp { tmpReg => emitLoadConstant(tmpReg, 4+af.length*4); - code.emit(SYSCALL, targetReg, tmpReg, SYS_GC_ALLOC, " allocate memory for class '"+name+"'"); - } - genTmp { tmpVal => + code.emit(SYSCALL, targetReg, tmpReg, SYS_GC_ALLOC, " allocate memory for instance of '"+name+"'"); + + /* pointer to class header */ + emitLoadConstant(tmpReg, name.sym.offset); + code.emit(STW, tmpReg, targetReg, 0); + + /* class variables */ for ( val x <- args.zip(af) ) { - genLoad(x._1, tmpVal); - code.emit(STW, tmpVal, targetReg, x._2.offset+4); + genLoad(x._1, tmpReg); + code.emit(STW, tmpReg, targetReg, x._2.offset+4); } } @@ -240,6 +297,23 @@ } case Call(receiver, method, args) => + + genTmp { tmpReg => + for ( val a <- args ) { + genLoad(a, tmpReg); + code.emit(PSH, tmpReg, SP, 4); + } + + genLoad(receiver, tmpReg); + //TODO check tmpReg != null + code.emit(PSH, tmpReg, SP, 4); // this TODO + code.emit(LDW, tmpReg, tmpReg, method.sym.offset); + //TODO check tmpReg != null + code.emit(RET, tmpReg); + } + + code.emit(ADDI, SP, SP, args.length*4); + // ... � compl�ter ... case If(cond, thenp, elsep) => diff --git a/unittest.py b/unittest.py index 0fef067..e7ac0c1 100644 --- a/unittest.py +++ b/unittest.py @@ -4,9 +4,10 @@ #@version: 1.0 #@date: 27. 1. 2006 # - +#~iclamp/soft/bin/risc-emu COMPILER = "scala -cp classes zweic.GeneratorTest" -RISC = "java -cp risc/lib/risc.jar risc.emulator.Main" +#RISC = "java -cp risc/lib/risc.jar risc.emulator.Main" +RISC = "/home/iclamp/soft/bin/risc-emu" OUTDIR = "asm" TABBING = '30'