Merge branch 'vardec_varass_dependency' into feature/multi_module

This commit is contained in:
Tristan B. Velloza Kildaire 2024-02-27 10:34:17 +02:00
commit 58caf6fc59
11 changed files with 426 additions and 128 deletions

View File

@ -136,10 +136,16 @@ public final class TypeChecker
* non-cyclic
*
*/
IFuncDefStore funcDefStore = new FuncDefStore(this);
DNodeGenerator dNodeGenerator = new DNodeGenerator(this, funcDefStore);
// Create a pooling mechanism
import tlang.compiler.typecheck.dependency.pool.interfaces;
import tlang.compiler.typecheck.dependency.pool.impls;
/* Create the dependency generator */
IPoolManager poolManager = new PoolManager();
IFuncDefStore funcDefStore = new FuncDefStore(this, poolManager);
DNodeGenerator dNodeGenerator = new DNodeGenerator(this, poolManager, funcDefStore);
/* Generate the dependency tree */
DNode rootNode = dNodeGenerator.generate(); /* TODO: This should make it acyclic */

View File

@ -27,9 +27,9 @@ public class ObjectInitializationNode : DNode
/* Object actual type */
private Clazz clazz;
this(DNodeGenerator dnodegen, Clazz objectActualType, NewExpression entity)
this(Clazz objectActualType, NewExpression entity)
{
super(dnodegen, entity);
super(entity);
// this.newExpression = entity;
this.clazz = objectActualType;

View File

@ -13,19 +13,22 @@ import tlang.compiler.typecheck.core;
import tlang.compiler.symbols.typing.core;
import tlang.compiler.symbols.typing.builtins;
import tlang.compiler.typecheck.dependency.core;
import std.conv : to;
public class ClassStaticNode : DNode
{
private Clazz entity;
this(DNodeGenerator dnodegen, Clazz entity)
this(Clazz entity)
{
super(dnodegen, entity);
super(entity);
this.entity = entity;
initName();
}
private void initName()
{
name = "ClassStaticInit: "~resolver.generateName(cast(Container)dnodegen.root.getEntity(), cast(Entity)entity);
name = "ClassStaticInit: "~to!(string)(entity);
}
}

View File

@ -13,11 +13,23 @@ import tlang.compiler.typecheck.core;
import tlang.compiler.symbols.typing.core;
import tlang.compiler.symbols.typing.builtins;
import tlang.compiler.typecheck.dependency.core;
import std.conv : to;
public class ClassVirtualInit : DNode
{
this(DNodeGenerator dnodegen, Clazz clazz)
private Clazz clazz;
this(Clazz clazz)
{
super(dnodegen, clazz);
super(clazz);
this.clazz = clazz;
initName();
}
private void initName()
{
name = "ClassVirtualInit: "~to!(string)(clazz);
}
}

View File

@ -13,6 +13,8 @@ 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.pool.interfaces;
import tlang.compiler.typecheck.dependency.pool.impls;
import tlang.compiler.typecheck.dependency.store.interfaces : IFuncDefStore;
@ -107,18 +109,13 @@ public class DNode
protected string name;
protected DNodeGenerator dnodegen;
protected Resolver resolver;
private bool visited;
private bool complete;
private DNode[] dependencies;
this(DNodeGenerator dnodegen, Statement entity)
this(Statement entity)
{
this.entity = entity;
this.dnodegen = dnodegen;
this.resolver = dnodegen.resolver;
initName();
}
@ -348,9 +345,9 @@ public final class DFunctionInnerGenerator : DNodeGenerator
{
private Function func;
this(TypeChecker tc, IFuncDefStore funcDefStore, Function func)
this(TypeChecker tc, IPoolManager poolManager, IFuncDefStore funcDefStore, Function func)
{
super(tc, funcDefStore);
super(tc, poolManager, funcDefStore);
this.func = func;
}
@ -383,23 +380,23 @@ public class DNodeGenerator
private IFuncDefStore funcDefStore;
/**
* Dependency node pooling
* management
*/
private IPoolManager poolManager;
/**
* DNode pool
*
* This holds unique pool entries
*/
private static DNode[] nodePool;
this(TypeChecker tc, IFuncDefStore funcDefStore)
this(TypeChecker tc, IPoolManager poolManager, IFuncDefStore funcDefStore)
{
// /* NOTE: NEW STUFF 1st Oct 2022 */
// Module modulle = tc.getModule();
// Context context = new Context(modulle, InitScope.STATIC);
// super(tc, context, context.getContainer().getStatements());
// TODO: See if we can pass it in rather, but
// ... because this needs a this we must make
// ... it here
this.poolManager = poolManager;
this.tc = tc;
this.resolver = tc.getResolver();
@ -462,23 +459,7 @@ public class DNodeGenerator
private DNode pool(Statement entity)
{
foreach(DNode dnode; nodePool)
{
if(dnode.getEntity() == entity)
{
return dnode;
}
}
/**
* If no DNode is found that is associated with
* the provided Entity then create a new one and
* pool it
*/
DNode newDNode = new DNode(this, entity);
nodePool ~= newDNode;
return newDNode;
return this.poolManager.pool(entity);
}
/**
@ -488,23 +469,27 @@ public class DNodeGenerator
*/
private DNodeType poolT(DNodeType, EntityType)(EntityType entity)
{
foreach(DNode dnode; nodePool)
static if(__traits(isSame, DNodeType, ExpressionDNode))
{
if(dnode.getEntity() == entity)
{
return cast(DNodeType)dnode;
}
return this.poolManager.poolExpression(cast(Expression)entity);
}
else static if(__traits(isSame, DNodeType, VariableNode))
{
return this.poolManager.poolVariable(cast(Variable)entity);
}
else static if(__traits(isSame, DNodeType, StaticVariableDeclaration))
{
return this.poolManager.poolStaticVariable(cast(Variable)entity);
}
else static if(__traits(isSame, DNodeType, FuncDecNode))
{
return this.poolManager.poolFuncDec(cast(Function)entity);
}
else
{
pragma(msg, "This is an invalid case");
static assert(false);
}
/**
* If no DNode is found that is associated with
* the provided Entity then create a new one and
* pool it
*/
DNodeType newDNode = new DNodeType(this, entity);
nodePool ~= newDNode;
return newDNode;
}
@ -534,7 +519,7 @@ public class DNodeGenerator
{
/* We don't pool anything here - a constructor call is unique */
ObjectInitializationNode node = new ObjectInitializationNode(this, clazz, newExpression);
ObjectInitializationNode node = new ObjectInitializationNode(clazz, newExpression);
/* TODO: Call a virtual pass over the class */
@ -966,23 +951,7 @@ public class DNodeGenerator
import tlang.compiler.typecheck.dependency.variables;
private ModuleVariableDeclaration pool_module_vardec(Variable entity)
{
foreach(DNode dnode; nodePool)
{
if(dnode.getEntity() == entity)
{
return cast(ModuleVariableDeclaration)dnode;
}
}
/**
* If no DNode is found that is associated with
* the provided Entity then create a new one and
* pool it
*/
ModuleVariableDeclaration newDNode = new ModuleVariableDeclaration(this, entity);
nodePool ~= newDNode;
return newDNode;
return this.poolManager.poolModuleVariableDeclaration(entity);
}
// TODO: Work in progress
@ -1560,25 +1529,7 @@ public class DNodeGenerator
// assert(clazz.getModifierType() == InitScope.STATIC);
}
foreach(DNode dnode; nodePool)
{
Statement entity = dnode.getEntity();
if(entity == clazz && cast(ClassStaticNode)dnode)
{
return cast(ClassStaticNode)dnode;
}
}
/**
* If no DNode is found that is associated with
* the provided Entity then create a new one and
* pool it
*/
ClassStaticNode newDNode = new ClassStaticNode(this, clazz);
nodePool ~= newDNode;
return newDNode;
return this.poolManager.poolClassStatic(clazz);
}
/**

View File

@ -13,12 +13,13 @@ import tlang.compiler.typecheck.core;
import tlang.compiler.symbols.typing.core;
import tlang.compiler.symbols.typing.builtins;
import tlang.compiler.typecheck.dependency.core;
import std.conv : to;
public class ExpressionDNode : DNode
{
this(DNodeGenerator dnodegen, Expression entity)
this(Expression entity)
{
super(dnodegen, entity);
super(entity);
initName();
}
@ -52,14 +53,16 @@ public class ExpressionDNode : DNode
*/
public class AccessDNode : DNode
{
private Entity entity;
/**
* Construct a new AccessNode given the `entity`
* being accessed
*/
this(DNodeGenerator dnodegen, Entity entity)
this(Entity entity)
{
super(dnodegen, entity);
// this.entity = entity;
super(entity);
this.entity = entity;
initName();
@ -67,8 +70,6 @@ public class AccessDNode : DNode
private void initName()
{
name = resolver.generateName(cast(Container)dnodegen.root.getEntity(), cast(Entity)entity);
name = "[AccessNode] (Name: "~name~")";
name = "[AccessNode] (Name: "~to!(string)(entity)~")";
}
}

View File

@ -0,0 +1,216 @@
/**
* Implementation of the `IPoolManager`
* interface
*/
module tlang.compiler.typecheck.dependency.pool.impls;
import tlang.compiler.typecheck.dependency.pool.interfaces;
import tlang.compiler.typecheck.dependency.core : DNode, DNodeGenerator;
import tlang.compiler.typecheck.dependency.expression : ExpressionDNode;
import tlang.compiler.typecheck.dependency.variables : VariableNode, FuncDecNode, StaticVariableDeclaration, ModuleVariableDeclaration;
import tlang.compiler.typecheck.dependency.classes.classStaticDep : ClassStaticNode;
import tlang.compiler.symbols.data : Statement, Expression, Variable, Function, Clazz;
import std.traits : isAssignable;
/**
* Provides an implementation of
* the `IPoolManager` interface
* such that you can use this
* as part of the dependency
* generation process
*/
public final class PoolManager : IPoolManager
{
/**
* The pool itself
*/
private DNode[] nodePool;
/**
* Constructs a new pooling manager
*/
this()
{
}
/**
* Pools the provided AST node
* to a dependency node, creating
* one if one did not yet exist
*
* Params:
* statement = the AST node
* Returns: the dependency node
*/
public DNode pool(Statement statement)
{
return poolT!(DNode, Statement)(statement);
}
/**
* Pools the provided `Clazz`
* AST node but with an additional
* check that it should match
* against a `ClassStaticNode`
* and if one does not exist
* then one such dependency
* node should be created
*
* Params:
* clazz = the class to statcally
* pool
* Returns: the pooled `ClassStaticNode`
*/
public ClassStaticNode poolClassStatic(Clazz clazz)
{
foreach(DNode dnode; nodePool)
{
Statement entity = dnode.getEntity();
if(entity == clazz && cast(ClassStaticNode)dnode)
{
return cast(ClassStaticNode)dnode;
}
}
/**
* If no DNode is found that is associated with
* the provided Entity then create a new one and
* pool it
*/
ClassStaticNode newDNode = new ClassStaticNode(clazz);
nodePool ~= newDNode;
return newDNode;
}
/**
* Pools the provided `Expression`
* AST node into an `ExpressionDNode`
*
* Params:
* expression = the AST node
* Returns: the pooled `ExpressionDNode`
*/
public ExpressionDNode poolExpression(Expression expression)
{
return poolT!(ExpressionDNode, Expression)(expression);
}
/**
* Pools the provided `Variable`
* AST node into a `VariableNode`
*
* Params:
* variable = the AST node
* Returns: the pooled `VariableNode`
*/
public VariableNode poolVariable(Variable variable)
{
return poolT!(VariableNode, Variable)(variable);
}
/**
* Pools the provided `Variable`
* AST node into a `StaticVariableDeclaration`
*
* Params:
* variable = the AST node
* Returns: the pooled `StaticVariableDeclaration`
*/
public StaticVariableDeclaration poolStaticVariable(Variable variable)
{
return poolT!(StaticVariableDeclaration, Variable)(variable);
}
/**
* Pools the provided `Variable`
* AST node into a `ModuleVariableDeclaration`
*
* Params:
* variable = the AST node
* Returns: the pooled `ModuleVariableDeclaration`
*/
public ModuleVariableDeclaration poolModuleVariableDeclaration(Variable variable)
{
return poolT!(ModuleVariableDeclaration, Variable)(variable);
}
/**
* Pools the provided `Function`
* AST node into a `FuncDecNode`
*
* Params:
* func = the AST node
* Returns: the pooled `FUncDecNode`
*/
public FuncDecNode poolFuncDec(Function func)
{
return poolT!(FuncDecNode, Function)(func);
}
/**
* Pools the provided AST node
* to a dependency node, creating
* one if one did not yet exist.
*
* This is a templatised version
* which lets you specify the
* kind-of `DNode` to be constructed
* (if it does not yet exist) and
* the incoming type of AST node.
*
* Params:
* entity = the AST node
* Returns: the dependency node
*/
public DNodeType poolT(DNodeType, EntityType)(EntityType entity)
if(isAssignable!(DNode, DNodeType))
{
foreach(DNode dnode; nodePool)
{
if(dnode.getEntity() == entity)
{
return cast(DNodeType)dnode;
}
}
/**
* If no DNode is found that is associated with
* the provided Entity then create a new one and
* pool it
*/
DNodeType newDNode = new DNodeType(entity);
nodePool ~= newDNode;
return newDNode;
}
}
version(unittest)
{
import tlang.compiler.symbols.data : Module, Variable;
import tlang.compiler.typecheck.core : TypeChecker;
}
/**
* Tests the pooling of AST nodes
* to dependency nodes using the
* `PoolManager` implementation
*/
unittest
{
// Create bogus module and type checker
Module testModule = new Module("myModule");
TypeChecker tc = new TypeChecker(testModule);
// Create a pool manager
IPoolManager pool = new PoolManager();
// Pool an AST node
Variable astNode = new Variable("int", "age");
DNode astDNode = pool.pool(astNode);
// Now pool it (again) and ensure it matches
// the dependency node just created
assert(astDNode is pool.pool(astNode));
}

View File

@ -0,0 +1,106 @@
/**
* Defines interfaces for managing
* the pooling of AST nodes to
* dependency nodes which are to be
* used within the dependency generator
* and later the codegen/typechecker
* which consumes these dependency
* nodes
*/
module tlang.compiler.typecheck.dependency.pool.interfaces;
import tlang.compiler.typecheck.dependency.core : DNode;
import tlang.compiler.typecheck.dependency.expression : ExpressionDNode;
import tlang.compiler.typecheck.dependency.variables : VariableNode, FuncDecNode, StaticVariableDeclaration, ModuleVariableDeclaration;
import tlang.compiler.typecheck.dependency.classes.classStaticDep : ClassStaticNode;
import tlang.compiler.symbols.data : Statement, Expression, Variable, Function, Clazz;
// TODO: In future if we do not require the specific `ExpressionDNode` et al
// ... then remove them from the interface definition below
/**
* Defines an interface by which
* `Statement`s (i.e. AST nodes)
* can be mapped to a `DNode`
* and if one does not exist
* then it is created on the
* first use
*/
public interface IPoolManager
{
/**
* Pools the provided AST node
* to a dependency node
*
* Params:
* statement = the AST node
* Returns: the pooled `DNode`
*/
public DNode pool(Statement statement);
/**
* Pools the provided `Clazz`
* AST node but with an additional
* check that it should match
* against a `ClassStaticNode`
* and if one does not exist
* then one such dependency
* node should be created
*
* Params:
* clazz = the class to statcally
* pool
* Returns: the pooled `ClassStaticNode`
*/
public ClassStaticNode poolClassStatic(Clazz clazz);
/**
* Pools the provided `Expression`
* AST node into an `ExpressionDNode`
*
* Params:
* expression = the AST node
* Returns: the pooled `ExpressionDNode`
*/
public ExpressionDNode poolExpression(Expression expression);
/**
* Pools the provided `Variable`
* AST node into a `VariableNode`
*
* Params:
* variable = the AST node
* Returns: the pooled `VariableNode`
*/
public VariableNode poolVariable(Variable variable);
/**
* Pools the provided `Variable`
* AST node into a `StaticVariableDeclaration`
*
* Params:
* variable = the AST node
* Returns: the pooled `StaticVariableDeclaration`
*/
public StaticVariableDeclaration poolStaticVariable(Variable variable);
/**
* Pools the provided `Variable`
* AST node into a `ModuleVariableDeclaration`
*
* Params:
* variable = the AST node
* Returns: the pooled `ModuleVariableDeclaration`
*/
public ModuleVariableDeclaration poolModuleVariableDeclaration(Variable variable);
/**
* Pools the provided `Function`
* AST node into a `FuncDecNode`
*
* Params:
* func = the AST node
* Returns: the pooled `FUncDecNode`
*/
public FuncDecNode poolFuncDec(Function func);
}

View File

@ -8,6 +8,7 @@ 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;
import tlang.compiler.typecheck.dependency.pool.interfaces : IPoolManager;
/**
* An implementation of the `IFuncDefStore`
@ -27,6 +28,11 @@ public final class FuncDefStore : IFuncDefStore
*/
private TypeChecker tc;
/**
* The pool management
*/
private IPoolManager poolManager;
/**
* Constructs a new function
* definition store with
@ -35,10 +41,12 @@ public final class FuncDefStore : IFuncDefStore
*
* Params:
* typeChecker = the `TypeChecker`
* poolManager = the `IPoolManager`
*/
this(TypeChecker typeChecker)
this(TypeChecker typeChecker, IPoolManager poolManager)
{
this.tc = typeChecker;
this.poolManager = poolManager;
}
/**
@ -70,7 +78,7 @@ public final class FuncDefStore : IFuncDefStore
* context etc.
*/
FunctionData funcData;
funcData.ownGenerator = new DFunctionInnerGenerator(tc, this, func);
funcData.ownGenerator = new DFunctionInnerGenerator(tc, this.poolManager, 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.getProgram(), func);

View File

@ -2,6 +2,7 @@ module tlang.compiler.typecheck.dependency.variables;
import tlang.compiler.typecheck.dependency.core;
import tlang.compiler.symbols.data;
import std.conv : to;
/**
* This module holds types related to variable declarations
@ -15,9 +16,9 @@ public class VariableNode : DNode
{
private Variable variable;
this(DNodeGenerator dnodegen, Variable variable)
this(Variable variable)
{
super(dnodegen, variable);
super(variable);
this.variable = variable;
@ -26,60 +27,55 @@ public class VariableNode : DNode
private void initName()
{
name = resolver.generateName(cast(Container)dnodegen.root.getEntity(), cast(Entity)entity);
name = to!(string)(variable);
}
}
public class FuncDecNode : DNode
{
private Function funcHandle;
this(DNodeGenerator dnodegen, Function funcHandle)
this(Function funcHandle)
{
super(dnodegen, funcHandle);
super(funcHandle);
this.funcHandle = funcHandle;
initName();
}
private void initName()
{
name = "FuncHandle:"~resolver.generateName(cast(Container)dnodegen.root.getEntity(), cast(Entity)entity);
name = "FuncHandle:"~to!(string)(funcHandle);
}
}
public class ModuleVariableDeclaration : VariableNode
{
this(DNodeGenerator dnodegen, Variable variable)
this(Variable variable)
{
super(dnodegen, variable);
super(variable);
initName();
}
private void initName()
{
name = "(S) "~resolver.generateName(cast(Container)dnodegen.root.getEntity(), cast(Entity)entity);
name = "(S) "~to!(string)(variable);
}
}
public class StaticVariableDeclaration : VariableNode
{
this(DNodeGenerator dnodegen, Variable variable)
this(Variable variable)
{
super(dnodegen, variable);
super(variable);
initName();
}
private void initName()
{
name = "(S) "~resolver.generateName(cast(Container)dnodegen.root.getEntity(), cast(Entity)entity);
name = "(S) "~to!(string)(variable);
}
}
@ -87,12 +83,11 @@ public class VariableAssignmentNode : DNode
{
private VariableAssignment variableAssignment;
this(DNodeGenerator dnodegen, VariableAssignment variableAssignment)
this(VariableAssignment variableAssignment)
{
super(dnodegen, variableAssignment);
super(variableAssignment);
this.variableAssignment = variableAssignment;
initName();
}
@ -101,6 +96,6 @@ public class VariableAssignmentNode : DNode
/* get the associated variable */
Variable associatedVariable = variableAssignment.getVariable();
name = resolver.generateName(cast(Container)dnodegen.root.getEntity(), associatedVariable)~" (assignment)";
name = to!(string)(associatedVariable)~" (assignment)";
}
}

BIN
tlang

Binary file not shown.