| |
---|
| | code.emit(BEQ,ZERO,init); |
---|
| | |
---|
| | // 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(); |
---|
| | code.anchorLabel(start); |
---|
| |
---|
| | code.freeRegister(r2); |
---|
| | 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 => |
---|
| | val valentin = code.getLabel(); |
---|
| |
---|
| | + targetReg + " not allocated"); |
---|
| | |
---|
| | tree match { |
---|
| | case NullLit() => |
---|
| | // TODO |
---|
| | // ... à compléter ... |
---|
| | |
---|
| | case IntLit(value) => |
---|
| | emitLoadConstant(targetReg, value) |
---|
| |
---|
| | code.emit(SUBI, SP, SP, code.getFrameSize()); |
---|
| | 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); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | case Select(prefix, selector) => |
---|
| |
---|
| | code.emit(LDW, targetReg, tmpReg, selector.sym.offset+4); |
---|
| | } |
---|
| | |
---|
| | 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) => |
---|
| | val elseLabel = code.getLabel(); |
---|
| |
---|
| | |