예제 #1
0
        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);
        }
예제 #2
0
        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();
        }
예제 #3
0
        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();
        }
예제 #4
0
        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);
        }
예제 #5
0
 public override void Accept(Expression expr)
 {
     expr.VisitChildren(this);
     methodBuilder.EmitInstruction(expr.Location, Opcode.Pop);
 }
예제 #6
0
        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);
        }