diff --git a/source/tlang/compiler/codegen/emit/dgen.d b/source/tlang/compiler/codegen/emit/dgen.d index 19caaa4..535c875 100644 --- a/source/tlang/compiler/codegen/emit/dgen.d +++ b/source/tlang/compiler/codegen/emit/dgen.d @@ -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) diff --git a/source/tlang/compiler/parsing/core.d b/source/tlang/compiler/parsing/core.d index 7736614..39e50e6 100644 --- a/source/tlang/compiler/parsing/core.d +++ b/source/tlang/compiler/parsing/core.d @@ -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(); diff --git a/source/tlang/testing/simple_extern.t b/source/tlang/testing/simple_extern.t index d523a84..02bf836 100644 --- a/source/tlang/testing/simple_extern.t +++ b/source/tlang/testing/simple_extern.t @@ -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; } \ No newline at end of file