diff --git a/source/tlang/compiler/codegen/emit/dgen.d b/source/tlang/compiler/codegen/emit/dgen.d index 77b6063a..9ef59601 100644 --- a/source/tlang/compiler/codegen/emit/dgen.d +++ b/source/tlang/compiler/codegen/emit/dgen.d @@ -386,6 +386,21 @@ public final class DCodeEmitter : CodeEmitter emit ~= transform(rhsAssExprInstr)~";"; + return emit; + } + /** + * Discard instruction (DiscardInstruction) + */ + else if(cast(DiscardInstruction)instruction) + { + DiscardInstruction discardInstruction = cast(DiscardInstruction)instruction; + Value valueInstruction = discardInstruction.getExpressionInstruction(); + + string emit; + + /* Transform the expression */ + emit ~= transform(valueInstruction)~";"; + return emit; } diff --git a/source/tlang/compiler/codegen/instruction.d b/source/tlang/compiler/codegen/instruction.d index ca8ee669..f1d23d74 100644 --- a/source/tlang/compiler/codegen/instruction.d +++ b/source/tlang/compiler/codegen/instruction.d @@ -439,4 +439,19 @@ public final class PointerDereferenceAssignmentInstruction : Instruction { return derefCount; } +} + +public final class DiscardInstruction : Instruction +{ + private Value exprInstr; + + this(Value exprInstr) + { + this.exprInstr = exprInstr; + } + + public Value getExpressionInstruction() + { + return exprInstr; + } } \ No newline at end of file diff --git a/source/tlang/compiler/parsing/core.d b/source/tlang/compiler/parsing/core.d index b1725871..7d5e1c81 100644 --- a/source/tlang/compiler/parsing/core.d +++ b/source/tlang/compiler/parsing/core.d @@ -963,7 +963,7 @@ public final class Parser * * TODO: Remove discard and implement the needed mirrors */ - private Expression parseDiscard() + private DiscardStatement parseDiscard() { /* Consume the `discard` */ nextToken(); @@ -975,7 +975,10 @@ public final class Parser expect(SymbolType.SEMICOLON, getCurrentToken()); nextToken(); - return expression; + /* Create a `discard` statement */ + DiscardStatement discardStatement = new DiscardStatement(expression); + + return discardStatement; } /** @@ -1648,6 +1651,12 @@ public final class Parser /* Parse the return statement */ statement = parseReturn(); } + /* If it is a `discard` statement */ + else if(symbol == SymbolType.DISCARD) + { + /* Parse the discard statement */ + statement = parseDiscard(); + } /* If it is a dereference assigment (a `*`) */ else if(symbol == SymbolType.STAR) { @@ -1735,8 +1744,6 @@ public final class Parser Module modulle; - /* TODO: Do parsing here */ - /* Expect `module` and module name and consume them (and `;`) */ expect(SymbolType.MODULE, getCurrentToken()); nextToken(); @@ -1819,9 +1826,10 @@ public final class Parser /* If it is a `discard` statement */ else if(symbol == SymbolType.DISCARD) { - Expression expression = parseDiscard(); + /* Parse the3 discard statement */ + Statement statement = parseDiscard(); - modulle.addStatement(expression); + modulle.addStatement(statement); } else { @@ -2030,6 +2038,66 @@ class myClass2 } } +/** + * Discard statement test case + */ +unittest +{ + import std.stdio; + import compiler.lexer; + import compiler.typecheck.core; + + + string sourceCode = ` +module parser_discard; + +void function() +{ + discard function(); +} +`; + + + Lexer currentLexer = new Lexer(sourceCode); + assert(currentLexer.performLex()); + + + Parser parser = new Parser(currentLexer.getTokens()); + + try + { + Module modulle = parser.parse(); + + /* Module name must be parser_discard */ + assert(cmp(modulle.getName(), "parser_discard")==0); + TypeChecker tc = new TypeChecker(modulle); + + + /* Find the function named `function` */ + Entity func = tc.getResolver().resolveBest(modulle, "function"); + assert(func); + assert(cast(Function)func); // Ensure it is a Funciton + + /* Get the function's body */ + Container funcContainer = cast(Container)func; + assert(funcContainer); + Statement[] functionStatements = funcContainer.getStatements(); + assert(functionStatements.length == 1); + + /* First statement should be a discard */ + DiscardStatement discard = cast(DiscardStatement)functionStatements[0]; + assert(discard); + + /* The statement being discarded should be a function call */ + FunctionCall functionCall = cast(FunctionCall)discard.getExpression(); + assert(functionCall); + } + catch(TError e) + { + assert(false); + } +} + /** * Function definition test case */ @@ -2062,7 +2130,7 @@ int myFunction(int i, int j) { Module modulle = parser.parse(); - /* Module name must be parser_while */ + /* Module name must be parser_function_def */ assert(cmp(modulle.getName(), "parser_function_def")==0); TypeChecker tc = new TypeChecker(modulle); @@ -2245,7 +2313,7 @@ int thing() { Module modulle = parser.parse(); - /* Module name must be parser_while */ + /* Module name must be simple_pointer */ assert(cmp(modulle.getName(), "simple_pointer")==0); TypeChecker tc = new TypeChecker(modulle); @@ -2329,7 +2397,7 @@ void function() { Module modulle = parser.parse(); - /* Module name must be parser_while */ + /* Module name must be parser_for */ assert(cmp(modulle.getName(), "parser_for")==0); TypeChecker tc = new TypeChecker(modulle); @@ -2451,7 +2519,7 @@ void function() { Module modulle = parser.parse(); - /* Module name must be parser_while */ + /* Module name must be parser_if */ assert(cmp(modulle.getName(), "parser_if")==0); TypeChecker tc = new TypeChecker(modulle); diff --git a/source/tlang/compiler/symbols/data.d b/source/tlang/compiler/symbols/data.d index adda5dcd..f73e1c1a 100644 --- a/source/tlang/compiler/symbols/data.d +++ b/source/tlang/compiler/symbols/data.d @@ -872,4 +872,27 @@ public final class Branch : Entity, Container { return "Branch"; } +} + +public final class DiscardStatement : Statement +{ + private Expression expression; + + this(Expression expression) + { + this.expression = expression; + + /* Weighted as 2 */ + weight = 2; + } + + public Expression getExpression() + { + return expression; + } + + public override string toString() + { + return "[DiscardStatement: (Exp: "~expression.toString()~")]"; + } } \ No newline at end of file diff --git a/source/tlang/compiler/typecheck/core.d b/source/tlang/compiler/typecheck/core.d index 3e10e487..e2a6bc98 100644 --- a/source/tlang/compiler/typecheck/core.d +++ b/source/tlang/compiler/typecheck/core.d @@ -1097,6 +1097,29 @@ public final class TypeChecker pointerDereferenceAssignmentInstruction.context = ptrDerefAss.context; addInstrB(pointerDereferenceAssignmentInstruction); } + /** + * Discard statement (DiscardStatement) + */ + else if(cast(DiscardStatement)statement) + { + DiscardStatement discardStatement = cast(DiscardStatement)statement; + + /* Pop off a Value instruction */ + Value exprInstr = cast(Value)popInstr(); + assert(exprInstr); + + /** + * Code gen + * + * 1. Create the DiscardInstruction containing the Value instruction + * `exprInstr` + * 2. Set the context + * 3. Add the instruction + */ + DiscardInstruction discardInstruction = new DiscardInstruction(exprInstr); + discardInstruction.context = discardStatement.context; + addInstrB(discardInstruction); + } /* Case of no matches */ else { diff --git a/source/tlang/compiler/typecheck/dependency/core.d b/source/tlang/compiler/typecheck/dependency/core.d index 0953ebe3..f0d9998f 100644 --- a/source/tlang/compiler/typecheck/dependency/core.d +++ b/source/tlang/compiler/typecheck/dependency/core.d @@ -1497,6 +1497,25 @@ public class DNodeGenerator return ptrAssDerefDNode; } + /** + * Discard statement (DiscardStatement) + */ + else if(cast(DiscardStatement)entity) + { + DiscardStatement discardStatement = cast(DiscardStatement)entity; + discardStatement.setContext(context); + DNode discardStatementDNode = pool(discardStatement); + + gprintln("Implement discard statement!", DebugType.ERROR); + + /* Pass the expression */ + Expression discardExpression = discardStatement.getExpression(); + DNode discardExpresionDNode = expressionPass(discardExpression, context); + discardStatementDNode.needs(discardExpresionDNode); + + + return discardStatementDNode; + } return null; } diff --git a/source/tlang/testing/simple_discard.t b/source/tlang/testing/simple_discard.t new file mode 100644 index 00000000..90329ff3 --- /dev/null +++ b/source/tlang/testing/simple_discard.t @@ -0,0 +1,11 @@ +module simple_discard; + +void hello() +{ + +} + +int myEntry() +{ + discard hello(); +}