- Added newline to release info print
- Fixed module docstring

Commands

- Added new command-line options: `syntaxcheck`, `typecheck`
- Added todo to `help` command
- Re-ordered commands for order of appearance in help text

Compiler

- Added docstring to `beginCompilation(string[])` function

Mapper

- Added debug print of the Container being used for the symbol lookup

CodeEmitter

- Re-worked CodeEmitter class to use a single so-called "selected queue"
- Added methods to move back and forth between said "selected queue", get the length, etc.
- Remove old queue-specific methods

DGen

- Use the new CodeEmitter "selected-queue" functionality
- Emit function definitions now supported

Exceptions

- Added this keyword

Check

- Added support for SymbolTYpe.OCURLY and SymbolType.CCURLY to `getCharacter(SymbolType)`

Data

- Added a `hasParams()` method to the Function entity type

TypeChecker

- Added support for emitting function definitions (required DNode.poes = [] (cleaning), codeQueue cleaning etc.)
- Added `getInitQueue()` method to make a copy of the current "scratchpad" `codeQueue`
- Build up a copy of the global queue now (make a copy similiar to what we did for `getInitQueue()` but inline)
- Added a debug print

Dependency

- Added a FIXME note for issue #46
- Added a TODO relating to `static DNode[] poes`

Test cases

- Added test case `simple_function_decls.t` to test function definition code emit
- Updated test case `simple_variables.t` to note that the T code generates invalid C code

README

- Build instructions now generate coverage files (`.lst`s)
- Updated link to documentation
This commit is contained in:
Tristan B. Velloza Kildaire 2022-12-14 19:49:08 +02:00
parent f17d38b74e
commit 8a481fb0ac
14 changed files with 613 additions and 117 deletions

View File

