Function return statement #7

Closed
opened 2022-10-04 11:03:17 +01:00 by deavmi · 12 comments
Owner

Add support for function return statements.

  • Parser support for return
  • Code generation
  • Emitting
    • transform() implementation
    • Testing of emitted code
Add support for function `return` statements. - [x] Parser support for `return` - [x] Code generation - [x] Emitting - [x] `transform()` implementation - [x] Testing of emitted code
deavmi added this to the Parser project 2022-10-04 11:03:17 +01:00
deavmi added the
typing
label 2022-10-04 11:03:22 +01:00
deavmi modified the project from Parser to Dependency tree, type-checking and codegen 2022-10-04 11:03:49 +01:00
deavmi modified the project from Dependency tree, type-checking and codegen to Parser 2022-10-04 11:03:53 +01:00
deavmi self-assigned this 2022-10-15 15:58:06 +01:00
deavmi added the
parser
label 2022-10-15 15:58:11 +01:00
deavmi changed reference from parser to vardec_varass_dependency 2022-12-13 10:02:33 +00:00
Author
Owner

I should actually get this done today.

I should actually get this done today.
Author
Owner

I lied to myself 💀

I lied to myself 💀
deavmi added a new dependency 2022-12-17 14:59:42 +00:00
Author
Owner

Function return statements being worked on now

Function return statements being worked on now
Author
Owner

Emmiting

I have now done the following:

  • Created a ReturnInstruction which embeds the epxresiosn instruction, so it can be pulled out by the emitter later and we can do the following:
/* ReturnInstruction */
else if(cast(ReturnInstruction)instruction)
{
	gprintln("type: ReturnInstruction");

    ReturnInstruction returnInstruction = cast(ReturnInstruction)instruction;
    Context context = returnInstruction.getContext();
    assert(context);

    /* Get the return expression instruction */
    Value returnExpressionInstr = returnInstruction.getReturnExpInstr();

    return "return "~transform(returnExpressionInstr)~";";
}
## Emmiting ✅ I have now done the following: * Created a `ReturnInstruction` which embeds the epxresiosn instruction, so it can be pulled out by the emitter later and we can do the following: ```d /* ReturnInstruction */ else if(cast(ReturnInstruction)instruction) { gprintln("type: ReturnInstruction"); ReturnInstruction returnInstruction = cast(ReturnInstruction)instruction; Context context = returnInstruction.getContext(); assert(context); /* Get the return expression instruction */ Value returnExpressionInstr = returnInstruction.getReturnExpInstr(); return "return "~transform(returnExpressionInstr)~";"; } ```
deavmi started working 2022-12-17 15:01:18 +00:00
deavmi added the
dependency
emit
labels 2022-12-17 15:01:28 +00:00
deavmi added the due date 2022-12-17 2022-12-17 15:01:41 +00:00
Author
Owner

Dependency

We have the following added to generalPass(Container, Context) now:

/**
* Return statement
*/
else if(cast(ReturnStmt)entity)
{
	ReturnStmt returnStatement = cast(ReturnStmt)entity;
    returnStatement.setContext(context);

    DNode returnStatementDNode = pool(returnStatement);

    /* Process the return expression */
    Expression returnExpression = returnStatement.getReturnExpression();
    DNode returnExpressionDNode = expressionPass(returnExpression, context);

    /* Make return depend on the return expression */
    returnStatementDNode.needs(returnExpressionDNode);

    /* Make this container depend on this return statement */
    node.needs(returnStatementDNode);
}
## Dependency ✅ We have the following added to `generalPass(Container, Context)` now: ```d /** * Return statement */ else if(cast(ReturnStmt)entity) { ReturnStmt returnStatement = cast(ReturnStmt)entity; returnStatement.setContext(context); DNode returnStatementDNode = pool(returnStatement); /* Process the return expression */ Expression returnExpression = returnStatement.getReturnExpression(); DNode returnExpressionDNode = expressionPass(returnExpression, context); /* Make return depend on the return expression */ returnStatementDNode.needs(returnExpressionDNode); /* Make this container depend on this return statement */ node.needs(returnStatementDNode); } ```
Author
Owner

Data (Parser nodes)

We have added a parser node ReturnStmt (this has been here for some time but we needed to actually weight it with a weight above the default of 0 - which actually misplaced it above variable declarations (Variable).

This should technically have same weighting as Variable as it is a statement. We only really use weighting to re-order definitions like types etc., but we should keepo this as 2 for the following reason:

We don't want the code:

int apple(int arg1, int arg2)
{
    return 1;
    int h = 69;

    arg1=1+arg1;

    k=arg1+arg2;
    simple_functions.k=arg1+arg2;
}

To re-order return to the bottom, no infact, we should be analysing the body of the parse tree in generalPass() (when analysing function definition) and ensuring that this statement actually appears only ad the end of the funciton).

SO yes, this should be kept with weighting of 2 on par I think, we want that order to remain - even if syntactically incorrect (i.e. a return statement must be the last statement in a function's body). As for finding issue with it, that is an aesthetic issue for #59 I think.

## Data (Parser nodes) ✅ We have added a parser node `ReturnStmt` (this has been here for some time but we needed to actually weight it with a weight above the default of `0` - which actually misplaced it above variable declarations (`Variable`). This should technically have same weighting as Variable as it is a statement. We only really use weighting to re-order definitions like types etc., but we should keepo this as `2` for the following reason: We don't want the code: ```d int apple(int arg1, int arg2) { return 1; int h = 69; arg1=1+arg1; k=arg1+arg2; simple_functions.k=arg1+arg2; } ``` To re-order `return` to the bottom, no infact, we should be analysing the body of the parse tree in `generalPass()` (when analysing function definition) and ensuring that this statement actually appears only ad the end of the funciton). ❗ **SO yes**, this should be kept with weighting of `2` on par I think, we want that order to remain - even if syntactically incorrect (i.e. a return statement must be the last statement in a function's body). As for finding issue with it, that is an aesthetic issue for #59 I think.
Author
Owner

CodeGen

No typechecking yet, but we do the following in order to pop the expression Value instruction that was on the stack codeQueue (scratchpad) and then we embed it into the ReturnInstruction and tack that on to the back of the codeQueue (scratchpad).

😊 We also don't forget to set the context hun 💅 :

/**
* Return statement (ReturnStmt)
*/
else if(cast(ReturnStmt)statement)
{
	ReturnStmt returnStatement = cast(ReturnStmt)statement;

    /**
    * Codegen
    *
    * 1. Pop the expression on the stack
    * 2. Create a new ReturnInstruction with the expression instruction
    * embedded in it
    * 3. Set the Context of the instruction
    * 4. Add this instruction back
    */
    Value returnExpressionInstr = cast(Value)popInstr();
    assert(returnExpressionInstr);
    ReturnInstruction returnInstr = new ReturnInstruction(returnExpressionInstr);
    returnInstr.context = returnStatement.getContext();
    addInstrB(returnInstr);
}
## CodeGen ✅ No typechecking yet, but we do the following in order to pop the expression `Value` instruction that was on the stack `codeQueue` (scratchpad) and then we embed it into the `ReturnInstruction` and tack that on to the back of the `codeQueue` (scratchpad). 😊 We also don't forget to set the context hun 💅 ✨ : ```d /** * Return statement (ReturnStmt) */ else if(cast(ReturnStmt)statement) { ReturnStmt returnStatement = cast(ReturnStmt)statement; /** * Codegen * * 1. Pop the expression on the stack * 2. Create a new ReturnInstruction with the expression instruction * embedded in it * 3. Set the Context of the instruction * 4. Add this instruction back */ Value returnExpressionInstr = cast(Value)popInstr(); assert(returnExpressionInstr); ReturnInstruction returnInstr = new ReturnInstruction(returnExpressionInstr); returnInstr.context = returnStatement.getContext(); addInstrB(returnInstr); } ```
Author
Owner

Typechecking is outstanding

Typechecking is outstanding
Author
Owner

Type checking is oustanding But will be handled from #61

Type checking is oustanding **But** will be handled from #61
Author
Owner

All that is left is semantic analysis, which shouldn't be too hard

All that is left is semantic analysis, which shouldn't be too hard
Author
Owner

Tests run and corerct values arise from the return statement in simple_functions.t on commit d1b3319a74efc4ed37c6b492a5d374f93e3f3e74 on vardec_varass_dependency branch.

Tests run and corerct values arise from the `return` statement in `simple_functions.t` on commit `d1b3319a74efc4ed37c6b492a5d374f93e3f3e74` on `vardec_varass_dependency` branch.
Author
Owner

Return statements are now implemented

Return statements are now implemented
deavmi stopped working 2022-12-17 17:06:34 +00:00
2 hours 5 minutes
deavmi added this to the Basics milestone 2022-12-17 17:12:34 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Total Time Spent: 2 hours 5 minutes
deavmi
2 hours 5 minutes
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

2022-12-17

Blocks
Reference: tlang/tlang#7
No description provided.