- Added comments and removed TODO for now complete feature on `parseTypedDeclaration()`

Dependency

- Added support for external variable symbols to `transform()` for declarations, assignments and variable expressions

Test cases

- Updated extern evar test case to new symbol name that wouldn't clash
- Added assignment usage and expression usage
This commit is contained in:
Tristan B. Velloza Kildaire 2023-01-19 09:03:19 +02:00
parent cb42713377
commit 9e79bc6f8b
3 changed files with 72 additions and 47 deletions

View File

@ -120,23 +120,33 @@ public final class DCodeEmitter : CodeEmitter
gprintln("Wazza contect: "~to!(string)(context.container));
auto typedEntityVariable = context.tc.getResolver().resolveBest(context.getContainer(), varAs.varName); //TODO: Remove `auto`
string renamedSymbol = SymbolMapper.symbolLookup(typedEntityVariable);
// If we are needed as part of a VariabvleDeclaration-with-assignment
if(varDecWantsConsumeVarAss)
/* If it is not external */
if(!typedEntityVariable.isExternal())
{
// Generate the code to emit (only the RHS of the = sign)
string emitCode = transform(varAs.data);
string renamedSymbol = SymbolMapper.symbolLookup(typedEntityVariable);
// Reset flag
varDecWantsConsumeVarAss = false;
// If we are needed as part of a VariabvleDeclaration-with-assignment
if(varDecWantsConsumeVarAss)
{
// Generate the code to emit (only the RHS of the = sign)
string emitCode = transform(varAs.data);
return emitCode;
// Reset flag
varDecWantsConsumeVarAss = false;
return emitCode;
}
return renamedSymbol~" = "~transform(varAs.data)~";";
}
/* If it is external */
else
{
return typedEntityVariable.getName()~" = "~transform(varAs.data)~";";
}
return renamedSymbol~" = "~transform(varAs.data)~";";
}
/* VariableDeclaration */
else if(cast(VariableDeclaration)instruction)
@ -148,36 +158,44 @@ public final class DCodeEmitter : CodeEmitter
Variable typedEntityVariable = cast(Variable)context.tc.getResolver().resolveBest(context.getContainer(), varDecInstr.varName); //TODO: Remove `auto`
//NOTE: We should remove all dots from generated symbol names as it won't be valid C (I don't want to say C because
// a custom CodeEmitter should be allowed, so let's call it a general rule)
//
//simple_variables.x -> simple_variables_x
//NOTE: We may need to create a symbol table actually and add to that and use that as these names
//could get out of hand (too long)
// NOTE: Best would be identity-mapping Entity's to a name
string renamedSymbol = SymbolMapper.symbolLookup(typedEntityVariable);
// Check to see if this declaration has an assignment attached
if(typedEntityVariable.getAssignment())
/* If the variable is not external */
if(!typedEntityVariable.isExternal())
{
// Set flag to expect different transform generation for VariableAssignment
varDecWantsConsumeVarAss = true;
//NOTE: We should remove all dots from generated symbol names as it won't be valid C (I don't want to say C because
// a custom CodeEmitter should be allowed, so let's call it a general rule)
//
//simple_variables.x -> simple_variables_x
//NOTE: We may need to create a symbol table actually and add to that and use that as these names
//could get out of hand (too long)
// NOTE: Best would be identity-mapping Entity's to a name
string renamedSymbol = SymbolMapper.symbolLookup(typedEntityVariable);
// Fetch the variable assignment instruction
// gprintln("Before crash: "~to!(string)(getCurrentInstruction()));
// nextInstruction();
// Instruction varAssInstr = getCurrentInstruction();
VariableAssignmentInstr varAssInstr = varDecInstr.getAssignmentInstr();
// Generate the code to emit
return typeTransform(cast(Type)varDecInstr.varType)~" "~renamedSymbol~" = "~transform(varAssInstr)~";";
// Check to see if this declaration has an assignment attached
if(typedEntityVariable.getAssignment())
{
// Set flag to expect different transform generation for VariableAssignment
varDecWantsConsumeVarAss = true;
// Fetch the variable assignment instruction
// gprintln("Before crash: "~to!(string)(getCurrentInstruction()));
// nextInstruction();
// Instruction varAssInstr = getCurrentInstruction();
VariableAssignmentInstr varAssInstr = varDecInstr.getAssignmentInstr();
// Generate the code to emit
return typeTransform(cast(Type)varDecInstr.varType)~" "~renamedSymbol~" = "~transform(varAssInstr)~";";
}
return typeTransform(cast(Type)varDecInstr.varType)~" "~renamedSymbol~";";
}
/* If the variable is external */
else
{
return "extern "~typeTransform(cast(Type)varDecInstr.varType)~" "~typedEntityVariable.getName()~";";
}
return typeTransform(cast(Type)varDecInstr.varType)~" "~renamedSymbol~";";
}
/* LiteralValue */
else if(cast(LiteralValue)instruction)
@ -198,12 +216,21 @@ public final class DCodeEmitter : CodeEmitter
Variable typedEntityVariable = cast(Variable)context.tc.getResolver().resolveBest(context.getContainer(), fetchValueVarInstr.varName); //TODO: Remove `auto`
//TODO: THis is giving me kak (see issue #54), it's generating name but trying to do it for the given container, relative to it
//TODO: We might need a version of generateName that is like generatenamebest (currently it acts like generatename, within)
/* If it is not external */
if(!typedEntityVariable.isExternal())
{
//TODO: THis is giving me kak (see issue #54), it's generating name but trying to do it for the given container, relative to it
//TODO: We might need a version of generateName that is like generatenamebest (currently it acts like generatename, within)
string renamedSymbol = SymbolMapper.symbolLookup(typedEntityVariable);
string renamedSymbol = SymbolMapper.symbolLookup(typedEntityVariable);
return renamedSymbol;
return renamedSymbol;
}
/* If it is external */
else
{
return typedEntityVariable.getName();
}
}
/* BinOpInstr */
else if(cast(BinOpInstr)instruction)

View File

@ -1366,6 +1366,7 @@ public final class Parser
// Only continue is function definitions are allowed
if(allowFuncDef)
{
/* Will consume the `}` (or `;` if wantsBody-false) */
funcDefPair pair = parseFuncDef(wantsBody);
generated = new Function(identifier, type, pair.bodyStatements, pair.params);
@ -1854,11 +1855,6 @@ public final class Parser
expect("Expected either extern function (efunc) or extern variable (evar)");
}
// TODO: If we are doing all this semi-colon stuff in `parseTypedDecaration()` then we ought
// ... to put the below code in there. Compare body ending `}` and nextToken()'ing it
// ... to a vardec finishing on `;` and then returning to `parseName()` which does nothing
// ... we could seem how we go about this, perhaps body is the exception case, and we should
// ... be nextToken()'ing and before that exoecting in `parseName()` and here, `parseExtern()'
/* Expect a semicolon to end it all and then consume it */
expect(SymbolType.SEMICOLON, getCurrentToken());
nextToken();

View File

@ -1,10 +1,12 @@
module simple_extern;
extern efunc uint write(uint fd, ubyte* buffer, uint count);
extern evar int stdin;
extern evar int kak;
void test()
{
ubyte* buff;
discard write(cast(uint)0, buff, cast(uint)1001);
kak = kak + 1;
}