tlang/source/tlang/compiler/symbols/data.d

520 lines
9.6 KiB
D

module compiler.symbols.data;
public import compiler.symbols.check;
import std.conv : to;
import compiler.typecheck.dependency.core : Context;
/**
* TODO: Implement the blow and use them
*
* These are just to use for keeping track of what
* valid identifiers are.
*
* Actually it might be, yeah it will
*/
public class Program
{
private string moduleName;
private Program[] importedModules;
private Statement[] statements;
this(string moduleName)
{
this.moduleName = moduleName;
}
public void addStatement(Statement statement)
{
statements ~= statement;
}
public static StatementType[] getAllOf(StatementType)(StatementType, Statement[] statements)
{
StatementType[] statementsMatched;
foreach(Statement statement; statements)
{
/* TODO: Remove null, this is for unimpemented */
if(statement !is null && cast(StatementType)statement)
{
statementsMatched ~= cast(StatementType)statement;
}
}
return statementsMatched;
}
public Variable[] getGlobals()
{
Variable[] variables;
foreach(Statement statement; statements)
{
if(typeid(statement) == typeid(Variable))
{
variables ~= cast(Variable)statement;
}
}
return variables;
}
/* TODO: Make this use weights */
public Statement[] getStatements()
{
/* Re-ordered by lowest wieght first */
Statement[] stmntsRed;
bool wCmp(Statement lhs, Statement rhs)
{
return lhs.weight < rhs.weight;
}
import std.algorithm.sorting;
stmntsRed = sort!(wCmp)(statements).release;
return stmntsRed;
}
}
public class Statement
{
public byte weight = 0;
/* !!!! BEGIN TYPE CHECK ROUTINES AND DATA !!!! */
/* TODO: Used for type checking */
public Context context;
public void setContext(Context context)
{
this.context = context;
}
public Context getContext()
{
return context;
}
/* !!!! END TYPE CHECK ROUTINES AND DATA !!!! */
private static ulong rollingCount = 0;
private Container container;
public final void parentTo(Container container)
{
this.container = container;
}
public final Container parentOf()
{
return container;
}
public override string toString()
{
return to!(string)(rollingCount++);
}
}
public enum AccessorType
{
PUBLIC, PRIVATE, PROTECTED, UNKNOWN
}
public enum InitScope
{
VIRTUAL, STATIC, UNKNOWN
}
public class Assignment : Statement
{
private string identifier;
private Expression assignmentExpression;
this(string identifier, Expression assignmentExpression)
{
this.identifier = identifier;
this.assignmentExpression = assignmentExpression;
}
}
/* Declared variables, defined classes and fucntions */
public class Entity : Statement
{
/* Accesor type */
private AccessorType accessorType = AccessorType.PUBLIC;
/* Function/Modifier type */
private InitScope initScope;
/* Name of the entity (class's name, function's name, variable's name) */
protected string name;
this(string name)
{
this.name = name;
}
public void setAccessorType(AccessorType accessorType)
{
this.accessorType = accessorType;
}
public AccessorType getAccessorType()
{
return accessorType;
}
public void setModifierType(InitScope initScope)
{
this.initScope = initScope;
}
public InitScope getModifierType()
{
return initScope;
}
public string getName()
{
return name;
}
private Entity[] deps;
public Entity[] getDeps()
{
return deps;
}
public void addDep(Entity entity)
{
deps ~= entity;
}
}
/* TODO: DO we need intermediary class, TypedEntity */
public class TypedEntity : Entity
{
private string type;
/* TODO: Return type/variable type in here (do what we did for ENtity with `name/identifier`) */
this(string name, string type)
{
super(name);
this.type = type;
}
public string getType()
{
return type;
}
}
public import compiler.symbols.containers;
public class ArgumentList
{
}
/* TODO: Don't make this a Container, or maybe (make sure I don't rely on COntainer casting for other shit
* though, also the recent changes) */
public class Function : TypedEntity, Container
{
private Variable[] params;
private Statement[] bodyStatements;
this(string name, string returnType, Statement[] bodyStatements, Variable[] args)
{
super(name, returnType);
this.bodyStatements = bodyStatements;
this.params = args;
/* Weighted as 1 */
weight = 1;
}
public Variable[] getParams()
{
return params;
}
public bool hasParams()
{
return params.length != 0;
}
public void addStatement(Statement statement)
{
this.bodyStatements~=statement;
}
public void addStatements(Statement[] statements)
{
this.bodyStatements~=statements;
}
public Statement[] getStatements()
{
import compiler.symbols.containers : weightReorder;
return weightReorder(bodyStatements);
}
/**
* This will sift through all the `Statement[]`'s in held
* within this Function and will find those which are Variable
*/
public Variable[] getVariables()
{
Variable[] variables;
foreach(Statement statement; bodyStatements)
{
if(statement !is null && cast(Variable)statement)
{
variables ~= cast(Variable)statement;
}
}
return variables;
}
public override string toString()
{
string argTypes;
for(ulong i = 0; i < params.length; i++)
{
Variable variable = params[i];
if(i == params.length-1)
{
argTypes ~= variable.getType();
}
else
{
argTypes ~= variable.getType() ~ ", ";
}
}
return "Function (Name: "~name~", ReturnType: "~type~", Args: "~argTypes~")";
}
}
public class Variable : TypedEntity
{
/* TODO: Just make this an Expression */
private VariableAssignment assignment;
this(string type, string identifier)
{
super(identifier, type);
/* Weighted as 2 */
weight = 2;
}
public void addAssignment(VariableAssignment assignment)
{
this.assignment = assignment;
}
public VariableAssignment getAssignment()
{
return assignment;
}
public override string toString()
{
return "Variable (Ident: "~name~", Type: "~type~")";
}
}
public import compiler.symbols.expressions;
/**
* TODO: Rename to `VariableDeclarationAssignment`
*/
public class VariableAssignment : Statement
{
private Expression expression;
private Variable variable;
this(Expression expression)
{
this.expression = expression;
}
public Expression getExpression()
{
return expression;
}
public Variable getVariable()
{
return variable;
}
public void setVariable(Variable variable)
{
this.variable = variable;
}
public override string toString()
{
return "[varAssignDec'd: To: "~variable.toString()~"]";
}
}
/**
* TODO: Rename to ``
*/
public class VariableAssignmentStdAlone : Statement
{
private Expression expression;
private string varName;
this(string varName, Expression expression)
{
this.varName = varName;
this.expression = expression;
/* Weighted as 2 */
weight = 2;
}
public Expression getExpression()
{
return expression;
}
public string getVariableName()
{
return varName;
}
public override string toString()
{
return "[varAssignStdAlone: To: "~varName~"]";
}
}
public class IdentExpression : Expression
{
/* name */
private string name;
this(string name)
{
this.name = name;
}
public string getName()
{
return name;
}
public void updateName(string newName)
{
name = newName;
}
}
public class VariableExpression : IdentExpression
{
this(string identifier)
{
super(identifier);
}
import compiler.typecheck.core;
public override string evaluateType(TypeChecker typeChecker, Container c)
{
string type;
return null;
}
public override string toString()
{
return "[varExp: "~getName()~"]";
}
}
public class Call : IdentExpression
{
this(string ident)
{
super(ident);
}
}
public final class FunctionCall : Call
{
/* Argument list */
private Expression[] arguments;
this(string functionName, Expression[] arguments)
{
super(functionName);
this.arguments = arguments;
}
public override string toString()
{
return super.toString()~" "~name~"()";
}
public Expression[] getCallArguments()
{
return arguments;
}
}
public final class ReturnStmt : Statement
{
// The Expression being returned
private Expression returnExpression;
this(Expression returnExpression)
{
this.returnExpression = returnExpression;
}
public Expression getReturnExpression()
{
return returnExpression;
}
}