void Parser::superclass(ClassGenerationContext *cgenc) { VMSymbol* superName; if (sym == Identifier) { superName = GetUniverse()->SymbolFor(text); accept(Identifier); } else { superName = GetUniverse()->SymbolFor("Object"); } cgenc->SetSuperName(superName); // Load the super class, if it is not nil (break the dependency cycle) if (superName != GetUniverse()->SymbolFor("nil")) { VMClass* superClass = GetUniverse()->LoadClass(superName); cgenc->SetInstanceFieldsOfSuper(superClass->GetInstanceFields()); cgenc->SetClassFieldsOfSuper(superClass->GetClass()->GetInstanceFields()); } else { // we hardcode here the field names for Class // since Object class superclass = Class // We avoid here any kind of dynamic solution to avoid further complexity. // However, that makes it static, it is going to make it harder to // change the definition of Class and Object vector<StdString> fieldNamesOfClass{ "class", "superClass", "name", "instanceFields", "instanceInvokables" }; VMArray* fieldNames = GetUniverse()->NewArrayFromStrings(fieldNamesOfClass); cgenc->SetClassFieldsOfSuper(fieldNames); } }
void Universe::LoadSystemClass(VMClass* systemClass) { VMClass* result = LoadClassBasic(systemClass->GetName(), systemClass); StdString s = systemClass->GetName()->GetStdString(); if (!result) { cout << "Can't load system class: " << s << endl; Universe::Quit(ERR_FAIL); } if (result->HasPrimitives() || result->GetClass()->HasPrimitives()) result->LoadPrimitives(classPath); }
VMClass* Universe::LoadClassBasic(VMSymbol* name, VMClass* systemClass) { StdString s_name = name->GetStdString(); //cout << s_name.c_str() << endl; VMClass* result; for (vector<StdString>::iterator i = classPath.begin(); i != classPath.end(); ++i) { SourcecodeCompiler compiler; result = compiler.CompileClass(*i, name->GetStdString(), systemClass); if (result) { if (dumpBytecodes) { Disassembler::Dump(result->GetClass()); Disassembler::Dump(result); } return result; } } return nullptr; }
VMClass* Universe::LoadClass(VMSymbol* name) { VMClass* result = static_cast<VMClass*>(GetGlobal(name)); if (result != nullptr) return result; result = LoadClassBasic(name, nullptr); if (!result) { // we fail silently, it is not fatal that loading a class failed return (VMClass*) nilObject; } if (result->HasPrimitives() || result->GetClass()->HasPrimitives()) result->LoadPrimitives(classPath); SetGlobal(name, result); return result; }