From b1d168ab44b6de6c08c7f922c56ebaf4e3895df0 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Sun, 15 Jan 2023 12:36:54 +0200 Subject: [PATCH] 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` as part of header in generated C code - `generateSignature(Function)` now uses `typeTransform()` for the return type emit --- source/tlang/compiler/codegen/emit/dgen.d | 62 +++++++++++++++++-- source/tlang/compiler/codegen/instruction.d | 4 +- source/tlang/compiler/typecheck/core.d | 4 +- .../compiler/typecheck/dependency/core.d | 5 +- 4 files changed, 66 insertions(+), 9 deletions(-) diff --git a/source/tlang/compiler/codegen/emit/dgen.d b/source/tlang/compiler/codegen/emit/dgen.d index 80b24f8..45f0424 100644 --- a/source/tlang/compiler/codegen/emit/dgen.d +++ b/source/tlang/compiler/codegen/emit/dgen.d @@ -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()); + // ( - 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"); + } + private void emitEntryPoint() { //TODO: Implement me diff --git a/source/tlang/compiler/codegen/instruction.d b/source/tlang/compiler/codegen/instruction.d index 99a578e..104ecaf 100644 --- a/source/tlang/compiler/codegen/instruction.d +++ b/source/tlang/compiler/codegen/instruction.d @@ -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; diff --git a/source/tlang/compiler/typecheck/core.d b/source/tlang/compiler/typecheck/core.d index 983811c..7bfdf4d 100644 --- a/source/tlang/compiler/typecheck/core.d +++ b/source/tlang/compiler/typecheck/core.d @@ -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; diff --git a/source/tlang/compiler/typecheck/dependency/core.d b/source/tlang/compiler/typecheck/dependency/core.d index ee7c3be..45b3bd6 100644 --- a/source/tlang/compiler/typecheck/dependency/core.d +++ b/source/tlang/compiler/typecheck/dependency/core.d @@ -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);