public override void Accept(ClassDeclaration classDecl)
        {
            ModuleCompiler compiler = new ModuleCompiler(symbolTable, methodBuilder.Module);
            IodineClass    clazz    = compiler.CompileClass(classDecl);

            methodBuilder.EmitInstruction(classDecl.Location, Opcode.LoadConst,
                                          methodBuilder.Module.DefineConstant(clazz));
            methodBuilder.EmitInstruction(classDecl.Location, Opcode.StoreLocal,
                                          symbolTable.GetSymbol(classDecl.Name).Index);
        }
Exemple #2
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);
        }