- 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)); 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 renamedSymbol = SymbolMapper.symbolLookup(typedEntityVariable);
/* If it is not external */
// If we are needed as part of a VariabvleDeclaration-with-assignment if(!typedEntityVariable.isExternal())
if(varDecWantsConsumeVarAss)
{ {
// Generate the code to emit (only the RHS of the = sign) string renamedSymbol = SymbolMapper.symbolLookup(typedEntityVariable);
string emitCode = transform(varAs.data);
// 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 */ /* VariableDeclaration */
else if(cast(VariableDeclaration)instruction) 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` 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 /* If the variable is not external */
// a custom CodeEmitter should be allowed, so let's call it a general rule) if(!typedEntityVariable.isExternal())
//
//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())
{ {
// Set flag to expect different transform generation for VariableAssignment //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
varDecWantsConsumeVarAss = true; // 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 // Check to see if this declaration has an assignment attached
return typeTransform(cast(Type)varDecInstr.varType)~" "~renamedSymbol~" = "~transform(varAssInstr)~";"; 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 */ /* LiteralValue */
else if(cast(LiteralValue)instruction) 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` 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 /* If it is not external */
//TODO: We might need a version of generateName that is like generatenamebest (currently it acts like generatename, within) 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 */ /* BinOpInstr */
else if(cast(BinOpInstr)instruction) else if(cast(BinOpInstr)instruction)

View File

@ -1366,6 +1366,7 @@ public final class Parser
// Only continue is function definitions are allowed // Only continue is function definitions are allowed
if(allowFuncDef) if(allowFuncDef)
{ {
/* Will consume the `}` (or `;` if wantsBody-false) */
funcDefPair pair = parseFuncDef(wantsBody); funcDefPair pair = parseFuncDef(wantsBody);
generated = new Function(identifier, type, pair.bodyStatements, pair.params); 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)"); 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 a semicolon to end it all and then consume it */
expect(SymbolType.SEMICOLON, getCurrentToken()); expect(SymbolType.SEMICOLON, getCurrentToken());
nextToken(); nextToken();

View File

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