Instruction
- Added `getOperator()` and `getOperand()` methods to `UnaryOpInstr` - Added new instruction `PointerDereferenceAssignmentInstruction` for pointer support DGen - Updated `transform()` to emit code for instruction type `UnaryOpInstr` - Updated `transform()` to emit code for instruction type `PointerDereferenceAssignmentInstruction` - Added testing emit code in `emitEntryPoint()` for pointer testing Parser - Updated `parseName()` to trigger `parseTypedDeclaration()` on occurene of `SymbolType.STAR` (for pointer type declarations) - Added pointer-type support for function parameters (so far only single) in `parseFuncDef()` - `parseExpression()` terminates on occurence of a single `=` (ASSIGN) operator - Declaring of pointers of any depth implemented in `parseTypedDeclaration()` - Added support for pointer dereferncing assignments with the addition of `parseDerefAssignment()` - `parseStatement()` will now call `parseDerefAssignment()` on occurence of a `SymbolType.STAR` - Added a unittest for testing pointers - Finished unittest for for loops Check - Added backmapping for `SymbolType.ASSIGN` -> `&` Data - Added new parser node type `PointerDereferenceAssignment` for pointer support in the parser TypeChecker - Because function parameters are type che cked upon function call I had to add typechecking code for pointer support in the `UnaryOperatorExpression` case - Added code generation support for `PointerDereferenceAssignment` type Dependency - Added support for `PointerDereferenceAssignment` type (pointer support) to `generalStatement()` Tests - Added pointer test `simple_pointer.t`
This commit is contained in:
parent
11b2d1d1ea
commit
5827f16e2a
|
@ -337,6 +337,55 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
// Close curly (body end)
|
// Close curly (body end)
|
||||||
emit~=genTabs(transformDepth)~"}";
|
emit~=genTabs(transformDepth)~"}";
|
||||||
|
|
||||||
|
return emit;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Unary operators (UnaryOpInstr)
|
||||||
|
*/
|
||||||
|
else if(cast(UnaryOpInstr)instruction)
|
||||||
|
{
|
||||||
|
UnaryOpInstr unaryOpInstr = cast(UnaryOpInstr)instruction;
|
||||||
|
Value operandInstruction = cast(Value)unaryOpInstr.getOperand();
|
||||||
|
assert(operandInstruction);
|
||||||
|
|
||||||
|
string emit;
|
||||||
|
|
||||||
|
/* The operator's symbol */
|
||||||
|
emit ~= getCharacter(unaryOpInstr.getOperator());
|
||||||
|
|
||||||
|
/* Transform the operand */
|
||||||
|
emit ~= transform(operandInstruction);
|
||||||
|
|
||||||
|
return emit;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Pointer dereference assignment (PointerDereferenceAssignmentInstruction)
|
||||||
|
*/
|
||||||
|
else if(cast(PointerDereferenceAssignmentInstruction)instruction)
|
||||||
|
{
|
||||||
|
PointerDereferenceAssignmentInstruction pointerDereferenceAssignmentInstruction = cast(PointerDereferenceAssignmentInstruction)instruction;
|
||||||
|
Value lhsPtrAddrExprInstr = pointerDereferenceAssignmentInstruction.getPointerEvalInstr();
|
||||||
|
assert(lhsPtrAddrExprInstr);
|
||||||
|
Value rhsAssExprInstr = pointerDereferenceAssignmentInstruction.getAssExprInstr();
|
||||||
|
assert(rhsAssExprInstr);
|
||||||
|
|
||||||
|
string emit;
|
||||||
|
|
||||||
|
/* Star followed by transformation of the pointer address expression */
|
||||||
|
string starsOfLiberty;
|
||||||
|
for(ulong i = 0; i < pointerDereferenceAssignmentInstruction.getDerefCount(); i++)
|
||||||
|
{
|
||||||
|
starsOfLiberty ~= "*";
|
||||||
|
}
|
||||||
|
emit ~= starsOfLiberty~transform(lhsPtrAddrExprInstr);
|
||||||
|
|
||||||
|
/* Assignment operator follows */
|
||||||
|
emit ~= " = ";
|
||||||
|
|
||||||
|
/* Expression to be assigned on the right hand side */
|
||||||
|
emit ~= transform(rhsAssExprInstr)~";";
|
||||||
|
|
||||||
|
|
||||||
return emit;
|
return emit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,6 +611,19 @@ int main()
|
||||||
printf("result: %d\n", result);
|
printf("result: %d\n", result);
|
||||||
assert(result == 3);
|
assert(result == 3);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}`);
|
||||||
|
}
|
||||||
|
else if(cmp(typeChecker.getModule().getName(), "simple_pointer") == 0)
|
||||||
|
{
|
||||||
|
file.writeln(`
|
||||||
|
#include<stdio.h>
|
||||||
|
#include<assert.h>
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
thing();
|
||||||
|
assert(t_87bc875d0b65f741b69fb100a0edebc7 == 4);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}`);
|
}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,6 +237,16 @@ public class UnaryOpInstr : Value
|
||||||
|
|
||||||
addInfo = "UnaryOpType: "~to!(string)(operator)~", Instr: "~exp.toString();
|
addInfo = "UnaryOpType: "~to!(string)(operator)~", Instr: "~exp.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SymbolType getOperator()
|
||||||
|
{
|
||||||
|
return operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instruction getOperand()
|
||||||
|
{
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -399,4 +409,34 @@ public final class BranchInstruction : Instruction
|
||||||
{
|
{
|
||||||
return bodyInstructions;
|
return bodyInstructions;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final class PointerDereferenceAssignmentInstruction : Instruction
|
||||||
|
{
|
||||||
|
private Value pointerEvalInstr;
|
||||||
|
private Value assigmnetExprInstr;
|
||||||
|
private ulong derefCount;
|
||||||
|
|
||||||
|
this(Value pointerEvalInstr, Value assigmnetExprInstr, ulong derefCount)
|
||||||
|
{
|
||||||
|
this.pointerEvalInstr = pointerEvalInstr;
|
||||||
|
this.assigmnetExprInstr = assigmnetExprInstr;
|
||||||
|
this.derefCount = derefCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Value getPointerEvalInstr()
|
||||||
|
{
|
||||||
|
return pointerEvalInstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Value getAssExprInstr()
|
||||||
|
{
|
||||||
|
return assigmnetExprInstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong getDerefCount()
|
||||||
|
{
|
||||||
|
return derefCount;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -420,6 +420,7 @@ public final class Parser
|
||||||
|
|
||||||
/* Save the name or type */
|
/* Save the name or type */
|
||||||
string nameTYpe = getCurrentToken().getToken();
|
string nameTYpe = getCurrentToken().getToken();
|
||||||
|
gprintln("parseName(): Current token: "~getCurrentToken().toString());
|
||||||
|
|
||||||
/* TODO: The problem here is I don't want to progress the token */
|
/* TODO: The problem here is I don't want to progress the token */
|
||||||
|
|
||||||
|
@ -438,8 +439,14 @@ public final class Parser
|
||||||
expect(SymbolType.SEMICOLON, getCurrentToken());
|
expect(SymbolType.SEMICOLON, getCurrentToken());
|
||||||
nextToken();
|
nextToken();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Either we have:
|
||||||
|
*
|
||||||
|
* 1. `int ptr` (and we looked ahead to `ptr`)
|
||||||
|
* 2. `int* ptr` (and we looked ahead to `*`)
|
||||||
|
*/
|
||||||
/* If we have an identifier/type then declaration */
|
/* If we have an identifier/type then declaration */
|
||||||
else if(type == SymbolType.IDENT_TYPE)
|
else if(type == SymbolType.IDENT_TYPE || type == SymbolType.STAR)
|
||||||
{
|
{
|
||||||
previousToken();
|
previousToken();
|
||||||
ret = parseTypedDeclaration();
|
ret = parseTypedDeclaration();
|
||||||
|
@ -875,6 +882,14 @@ public final class Parser
|
||||||
string type = getCurrentToken().getToken();
|
string type = getCurrentToken().getToken();
|
||||||
nextToken();
|
nextToken();
|
||||||
|
|
||||||
|
/* If it is a star `*` */
|
||||||
|
if(getSymbolType(getCurrentToken()) == SymbolType.STAR)
|
||||||
|
{
|
||||||
|
// Make type a pointer
|
||||||
|
type = type~"*";
|
||||||
|
nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the identifier (This CAN NOT be dotted) */
|
/* Get the identifier (This CAN NOT be dotted) */
|
||||||
expect(SymbolType.IDENT_TYPE, getCurrentToken());
|
expect(SymbolType.IDENT_TYPE, getCurrentToken());
|
||||||
if(!isIdentifier_NoDot(getCurrentToken()))
|
if(!isIdentifier_NoDot(getCurrentToken()))
|
||||||
|
@ -1152,7 +1167,7 @@ public final class Parser
|
||||||
addRetExp(toAdd);
|
addRetExp(toAdd);
|
||||||
}
|
}
|
||||||
/* Detect if this expression is coming to an end, then return */
|
/* Detect if this expression is coming to an end, then return */
|
||||||
else if (symbol == SymbolType.SEMICOLON || symbol == SymbolType.RBRACE || symbol == SymbolType.COMMA)
|
else if (symbol == SymbolType.SEMICOLON || symbol == SymbolType.RBRACE || symbol == SymbolType.COMMA || symbol == SymbolType.ASSIGN)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1253,8 +1268,20 @@ public final class Parser
|
||||||
string type = getCurrentToken().getToken();
|
string type = getCurrentToken().getToken();
|
||||||
string identifier;
|
string identifier;
|
||||||
|
|
||||||
/* Expect an identifier (CAN NOT be dotted) */
|
|
||||||
|
// TODO: Insert pointer `*`-handling code here
|
||||||
nextToken();
|
nextToken();
|
||||||
|
ulong derefCount = 0;
|
||||||
|
|
||||||
|
/* If we have a star */
|
||||||
|
while(getSymbolType(getCurrentToken()) == SymbolType.STAR)
|
||||||
|
{
|
||||||
|
derefCount+=1;
|
||||||
|
type=type~"*";
|
||||||
|
nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expect an identifier (CAN NOT be dotted) */
|
||||||
expect(SymbolType.IDENT_TYPE, getCurrentToken());
|
expect(SymbolType.IDENT_TYPE, getCurrentToken());
|
||||||
if(!isIdentifier_NoDot(getCurrentToken()))
|
if(!isIdentifier_NoDot(getCurrentToken()))
|
||||||
{
|
{
|
||||||
|
@ -1520,6 +1547,45 @@ public final class Parser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Statement parseDerefAssignment()
|
||||||
|
{
|
||||||
|
gprintln("parseDerefAssignment(): Enter", DebugType.WARNING);
|
||||||
|
|
||||||
|
Statement statement;
|
||||||
|
|
||||||
|
/* Consume the star `*` */
|
||||||
|
nextToken();
|
||||||
|
ulong derefCnt = 1;
|
||||||
|
|
||||||
|
/* Check if there is another star */
|
||||||
|
while(getSymbolType(getCurrentToken()) == SymbolType.STAR)
|
||||||
|
{
|
||||||
|
derefCnt+=1;
|
||||||
|
nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expect an expression */
|
||||||
|
Expression pointerExpression = parseExpression();
|
||||||
|
|
||||||
|
/* Expect an assignment operator */
|
||||||
|
expect(SymbolType.ASSIGN, getCurrentToken());
|
||||||
|
nextToken();
|
||||||
|
|
||||||
|
/* Expect an expression */
|
||||||
|
Expression assigmentExpression = parseExpression();
|
||||||
|
|
||||||
|
/* Expect a semicolon */
|
||||||
|
expect(SymbolType.SEMICOLON, getCurrentToken());
|
||||||
|
nextToken();
|
||||||
|
|
||||||
|
// FIXME: We should make a LHSPiinterAssignmentThing
|
||||||
|
statement = new PointerDereferenceAssignment(pointerExpression, assigmentExpression, derefCnt);
|
||||||
|
|
||||||
|
gprintln("parseDerefAssignment(): Leave", DebugType.WARNING);
|
||||||
|
|
||||||
|
return statement;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: This ic currently dead code and ought to be used/implemented
|
// TODO: This ic currently dead code and ought to be used/implemented
|
||||||
private Statement parseStatement(SymbolType terminatingSymbol = SymbolType.SEMICOLON)
|
private Statement parseStatement(SymbolType terminatingSymbol = SymbolType.SEMICOLON)
|
||||||
{
|
{
|
||||||
|
@ -1582,6 +1648,11 @@ public final class Parser
|
||||||
/* Parse the return statement */
|
/* Parse the return statement */
|
||||||
statement = parseReturn();
|
statement = parseReturn();
|
||||||
}
|
}
|
||||||
|
/* If it is a dereference assigment (a `*`) */
|
||||||
|
else if(symbol == SymbolType.STAR)
|
||||||
|
{
|
||||||
|
statement = parseDerefAssignment();
|
||||||
|
}
|
||||||
/* Error out */
|
/* Error out */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2127,15 +2198,90 @@ void function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
import std.stdio;
|
||||||
|
import compiler.lexer;
|
||||||
|
import compiler.typecheck.core;
|
||||||
|
|
||||||
|
string sourceCode = `
|
||||||
|
module simple_pointer;
|
||||||
|
|
||||||
|
int j;
|
||||||
|
|
||||||
|
int function(int* ptr)
|
||||||
|
{
|
||||||
|
*ptr = 2+2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thing()
|
||||||
|
{
|
||||||
|
int discardExpr = function(&j);
|
||||||
|
int** l;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
Lexer currentLexer = new Lexer(sourceCode);
|
||||||
|
assert(currentLexer.performLex());
|
||||||
|
|
||||||
|
|
||||||
|
Parser parser = new Parser(currentLexer.getTokens());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Module modulle = parser.parse();
|
||||||
|
|
||||||
|
/* Module name must be parser_while */
|
||||||
|
assert(cmp(modulle.getName(), "simple_pointer")==0);
|
||||||
|
TypeChecker tc = new TypeChecker(modulle);
|
||||||
|
|
||||||
|
/* Find the function named `function` */
|
||||||
|
Entity funcFunction = tc.getResolver().resolveBest(modulle, "function");
|
||||||
|
assert(funcFunction);
|
||||||
|
assert(cast(Function)funcFunction); // Ensure it is a Function
|
||||||
|
|
||||||
|
/* Find the function named `thing` */
|
||||||
|
Entity funcThing = tc.getResolver().resolveBest(modulle, "thing");
|
||||||
|
assert(funcThing);
|
||||||
|
assert(cast(Function)funcThing); // Ensure it is a Function
|
||||||
|
|
||||||
|
/* Find the variable named `j` */
|
||||||
|
Entity variableJ = tc.getResolver().resolveBest(modulle, "j");
|
||||||
|
assert(variableJ);
|
||||||
|
assert(cast(Variable)variableJ);
|
||||||
|
|
||||||
|
|
||||||
|
/* Get the `function`'s body */
|
||||||
|
Container funcFunctionContainer = cast(Container)funcFunction;
|
||||||
|
assert(funcFunctionContainer);
|
||||||
|
Statement[] funcFunctionStatements = funcFunctionContainer.getStatements();
|
||||||
|
assert(funcFunctionStatements.length == 3); // Remember this includes the parameters
|
||||||
|
|
||||||
|
/* Get the `thing`'s body */
|
||||||
|
Container funcThingContainer = cast(Container)funcThing;
|
||||||
|
assert(funcThingContainer);
|
||||||
|
Statement[] funcThingStatements = funcThingContainer.getStatements();
|
||||||
|
assert(funcThingStatements.length == 2);
|
||||||
|
|
||||||
|
// TODO: Finish this
|
||||||
|
// TODO: Add a check for the Statement types in the bodies, the arguments and the parameters
|
||||||
|
}
|
||||||
|
catch(TError e)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do-while loop tests (TODO: Add this)
|
* Do-while loop tests (TODO: Add this)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For loop tests (TODO: Add this)
|
* For loop tests (TODO: FInish this)
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* While loop test case (nested)
|
|
||||||
*/
|
*/
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
|
@ -2231,45 +2377,17 @@ void function()
|
||||||
VariableAssignmentStdAlone outerLoopBranchBodyStmt3 = cast(VariableAssignmentStdAlone)outerLoopBranchBody[2];
|
VariableAssignmentStdAlone outerLoopBranchBodyStmt3 = cast(VariableAssignmentStdAlone)outerLoopBranchBody[2];
|
||||||
assert(outerLoopBranchBodyStmt3);
|
assert(outerLoopBranchBodyStmt3);
|
||||||
|
|
||||||
|
/* Start examining the inner for-loop */
|
||||||
|
Branch innerLoopBranch = innerLoop.getBranch();
|
||||||
|
assert(innerLoopBranch);
|
||||||
|
|
||||||
// /* The outer loop should have a Variable as pre-run Statement */
|
/* The branch should have a condition */
|
||||||
// Statement preRunStatement = outerLoop.getPreLoopStatement();
|
Expression innerLoopBranchCondition = innerLoopBranch.getCondition();
|
||||||
// assert(preRunStatement);
|
assert(innerLoopBranchCondition);
|
||||||
// assert(cast(Variable)preRunStatement);
|
|
||||||
|
|
||||||
// /* The outer loop should have a variable assignment as the post-iteration statement */
|
/* The branch should have a body made up of [postIteration] */
|
||||||
// Statement postIrerationStatement = outerLoop.getPreIterationStatement();
|
Statement[] innerLoopBranchBody = innerLoopBranch.getStatements();
|
||||||
// assert(postIrerationStatement);
|
assert(innerLoopBranchBody.length == 1);
|
||||||
// assert(cast(VariableAssignmentStdAlone)postIrerationStatement);
|
|
||||||
|
|
||||||
// /* Extract the statements of the body of the outer loop */
|
|
||||||
// Branch outerLoopBranch = outerLoop.getBranch();
|
|
||||||
// assert(outerLoopBranch);
|
|
||||||
// Statement[] outerLoopBody = outerLoopBranch.getStatements();
|
|
||||||
// assert(outerLoopBody.length == 2);
|
|
||||||
|
|
||||||
// /* First statement is a VarAssStdAlone */
|
|
||||||
// assert(cast(VariableAssignmentStdAlone)outerLoopBody[0]);
|
|
||||||
|
|
||||||
// /* Second statement is a for loop */
|
|
||||||
// ForLoop innerLoop = cast(ForLoop)outerLoopBody[1];
|
|
||||||
// assert(innerLoop);
|
|
||||||
|
|
||||||
// /* The inner loop should have a Variable as pre-run Statement */
|
|
||||||
// Statement innerPreRunStatement = innerLoop.getPreLoopStatement();
|
|
||||||
// assert(innerPreRunStatement);
|
|
||||||
// assert(cast(Variable)innerPreRunStatement);
|
|
||||||
|
|
||||||
// /* The inner loop should have a variable assignment as the post-iteration statement */
|
|
||||||
// Statement innerPostIrerationStatement = outerLoop.getPreIterationStatement();
|
|
||||||
// assert(innerPostIrerationStatement);
|
|
||||||
// assert(cast(VariableAssignmentStdAlone)innerPostIrerationStatement);
|
|
||||||
|
|
||||||
// /* Extract the statements of the body of the inner loop */
|
|
||||||
// Branch innerLoopBranch = innerLoop.getBranch();
|
|
||||||
// assert(innerLoopBranch);
|
|
||||||
// Statement[] innerLoopBody = innerLoopBranch.getStatements();
|
|
||||||
// assert(innerLoopBody.length == 0);
|
|
||||||
}
|
}
|
||||||
catch(TError e)
|
catch(TError e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -517,6 +517,10 @@ public string getCharacter(SymbolType symbolIn)
|
||||||
{
|
{
|
||||||
return ">=";
|
return ">=";
|
||||||
}
|
}
|
||||||
|
else if(symbolIn == SymbolType.AMPERSAND)
|
||||||
|
{
|
||||||
|
return "&";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gprintln("getCharacter: No back-mapping for "~to!(string)(symbolIn), DebugType.ERROR);
|
gprintln("getCharacter: No back-mapping for "~to!(string)(symbolIn), DebugType.ERROR);
|
||||||
|
|
|
@ -445,6 +445,43 @@ public class VariableAssignmentStdAlone : Statement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class PointerDereferenceAssignment : Statement
|
||||||
|
{
|
||||||
|
private Expression assignmentExpression;
|
||||||
|
private Expression pointerExpression;
|
||||||
|
private ulong derefCount;
|
||||||
|
|
||||||
|
this(Expression pointerExpression, Expression assignmentExpression, ulong derefCount = 1)
|
||||||
|
{
|
||||||
|
this.pointerExpression = pointerExpression;
|
||||||
|
this.assignmentExpression = assignmentExpression;
|
||||||
|
this.derefCount = derefCount;
|
||||||
|
|
||||||
|
/* Weighted as 2 */
|
||||||
|
weight = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expression getExpression()
|
||||||
|
{
|
||||||
|
return assignmentExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expression getPointerExpression()
|
||||||
|
{
|
||||||
|
return pointerExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong getDerefCount()
|
||||||
|
{
|
||||||
|
return derefCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string toString()
|
||||||
|
{
|
||||||
|
return "[pointerDeref: From: "~pointerExpression.toString()~"]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class IdentExpression : Expression
|
public class IdentExpression : Expression
|
||||||
{
|
{
|
||||||
|
|
|
@ -618,6 +618,12 @@ public final class TypeChecker
|
||||||
* (so that we can construct the Type* (the pointer type))
|
* (so that we can construct the Type* (the pointer type))
|
||||||
*/
|
*/
|
||||||
gprintln("ExpType: "~expType.toString());
|
gprintln("ExpType: "~expType.toString());
|
||||||
|
|
||||||
|
Type ptrType = new Pointer(expType);
|
||||||
|
addType(ptrType);
|
||||||
|
|
||||||
|
gprintln("Ampersand operator not yet implemented", DebugType.ERROR);
|
||||||
|
// assert(false);
|
||||||
}
|
}
|
||||||
/* This should never occur */
|
/* This should never occur */
|
||||||
else
|
else
|
||||||
|
@ -1075,6 +1081,33 @@ public final class TypeChecker
|
||||||
|
|
||||||
gprintln("Look at that y'all, cause this is it: "~to!(string)(branch));
|
gprintln("Look at that y'all, cause this is it: "~to!(string)(branch));
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Dereferencing pointer assignment statement (PointerDereferenceAssignment)
|
||||||
|
*/
|
||||||
|
else if(cast(PointerDereferenceAssignment)statement)
|
||||||
|
{
|
||||||
|
PointerDereferenceAssignment ptrDerefAss = cast(PointerDereferenceAssignment)statement;
|
||||||
|
|
||||||
|
/* Pop off the pointer dereference expression instruction (LHS) */
|
||||||
|
Value lhsPtrExprInstr = cast(Value)popInstr();
|
||||||
|
assert(lhsPtrExprInstr);
|
||||||
|
|
||||||
|
/* Pop off the assignment instruction (RHS expression) */
|
||||||
|
Value rhsExprInstr = cast(Value)popInstr();
|
||||||
|
assert(rhsExprInstr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code gen
|
||||||
|
*
|
||||||
|
* 1. Create the PointerDereferenceAssignmentInstruction containing the `lhsPtrExprInstr`
|
||||||
|
* and `rhsExprInstr`
|
||||||
|
* 2. Set the context
|
||||||
|
* 3. Add the instruction
|
||||||
|
*/
|
||||||
|
PointerDereferenceAssignmentInstruction pointerDereferenceAssignmentInstruction = new PointerDereferenceAssignmentInstruction(lhsPtrExprInstr, rhsExprInstr, ptrDerefAss.getDerefCount());
|
||||||
|
pointerDereferenceAssignmentInstruction.context = ptrDerefAss.context;
|
||||||
|
addInstrB(pointerDereferenceAssignmentInstruction);
|
||||||
|
}
|
||||||
/* Case of no matches */
|
/* Case of no matches */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1476,6 +1476,27 @@ public class DNodeGenerator
|
||||||
|
|
||||||
return forLoopDNode;
|
return forLoopDNode;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Pointer dereference assigmnets (PointerDereferenceAssignment)
|
||||||
|
*/
|
||||||
|
else if(cast(PointerDereferenceAssignment)entity)
|
||||||
|
{
|
||||||
|
PointerDereferenceAssignment ptrAssDeref = cast(PointerDereferenceAssignment)entity;
|
||||||
|
ptrAssDeref.setContext(context);
|
||||||
|
DNode ptrAssDerefDNode = pool(ptrAssDeref);
|
||||||
|
|
||||||
|
/* Pass the expression being assigned */
|
||||||
|
Expression assignmentExpression = ptrAssDeref.getExpression();
|
||||||
|
DNode assignmentExpressionDNode = expressionPass(assignmentExpression, context);
|
||||||
|
ptrAssDerefDNode.needs(assignmentExpressionDNode);
|
||||||
|
|
||||||
|
/* Pass the pointer expression */
|
||||||
|
Expression pointerExpression = ptrAssDeref.getPointerExpression();
|
||||||
|
DNode pointerExpressionDNode = expressionPass(pointerExpression, context);
|
||||||
|
ptrAssDerefDNode.needs(pointerExpressionDNode);
|
||||||
|
|
||||||
|
return ptrAssDerefDNode;
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
module simple_pointer;
|
||||||
|
|
||||||
|
int j;
|
||||||
|
|
||||||
|
int function(int* ptr)
|
||||||
|
{
|
||||||
|
*ptr = 2+2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thing()
|
||||||
|
{
|
||||||
|
int discardExpr = function(&j);
|
||||||
|
int** l;
|
||||||
|
}
|
Loading…
Reference in New Issue