Typechecker

- Extract the `Variable`'s `Type` object and pass it into the instruction constructor

Instruction

- `VariableDeclaration` instruction now takes in an instance of `Type` upon construction

Dependency

- Fixed null pointer exception where Function did not have its `context` set

DGen

- Added `typeTransform(Type)` to transform the given types into the C equivalent
- Variable declarations use `typeTransform()` now
- Casting instructions use `typeTransform()` now
- Added `emitStdint()` to emit `#include<stdint.h>` as part of header in generated C code
- `generateSignature(Function)` now uses `typeTransform()` for the return type emit
This commit is contained in:
Tristan B. Velloza Kildaire 2023-01-15 12:36:54 +02:00
parent b7b30db391
commit b1d168ab44
4 changed files with 66 additions and 9 deletions

View File

@ -17,7 +17,7 @@ import compiler.codegen.mapper : SymbolMapper;
import compiler.symbols.data : SymbolType, Variable, Function, VariableParameter; import compiler.symbols.data : SymbolType, Variable, Function, VariableParameter;
import compiler.symbols.check : getCharacter; import compiler.symbols.check : getCharacter;
import misc.utils : Stack; import misc.utils : Stack;
import compiler.symbols.typing.core : Type, Primitive; import compiler.symbols.typing.core : Type, Primitive, Integer, Void;
public final class DCodeEmitter : CodeEmitter public final class DCodeEmitter : CodeEmitter
{ {
@ -44,6 +44,48 @@ public final class DCodeEmitter : CodeEmitter
return tabStr; return tabStr;
} }
/**
* Given an instance of a Type this will transform it to a string
*
* Params:
* typeIn = The Type to transform
*
* Returns: The string representation of the transformed type
*/
public string typeTransform(Type typeIn)
{
string stringRepr;
// TODO: Some types will ident transform
/* Integral types transformation */
if(cast(Integer)typeIn)
{
Integer integralType = cast(Integer)typeIn;
/* u<>_t or <>_t (Determine signedness) */
string typeString = integralType.isSigned() ? "int" : "uint";
/* Width of integer */
typeString ~= to!(string)(integralType.getSize()*8);
/* Trailing `_t` */
typeString ~= "_t";
return typeString;
}
/* Void type */
else if(cast(Void)typeIn)
{
return "void";
}
gprintln("Type transform unimplemented");
assert(false);
// return stringRepr;
}
public override string transform(const Instruction instruction) public override string transform(const Instruction instruction)
{ {
writeln("\n"); writeln("\n");
@ -120,12 +162,12 @@ public final class DCodeEmitter : CodeEmitter
VariableAssignmentInstr varAssInstr = varDecInstr.getAssignmentInstr(); VariableAssignmentInstr varAssInstr = varDecInstr.getAssignmentInstr();
// Generate the code to emit // Generate the code to emit
return varDecInstr.varType~" "~renamedSymbol~" = "~transform(varAssInstr)~";"; return typeTransform(cast(Type)varDecInstr.varType)~" "~renamedSymbol~" = "~transform(varAssInstr)~";";
} }
return varDecInstr.varType~" "~renamedSymbol~";"; return typeTransform(cast(Type)varDecInstr.varType)~" "~renamedSymbol~";";
} }
/* LiteralValue */ /* LiteralValue */
else if(cast(LiteralValue)instruction) else if(cast(LiteralValue)instruction)
@ -423,7 +465,7 @@ public final class DCodeEmitter : CodeEmitter
if(cast(Primitive)castingTo) if(cast(Primitive)castingTo)
{ {
/* Add the actual cast */ /* Add the actual cast */
emit ~= "("~to!(string)(castingTo)~")"; emit ~= "("~typeTransform(castingTo)~")";
/* The expression being casted */ /* The expression being casted */
emit ~= transform(uncastedInstruction); emit ~= transform(uncastedInstruction);
@ -450,6 +492,9 @@ public final class DCodeEmitter : CodeEmitter
// Emit header comment (NOTE: Change this to a useful piece of text) // Emit header comment (NOTE: Change this to a useful piece of text)
emitHeaderComment("Place any extra information by code generator here"); // NOTE: We can pass a string with extra information to it if we want to emitHeaderComment("Place any extra information by code generator here"); // NOTE: We can pass a string with extra information to it if we want to
// Emit standard integer header import
emitStdint();
// Emit static allocation code // Emit static allocation code
emitStaticAllocations(); emitStaticAllocations();
@ -552,8 +597,10 @@ public final class DCodeEmitter : CodeEmitter
{ {
string signature; string signature;
Type returnType = typeChecker.getType(func.context.container, func.getType());
// <type> <functionName> ( // <type> <functionName> (
signature = func.getType()~" "~func.getName()~"("; signature = typeTransform(returnType)~" "~func.getName()~"(";
// Generate parameter list // Generate parameter list
if(func.hasParams()) if(func.hasParams())
@ -651,6 +698,11 @@ public final class DCodeEmitter : CodeEmitter
file.writeln(); file.writeln();
} }
private void emitStdint()
{
file.writeln("#include<stdint.h>");
}
private void emitEntryPoint() private void emitEntryPoint()
{ {
//TODO: Implement me //TODO: Implement me

View File

@ -79,13 +79,13 @@ public final class VariableDeclaration : StorageDeclaration
public const byte length; public const byte length;
/* Type of the variable being declared */ /* Type of the variable being declared */
public const string varType; public const Type varType;
/* VariableAssignmentInstr-instruction to be assigned */ /* VariableAssignmentInstr-instruction to be assigned */
private VariableAssignmentInstr varAssInstr; private VariableAssignmentInstr varAssInstr;
//TODO: This must take in type information //TODO: This must take in type information
this(string varName, byte len, string varType, VariableAssignmentInstr varAssInstr) this(string varName, byte len, Type varType, VariableAssignmentInstr varAssInstr)
{ {
this.varName = varName; this.varName = varName;
this.length = len; this.length = len;

View File

@ -843,7 +843,9 @@ public final class TypeChecker
} }
VariableDeclaration varDecInstr = new VariableDeclaration(variableName, 4, variablePNode.getType(), assignmentInstr); Type variableDeclarationType = getType(variablePNode.context.container, variablePNode.getType());
VariableDeclaration varDecInstr = new VariableDeclaration(variableName, 4, variableDeclarationType, assignmentInstr);
/* NEW CODE (9th November 2021) Set the context */ /* NEW CODE (9th November 2021) Set the context */
varDecInstr.context = variablePNode.context; varDecInstr.context = variablePNode.context;

View File

@ -1304,9 +1304,12 @@ public class DNodeGenerator
*/ */
else if(cast(Function)entity) else if(cast(Function)entity)
{ {
// /* Grab the function */ /* Grab the function */
Function func = cast(Function)entity; Function func = cast(Function)entity;
/* Don't forget to set its context */
func.context = context;
/* Add funtion definition */ /* Add funtion definition */
gprintln("Hello"); gprintln("Hello");
addFunctionDef(tc, func); addFunctionDef(tc, func);