@ -3,16 +3,16 @@ tlang
Official Tristan Language project compiler
## Docs
## Documentation
Docs are available [here](http://deavmi.assigned.network/secret/tlang).
Docs are available [here](http://deavmi.assigned.network/projects/tlang/).
## Building
To build you will need `dmd` and `dub` installed. You can then run the following:
```
dub test
dub test --coverage
dub build
```

View File

@ -1,11 +1,9 @@
/**
* Tristan's programming language
*
* This is TOP SECRET code, not for RELEASE!
* Violators WILL BE PUT UP AGAINST A WALL AND
* SHOT!
*/
* TLP reference compiler
*
* This is the entry point for the TLP
* reference compiler.
*/
module tlang;
import std.stdio;
@ -14,7 +12,7 @@ import commandline.args;
void main(string[] args)
{
/* TODO: Replace with something else */
writeln("tlang NO_PUBLISH_RELEASE");
writeln("tlang NO_PUBLISH_RELEASE\n");
/* Parse the command-line arguments */
parseCommandLine(args);

View File

@ -1,8 +1,8 @@
/**
* Commands
*
* All command-line arguments and their impementations
*/
* Commands
*
* All command-line arguments and their impementations
*/
module commandline.commands;
@ -10,19 +10,11 @@ import jcli;
import std.stdio;
import compiler.compiler : beginCompilation;
import std.exception : ErrnoException;
import compiler.lexer : Lexer;
import compiler.lexer : Lexer, Token;
import compiler.parsing.core : Parser;
import compiler.typecheck.core : TypeChecker;
// import jcli.cli;
@Command("help", "Shows the help screen")
struct helpCommand
{
/* TODO: Add missing implementation for this */
void onExecute()
{
}
}
//TODO: Re-order the definitions below so that they appear with compile first, then lex, parse, ..., help
/**
* Compile the given source file from start to finish
@ -40,11 +32,6 @@ struct compileCommand
void onExecute()
{
writeln("Compiling source file: "~sourceFile);
/* TODO: Read file */
string sourceCode = "";
beginCompilation([sourceFile]);
}
}
@ -55,7 +42,7 @@ struct compileCommand
@Command("lex", "Performs tokenization of the given file(s)")
struct lexCommand
{
@ArgPositional("source file", "The source file to compile")
@ArgPositional("source file", "The source file to lex")
string sourceFile;
void onExecute()
@ -72,6 +59,7 @@ struct lexCommand
data.length = fSize;
data = file.rawRead(data);
string sourceText = cast(string)data;
file.close();
/* Begin lexing process */
Lexer lexer = new Lexer(sourceText);
@ -92,4 +80,175 @@ struct lexCommand
writeln("Could not open source file "~sourceFile);
}
}
}
@Command("syntaxcheck", "Check the syntax of the program")
struct parseCommand
{
@ArgPositional("source file", "The source file to check syntax of")
string sourceFile;
/* TODO: Add missing implementation for this */
void onExecute()
{
// TODO: Add call to typechecker here
try
{
/* Read the source file's data */
File file;
file.open(sourceFile, "r");
ulong fSize = file.size();
byte[] data;
data.length = fSize;
data = file.rawRead(data);
string sourceText = cast(string)data;
file.close();
/* Begin lexing process */
Lexer lexer = new Lexer(sourceText);
if(lexer.performLex())
{
Token[] tokens = lexer.getTokens();
writeln("=== Tokens ===\n");
writeln(tokens);
// TODO: Catch exception
Parser parser = new Parser(tokens);
// TODO: Do something with the returned module
auto modulel = parser.parse();
}
else
{
/* TODO: Is the lexer.performLex() return value used? */
writeln("There was an error whilst performing tokenization");
}
}
catch(ErrnoException e)
{
/* TODO: Use gogga error */
writeln("Could not open source file "~sourceFile);
}
}
}
@Command("typecheck", "Perform typechecking on the program")
struct typecheckCommand
{
@ArgPositional("source file", "The source file to typecheck")
string sourceFile;
/* TODO: Add missing implementation for this */
void onExecute()
{
// TODO: Add call to typechecker here
try
{
/* Read the source file's data */
File file;
file.open(sourceFile, "r");
ulong fSize = file.size();
byte[] data;
data.length = fSize;
data = file.rawRead(data);
string sourceText = cast(string)data;
file.close();
/* Begin lexing process */
Lexer lexer = new Lexer(sourceText);
if(lexer.performLex())
{
Token[] tokens = lexer.getTokens();
writeln("=== Tokens ===\n");
writeln(tokens);
// TODO: Catch exception
Parser parser = new Parser(tokens);
// TODO: Do something with the returned module
auto modulel = parser.parse();
//TODO: collect results here
//TODO: catch exceptions
TypeChecker typeChecker = new TypeChecker(modulel);
typeChecker.beginCheck();
}
else
{
/* TODO: Is the lexer.performLex() return value used? */
writeln("There was an error whilst performing tokenization");
}
}
catch(ErrnoException e)
{
/* TODO: Use gogga error */
writeln("Could not open source file "~sourceFile);
}
}
}
// @Command("emit", "Perform emitting on the program")
// struct emitCommand
// {
// @ArgPositional("source file", "The source file to emit")
// string sourceFile;
// /* TODO: Add missing implementation for this */
// void onExecute()
// {
// // TODO: Add call to typechecker here
// try
// {
// /* Read the source file's data */
// File file;
// file.open(sourceFile, "r");
// ulong fSize = file.size();
// byte[] data;
// data.length = fSize;
// data = file.rawRead(data);
// string sourceText = cast(string)data;
// file.close();
// /* Begin lexing process */
// Lexer lexer = new Lexer(sourceText);
// if(lexer.performLex())
// {
// Token[] tokens = lexer.getTokens();
// writeln("=== Tokens ===\n");
// writeln(tokens);
// // TODO: Catch exception
// Parser parser = new Parser(tokens);
// // TODO: Do something with the returned module
// auto modulel = parser.parse();
// //TODO: collect results here
// //TODO: catch exceptions
// TypeChecker typeChecker = new TypeChecker(modulel);
// typeChecker.beginCheck();
// //TODO: emit is basically full cpmpile or nah? we should write emit to stdout actually
// //or nah?
// }
// else
// {
// /* TODO: Is the lexer.performLex() return value used? */
// writeln("There was an error whilst performing tokenization");
// }
// }
// catch(ErrnoException e)
// {
// /* TODO: Use gogga error */
// writeln("Could not open source file "~sourceFile);
// }
// }
// }
@Command("help", "Shows the help screen")
struct helpCommand
{
/* TODO: Add missing implementation for this */
void onExecute()
{
/* TODO: We want to show the commands list, not a seperate help command */
}
}

View File

