Instruction
- Make the name of the function const and public for FuncCallInstr CodeEmitter - Added methods `getCursor()`, `getSelectedQueueLength()` and `getQueueLength()` - Removed old queue-specific methods DGen - Added emitting for FuncCallInstr instruction (function call support) - Now emit globals first BEFORE function definitions - Added debug prints per instruction to know what instruction is currently being transform()'d - After emitting sections add newlines between each to make for neater C code - `emitEntryPoint()` now adds a test for `simple_function_decls.t` (This should be removed soon) - Removed incorrect TODO in `finalize()` Dependency - Make the `nodePool` static, to ensure pooling carries over across multiple `DNodeGenerator` instances - Fixed handling of function calls in `expressionPass()` - do NOT add a so-called `FunctionDefNode` (remember functions are defined by `addFuncDef()`) - Set the Context of standalone variable assignments to the Context of the Variable entity representing the variable being assigned to TypeChecker - Assign the Context object stored in the `FunctionCall` statement to the `FuncCallInstr` Test cases - Updated test case `simple_function_decls.t`
This commit is contained in:
parent
8a481fb0ac
commit
2a12c310a6
|
@ -20,6 +20,7 @@ import std.conv : to;
|
||||||
public abstract class CodeEmitter
|
public abstract class CodeEmitter
|
||||||
{
|
{
|
||||||
protected TypeChecker typeChecker;
|
protected TypeChecker typeChecker;
|
||||||
|
protected File file;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The selected queue is the queue to be used
|
* The selected queue is the queue to be used
|
||||||
|
@ -88,6 +89,20 @@ public abstract class CodeEmitter
|
||||||
return selectedQueue[queueCursor];
|
return selectedQueue[queueCursor];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final ulong getCursor()
|
||||||
|
{
|
||||||
|
return queueCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final ulong getSelectedQueueLength()
|
||||||
|
{
|
||||||
|
return selectedQueue.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final ulong getQueueLength()
|
||||||
|
{
|
||||||
|
return selectedQueue.length;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required queues
|
* Required queues
|
||||||
|
@ -100,67 +115,16 @@ public abstract class CodeEmitter
|
||||||
*/
|
*/
|
||||||
private Instruction[][string] functionBodyInstrs;
|
private Instruction[][string] functionBodyInstrs;
|
||||||
|
|
||||||
|
public final ulong getFunctionDefinitionsCount()
|
||||||
protected File file;
|
|
||||||
|
|
||||||
public final ulong getQueueLength()
|
|
||||||
{
|
{
|
||||||
return selectedQueue.length;
|
return functionBodyInstrs.keys().length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public final string[] getFunctionDefinitionNames()
|
public final string[] getFunctionDefinitionNames()
|
||||||
{
|
{
|
||||||
return functionBodyInstrs.keys();
|
return functionBodyInstrs.keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Make some sort of like cursor object here that lets you move for function
|
|
||||||
* or actually just have a function cuirsor
|
|
||||||
*/
|
|
||||||
private ulong globalCurrentFunctionDefintionCodeQueueIdx = 0;
|
|
||||||
private string currentFunctionDefinitionName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves thr cursor (for the CFDCQ) back to the starting
|
|
||||||
* position (zero)
|
|
||||||
*/
|
|
||||||
public final void resetCFDCQCursor()
|
|
||||||
{
|
|
||||||
globalCurrentFunctionDefintionCodeQueueIdx = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final bool hasFunctionDefinitionInstructions()
|
|
||||||
{
|
|
||||||
return globalCurrentFunctionDefintionCodeQueueIdx < functionBodyInstrs[currentFunctionDefinitionName].length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void nextFunctionDefinitionCode()
|
|
||||||
{
|
|
||||||
globalCurrentFunctionDefintionCodeQueueIdx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void previousFunctionDefinitionCode()
|
|
||||||
{
|
|
||||||
globalCurrentFunctionDefintionCodeQueueIdx--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Instruction getCurrentFunctionDefinitionInstruction()
|
|
||||||
{
|
|
||||||
return functionBodyInstrs[currentFunctionDefinitionName][globalCurrentFunctionDefintionCodeQueueIdx];
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void setCurrentFunctionDefinition(string functionDefinitionName)
|
|
||||||
{
|
|
||||||
currentFunctionDefinitionName = functionDefinitionName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this(TypeChecker typeChecker, File file)
|
this(TypeChecker typeChecker, File file)
|
||||||
{
|
{
|
||||||
this.typeChecker = typeChecker;
|
this.typeChecker = typeChecker;
|
||||||
|
|
|
@ -33,15 +33,20 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
|
|
||||||
public override string transform(const Instruction instruction)
|
public override string transform(const Instruction instruction)
|
||||||
{
|
{
|
||||||
|
import std.stdio;
|
||||||
|
writeln("\n");
|
||||||
gprintln("transform(): "~to!(string)(instruction));
|
gprintln("transform(): "~to!(string)(instruction));
|
||||||
|
|
||||||
/* VariableAssignmentInstr */
|
/* VariableAssignmentInstr */
|
||||||
if(cast(VariableAssignmentInstr)instruction)
|
if(cast(VariableAssignmentInstr)instruction)
|
||||||
{
|
{
|
||||||
|
gprintln("type: VariableAssignmentInstr");
|
||||||
|
|
||||||
VariableAssignmentInstr varAs = cast(VariableAssignmentInstr)instruction;
|
VariableAssignmentInstr varAs = cast(VariableAssignmentInstr)instruction;
|
||||||
Context context = varAs.getContext();
|
Context context = varAs.getContext();
|
||||||
|
|
||||||
gprintln("Is ContextNull?: "~to!(string)(context is null));
|
gprintln("Is ContextNull?: "~to!(string)(context is null));
|
||||||
|
gprintln("Wazza contect: "~to!(string)(context.container));
|
||||||
auto typedEntityVariable = context.tc.getResolver().resolveBest(context.getContainer(), varAs.varName); //TODO: Remove `auto`
|
auto typedEntityVariable = context.tc.getResolver().resolveBest(context.getContainer(), varAs.varName); //TODO: Remove `auto`
|
||||||
string typedEntityVariableName = context.tc.getResolver().generateName(context.getContainer(), typedEntityVariable);
|
string typedEntityVariableName = context.tc.getResolver().generateName(context.getContainer(), typedEntityVariable);
|
||||||
|
|
||||||
|
@ -66,6 +71,8 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
/* VariableDeclaration */
|
/* VariableDeclaration */
|
||||||
else if(cast(VariableDeclaration)instruction)
|
else if(cast(VariableDeclaration)instruction)
|
||||||
{
|
{
|
||||||
|
gprintln("type: VariableDeclaration");
|
||||||
|
|
||||||
VariableDeclaration varDecInstr = cast(VariableDeclaration)instruction;
|
VariableDeclaration varDecInstr = cast(VariableDeclaration)instruction;
|
||||||
Context context = varDecInstr.getContext();
|
Context context = varDecInstr.getContext();
|
||||||
|
|
||||||
|
@ -89,6 +96,7 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
varDecWantsConsumeVarAss = true;
|
varDecWantsConsumeVarAss = true;
|
||||||
|
|
||||||
// Fetch the variable assignment instruction
|
// Fetch the variable assignment instruction
|
||||||
|
gprintln("Before crash: "~to!(string)(getCurrentInstruction()));
|
||||||
nextInstruction();
|
nextInstruction();
|
||||||
Instruction varAssInstr = getCurrentInstruction();
|
Instruction varAssInstr = getCurrentInstruction();
|
||||||
|
|
||||||
|
@ -103,6 +111,8 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
/* LiteralValue */
|
/* LiteralValue */
|
||||||
else if(cast(LiteralValue)instruction)
|
else if(cast(LiteralValue)instruction)
|
||||||
{
|
{
|
||||||
|
gprintln("type: LiteralValue");
|
||||||
|
|
||||||
LiteralValue literalValueInstr = cast(LiteralValue)instruction;
|
LiteralValue literalValueInstr = cast(LiteralValue)instruction;
|
||||||
|
|
||||||
return to!(string)(literalValueInstr.data);
|
return to!(string)(literalValueInstr.data);
|
||||||
|
@ -110,6 +120,8 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
/* FetchValueVar */
|
/* FetchValueVar */
|
||||||
else if(cast(FetchValueVar)instruction)
|
else if(cast(FetchValueVar)instruction)
|
||||||
{
|
{
|
||||||
|
gprintln("type: FetchValueVar");
|
||||||
|
|
||||||
FetchValueVar fetchValueVarInstr = cast(FetchValueVar)instruction;
|
FetchValueVar fetchValueVarInstr = cast(FetchValueVar)instruction;
|
||||||
Context context = fetchValueVarInstr.getContext();
|
Context context = fetchValueVarInstr.getContext();
|
||||||
|
|
||||||
|
@ -123,10 +135,56 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
/* BinOpInstr */
|
/* BinOpInstr */
|
||||||
else if(cast(BinOpInstr)instruction)
|
else if(cast(BinOpInstr)instruction)
|
||||||
{
|
{
|
||||||
|
gprintln("type: BinOpInstr");
|
||||||
|
|
||||||
BinOpInstr binOpInstr = cast(BinOpInstr)instruction;
|
BinOpInstr binOpInstr = cast(BinOpInstr)instruction;
|
||||||
|
|
||||||
return transform(binOpInstr.lhs)~to!(string)(getCharacter(binOpInstr.operator))~transform(binOpInstr.rhs);
|
return transform(binOpInstr.lhs)~to!(string)(getCharacter(binOpInstr.operator))~transform(binOpInstr.rhs);
|
||||||
}
|
}
|
||||||
|
/* FuncCallInstr */
|
||||||
|
else if(cast(FuncCallInstr)instruction)
|
||||||
|
{
|
||||||
|
gprintln("type: FuncCallInstr");
|
||||||
|
|
||||||
|
FuncCallInstr funcCallInstr = cast(FuncCallInstr)instruction;
|
||||||
|
Context context = funcCallInstr.getContext();
|
||||||
|
assert(context);
|
||||||
|
|
||||||
|
Function functionToCall = cast(Function)context.tc.getResolver().resolveBest(context.getContainer(), funcCallInstr.functionName); //TODO: Remove `auto`
|
||||||
|
|
||||||
|
// TODO: SymbolLookup?
|
||||||
|
|
||||||
|
string emit = functionToCall.getName()~"(";
|
||||||
|
|
||||||
|
//TODO: Insert argument passimng code here
|
||||||
|
//NOTE: Typechecker must have checked for passing arguments to a function that doesn't take any, for example
|
||||||
|
|
||||||
|
//NOTE (Behaviour): We may want to actually have an preinliner for these arguments
|
||||||
|
//such to enforce a certain ordering. I believe this should be done in the emitter stage,
|
||||||
|
//so it is best placed here
|
||||||
|
if(functionToCall.hasParams())
|
||||||
|
{
|
||||||
|
Value[] argumentInstructions = funcCallInstr.getEvaluationInstructions();
|
||||||
|
string argumentString;
|
||||||
|
|
||||||
|
for(ulong argIdx = 0; argIdx < argumentInstructions.length; argIdx++)
|
||||||
|
{
|
||||||
|
Value currentArgumentInstr = argumentInstructions[argIdx];
|
||||||
|
argumentString~=transform(currentArgumentInstr);
|
||||||
|
|
||||||
|
if(argIdx != (argumentInstructions.length-1))
|
||||||
|
{
|
||||||
|
argumentString~=", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit~=argumentString;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit ~= ")";
|
||||||
|
|
||||||
|
return emit;
|
||||||
|
}
|
||||||
|
|
||||||
return "<TODO: Base emit: "~to!(string)(instruction)~">";
|
return "<TODO: Base emit: "~to!(string)(instruction)~">";
|
||||||
}
|
}
|
||||||
|
@ -139,12 +197,13 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
|
|
||||||
emitStaticAllocations();
|
emitStaticAllocations();
|
||||||
|
|
||||||
gprintln("Function definitions needed: "~to!(string)(1)); //TODO: fix counter here
|
emitCodeQueue();
|
||||||
|
|
||||||
emitFunctionDefinitions();
|
emitFunctionDefinitions();
|
||||||
|
|
||||||
gprintln("\n\n\n");
|
gprintln("\n\n\n");
|
||||||
|
|
||||||
emitCodeQueue();
|
// emitCodeQueue();
|
||||||
|
|
||||||
gprintln("\n\n\n");
|
gprintln("\n\n\n");
|
||||||
|
|
||||||
|
@ -194,6 +253,8 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
{
|
{
|
||||||
selectQueue(QueueType.ALLOC_QUEUE);
|
selectQueue(QueueType.ALLOC_QUEUE);
|
||||||
gprintln("Static allocations needed: "~to!(string)(getQueueLength()));
|
gprintln("Static allocations needed: "~to!(string)(getQueueLength()));
|
||||||
|
|
||||||
|
file.writeln();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -201,6 +262,8 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
*/
|
*/
|
||||||
private void emitFunctionDefinitions()
|
private void emitFunctionDefinitions()
|
||||||
{
|
{
|
||||||
|
gprintln("Function definitions needed: "~to!(string)(getFunctionDefinitionsCount()));
|
||||||
|
|
||||||
Instruction[][string] functionBodyInstrs = typeChecker.getFunctionBodyCodeQueues();
|
Instruction[][string] functionBodyInstrs = typeChecker.getFunctionBodyCodeQueues();
|
||||||
|
|
||||||
string[] functionNames = getFunctionDefinitionNames();
|
string[] functionNames = getFunctionDefinitionNames();
|
||||||
|
@ -210,9 +273,8 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
foreach(string currentFunctioName; functionNames)
|
foreach(string currentFunctioName; functionNames)
|
||||||
{
|
{
|
||||||
emitFunctionDefinition(currentFunctioName);
|
emitFunctionDefinition(currentFunctioName);
|
||||||
|
file.writeln();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string generateSignature(Function func)
|
private string generateSignature(Function func)
|
||||||
|
@ -251,13 +313,10 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
|
|
||||||
private void emitFunctionDefinition(string functionName)
|
private void emitFunctionDefinition(string functionName)
|
||||||
{
|
{
|
||||||
// // Reset the cursor
|
|
||||||
// resetCFDCQCursor();
|
|
||||||
|
|
||||||
// // Set the function we want to examine in CodeEmitter
|
|
||||||
// setCurrentFunctionDefinition(functionName);
|
|
||||||
selectQueue(QueueType.FUNCTION_DEF_QUEUE, functionName);
|
selectQueue(QueueType.FUNCTION_DEF_QUEUE, functionName);
|
||||||
|
|
||||||
|
gprintln("emotFunctionDefinition(): Function: "~functionName~", with "~to!(string)(getSelectedQueueLength())~" many instructions");
|
||||||
|
|
||||||
//TODO: Look at nested definitions or nah? (Context!!)
|
//TODO: Look at nested definitions or nah? (Context!!)
|
||||||
//TODO: And what about methods defined in classes? Those should technically be here too
|
//TODO: And what about methods defined in classes? Those should technically be here too
|
||||||
Function functionEntity = cast(Function)typeChecker.getResolver().resolveBest(typeChecker.getModule(), functionName); //TODO: Remove `auto`
|
Function functionEntity = cast(Function)typeChecker.getResolver().resolveBest(typeChecker.getModule(), functionName); //TODO: Remove `auto`
|
||||||
|
@ -296,15 +355,23 @@ public final class DCodeEmitter : CodeEmitter
|
||||||
|
|
||||||
nextInstruction();
|
nextInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.writeln();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void emitEntryPoint()
|
private void emitEntryPoint()
|
||||||
{
|
{
|
||||||
//TODO: Implement me
|
//TODO: Implement me
|
||||||
|
|
||||||
|
// NOTE: Remove this printf
|
||||||
file.writeln(`
|
file.writeln(`
|
||||||
|
// NOTE: The below is testing code and should be removed
|
||||||
|
#include<stdio.h>
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
printf("k: %u\n", t_0c9714cea1ccdfdd0345347c86885620);
|
||||||
|
banana(1);
|
||||||
|
printf("k: %u\n", t_0c9714cea1ccdfdd0345347c86885620);
|
||||||
return 0;
|
return 0;
|
||||||
}`);
|
}`);
|
||||||
}
|
}
|
||||||
|
@ -326,21 +393,18 @@ int main()
|
||||||
//NOTE: Change to system compiler (maybe, we need to choose a good C compiler)
|
//NOTE: Change to system compiler (maybe, we need to choose a good C compiler)
|
||||||
Pid ccPID = spawnProcess(["clang", "-o", "tlang.out", file.name()]);
|
Pid ccPID = spawnProcess(["clang", "-o", "tlang.out", file.name()]);
|
||||||
|
|
||||||
//NOTE: Case where it exited and Pid now inavlid (if it happens it would throw processexception surely)?
|
|
||||||
int code = wait(ccPID);
|
int code = wait(ccPID);
|
||||||
gprintln(code);
|
|
||||||
|
|
||||||
if(code)
|
if(code)
|
||||||
{
|
{
|
||||||
//NOTE: Make this a TLang exception
|
//NOTE: Make this a TLang exception
|
||||||
throw new Exception("The CC exited with a non-zero exit code");
|
throw new Exception("The CC exited with a non-zero exit code ("~to!(string)(code)~")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(ProcessException e)
|
catch(ProcessException e)
|
||||||
{
|
{
|
||||||
gprintln("NOTE: Case where it exited and Pid now inavlid (if it happens it would throw processexception surely)?", DebugType.ERROR);
|
gprintln("NOTE: Case where it exited and Pid now inavlid (if it happens it would throw processexception surely)?", DebugType.ERROR);
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -244,7 +244,7 @@ public class FuncCallInstr : CallInstr
|
||||||
/* Per-argument instrructions */
|
/* Per-argument instrructions */
|
||||||
private Value[] evaluationInstructions;
|
private Value[] evaluationInstructions;
|
||||||
|
|
||||||
private string functionName;
|
public const string functionName;
|
||||||
|
|
||||||
this(string functionName, ulong argEvalInstrsSize)
|
this(string functionName, ulong argEvalInstrsSize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -713,12 +713,14 @@ public final class TypeChecker
|
||||||
/**
|
/**
|
||||||
* TODO:
|
* TODO:
|
||||||
*
|
*
|
||||||
* 1. Create FUncCallInstr
|
* 1. Create FuncCallInstr
|
||||||
* 2. Evaluate args and process them?! wait done elsewhere yeah!!!
|
* 2. Evaluate args and process them?! wait done elsewhere yeah!!!
|
||||||
* 3. Pop arts into here
|
* 3. Pop arts into here
|
||||||
* 4. AddInstr(combining those args)
|
* 4. AddInstr(combining those args)
|
||||||
* 5. DOne
|
* 5. DOne
|
||||||
*/
|
*/
|
||||||
|
funcCallInstr.context = funcCall.getContext();
|
||||||
|
|
||||||
addInstr(funcCallInstr);
|
addInstr(funcCallInstr);
|
||||||
addType(getType(func.parentOf(), func.getType()));
|
addType(getType(func.parentOf(), func.getType()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -410,7 +410,7 @@ public class DNodeGenerator
|
||||||
*
|
*
|
||||||
* This holds unique pool entries
|
* This holds unique pool entries
|
||||||
*/
|
*/
|
||||||
private DNode[] nodePool;
|
private static DNode[] nodePool;
|
||||||
|
|
||||||
this(TypeChecker tc)
|
this(TypeChecker tc)
|
||||||
{
|
{
|
||||||
|
@ -582,12 +582,21 @@ public class DNodeGenerator
|
||||||
FunctionCall funcCall = cast(FunctionCall)exp;
|
FunctionCall funcCall = cast(FunctionCall)exp;
|
||||||
gprintln("FuncCall: "~funcCall.getName());
|
gprintln("FuncCall: "~funcCall.getName());
|
||||||
|
|
||||||
|
|
||||||
/* TODO: We need to fetch the cached function definition here and call it */
|
/* TODO: We need to fetch the cached function definition here and call it */
|
||||||
Entity funcEntity = resolver.resolveWithin(context.container, funcCall.getName());
|
Entity funcEntity = resolver.resolveBest(context.container, funcCall.getName());
|
||||||
DNode funcDefDNode = retrieveFunctionDefinitionNode(tc.getResolver().generateName(tc.getModule(), funcEntity));
|
assert(funcEntity);
|
||||||
gprintln("FuncCall (FuncDefNode): "~to!(string)(funcDefDNode));
|
|
||||||
dnode.needs(funcDefDNode); /* NOTE: New code as of 4th October 2022 */
|
// FIXME: The below is failing (we probably need a forward look ahead?)
|
||||||
|
// OR use the addFuncDef list?
|
||||||
|
//WAIT! We don't need a funcDefNode actually. No, we lierally do not.
|
||||||
|
//Remmeber, they are done in a seperate pass, what we need is just our FUncCall DNode
|
||||||
|
// WHICH we have below as `dnode`!!!!
|
||||||
|
// DNode funcDefDNode = retrieveFunctionDefinitionNode(tc.getResolver().generateName(tc.getModule(), funcEntity));
|
||||||
|
// gprintln("FuncCall (FuncDefNode): "~to!(string)(funcDefDNode));
|
||||||
|
// dnode.needs(funcDefDNode); /* NOTE: New code as of 4th October 2022 */
|
||||||
|
|
||||||
|
//NOTE: Check if we need to set a context here to that of the context we occuring in
|
||||||
|
funcCall.context = context;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1276,9 +1285,6 @@ public class DNodeGenerator
|
||||||
{
|
{
|
||||||
VariableAssignmentStdAlone vAsStdAl = cast(VariableAssignmentStdAlone)entity;
|
VariableAssignmentStdAlone vAsStdAl = cast(VariableAssignmentStdAlone)entity;
|
||||||
|
|
||||||
/* Set the Context */
|
|
||||||
vAsStdAl.setContext(context);
|
|
||||||
|
|
||||||
/* TODO: CHeck avriable name even */
|
/* TODO: CHeck avriable name even */
|
||||||
gprintln("YEAST ENJOYER");
|
gprintln("YEAST ENJOYER");
|
||||||
|
|
||||||
|
@ -1286,10 +1292,14 @@ public class DNodeGenerator
|
||||||
// FIXME: The below assert fails for function definitions trying to refer to global values
|
// FIXME: The below assert fails for function definitions trying to refer to global values
|
||||||
// as a reoslveBest (up) is needed. We should firstly check if within fails, if so,
|
// as a reoslveBest (up) is needed. We should firstly check if within fails, if so,
|
||||||
// resolveBest, if that fails, then it is an error (see #46)
|
// resolveBest, if that fails, then it is an error (see #46)
|
||||||
assert(tc.getResolver().resolveWithin(c, vAsStdAl.getVariableName()));
|
assert(tc.getResolver().resolveBest(c, vAsStdAl.getVariableName()));
|
||||||
gprintln("YEAST ENJOYER");
|
gprintln("YEAST ENJOYER");
|
||||||
Variable variable = cast(Variable)tc.getResolver().resolveWithin(c, vAsStdAl.getVariableName());
|
Variable variable = cast(Variable)tc.getResolver().resolveBest(c, vAsStdAl.getVariableName());
|
||||||
assert(variable);
|
assert(variable);
|
||||||
|
|
||||||
|
/* Set the context of the assignment to the Context of the Variable being assigned to */
|
||||||
|
vAsStdAl.setContext(variable.getContext());
|
||||||
|
|
||||||
/* Pool the variable */
|
/* Pool the variable */
|
||||||
DNode varDecDNode = pool(variable);
|
DNode varDecDNode = pool(variable);
|
||||||
|
|
||||||
|
@ -1394,14 +1404,14 @@ public class DNodeGenerator
|
||||||
/* TODO: New code from 1st October */
|
/* TODO: New code from 1st October */
|
||||||
/* Recurse downwards */
|
/* Recurse downwards */
|
||||||
/* FIXME: The context container must be fixed, see passClazz, we pass the euiavlent of `func` in there */
|
/* FIXME: The context container must be fixed, see passClazz, we pass the euiavlent of `func` in there */
|
||||||
Context funcContext = new Context(tc.getModule(), InitScope.STATIC);
|
// Context funcContext = new Context(tc.getModule(), InitScope.STATIC);
|
||||||
DNode funcDefDNode = generalPass(func, funcContext);
|
// DNode funcDefDNode = generalPass(func, funcContext);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the function dnode for lookup later
|
* Save the function dnode for lookup later
|
||||||
*/
|
*/
|
||||||
saveFunctionDefinitionNode(funcDefDNode);
|
// saveFunctionDefinitionNode(funcDefDNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ module simple_function_decls;
|
||||||
int j = 21;
|
int j = 21;
|
||||||
int k = 22;
|
int k = 22;
|
||||||
|
|
||||||
int apple(int j)
|
int apple(int j, int arg2)
|
||||||
{
|
{
|
||||||
int h = 69;
|
int h = 69;
|
||||||
}
|
}
|
||||||
|
@ -11,5 +11,7 @@ int apple(int j)
|
||||||
int banana(int j)
|
int banana(int j)
|
||||||
{
|
{
|
||||||
int h = 64;
|
int h = 64;
|
||||||
k=1;
|
|
||||||
|
k=1+h+apple(1, apple(2, 3));
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue