From c55cd74596fe4273d739ca605145536a51c25d9d Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Tue, 27 Feb 2024 09:33:18 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9=EF=B8=8F=F0=9F=A7=BC=20Cleanup:=20?= =?UTF-8?q?addFuncDef/clearFuncDefs=20should=20all=20use=20a=20non-static?= =?UTF-8?q?=20pool=20(#34)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * IFuncDefStore - Added new interface * FuncDefStore - Implemented new `IFuncDefStore` type * FuncDefStore - The constructor now takes in a `TypeChecker` instance - Implemented `addFunctionDef(Function func)` * FuncDefStore - Added a TODO + some code for a future naming setup I want to se * IPoolManager - Added documentation - Added new method `grabFunctionDef(string name)` to the API * FuncDefStoreException - Added new exception type * IPoolManager - Added more docs for `grabFunctionDef(string name)` * FuncDefStore - Pass in ourselves (a `IFuncDefStore`) into the `DFunctionInnerGenerator` when adding a function definition - Implemented `grabFunctionDef(string name)` from the updated `IFuncDefStore` API * DNodeGenerator - Constructor now takes in a `IFuncDefStore` - When we encounter a `Function` we will add it to the store of function definitions by using the new `IFuncDefStore` (instead of the old `addFunctionDef(TypeChecker, Function)` - Removed unused method `saveFunctionDefinitionNode(DNode funcDefNode)` - Removed unused method `retrieveFunctionDefinitionNode(string functionAbsolutePath)` - Removed the old method `addFunctionDef(TypeChecker tc, Function func)` (as we are now using the `IFuncDefStore`) - Removed the `clearFuncDefs()` as we are now using the `IFuncDefStore` - Removed the `grabFunctionDefs()` as we are now using the `IFuncDefStore` - Removed the `FunctionData[string]` as we are now using the `IFuncDefStore` DFunctionInnerGenerator - Constructor now takes in a `IFuncDefStore` * TypeChecker - `dependencyCheck()` no lomger calls the removed `clearFuncDefs()` from the `dependency.core` module - `dependencyCheck()` now constructs a new `IFuncDefStore` and then passes it into the `DNodeGenerator` when dependency generation needs to occur * IFuncDefStore - Added module-level documentation * FuncDefStore - Documented class - Documented module * FuncDefStoreException - Documented constructor and class * IFuncDefStore - `addFunctionDef(Function func)` may now throw a `FuncDefStoreException` when you add a function that already exists * FuncDefStore - `addFunctionDef(Function func)` now throws a `FuncDefStoreException` when you provide a `Function` that has already been added * IFuncDefStore - Moved import to the top * FuncDefStore - Cleaned up --- source/tlang/compiler/typecheck/core.d | 19 +-- .../compiler/typecheck/dependency/core.d | 106 ++-------------- .../typecheck/dependency/store/impls.d | 119 ++++++++++++++++++ .../typecheck/dependency/store/interfaces.d | 70 +++++++++++ 4 files changed, 202 insertions(+), 112 deletions(-) create mode 100644 source/tlang/compiler/typecheck/dependency/store/impls.d create mode 100644 source/tlang/compiler/typecheck/dependency/store/interfaces.d diff --git a/source/tlang/compiler/typecheck/core.d b/source/tlang/compiler/typecheck/core.d index aba289a..73f30e2 100644 --- a/source/tlang/compiler/typecheck/core.d +++ b/source/tlang/compiler/typecheck/core.d @@ -16,6 +16,8 @@ import std.container.slist; import std.algorithm : reverse; import tlang.compiler.typecheck.meta; import tlang.compiler.configuration; +import tlang.compiler.typecheck.dependency.store.interfaces : IFuncDefStore; +import tlang.compiler.typecheck.dependency.store.impls : FuncDefStore; /** * The Parser only makes sure syntax @@ -107,14 +109,6 @@ public final class TypeChecker /* TODO: Implement me */ checkClassInherit(modulle); - // TODO: Issue 88: Don't use static state - scope(exit) - { - /* Clear the FunctionData map (for next compilation) */ - clearFuncDefs(); - } - - /** * Dependency tree generation * @@ -124,9 +118,10 @@ public final class TypeChecker * non-cyclic * */ - - DNodeGenerator dNodeGenerator = new DNodeGenerator(this); + + IFuncDefStore funcDefStore = new FuncDefStore(this); + DNodeGenerator dNodeGenerator = new DNodeGenerator(this, funcDefStore); /* Generate the dependency tree */ DNode rootNode = dNodeGenerator.generate(); /* TODO: This should make it acyclic */ @@ -157,7 +152,7 @@ public final class TypeChecker assert(codeQueue.empty() == true); /* Grab functionData ??? */ - FunctionData[string] functionDefinitions = grabFunctionDefs(); + FunctionData[string] functionDefinitions = funcDefStore.grabFunctionDefs(); gprintln("Defined functions: "~to!(string)(functionDefinitions)); foreach(FunctionData funcData; functionDefinitions.values) @@ -208,8 +203,6 @@ public final class TypeChecker gprintln("FUNCDEF DONE: "~to!(string)(functionBodyCodeQueues[funcData.name])); } - - // NOTE: Check scope guard for "exit routines" which run here } diff --git a/source/tlang/compiler/typecheck/dependency/core.d b/source/tlang/compiler/typecheck/dependency/core.d index 7d7c88b..1201cac 100644 --- a/source/tlang/compiler/typecheck/dependency/core.d +++ b/source/tlang/compiler/typecheck/dependency/core.d @@ -13,6 +13,7 @@ import tlang.compiler.typecheck.core; import tlang.compiler.symbols.typing.core; import tlang.compiler.symbols.typing.builtins; import tlang.compiler.typecheck.dependency.exceptions : DependencyException, DependencyError; +import tlang.compiler.typecheck.dependency.store.interfaces : IFuncDefStore; /** @@ -91,72 +92,6 @@ public struct FunctionData } } -/** -* All declared functions -*/ -private FunctionData[string] functions; - - -/** - * Returns the declared functions - */ -public FunctionData[string] grabFunctionDefs() -{ - return functions; -} - -/** - * Clars the `FunctionData[string]` map - * - * This is called normally after the - * typechecking and code generation such - * that the module-static field inside - * this module can be cleared and not - * persist across compilations - */ -public void clearFuncDefs() -{ - foreach(string key; functions.keys()) - { - functions.remove(key); - } -} - -/** -* Creates a new FunctionData and adds it to the -* list of declared functions -* -* Requires a TypeChecker `tc` -*/ -private void addFunctionDef(TypeChecker tc, Function func) -{ - /* (Sanity Check) This should never be called again */ - foreach(string cFuncKey; functions.keys()) - { - FunctionData cFuncData = functions[cFuncKey]; - Function cFunc = cFuncData.func; - - if(cFunc == func) - { - assert(false); - } - } - - /** - * Create the FunctionData, coupled with it own DNodeGenerator - * context etc. - */ - FunctionData funcData; - funcData.ownGenerator = new DFunctionInnerGenerator(tc, func); - funcData.name = func.getName(); - funcData.func = func; - - - functions[funcData.name] = funcData; - - -} - /** * DNode * @@ -408,9 +343,9 @@ public final class DFunctionInnerGenerator : DNodeGenerator { private Function func; - this(TypeChecker tc, Function func) + this(TypeChecker tc, IFuncDefStore funcDefStore, Function func) { - super(tc); + super(tc, funcDefStore); this.func = func; } @@ -441,35 +376,7 @@ public class DNodeGenerator */ private DNode[string] functionDefinitions; - /** - * Given a DNode generated by a Function (function definition) - * this will extract the name of the function and save the DNode - * into the map for later retrieval by `retrieveFunctionDefinitionNode` - */ - private void saveFunctionDefinitionNode(DNode funcDefNode) - { - gprintln("saveFunctionDefinitionNode: Implement me please"); - - // Extract the name of the function - Function functionDefinition = cast(Function)funcDefNode.getEntity(); - assert(functionDefinition); - string functionNameAbsolutePath = resolver.generateName(cast(Container)root.getEntity(), cast(Entity)functionDefinition); - - // Save to the map - functionDefinitions[functionNameAbsolutePath] = funcDefNode; - } - - /** - * Given the absolute path to a function, this will retrieve the - * Function (function definition) DNode from the map - */ - private DNode retrieveFunctionDefinitionNode(string functionAbsolutePath) - { - gprintln("retrieveFunctionDefinitionNode: Implement me please"); - - // TODO: Add an assertion for failed lookup - return functionDefinitions[functionAbsolutePath]; - } + private IFuncDefStore funcDefStore; /** @@ -479,7 +386,7 @@ public class DNodeGenerator */ private static DNode[] nodePool; - this(TypeChecker tc) + this(TypeChecker tc, IFuncDefStore funcDefStore) { // /* NOTE: NEW STUFF 1st Oct 2022 */ // Module modulle = tc.getModule(); @@ -491,6 +398,7 @@ public class DNodeGenerator this.tc = tc; this.resolver = tc.getResolver(); + this.funcDefStore = funcDefStore; /* TODO: Make this call in the TypeChecker instance */ //generate(); @@ -1280,7 +1188,7 @@ public class DNodeGenerator /* Add funtion definition */ gprintln("Hello"); - addFunctionDef(tc, func); + this.funcDefStore.addFunctionDef(func); return null; } diff --git a/source/tlang/compiler/typecheck/dependency/store/impls.d b/source/tlang/compiler/typecheck/dependency/store/impls.d new file mode 100644 index 0000000..cd30269 --- /dev/null +++ b/source/tlang/compiler/typecheck/dependency/store/impls.d @@ -0,0 +1,119 @@ +/** + * Provides implementation of the `IFuncDefStore` + * interface + */ +module tlang.compiler.typecheck.dependency.store.impls; + +import tlang.compiler.typecheck.dependency.store.interfaces; +import tlang.compiler.symbols.data : Function; +import tlang.compiler.typecheck.dependency.core : FunctionData, DFunctionInnerGenerator; +import tlang.compiler.typecheck.core : TypeChecker; + +/** + * An implementation of the `IFuncDefStore` + * which provides us with a way to store + * function definitions and retrieve them + * later + */ +public final class FuncDefStore : IFuncDefStore +{ + /** + * All declared functions + */ + private FunctionData[string] functions; + + /** + * The type checker instance + */ + private TypeChecker tc; + + /** + * Constructs a new function + * definition store with + * the provided type + * checking instance + * + * Params: + * typeChecker = the `TypeChecker` + */ + this(TypeChecker typeChecker) + { + this.tc = typeChecker; + } + + /** + * Adds the function definition + * to the store + * + * Params: + * func = the function to add + * Throws: + * FuncDefStoreException if the function + * has already been added + */ + public void addFunctionDef(Function func) + { + /* (Sanity Check) This should never be called again */ + foreach(string cFuncKey; functions.keys()) + { + FunctionData cFuncData = functions[cFuncKey]; + Function cFunc = cFuncData.func; + + if(cFunc == func) + { + throw new FuncDefStoreException("The provided Function already exists within the store"); + } + } + + /** + * Create the FunctionData, coupled with it own DNodeGenerator + * context etc. + */ + FunctionData funcData; + funcData.ownGenerator = new DFunctionInnerGenerator(tc, this, func); + // TODO: Should we not generate a HELLA long name rather, to avoid duplication problems and overwrites of key values + + funcData.name = tc.getResolver().generateName(tc.getModule(), func); + + funcData.name = func.getName(); + funcData.func = func; + + + functions[funcData.name] = funcData; + } + + /** + * Grabs all of the function + * definitions currently stored + * + * Returns: a `FunctionData[string]` + * map + */ + public FunctionData[string] grabFunctionDefs() + { + return this.functions.dup; + } + + /** + * Grabs a function definition by its + * name + * + * Params: + * name = the name of the function + * Returns: the `FunctionData` + * Throws: + * FuncDefStoreException if the function + * could not be found + */ + public FunctionData grabFunctionDef(string name) + { + if(name in this.functions) + { + return this.functions[name]; + } + else + { + throw new FuncDefStoreException("Could not find function by name '"~name~"'"); + } + } +} \ No newline at end of file diff --git a/source/tlang/compiler/typecheck/dependency/store/interfaces.d b/source/tlang/compiler/typecheck/dependency/store/interfaces.d new file mode 100644 index 0000000..0e6ace4 --- /dev/null +++ b/source/tlang/compiler/typecheck/dependency/store/interfaces.d @@ -0,0 +1,70 @@ +/** + * Provides the definition of a function definition + * store and retrieval system + */ +module tlang.compiler.typecheck.dependency.store.interfaces; + +import tlang.compiler.symbols.data : Function; +import tlang.compiler.typecheck.dependency.core : FunctionData; +import misc.exceptions : TError; + +/** + * Represents a storage mechanism + * which can store and retrieve + * function definition datas + */ +public interface IFuncDefStore +{ + /** + * Adds the function definition + * to the store + * + * Params: + * func = the function to add + * Throws: + * FuncDefStoreException if the function + * has already been added + */ + public void addFunctionDef(Function func); + + /** + * Grabs all of the function + * definitions currently stored + * + * Returns: a `FunctionData[string]` + * map + */ + public FunctionData[string] grabFunctionDefs(); + + /** + * Grabs a function definition by its + * name + * + * Params: + * name = the name of the function + * Returns: the `FunctionData` + * Throws: + * FuncDefStoreException if the function + * could not be found + */ + public FunctionData grabFunctionDef(string name); +} + +/** + * Exception thrown when an error occurs + * with the `IFuncDefStore` system + */ +public final class FuncDefStoreException : TError +{ + /** + * Constructs a new `FuncDefStoreException` + * with the given error message + * + * Params: + * msg = the error message + */ + this(string msg) + { + super(msg); + } +} \ No newline at end of file