From 1ea77c3fb07c46a9293a09e1f35402ab0f7581df Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Mon, 30 Jan 2023 19:08:48 +0200 Subject: [PATCH] DGen - Added a note to fix the way we do standalone variable assignments, we should embed them in a way similiar to that of `VariableDeclaration`'s (with assignments enabled) TypeChecker/Codegen - Initial work on handling `IntegerLiteral` parser node types added VariableAssignmentNode - Push the type onto the typestack and make it the type fo what was popped (relates to the embedded instruction) StaticVariableDeclaration - Initial work on type coercion begun VariableAssignmentStdAlone - Make handling of this fail now till we do the dependency node fix up for this DGen - Added debug prints which until they stop segfaulting we will know if everything is okay --- source/tlang/compiler/codegen/emit/dgen.d | 7 + source/tlang/compiler/typecheck/core.d | 127 ++++++++++++++++-- .../compiler/typecheck/dependency/core.d | 2 + 3 files changed, 127 insertions(+), 9 deletions(-) diff --git a/source/tlang/compiler/codegen/emit/dgen.d b/source/tlang/compiler/codegen/emit/dgen.d index 48dbc273..ef62e263 100644 --- a/source/tlang/compiler/codegen/emit/dgen.d +++ b/source/tlang/compiler/codegen/emit/dgen.d @@ -127,6 +127,13 @@ public final class DCodeEmitter : CodeEmitter gprintln("Is ContextNull?: "~to!(string)(context is null)); gprintln("Wazza contect: "~to!(string)(context.container)); auto typedEntityVariable = typeChecker.getResolver().resolveBest(context.getContainer(), varAs.varName); //TODO: Remove `auto` + gprintln("Hi"~to!(string)(varAs)); + gprintln("Hi"~to!(string)(varAs.data)); + gprintln("Hi"~to!(string)(varAs.data.type)); + + // NOTE: For tetsing issue #94 coercion (remove when done) + string typeName = (cast(Type)varAs.data.type).getName(); + gprintln("VariableAssignmentInstr: The data to assign's type is: "~typeName); /* If it is not external */ diff --git a/source/tlang/compiler/typecheck/core.d b/source/tlang/compiler/typecheck/core.d index 096d19d7..03b140ff 100644 --- a/source/tlang/compiler/typecheck/core.d +++ b/source/tlang/compiler/typecheck/core.d @@ -425,24 +425,35 @@ public final class TypeChecker { IntegerLiteral integerLitreal = cast(IntegerLiteral)statement; - - ulong i = to!(ulong)(integerLitreal.getNumber()); + /** + * Determine the type of this value instruction by finding + * the encoding of the integer literal (part of doing issue #94) + */ + Type literalEncodingType; + if(integerLitreal.getEncoding() == IntegerLiteralEncoding.SIGNED_INTEGER) + { + literalEncodingType = getType(modulle, "int"); + } + assert(literalEncodingType); // TODO: Insert getEncoding stuff here - LiteralValue litValInstr = new LiteralValue(i, 4); + LiteralValue litValInstr = new LiteralValue(integerLitreal.getNumber(), literalEncodingType); valInstr = litValInstr; // TODO: Insert get encoding stuff here - addType(getType(modulle, "int")); + addType(literalEncodingType); } /* Generate a LiteralValueFloat (FloatingLiteral) */ else { FloatingLiteral floatLiteral = cast(FloatingLiteral)statement; - double i = to!(float)(floatLiteral.getNumber()); - LiteralValueFloat litValInstr = new LiteralValueFloat(i, 4); + gprintln("We haven't sorted ouyt literal encoding for floating onts yet (null below hey!)", DebugType.ERROR); + Type bruhType = null; + assert(bruhType); + + LiteralValueFloat litValInstr = new LiteralValueFloat(floatLiteral.getNumber(), bruhType); valInstr = litValInstr; @@ -810,13 +821,25 @@ public final class TypeChecker * 3. Generate VarAssignInstruction with Value-instruction * 4. Set the VarAssignInstr's Context to that of the Variable assigning to */ - Instruction valueInstr = popInstr(); + Instruction instr = popInstr(); + assert(instr); + Value valueInstr = cast(Value)instr; + assert(valueInstr); gprintln("VaribleAssignmentNode(): Just popped off valInstr?: "~to!(string)(valueInstr), DebugType.WARNING); + + + Type rightHandType = popType(); + gprintln("RightHandType (assignment): "~to!(string)(rightHandType)); + + gprintln(valueInstr is null);/*TODO: FUnc calls not implemented? Then is null for simple_1.t */ VariableAssignmentInstr varAssInstr = new VariableAssignmentInstr(variableName, valueInstr); varAssInstr.context = variableAssignmentContext; addInstr(varAssInstr); + + // Push the type we popped (as the Value Instr's type is our VarAssNode type) + addType(rightHandType); } /* TODO: Add support */ /** @@ -840,18 +863,86 @@ public final class TypeChecker gprintln("HELLO FELLA (name): "~variableName); + Type variableDeclarationType = getType(variablePNode.context.container, variablePNode.getType()); + // CHeck if this variable declaration has an assignment attached VariableAssignmentInstr assignmentInstr; if(variablePNode.getAssignment()) { + // TODO: A popType() should be done here techncially, IF we do this then it + // ... must be pushed by VariableAssigmnetNode + Type assignmentType = popType(); + assert(assignmentType); + Instruction poppedInstr = popInstr(); assignmentInstr = cast(VariableAssignmentInstr)poppedInstr; assert(assignmentInstr); + + + // TODO: We should add a typecheck here where we update the type of the valInstr if it is of + // ... type NumberLiteral and coerce it to the variable referred to by the VariableAssignment + // ... see issue #94 part on "Coercion" + // If the types match then everything is fine + if(isSameType(variableDeclarationType, assignmentType)) + { + gprintln("Variable's declared type ('"~to!(string)(variableDeclarationType)~"') matches that of assignment expression's type ('"~to!(string)(assignmentType)~"')"); + } + // If the types do not match + else + { + // Obtain the embedded instruction of the variable assignment instruction + assert(assignmentInstr.data); + Value embeddedInstruction = cast(Value)assignmentInstr.data; + assert(embeddedInstruction); + + // If it is a LiteralValue (integer literal) (support for issue #94) + if(cast(LiteralValue)embeddedInstruction) + { + // TODO: Add a check for if these types are both atleast integral (as in the Variable's type) + // ... THEN (TODO): Check if range makes sense + bool isIntegral = !(cast(Integer)variableDeclarationType is null); // Integrality check + + if(isIntegral) + { + bool isCoercible = true; // TODO: Range check + + if(isCoercible) + { + // TODO: Coerce here by changing the embedded instruction's type (I think this makes sense) + // ... as during code emit that is what will be hoisted out and checked regarding its type + // NOTE: Referrring to same type should not be a problem (see #96 Question 1) + embeddedInstruction.type = variableDeclarationType; + } + else + { + gprintln("Not coercible (range violation)", DebugType.ERROR); + assert(false); + } + } + else + { + gprintln("Not coercible (lacking integral var type)", DebugType.ERROR); + assert(false); + } + + } + // If it is a LiteralFloatingValue (support for issue #94) + else if(cast(LiteralValue)embeddedInstruction) + { + gprintln("Coercion not yet supported for floating point literals", DebugType.ERROR); + assert(false); + } + else + { + gprintln("MISMATCH: Variable's declared type ('"~to!(string)(variableDeclarationType)~"') does not match that of assignment expression's type ('"~to!(string)(assignmentType)~"')", DebugType.ERROR); + assert(false); + } + } } - Type variableDeclarationType = getType(variablePNode.context.container, variablePNode.getType()); + VariableDeclaration varDecInstr = new VariableDeclaration(variableName, 4, variableDeclarationType, assignmentInstr); @@ -899,7 +990,22 @@ public final class TypeChecker * 2. Pop Value-instruction * 3. Generate VarAssignInstruction with Value-instruction */ - Instruction valueInstr = popInstr(); + Instruction instr = popInstr(); + assert(instr); + Value valueInstr = cast(Value)instr; + assert(valueInstr); + + // TODO: A popType() should be done here techncially, IF we do this then it + // ... must be pushed by VariableAssigmnetNode + Type assignmentType = popType(); + assert(assignmentType); + + + gprintln("Instruction popped: "~to!(string)(instr)); + gprintln("Type popped: "~to!(string)(assignmentType)); + + + // TODO: WOAH! We should be consuming here though!!! not making!?!? VariableAssignmentInstr vAInstr = new VariableAssignmentInstr(variableName, valueInstr); /* Set the VariableAssigmmentInstruction's context to that of the stdalone entity */ @@ -908,6 +1014,9 @@ public final class TypeChecker addInstrB(vAInstr); gprintln("VariableAssignmentStdAlone", DebugType.ERROR); + + gprintln("VariableAssignmentStdAlone needs some reworking", DebugType.ERROR); + assert(false); } /** * Return statement (ReturnStmt) diff --git a/source/tlang/compiler/typecheck/dependency/core.d b/source/tlang/compiler/typecheck/dependency/core.d index 73ae2e56..ed02bf12 100644 --- a/source/tlang/compiler/typecheck/dependency/core.d +++ b/source/tlang/compiler/typecheck/dependency/core.d @@ -1333,6 +1333,8 @@ public class DNodeGenerator DNode vStdAlDNode = pool(vAsStdAl); // node.needs(vStdAlDNode); + // FIXME: Convert to using a VariableAssignmentNode (for the sake of uniformity) + DNode expression = expressionPass(vAsStdAl.getExpression(), context); vStdAlDNode.needs(expression);