sclass LASClassDef { settable S userGivenName; settable S classDefPrefix = "userCode."; replace Tb with GazelleV_LeftArrowScript. delegate FunctionDef to Tb. new L fields; new L methods; sclass FieldDef { settable S name; settable Class type; } S structForHash() { ret struct(litorderedmap(+userGivenName, +fields)); } simplyCached S classHash() { ret md5(structForHash()); } S finalClassName() { ret classDefPrefix() + finalClassNameWithoutPrefix(); } S finalClassNameWithoutPrefix() { ret or2(userGivenName, "C") + "_" + classHash(); } simplyCached byte[] toBytes() { ClassMaker classMaker = new(finalClassName()); for (field : fields) { FieldGen fg = new(Const.ACC_PUBLIC, classToBCELType(field.type), field.name, classMaker.getConstantPool()); classMaker.addField(fg); } for (method : methods) compileMethod(classMaker, method); classMaker.addDefaultConstructor(); ret classMaker.toBytes(); } // all function defs inside a class are fully compiled to byte code void compileMethod(ClassMaker classMaker, FunctionDef method) { MethodMaker mm = new(classMaker, O.class, method.name, repArray(Class.class, O.class, l(method.args))); var tbc = LASToByteCode(mm) { JVMStackCellType compileGetVar(Tb.GetVar code) { // load method argument int iArg = indexOf(method.args, code.name); if (iArg >= 0) { mm.aload(iArg+1); ret JVMStackCellType.objValue; } ret super.compileGetVar(code); } }; tbc.postConversion = stackTop -> mm.convertToObject(stackTop); tbc.compileScript(method.body); mm.areturn(); mm.done(); } }