First { void main (string[] args) { var x = 25 metoda(x) }
void metoda (int param) { print param } }
2. 作用域
为了可以访问其他的函数或者变量,他们需要在同一个作用域下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
public class Scope { private List<Identifier> identifiers; //think of it as a variables for now private List<FunctionSignature> functionSignatures; private final MetaData metaData; //currently stores only class name
public Scope(MetaData metaData) { identifiers = new ArrayList<>(); functionSignatures = new ArrayList<>(); this.metaData = metaData; }
public Scope(Scope scope) { metaData = scope.metaData; identifiers = Lists.newArrayList(scope.identifiers); functionSignatures = Lists.newArrayList(scope.functionSignatures); } //some other methods that expose data to the outside }
public class MethodGenerator { private final ClassWriter classWriter;
public MethodGenerator(ClassWriter classWriter) { this.classWriter = classWriter; }
public void generate(Function function) { Scope scope = function.getScope(); String name = function.getName(); String description = DescriptorFactory.getMethodDescriptor(function); Collection<Statement> instructions = function.getStatements(); int access = Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC; MethodVisitor mv = classWriter.visitMethod(access, name, description, null, null); mv.visitCode(); StatementGenerator statementScopeGenrator = new StatementGenerator(mv); instructions.forEach(instr -> statementScopeGenrator.generate(instr,scope)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1,-1); //asm autmatically calculate those but the call is required mv.visitEnd(); } }
5. 效果
如下 Enkel 代码:
1 2 3 4 5 6 7 8 9 10
First { void main (string[] args) { var x = 25 metoda(x) }
void metoda (int param) { print param } }
会被编译成如下所示的字节码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
$ javap -c First public class First { public static void main(java.lang.String[]); Code: 0: bipush 25 //push value 25 onto the stack 2: istore_0 //store value from stack into variable at index 0 3: iload_0 //load variable at index onto the stack 5: invokestatic #10 //call metod Method metoda:(I)V 8: return