diff --git a/source/tlang/compiler/typecheck/core.d b/source/tlang/compiler/typecheck/core.d index 8b28a129..707ca60f 100644 --- a/source/tlang/compiler/typecheck/core.d +++ b/source/tlang/compiler/typecheck/core.d @@ -90,15 +90,8 @@ public final class TypeChecker /* TODO: Process class ? vars funcs ?*/ import compiler.typecheck.dependancy; - dependancyGenerate(this, modulle); - - string depsString; - foreach(string key; keysOrder) - { - depsString ~= key~": "~to!(string)(deps[key])~", "; - } - gprintln("Final deps: "~to!(string)(depsString)); - findEnd(this); + StructuralOrganizer so = new StructuralOrganizer(this); + so.checkContainer(modulle); } /** diff --git a/source/tlang/compiler/typecheck/dependancy.d b/source/tlang/compiler/typecheck/dependancy.d index dbdf25bb..d5939a6e 100644 --- a/source/tlang/compiler/typecheck/dependancy.d +++ b/source/tlang/compiler/typecheck/dependancy.d @@ -7,353 +7,63 @@ import compiler.typecheck.core; import std.conv : to; -/** -* A list of all the full-paths of entities and what they rely on -* -* TODO: -* So far we are looking at types and seeing what they depend on, not yet -* for assignments. When we get to assignments we should then add more -*/ -public string[][string] deps; - -public string[] keysOrder; - -public void encounter(string entityName, string dependentOn) +public final class StructuralOrganizer { - if(entityName !in deps) + /* The associated TypeChecker */ + private TypeChecker tc; + + this(TypeChecker tc) { - keysOrder ~= entityName; + this.tc = tc; } - deps[entityName] ~= dependentOn; - gprintln("[Encounter] Entity: \""~entityName~"\" set to be dependent on \""~dependentOn~"\""); -} -public void encounter(TypeChecker tc, Entity entityDependee, Entity dependentOn) -{ - /* Full path of thing depending on something else */ - string dependee = tc.getResolver().generateName(tc.getModule(), entityDependee); - - /* Full path of the thing it is dependent on */ - string dependency = tc.getResolver().generateName(tc.getModule(), dependentOn); - - encounter(dependee, dependency); -} - -/** -* Given a path to a class and a relative container to start at -* this will start at the top of the path and dependencyGneerate -* on each of them -* -* Example: -* -* module j; -* A.B.C cInstance; -* -* class A -* { -* class B -* { -* -* } -* } -*/ - -/* TODO: Implement me */ - - -public bool hasDepChecked(TypeChecker tc, Entity entity) -{ - /* Full path of the entity */ - string entityFullPath = tc.getResolver().generateName(tc.getModule(), entity); - - /** - * Check if it is in there - * TODO: Use `in` - */ - foreach(string key; deps.keys) + /* TODO: Return a list of Statement, in their init order */ + public void checkContainer(Container container) { - import std.string : cmp; - if(cmp(key, entityFullPath) == 0) + /* Get all Entities */ + Entity[] entities; + foreach(Statement statement; container.getStatements()) { - return true; - } - } - - return false; -} - - -import compiler.typecheck.reliance; - -/** -* Statically initilizes a given class -*/ -public void staticInitClass(TypeChecker tc, Clazz clazz) -{ - /** - * Don't init if we have initted before - */ - if(hasDepChecked(tc, clazz)) - { - return; - } - - - - /** - * Get all Entities of the class that are static - */ - Entity[] staticEntities; - foreach (Statement statement; clazz.getStatements()) - { - if (statement !is null && cast(Entity) statement) - { - Entity entity = cast(Entity)statement; - if(entity.getModifierType() == InitScope.STATIC) + if(statement !is null && cast(Entity)statement) { - staticEntities ~= cast(Entity) statement; + entities ~= cast(Entity)statement; } } - } - /** - * Process the static members - */ - foreach(Entity staticMember; staticEntities) - { /** - * If the static member is a variable - * declaration + * Process entities */ - if(cast(Variable)staticMember) - { - Variable variable = cast(Variable)staticMember; - - /* Get the variable's type */ - Type variableType = tc.getType(clazz, variable.getType()); - - /** - * Check if the type is a class type - */ - if(cast(Clazz)variableType) - { - Clazz classType = cast(Clazz)variableType; - - /* Static initialize the class if it is not this class-type */ - if(classType != clazz) - { - /* Set this class to be dependent on the class of the class-type */ - encounter(tc, clazz, classType); - - /* Initialize (statically) the class referred to by the class-type */ - staticInitClass(tc, classType); - } - } - - - /* This class depends on this variable being initialized */ - encounter(tc, clazz, variable); - - /* If then variable has an assignment */ - if(variable.getAssignment()) - { - /* TODO: Add assignment support */ - } - } - - encounter(tc, staticMember, staticMember); - - } -} - -public bool isClassMember(TypeChecker tc, Clazz c, string memberName) -{ - return false; -} - -public string findEnd(TypeChecker tc) -{ - string end; - - foreach(string entityPath; deps.keys) - { - string[] dependencies = deps[entityPath]; - - foreach(string dependency; dependencies) - { - /* Check if the dependency has only itself */ - string visitedNode = dependency; - string[] visistedNodeDependencies = deps[visitedNode]; - - /* If only one dep, add to top of init queue */ - if(visistedNodeDependencies.length == 1) - { - - } - else - { - foreach(string vNodeDep; visistedNodeDependencies) - { - - } - } - - } - } - - return end; -} - -public void virtualInitClass(TypeChecker tc, Clazz clazz) -{ - -} - - - -/** -* Returns true if the path downwards is all static dentities -*/ - -public void dependancyGenerate(TypeChecker tc, Container container) -{ - /** - * The Container Entity - */ - Entity containerEntity = cast(Entity)container; - assert(containerEntity); - string containerEntityName = tc.getResolver().generateName(tc.getModule(), containerEntity); - - /** - * Get all Entities - */ - Entity[] containerEntities; - foreach (Statement statement; container.getStatements()) - { - if (statement !is null && cast(Entity) statement) - { - containerEntities ~= cast(Entity) statement; - } - } - - gprintln("[dependencyGenerate] Container: \""~containerEntityName~"\" has the following members:\n\n"~to!(string)(containerEntities)); - - /** - * Process all entities - * - * The natural order would be classes, funcitons/variables (I cannot remember TOOD: check this) - * - * If, for example, we have `A aInstance;` as a module-level variable declaration then - * we must statically initialize A (the class as that is a class-type reference) - we do - * this by visiting the class and initializing all of it's things - */ - foreach(Entity entity; containerEntities) - { - /** - * If we are at Module level then things differ - * ever so slightly - */ - if(container == tc.getModule()) + foreach(Entity entity; entities) { /** - * If we have a module-level variable declaration then we want to check - * if the type of the variable being declared is: - * - * 1. Basic (int, float, etc.) - * - Then we will do nothing, it is not dependent - * 2. Non-basic (Class-case only) - * - Then we will check if that class is accessible - * 1. If it is at the module-level then it is implied static so it would be - * 2. If at a level deeper then more care must be taken - * - * TODO: Assignments still not supported as this means more checking + * Variable declaration */ if(cast(Variable)entity) { + /* Variable being declared */ Variable variable = cast(Variable)entity; /* Get the variable's type */ - Type variableType = tc.getType(container, variable.getType()); + Type type = tc.getType(container, variable.getType()); - /** - * Check if the type is a class type - */ - if(cast(Clazz)variableType) + /* If the variable has a class-type */ + if(cast(Clazz)type) { - Clazz classType = cast(Clazz)variableType; + /* Get the class-type */ + Clazz classType = cast(Clazz)type; - /* If the class is defined at the module-level then it is static by default */ - if(classType.parentOf() == tc.getModule()) - { - /** - * Then mark the class as a dependency (the class-name/type reference) - * must cause the static initialization to go off - * - * module pp; - * Person k; - * class Person { } - * - * Above it means that because the type of `k` is `Person` and that is a - * class type therefore the Person class should have its static constructor - * run (=> all static members should be initialized) - * - * Okay, so we do all of the above SECOND, first the class must be checked itself - */ - staticInitClass(tc, classType); - encounter(tc, variable, classType); - } - else - { - /* TODO: Possible errors but may work too */ - gprintln("Woah there cowboy, this is dangerous territory", DebugType.WARNING); - } - } - /** - * Anything else (TODO: Checking) - */ - else - { - /* TODO: EVerything else is fine */ - /* TODO: Either struct or primtive, neither have static initlization */ - - /* We need to still know it exists */ - encounter(tc, variable, variable); + /* TODO: Ensure that we set dependences as A.B.C with A B C all static */ } - /* If then variable has an assignment */ + + /* TODO: Handle assignment case */ if(variable.getAssignment()) { - /* TODO: Add assignment support */ + /* TODO: Implement me */ } } } - /** - * If we are at the Class level - */ - else if(cast(Clazz)container) - { - /* TODO: Only should be called in static-initialization case */ - // Clazz clazz = cast(Clazz)container; - // assert(clazz.); - - } - /** - * If we are at the Struct level - */ - else if(cast(Struct)container) - { - - } - /** - * Any other type of Container - */ - else - { - /* This shouldn't happen */ - gprintln("BAAD", DebugType.ERROR); - assert(false); - } } } \ No newline at end of file