@ -8,6 +8,8 @@ import std.stdio;
import std.file;
import compiler.codegen.instruction : Instruction;
import std.range : walkLength;
import gogga;
import std.conv : to;
/**
* TODO: Perhaps have an interface that can emit(Context/Parent, Statement)
@ -19,65 +21,157 @@ public abstract class CodeEmitter
{
protected TypeChecker typeChecker;
/**
* The selected queue is the queue to be used
* when using the cursor instructions such as
* `nextInstruction()`, `previousInstruction()`
* etc.
*/
private Instruction[] selectedQueue;
public enum QueueType
{
ALLOC_QUEUE,
GLOBALS_QUEUE,
FUNCTION_DEF_QUEUE
}
private ulong queueCursor = 0;
public final void selectQueue(QueueType queueType, string funcDefName = "")
{
// Move the cursor back to the starting position
resetCursor();
if(queueType == QueueType.ALLOC_QUEUE)
{
selectedQueue = initQueue;
}
else if(queueType == QueueType.GLOBALS_QUEUE)
{
selectedQueue = globalCodeQueue;
}
else
{
//TODO: Ensure valid name by lookup via tc
selectedQueue = functionBodyInstrs[funcDefName];
}
}
public final void resetCursor()
{
queueCursor = 0;
}
public final void nextInstruction()
{
// TODO: Sanity check on length
queueCursor++;
}
public final void previousInstruction()
{
// TODO: Sanity check on lenght
queueCursor--;
}
public final bool hasInstructions()
{
return queueCursor < selectedQueue.length;
}
public final Instruction getCurrentInstruction()
{
return selectedQueue[queueCursor];
}
/**
* Required queues
*/
private Instruction[] initQueue;
private Instruction[] codeQueue;
private Instruction[] globalCodeQueue;
/**
* Required queues (maps to them)
*/
private Instruction[][string] functionBodyInstrs;
// alias instructions = codeQueue;
protected File file;
private ulong codeQueueIdx = 0;
public final Instruction getCurrentCodeInstruction()
public final ulong getQueueLength()
{
return codeQueue[codeQueueIdx];
}
public final bool hasCodeInstructions()
{
return codeQueueIdx < codeQueue.length;
}
public final void nextCodeInstruction()
{
codeQueueIdx++;
}
public final void previousCodeInstruction()
{
codeQueueIdx--;
return selectedQueue.length;
}
public final ulong getInitQueueLen()
public final string[] getFunctionDefinitionNames()
{
return initQueue.length;
return functionBodyInstrs.keys();
}
public final ulong getCodeQueueLen()
/**
* 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()
{
return codeQueue.length;
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;
/* Extract the allocation queue, the code queue */
foreach(Instruction currentInstruction; typeChecker.getInitQueue())
{
initQueue~=currentInstruction;
}
foreach(Instruction currentInstruction; typeChecker.getCodeQueue())
{
codeQueue~=currentInstruction;
}
initQueue = typeChecker.getInitQueue();
globalCodeQueue = typeChecker.getGlobalCodeQueue();
/* Extract the function definitions string-queue mapping */
functionBodyInstrs = typeChecker.getFunctionBodyCodeQueues();
gprintln("CodeEmitter: Got number of function defs: "~to!(string)(functionBodyInstrs));
this.file = file;
}

View File

