private IodineMethod CompileMethod(FunctionDeclaration funcDecl) { symbolTable.NextScope(); IodineMethod methodBuilder = new IodineMethod(module, funcDecl.Name, funcDecl.InstanceMethod, funcDecl.Parameters.Count, symbolTable.CurrentScope.SymbolCount); FunctionCompiler compiler = new FunctionCompiler(symbolTable, methodBuilder); methodBuilder.Variadic = funcDecl.Variadic; methodBuilder.AcceptsKeywordArgs = funcDecl.AcceptsKeywordArgs; for (int i = 0; i < funcDecl.Parameters.Count; i++) { methodBuilder.Parameters [funcDecl.Parameters [i]] = symbolTable.GetSymbol (funcDecl.Parameters [i]).Index; } funcDecl.Children [0].Visit(compiler); AstNode lastNode = funcDecl.Children [0].LastOrDefault(); if (lastNode != null) { methodBuilder.EmitInstruction(lastNode.Location, Opcode.LoadNull); } else { methodBuilder.EmitInstruction(funcDecl.Location, Opcode.LoadNull); } methodBuilder.FinalizeLabels(); symbolTable.LeaveScope(); return(methodBuilder); }
public override void Accept(LambdaExpression lambda) { symbolTable.NextScope(); int locals = methodBuilder.LocalCount > 0 ? methodBuilder.LocalCount : symbolTable.CurrentScope.SymbolCount; IodineMethod anonMethod = new IodineMethod(methodBuilder, methodBuilder.Module, null, lambda.InstanceMethod, lambda.Parameters.Count, locals); FunctionCompiler compiler = new FunctionCompiler(symbolTable, anonMethod); for (int i = 0; i < lambda.Parameters.Count; i++) { anonMethod.Parameters [lambda.Parameters [i]] = symbolTable.GetSymbol (lambda.Parameters [i]).Index; } lambda.Children [0].Visit(compiler); anonMethod.EmitInstruction(lambda.Location, Opcode.LoadNull); anonMethod.Variadic = lambda.Variadic; anonMethod.FinalizeLabels(); methodBuilder.EmitInstruction(lambda.Location, Opcode.LoadConst, methodBuilder.Module.DefineConstant(anonMethod)); if (methodBuilder.LocalCount > 0) { methodBuilder.EmitInstruction(lambda.Location, Opcode.BuildClosure); } symbolTable.LeaveScope(); }
public override void Accept(FunctionDeclaration funcDecl) { symbolTable.NextScope(); IodineMethod anonMethod = new IodineMethod(methodBuilder, methodBuilder.Module, null, funcDecl.InstanceMethod, funcDecl.Parameters.Count, methodBuilder.LocalCount); FunctionCompiler compiler = new FunctionCompiler(symbolTable, anonMethod); for (int i = 0; i < funcDecl.Parameters.Count; i++) { anonMethod.Parameters [funcDecl.Parameters [i]] = symbolTable.GetSymbol (funcDecl.Parameters [i]).Index; } funcDecl.Children [0].Visit(compiler); anonMethod.EmitInstruction(funcDecl.Location, Opcode.LoadNull); anonMethod.Variadic = funcDecl.Variadic; anonMethod.AcceptsKeywordArgs = funcDecl.AcceptsKeywordArgs; anonMethod.FinalizeLabels(); methodBuilder.EmitInstruction(funcDecl.Location, Opcode.LoadConst, methodBuilder.Module.DefineConstant(anonMethod)); methodBuilder.EmitInstruction(funcDecl.Location, Opcode.BuildClosure); methodBuilder.EmitInstruction(funcDecl.Location, Opcode.StoreLocal, symbolTable.GetSymbol(funcDecl.Name).Index); symbolTable.LeaveScope(); }
public override void Accept(BinaryExpression pattern) { IodineLabel shortCircuitTrueLabel = methodBuilder.CreateLabel(); IodineLabel shortCircuitFalseLabel = methodBuilder.CreateLabel(); IodineLabel endLabel = methodBuilder.CreateLabel(); pattern.Left.Visit(this); /* * Short circuit evaluation */ switch (pattern.Operation) { case BinaryOperation.And: methodBuilder.EmitInstruction(pattern.Location, Opcode.Dup); methodBuilder.EmitInstruction(pattern.Location, Opcode.JumpIfFalse, shortCircuitFalseLabel); break; case BinaryOperation.Or: methodBuilder.EmitInstruction(pattern.Location, Opcode.Dup); methodBuilder.EmitInstruction(pattern.Location, Opcode.JumpIfTrue, shortCircuitTrueLabel); break; } pattern.Right.Visit(this); methodBuilder.EmitInstruction(pattern.Location, Opcode.BinOp, (int)pattern.Operation); methodBuilder.EmitInstruction(pattern.Location, Opcode.Jump, endLabel); methodBuilder.MarkLabelPosition(shortCircuitTrueLabel); methodBuilder.EmitInstruction(pattern.Location, Opcode.Pop); methodBuilder.EmitInstruction(pattern.Location, Opcode.LoadTrue); methodBuilder.EmitInstruction(pattern.Location, Opcode.Jump, endLabel); methodBuilder.MarkLabelPosition(shortCircuitFalseLabel); methodBuilder.EmitInstruction(pattern.Location, Opcode.Pop); methodBuilder.EmitInstruction(pattern.Location, Opcode.LoadFalse); methodBuilder.MarkLabelPosition(endLabel); }
public override void Accept(Expression expr) { expr.VisitChildren(this); methodBuilder.EmitInstruction(expr.Location, Opcode.Pop); }
public IodineClass CompileClass(ClassDeclaration classDecl) { IodineMethod constructor = CompileMethod(classDecl.Constructor); if (classDecl.Constructor.Children [0].Children.Count == 0 || !(classDecl.Constructor.Children [0].Children [0] is SuperCallExpression)) { if (classDecl.Base.Count > 0) { foreach (string subclass in classDecl.Base) { string[] contract = subclass.Split('.'); constructor.EmitInstruction(classDecl.Location, Opcode.LoadGlobal, constructor.Module.DefineConstant(new IodineName(contract [0]))); for (int j = 1; j < contract.Length; j++) { constructor.EmitInstruction(classDecl.Location, Opcode.LoadAttribute, constructor.Module.DefineConstant(new IodineName(contract [0]))); } constructor.EmitInstruction(classDecl.Location, Opcode.InvokeSuper, 0); } } } IodineMethod initializer = new IodineMethod(module, "__init__", false, 0, 0); IodineClass clazz = new IodineClass(classDecl.Name, initializer, constructor); FunctionCompiler compiler = new FunctionCompiler(symbolTable, clazz.Initializer); for (int i = 1; i < classDecl.Children.Count; i++) { if (classDecl.Children [i] is FunctionDeclaration) { FunctionDeclaration func = classDecl.Children [i] as FunctionDeclaration; if (func.InstanceMethod) { clazz.AddInstanceMethod(CompileMethod(func)); } else { clazz.SetAttribute(func.Name, CompileMethod(func)); } } else if (classDecl.Children [i] is ClassDeclaration) { ClassDeclaration subclass = classDecl.Children [i] as ClassDeclaration; clazz.SetAttribute(subclass.Name, CompileClass(subclass)); } else if (classDecl.Children [i] is EnumDeclaration) { EnumDeclaration enumeration = classDecl.Children [i] as EnumDeclaration; clazz.SetAttribute(enumeration.Name, CompileEnum(enumeration)); } else if (classDecl.Children [i] is BinaryExpression) { BinaryExpression expr = classDecl.Children [i] as BinaryExpression; NameExpression name = expr.Left as NameExpression; expr.Right.Visit(compiler); initializer.EmitInstruction(classDecl.Location, Opcode.LoadGlobal, module.DefineConstant(new IodineName(classDecl.Name))); initializer.EmitInstruction(classDecl.Location, Opcode.StoreAttribute, module.DefineConstant(new IodineName(name.Value))); } else { classDecl.Children [i].Visit(compiler); } } clazz.Initializer.FinalizeLabels(); return(clazz); }