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); }
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); }