🧹🧼 Cleanup: addFuncDef/clearFuncDefs should all use a non-static pool (#34)

* 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
This commit is contained in:
Tristan B. Velloza Kildaire 2024-02-27 09:33:18 +02:00 committed by GitHub
parent ee537f2b25
commit c55cd74596
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 202 additions and 112 deletions

View File

@ -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
}

View File

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

View File

@ -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~"'");
}
}
}

View File

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