Run type checker system

WIP: Resolution of names

Reworked type hierachy for Enity in relation to Function, Variable and Class

Updated test case
develop_before_lexer_parser_merge_parseName
Tristan B. Kildaire 2021-03-23 21:35:13 +02:00
parent 69afebbe04
commit 5c8e30f1f5
6 changed files with 139 additions and 11 deletions

View File

@ -43,5 +43,6 @@ void beginCompilation(string[] sourceFiles)
gprintln("Type checking and symbol resolution...");
TypeChecker typeChecker = new TypeChecker(program);
typeChecker.check();
}
}

View File

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

View File

@ -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 */

View File

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

View File

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

View File

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