Run type checker system
WIP: Resolution of names Reworked type hierachy for Enity in relation to Function, Variable and Class Updated test casedevelop_before_lexer_parser_merge_parseName
parent
69afebbe04
commit
5c8e30f1f5
|
@ -43,5 +43,6 @@ void beginCompilation(string[] sourceFiles)
|
|||
|
||||
gprintln("Type checking and symbol resolution...");
|
||||
TypeChecker typeChecker = new TypeChecker(program);
|
||||
typeChecker.check();
|
||||
}
|
||||
}
|
|
@ -625,7 +625,7 @@ public final class Parser
|
|||
gprintln("ParseTypedDec: VariableDeclarationWithAssingment: (Type: "
|
||||
~ type ~ ", Identifier: " ~ identifier ~ ")", DebugType.WARNING);
|
||||
|
||||
Variable variable = new Variable(identifier, type);
|
||||
Variable variable = new Variable(type, identifier);
|
||||
variable.addAssignment(varAssign);
|
||||
|
||||
generated = variable;
|
||||
|
|
|
@ -391,6 +391,14 @@ public class Entity : Statement
|
|||
/* Accesor type */
|
||||
private AccessorType accessorType = AccessorType.PUBLIC;
|
||||
|
||||
/* Name of the entity (class's name, function's name, variable's name) */
|
||||
private string name;
|
||||
|
||||
this(string name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setAccessorType(AccessorType accessorType)
|
||||
{
|
||||
this.accessorType = accessorType;
|
||||
|
@ -400,15 +408,26 @@ public class Entity : Statement
|
|||
{
|
||||
return accessorType;
|
||||
}
|
||||
|
||||
public string getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: DO we need intermediary class, TypedEntity */
|
||||
public class TypedEntity : Entity {}
|
||||
public class TypedEntity : Entity
|
||||
{
|
||||
/* TODO: Return type/variable type in here (do what we did for ENtity with `name/identifier`) */
|
||||
this(string name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class Clazz : Entity
|
||||
{
|
||||
private string name;
|
||||
private string parentClass;
|
||||
private string[] interfaces;
|
||||
|
||||
|
@ -416,7 +435,7 @@ public class Clazz : Entity
|
|||
|
||||
this(string name)
|
||||
{
|
||||
this.name = name;
|
||||
super(name);
|
||||
}
|
||||
|
||||
public void addStatements(Statement[] statements)
|
||||
|
@ -424,6 +443,25 @@ public class Clazz : Entity
|
|||
this.statements ~= statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks all added Statement[]s and makes sure they
|
||||
* are either of type Variable, Function or Class
|
||||
*/
|
||||
public bool isFine()
|
||||
{
|
||||
foreach(Statement statement; statements)
|
||||
{
|
||||
if(typeid(statement) != typeid(Variable) &&
|
||||
typeid(statement) != typeid(Function) &&
|
||||
typeid(statement) != typeid(Clazz))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string toString()
|
||||
{
|
||||
return "Class (Name: "~name~", Parent: "~parentClass~", Interfaces: "~to!(string)(interfaces)~")";
|
||||
|
@ -438,14 +476,13 @@ public class ArgumentList
|
|||
|
||||
public class Function : TypedEntity
|
||||
{
|
||||
private string name;
|
||||
private string returnType;
|
||||
private Variable[] params;
|
||||
private Statement[] bodyStatements;
|
||||
|
||||
this(string name, string returnType, Statement[] bodyStatements, Variable[] args)
|
||||
{
|
||||
this.name = name;
|
||||
super(name);
|
||||
this.returnType = returnType;
|
||||
this.bodyStatements = bodyStatements;
|
||||
this.params = args;
|
||||
|
@ -495,14 +532,13 @@ public class Function : TypedEntity
|
|||
public class Variable : TypedEntity
|
||||
{
|
||||
private string type;
|
||||
private string identifier;
|
||||
|
||||
private VariableAssignment assignment;
|
||||
|
||||
this(string type, string identifier)
|
||||
{
|
||||
super(identifier);
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public void addAssignment(VariableAssignment assignment)
|
||||
|
@ -522,7 +558,7 @@ public class Variable : TypedEntity
|
|||
|
||||
public override string toString()
|
||||
{
|
||||
return "Variable (Ident: "~identifier~", Type: "~type~")";
|
||||
return "Variable (Ident: "~name~", Type: "~type~")";
|
||||
}
|
||||
|
||||
/* Code gen */
|
||||
|
|
|
@ -10,13 +10,88 @@ import std.conv : to;
|
|||
*/
|
||||
public final class TypeChecker
|
||||
{
|
||||
private Program program;
|
||||
|
||||
this(Program program)
|
||||
{
|
||||
this.program = program;
|
||||
|
||||
import std.stdio;
|
||||
writeln("Got globals: "~to!(string)(program.getAllOf(new Variable(null, null))));
|
||||
writeln("Got functions: "~to!(string)(program.getAllOf(new Function(null, null, null, null))));
|
||||
writeln("Got classes: "~to!(string)(program.getAllOf(new Clazz(null))));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will walk, recursively, through
|
||||
* each Statement at the top-level and generate
|
||||
* names of declared items in a global array
|
||||
*
|
||||
* This is top-level, iterative then recursive within
|
||||
* each iteration
|
||||
*
|
||||
* The point of this is to know of all symbols
|
||||
* that exist so that we can do a second pass
|
||||
* and see if symbols in use (declaration does
|
||||
* not count as "use") are infact valid references
|
||||
*/
|
||||
public void nameResolution()
|
||||
{
|
||||
string[] names;
|
||||
|
||||
foreach(Statement statement; program.getAllOf(new Statement()))
|
||||
{
|
||||
/* TODO: Add container name */
|
||||
// names ~=
|
||||
// string[] receivedNameSet = resolveNames(statement);
|
||||
}
|
||||
}
|
||||
|
||||
private string[] resolveNames(Statement statement)
|
||||
{
|
||||
// string containerName
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void check()
|
||||
{
|
||||
checkDuplicateTopLevel();
|
||||
|
||||
/* TODO: Process globals */
|
||||
/* TODO: Process classes */
|
||||
/* TODO: Process functions */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Ensures that at the top-level there are no duplicate names
|
||||
*/
|
||||
private bool checkDuplicateTopLevel()
|
||||
{
|
||||
import misc.utils;
|
||||
import compiler.parser : Parser;
|
||||
|
||||
/* List of names travsersed so far */
|
||||
string[] names;
|
||||
|
||||
/* Add all global variables */
|
||||
foreach(Variable variable; program.getAllOf(new Variable(null, null)))
|
||||
{
|
||||
string name = variable.getName();
|
||||
|
||||
if(isPresent(names, name))
|
||||
{
|
||||
Parser.expect("Bruh duplicate var"~name);
|
||||
}
|
||||
else
|
||||
{
|
||||
names ~= variable.getName();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
module misc.utils;
|
||||
|
||||
import std.string : cmp;
|
||||
|
||||
public bool isPresent(string[] arr, string t)
|
||||
{
|
||||
foreach(string j; arr)
|
||||
{
|
||||
if(cmp(j, t) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -5,8 +5,8 @@ int x;
|
|||
ubyte y;
|
||||
|
||||
public ubyte k = 1;
|
||||
private ubyte k = 1;
|
||||
protected ubyte k = 1;
|
||||
private ubyte k2 = 1;
|
||||
protected ubyte k3 = -1;
|
||||
|
||||
|
||||
public class clazz1
|
||||
|
|
Loading…
Reference in New Issue