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.check : getCharacter;
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
{
@ -44,6 +44,48 @@ public final class DCodeEmitter : CodeEmitter
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)
{
writeln("\n");
@ -120,12 +162,12 @@ public final class DCodeEmitter : CodeEmitter
VariableAssignmentInstr varAssInstr = varDecInstr.getAssignmentInstr();
// 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 */
else if(cast(LiteralValue)instruction)
@ -423,7 +465,7 @@ public final class DCodeEmitter : CodeEmitter
if(cast(Primitive)castingTo)
{
/* Add the actual cast */
emit ~= "("~to!(string)(castingTo)~")";
emit ~= "("~typeTransform(castingTo)~")";
/* The expression being casted */
emit ~= transform(uncastedInstruction);
@ -450,6 +492,9 @@ public final class DCodeEmitter : CodeEmitter
// 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
// Emit standard integer header import
emitStdint();
// Emit static allocation code
emitStaticAllocations();
@ -552,8 +597,10 @@ public final class DCodeEmitter : CodeEmitter
{
string signature;
Type returnType = typeChecker.getType(func.context.container, func.getType());
// <type> <functionName> (
signature = func.getType()~" "~func.getName()~"(";
signature = typeTransform(returnType)~" "~func.getName()~"(";
// Generate parameter list
if(func.hasParams())
@ -651,6 +698,11 @@ public final class DCodeEmitter : CodeEmitter
file.writeln();
}
private void emitStdint()
{
file.writeln("#include<stdint.h>");
}
private void emitEntryPoint()
{
//TODO: Implement me

View File

@ -79,13 +79,13 @@ public final class VariableDeclaration : StorageDeclaration
public const byte length;
/* Type of the variable being declared */
public const string varType;
public const Type varType;
/* VariableAssignmentInstr-instruction to be assigned */
private VariableAssignmentInstr varAssInstr;
//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.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 */
varDecInstr.context = variablePNode.context;

View File

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