@ -12,17 +12,14 @@ import gogga;
import std.range : walkLength;
import std.string : wrap;
import std.process : spawnProcess, Pid, ProcessException, wait;
import compiler.typecheck.dependency.core : Context;
import compiler.typecheck.dependency.core : Context, FunctionData, DNode;
import compiler.codegen.mapper : SymbolMapper;
import compiler.symbols.data : SymbolType, Variable;
import compiler.symbols.data : SymbolType, Variable, Function;
import compiler.symbols.check : getCharacter;
import misc.utils : Stack;
public final class DCodeEmitter : CodeEmitter
{
private Stack!(Instruction) varAssStack;
{
// Set to true when processing a variable declaration
// which expects an assignment. Set to false when
// said variable assignment has been processed
@ -32,12 +29,12 @@ public final class DCodeEmitter : CodeEmitter
this(TypeChecker typeChecker, File file)
{
super(typeChecker, file);
varAssStack = new Stack!(Instruction)();
}
public override string transform(const Instruction instruction)
{
gprintln("transform(): "~to!(string)(instruction));
/* VariableAssignmentInstr */
if(cast(VariableAssignmentInstr)instruction)
{
@ -92,8 +89,8 @@ public final class DCodeEmitter : CodeEmitter
varDecWantsConsumeVarAss = true;
// Fetch the variable assignment instruction
nextCodeInstruction();
Instruction varAssInstr = getCurrentCodeInstruction();
nextInstruction();
Instruction varAssInstr = getCurrentInstruction();
// Generate the code to emit
return varDecInstr.varType~" "~renamedSymbol~" = "~transform(varAssInstr)~";";
@ -140,12 +137,17 @@ public final class DCodeEmitter : CodeEmitter
// Emit header comment (NOTE: Change this to a useful piece of text)
emitHeaderComment("Place any extra information by code generator here"); // NOTE: We can pass a string with extra information to it if we want to
gprintln("Static allocations needed: "~to!(string)(getInitQueueLen()));
emitStaticAllocations();
gprintln("Code emittings needed: "~to!(string)(getCodeQueueLen()));
gprintln("Function definitions needed: "~to!(string)(1)); //TODO: fix counter here
emitFunctionDefinitions();
gprintln("\n\n\n");
emitCodeQueue();
gprintln("\n\n\n");
//TODO: Emit function definitions
//TODO: Emit main (entry point)
@ -190,17 +192,109 @@ public final class DCodeEmitter : CodeEmitter
*/
private void emitStaticAllocations()
{
selectQueue(QueueType.ALLOC_QUEUE);
gprintln("Static allocations needed: "~to!(string)(getQueueLength()));
}
/**
* TOOD: We should have an nextInstruction() esque thing for this
*/
private void emitFunctionDefinitions()
{
Instruction[][string] functionBodyInstrs = typeChecker.getFunctionBodyCodeQueues();
string[] functionNames = getFunctionDefinitionNames();
gprintln("WOAH: "~to!(string)(functionNames));
foreach(string currentFunctioName; functionNames)
{
emitFunctionDefinition(currentFunctioName);
}
}
private string generateSignature(Function func)
{
string signature;
// <type> <functionName> (
signature = func.getType()~" "~func.getName()~"(";
// Generate parameter list
if(func.hasParams())
{
Variable[] parameters = func.getParams();
string parameterString;
for(ulong parIdx = 0; parIdx < parameters.length; parIdx++)
{
Variable currentParameter = parameters[parIdx];
parameterString~=currentParameter.getType()~" "~currentParameter.getName();
if(parIdx != (parameters.length-1))
{
parameterString~=", ";
}
}
signature~=parameterString;
}
// )
signature~=")";
return signature;
}
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);
//TODO: Look at nested definitions or nah? (Context!!)
//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`
// Emit the function signature
file.writeln(generateSignature(functionEntity));
// Emit opening curly brace
file.writeln(getCharacter(SymbolType.OCURLY));
// Emit body
while(hasInstructions())
{
Instruction curFuncBodyInstr = getCurrentInstruction();
string emit = transform(curFuncBodyInstr);
gprintln("emitFunctionDefinition("~functionName~"): Emit: "~emit);
file.writeln("\t"~emit);
nextInstruction();
}
// Emit closing curly brace
file.writeln(getCharacter(SymbolType.CCURLY));
}
private void emitCodeQueue()
{
while(hasCodeInstructions())
selectQueue(QueueType.GLOBALS_QUEUE);
gprintln("Code emittings needed: "~to!(string)(getQueueLength()));
while(hasInstructions())
{
Instruction currentInstruction = getCurrentCodeInstruction();
Instruction currentInstruction = getCurrentInstruction();
file.writeln(transform(currentInstruction));
nextCodeInstruction();
nextInstruction();
}
}

View File

@ -2,6 +2,8 @@ module compiler.codegen.mapper;
import compiler.typecheck.core;
import compiler.symbols.data;
import std.conv : to;
import gogga;
/**
* SymbolMapper
@ -28,6 +30,8 @@ public final class SymbolMapper
auto entity = tc.getResolver().resolveBest(container, entityNameIn); //TODO: Remove `auto`
string entityNameAbsolute = tc.getResolver().generateName(tc.getModule(), entity);
gprintln("symbolLookup(): "~to!(string)(container));
// Hash the absolute path name
// FIXME: Ensure these hashes are unique (use the smbyol table!)
import std.digest : toHexString, LetterCase;

View File

@ -13,6 +13,12 @@ import core.stdc.stdlib;
import compiler.codegen.emit.core;
import compiler.codegen.emit.dgen;
/**
* Performs compilation of the provided module(s)
*
* Params:
* sourceFiles = The module(s) to perform compilation with
*/
void beginCompilation(string[] sourceFiles)
{
/* TODO: Begin compilation process, take in data here */

View File

@ -17,8 +17,6 @@ public class ParserException : TError
super(message);
this.parser = parser;
}
}
public final class SyntaxError : ParserException
@ -30,7 +28,7 @@ public final class SyntaxError : ParserException
this(Parser parser, SymbolType expected, Token providedToken)
{
this.expected = expected;
provided = getSymbolType(providedToken);
this.provided = getSymbolType(providedToken);
this.providedToken = providedToken;
super(parser, "Syntax error: Expected "~to!(string)(expected)~" but got "~to!(string)(provided)~", see "~providedToken.toString());

View File

@ -482,6 +482,14 @@ public string getCharacter(SymbolType symbolIn)
{
return "/";
}
else if(symbolIn == SymbolType.OCURLY)
{
return "{";
}
else if(symbolIn == SymbolType.CCURLY)
{
return "}";
}
else
{
gprintln("getCharacter: No back-mapping for "~to!(string)(symbolIn), DebugType.ERROR);

View File

@ -253,6 +253,11 @@ public class Function : TypedEntity, Container
return params;
}
public bool hasParams()
{
return params.length != 0;
}
public void addStatement(Statement statement)
{
this.bodyStatements~=statement;

View File

@ -86,43 +86,144 @@ public final class TypeChecker
gprintln(tree);
/* Grab functionData ??? */
FunctionData[string] functions = grabFunctionDefs();
gprintln("Defined functions: "~to!(string)(functions));
/* TODO: Disable, this is just to peep */
// foreach(FunctionData funcData; functions.values)
// {
// DNode funcNode = funcData.generate();
// DNode[] actionListFunc = funcNode.poes;
// doTypeCheck(actionListFunc);
// printTypeQueue();
// gprintln(funcNode.print());
// }
/* TODO: Work in progress (NEW!!!) */
/* Get the action-list (linearised bottom up graph) */
DNode[] actionList = rootNode.poes;
doTypeCheck(actionList);
printTypeQueue();
/**
* TODO: What's next?
*
* 1. Fetch the tree from the DNodeGenerator
*/
* After processing globals executions the instructions will
* be placed into `codeQueue`, therefore copy them from the temporary
* scratchpad queue into `globalCodeQueue`.
*
* Then clean the codeQueue for next use
*/
foreach(Instruction curGlobInstr; codeQueue)
{
globalCodeQueue~=curGlobInstr;
}
codeQueue.clear();
assert(codeQueue.empty() == true);
//FIXME: Look at this, ffs why is it static
//Clear tree/linearized version (todo comment)
DNode.poes=[];
/* Grab functionData ??? */
FunctionData[string] functionDefinitions = grabFunctionDefs();
gprintln("Defined functions: "~to!(string)(functionDefinitions));
foreach(FunctionData funcData; functionDefinitions.values)
{
assert(codeQueue.empty() == true);
DNode funcNode = funcData.generate();
//NOTE: We need to call this, it generates tree but also does the linearization
//NOTE: Rename that
funcNode.print();
DNode[] actionListFunc = funcNode.poes;
//TODO: Would this not mess with our queues?
doTypeCheck(actionListFunc);
printTypeQueue();
gprintln(funcNode.print());
// The current code queue would be the function's body instructions
// a.k.a. the `codeQueue`
// functionBodies[funcData.name] = codeQueue;
// The call to `doTypeCheck()` above adds to this queue
// so we should clean it out before the next run
//
// NOTE: Static allocations in? Well, we don't clean init queue
// so is it fine then? We now have seperate dependency trees,
// we should make checking methods that check the `initQueue`
// whenever we come past a `ClassStaticNode` for example
// codeQueue.clear();
/**
* Copy over the function code queue into
* the function code queue respective key.
*
* Then clear the scratchpad code queue
*/
functionBodyCodeQueues[funcData.name]=[];
foreach(Instruction curFuncInstr; codeQueue)
{
//TODO: Think about class funcs? Nah
functionBodyCodeQueues[funcData.name]~=curFuncInstr;
gprintln("FuncDef ("~funcData.name~"): Adding body instruction: "~to!(string)(curFuncInstr));
}
codeQueue.clear();
// Clear the linearization for the next round
DNode.poes=[];
gprintln("FUNCDEF DONE: "~to!(string)(functionBodyCodeQueues[funcData.name]));
}
}
/* Main code queue */
private SList!(Instruction) codeQueue;
/**
* Function definitions
*
* Holds their action lists which are to be used for the
* (later) emitting of their X-lang emit code
*/
//FUnctionDeifnition should couple `linearizedList` but `functionEntity`
// private FunctionDefinition[string] functionDefinitions2; //TODO: Use this
/**
* Concrete queues
*
* These queues below are finalized and not used as a scratchpad.
*
* 1. Global code queue
* - This accounts for the globals needing to be executed
* 2. Function body code queues
* - This accounts for (every) function definition's code queue
*/
private Instruction[] globalCodeQueue;
private Instruction[][string] functionBodyCodeQueues;
public Instruction[] getGlobalCodeQueue()
{
return globalCodeQueue;
}
public Instruction[][string] getFunctionBodyCodeQueues()
{
return functionBodyCodeQueues;
}
/* Main code queue (used for temporary passes) */
private SList!(Instruction) codeQueue; //TODO: Rename to `currentCodeQueue`
/* Initialization queue */
private SList!(Instruction) initQueue;
public SList!(Instruction) getInitQueue()
//TODO: CHange to oneshot in the function
public Instruction[] getInitQueue()
{
return initQueue;
Instruction[] initQueueConcrete;
foreach(Instruction currentInstruction; initQueue)
{
initQueueConcrete~=currentInstruction;
}
return initQueueConcrete;
}
/* Adds an initialization instruction to the initialization queue (at the back) */
@ -176,10 +277,17 @@ public final class TypeChecker
return codeQueue.empty;
}
public SList!(Instruction) getCodeQueue()
{
return codeQueue;
}
// public Instruction[] getCodeQueue()
// {
// Instruction[] codeQueueConcrete;
// foreach(Instruction currentInstruction; codeQueue)
// {
// codeQueueConcrete~=currentInstruction;
// }
// return codeQueueConcrete;
// }
/*
* Prints the current contents of the code-queue
@ -702,7 +810,8 @@ public final class TypeChecker
/* TODO: Get the STatement */
Statement statement = dnode.getEntity();
gprintln("Generic DNode typecheck(): Begin");
gprintln("Generic DNode typecheck(): Begin (examine: "~to!(string)(dnode)~" )");
/* VariableAssignmentStdAlone */
if(cast(VariableAssignmentStdAlone)statement)

View File

@ -163,7 +163,8 @@ public class DNode
private DNode[] dependencies;
//TODO: Commen this
//NOTE: This is the linearized version
public static DNode[] poes;
this(DNodeGenerator dnodegen, Statement entity)
@ -1280,6 +1281,11 @@ public class DNodeGenerator
/* TODO: CHeck avriable name even */
gprintln("YEAST ENJOYER");
// 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,
// resolveBest, if that fails, then it is an error (see #46)
assert(tc.getResolver().resolveWithin(c, vAsStdAl.getVariableName()));
gprintln("YEAST ENJOYER");
Variable variable = cast(Variable)tc.getResolver().resolveWithin(c, vAsStdAl.getVariableName());

View File

@ -0,0 +1,15 @@
module simple_function_decls;
int j = 21;
int k = 22;
int apple(int j)
{
int h = 69;
}
int banana(int j)
{
int h = 64;
k=1;
}

View File

@ -3,7 +3,7 @@ module simple_variables_decls_ass;
int x = 1+2*2/1-6;
discard "TDOO: Technically also not allowed (not compile-time constant in C)"
discard "TDOO: Technically also not allowed (not compile-time constant in C)";
int y = 2+x;
discard "TODO: Technically the below should not be allowed as we cannot do it in C - sadly";