Advertisement
Guest User

Untitled

a guest
Feb 25th, 2015
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 6.31 KB | None | 0 0
  1. void analyze(ClassDeclaration d, Class c) {
  2.         // what are d and c exactly? and what's the difference? when (and why) is this function being called?
  3.         import std.stdio;
  4.         auto oldManglePrefix = manglePrefix;
  5.         auto oldScope = currentScope;
  6.         auto oldThisType = thisType;
  7.         auto oldFieldIndex = fieldIndex;
  8.         auto oldMethodIndex = methodIndex;
  9.        
  10.         scope(exit) {
  11.             manglePrefix = oldManglePrefix;
  12.             currentScope = oldScope;
  13.             thisType = oldThisType;
  14.             fieldIndex = oldFieldIndex;
  15.             methodIndex = oldMethodIndex;
  16.         }
  17.        
  18.         thisType = Type.get(c).getParamType(false, true); // get the type of the class??
  19.        
  20.         // Update mangle prefix.
  21.         auto name = c.name.toString(context); // name of class
  22.        
  23.         writeln("sid1: ", name);
  24.        
  25.         manglePrefix = manglePrefix ~ to!string(name.length) ~ name; // some mangle prefix stuff :P
  26.        
  27.         c.mangle = "C" ~ manglePrefix;
  28.         writeln("sid2: ", c.mangle);
  29.        
  30.         auto dscope = currentScope = c.dscope = c.hasContext // getting the current scope of the class?
  31.             ? new VoldemortScope(c, oldScope)
  32.             : new AggregateScope(c, oldScope);
  33.        
  34.         Field[] baseFields; // list of fields inherited from the base class(es)
  35.         Method[] baseMethods; // list of methods inherited from the base class(es)
  36.         // i guess here we're visiting each of the base classes and converting them into some sort of structure to be used later?
  37.         foreach(i; d.bases) {
  38.             writeln("sid5: ", i.name.toString(context));
  39.             import d.semantic.identifier : AliasResolver;
  40.             c.base = AliasResolver!(function Class(identified) {
  41.                 static if(is(typeof(identified) : Symbol)) {
  42.                     if(auto c = cast(Class) identified) {
  43.                         return c;
  44.                     }
  45.                 }
  46.                
  47.                 static if(is(typeof(identified.location))) {
  48.                     import d.exception;
  49.                     throw new CompileException(identified.location, typeid(identified).toString() ~ " is not a class.");
  50.                 } else {
  51.                     // for typeof(null)
  52.                     assert(0);
  53.                 }
  54.             })(pass).visit(i);
  55.            
  56.             break; // ?? meaning process only one item??
  57.         }
  58.        
  59.         // If no inheritance is specified, inherit from object.
  60.         if(!c.base) {
  61.             c.base = pass.object.getObject();
  62.         }
  63.        
  64.         methodIndex = 0;
  65.        
  66.         // building the vtable begins?
  67.        
  68.         // object.Object, let's do some compiler magic.
  69.         if(c is c.base) {
  70.            
  71.             auto vtblType = Type.get(BuiltinType.Void).getPointer(TypeQualifier.Immutable); // i.e. vtableType is immutable?
  72.            
  73.             // TODO: use defaultinit.
  74.             auto vtbl = new Field(d.location, 0, vtblType, BuiltinName!"__vtbl", null); // vtable is a field??
  75.             vtbl.step = Step.Processed; // ??
  76.            
  77.             baseFields = [vtbl];
  78.            
  79.             fieldIndex = 1;
  80.         } else {
  81.             scheduler.require(c.base); // ??
  82.            
  83.             fieldIndex = 0;
  84.             foreach(m; c.base.members) {
  85.                 if(auto field = cast(Field) m) {
  86.                     baseFields ~= field;
  87.                     fieldIndex = max(fieldIndex, field.index); // why?
  88.                    
  89.                     c.dscope.addSymbol(field); // add the field to the current scope?
  90.                 } else if(auto method = cast(Method) m) {
  91.                     baseMethods ~= method;
  92.                     methodIndex = max(methodIndex, method.index);
  93.                    
  94.                     c.dscope.addOverloadableSymbol(method); // ?
  95.                 }
  96.             }
  97.            
  98.             fieldIndex++;
  99.         }
  100.        
  101.         if (c.hasContext) { // ?? what is a context? how do you define it?
  102.             // XXX: check for duplicate.
  103.             auto ctxPtr = Type.getContextType(ctxSym).getPointer();
  104.             auto ctx = new Field(c.location, fieldIndex++, ctxPtr, BuiltinName!"__ctx", new NullLiteral(c.location, ctxPtr));
  105.             ctx.step = Step.Processed;
  106.            
  107.             baseFields ~= ctx;
  108.         }
  109.        
  110.         auto members = DeclarationVisitor(pass, AggregateType.Class).flatten(d.members, c); // what is d.members? and c? flatten converts to a list?
  111.        
  112.         c.step = Step.Signed;
  113.         // process the members individually now? check for overrides?
  114.         uint overloadCount = 0;
  115.         foreach(m; members) {
  116.             if(auto method = cast(Method) m) {
  117.                 scheduler.require(method, Step.Signed); // ??
  118.                
  119.                 auto mt = method.type;
  120.                 auto rt = mt.returnType;
  121.                 auto ats = mt.parameters[1 .. $]; // are these arguments?
  122.                 writeln("sid3: ", method.name.toString(context));
  123.                 CandidatesLoop: foreach(ref candidate; baseMethods) {
  124.                     writeln("sid4%");
  125.                     writeln("sid4:   ", candidate.name);
  126.                     if (!candidate || method.name != candidate.name) {
  127.                         continue;
  128.                     }
  129.                    
  130.                     auto ct = candidate.type;
  131.                     if (ct.isVariadic != mt.isVariadic) {
  132.                         continue;
  133.                     }
  134.                    
  135.                     auto crt = ct.returnType;
  136.                     auto cts = ct.parameters[1 .. $];
  137.                     if (ats.length != cts.length || rt.isRef != crt.isRef) {
  138.                         continue;
  139.                     }
  140.                    
  141.                     if (implicitCastFrom(pass, rt.getType(), crt.getType()) < CastKind.Exact) { // ??
  142.                         continue;
  143.                     }
  144.                    
  145.                     import std.range;
  146.                     foreach(at, ct; lockstep(ats, cts)) { // ??
  147.                         if (at.isRef != ct.isRef) {
  148.                             continue CandidatesLoop;
  149.                         }
  150.                        
  151.                         if (implicitCastFrom(pass, ct.getType(), at.getType()) < CastKind.Exact) { // ??
  152.                             continue CandidatesLoop;
  153.                         }
  154.                     }
  155.                     // ??
  156.                     if(method.index == 0) {
  157.                         method.index = candidate.index;
  158.                        
  159.                         // Remove candidate from scope.
  160.                         auto os = cast(OverloadSet) dscope.resolve(method.name);
  161.                         assert(os, "This must be an overload set");
  162.                        
  163.                         uint i = 0;
  164.                         while (os.set[i] !is candidate) {
  165.                             i++;
  166.                         }
  167.                        
  168.                         foreach(s; os.set[i + 1 .. $]) {
  169.                             os.set[i++] = s;
  170.                         }
  171.                        
  172.                         os.set = os.set[0 .. i];
  173.                        
  174.                         overloadCount++;
  175.                         candidate = null;
  176.                         break;
  177.                     } else {
  178.                         import d.exception;
  179.                         throw new CompileException(
  180.                             method.location,
  181.                             method.name.toString(context) ~ " overrides a base class methode but is not marked override",
  182.                         );
  183.                     }
  184.                 }
  185.                
  186.                 if(method.index == 0) {
  187.                     import d.exception;
  188.                     throw new CompileException(method.location, "Override not found for " ~ method.name.toString(context));
  189.                 }
  190.             }
  191.         }
  192.        
  193.         // Remove overloaded base method. // ??
  194.         if (overloadCount) {
  195.             uint i = 0;
  196.             while (baseMethods[i] !is null) {
  197.                 i++;
  198.             }
  199.            
  200.             foreach(baseMethod; baseMethods[i + 1 .. $]) {
  201.                 if(baseMethod) {
  202.                     baseMethods[i++] = baseMethod;
  203.                 }
  204.             }
  205.            
  206.             baseMethods = baseMethods[0 .. i];
  207.         }
  208.        
  209.         c.members = cast(Symbol[]) baseFields;
  210.         c.members ~= baseMethods;
  211.         scheduler.require(members);
  212.         c.members ~= members;
  213.         //writeln("sid: ", c.members);
  214.         c.step = Step.Processed; // ??
  215.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement