- Refer .asm library imported global variables to the the namespace where the global variable resides.

- Generalized the AsmLibrary procedures to symbols, to also allow exporting variables.
- Removed the initialization part of .asm library header generation for global exported variables.
- The directive __asm_export can now also be used to indicate global variables exporting within C libraries (for potential .asm library generation).
- Converted the usage of typedef to struct for __conio global variable in cx16_conio.c
- Updated example code.
- Fixed a bug where for exported structs and imported structs, the variables were defined as volatile to non-volatile.
- VariableBuilder constructor now also received the program variable to refer to program level configurations defined.
- Remove to declare string constants as .asm library exported global variables.
- Removed the optimization PassNAsmLibraryGlobalVarsExport. It is not needed. Each global variable export must be explicitly declared using asm_export or __asm_export.
- Improved naming of variables and procedures to retrieve and manage import and export libraries within the program.
This commit is contained in:
Flight_Control 2024-04-26 12:40:14 +03:00
parent 00df07b7bf
commit 1a53d6a913
17 changed files with 111 additions and 130 deletions

View File

@ -421,7 +421,6 @@ public class Compiler {
optimizations.add(new PassNEliminateUnusedVars(program, true)); // Notice sequence is important
optimizations.add(new PassNEliminateEmptyProcedure(program));
optimizations.add(new PassNEliminateEmptyStart(program));
optimizations.add(new PassNAsmLibraryGlobalVarsExport(program));
if(enableLoopHeadConstant) {
optimizations.add(new PassNStatementIndices(program));
optimizations.add(() -> {

View File

@ -431,7 +431,7 @@ public class KickC implements Callable<Integer> {
// In case of asm library exports, we generate the exported procedure prototypes,
// to be imported into the C program. These prototypes set the register and zeropage usages.
// TODO: I need to add an assert function to validate that each exported procedure is also declared and defined!
for(AsmLibrary asmLibrary : program.getAsmExports().values()) {
for(AsmLibrary asmLibrary : program.getAsmExportLibraries().values()) {
String headers = asmLibrary.generateHeaders(program);
Path asmExportHeaderPath = program.getOutputFileManager().getAsmExportHeaderFile();
System.out.println("Writing asm export header file " + asmExportHeaderPath);

View File

@ -321,13 +321,18 @@ public class AsmFormat {
// Explicit reference to global symbol
return "@" + asmFix(asmName);
else
// Implicit reference to global symbol
if (symbol instanceof Procedure) {
// Implicit reference to imported .asm library procedure.
String namespace = ((Procedure)symbol).getAsmLibraryLabel();
if (namespace != null)
asmName = namespace + "." + asmName;
} else if(symbol instanceof Variable var) {
// Implicit reference to imported global .asm library variable.
String namespace = ((Variable)symbol).getImportAsmLibrary();
if(namespace != null)
asmName = namespace + "." + asmName;
}
return asmFix(asmName);
return asmFix(asmName);
}
} else {
// Reference to local symbol

View File

@ -29,35 +29,35 @@ public class AsmLibrary extends AsmLine {
private final AsmIdentifier asmLibraryName;
private final HashMap<String, Procedure.CallingConvention> procedures;
private final HashMap<String, Procedure.CallingConvention> symbols;
public AsmLibrary(String asmLibraryName, Path resource, HashMap<String, Procedure.CallingConvention> procedures) {
public AsmLibrary(String asmLibraryName, Path resource, HashMap<String, Procedure.CallingConvention> symbols) {
if(asmLibraryName!=null) {
this.asmLibraryName = new AsmIdentifier(asmLibraryName);
} else {
this.asmLibraryName = null;
}
this.procedures = procedures;
this.symbols = symbols;
}
public AsmLibrary(String asmLibraryName, Path resource) {
this(asmLibraryName, resource, new LinkedHashMap<>());
}
public Set<String> getProcedures() {
return this.procedures.keySet();
public Set<String> getSymbols() {
return this.symbols.keySet();
}
public void addProcedure(String procedureName, Procedure.CallingConvention callingConvention) {
procedures.put(procedureName, callingConvention);
public void addSymbol(String symbolName, Procedure.CallingConvention callingConvention) {
symbols.put(symbolName, callingConvention);
}
public Procedure.CallingConvention getProcedureCallingConvention(String procedureName) {
return procedures.get(procedureName);
return symbols.get(procedureName);
}
public boolean hasProcedure(String procedureName) {
return procedures.containsKey(procedureName);
public boolean hasSymbol(String symbolName) {
return symbols.containsKey(symbolName);
}
@ -281,9 +281,9 @@ public class AsmLibrary extends AsmLine {
// signature.append(variable.getType().toCDecl());
// signature.append(variable.getLocalName()).append(" ");
signature.append(variable.toCDecl());
if(variable.isKindConstant()) {
signature.append(" = ").append(variable.getInitValue());
}
// if(variable.isKindConstant()) {
// signature.append(" = ").append(variable.getInitValue());
// }
signature.append(";");
signature.append("\n");
// Always add the signature comments...
@ -325,7 +325,7 @@ public class AsmLibrary extends AsmLine {
// This requires rework. It is a challenge to generate only those global var
// By default at this moment, all global variables in libraries are encapsulated in the asm namespace.
// This prevents any conflict of global variables.
// headers.append(generateVariableHeader(globalVariable, program));
headers.append(generateVariableHeader(globalVariable, program));
structs.append(generateVariableStructForward(globalVariable, program));
}
}
@ -334,7 +334,7 @@ public class AsmLibrary extends AsmLine {
headers.insert(0, "#pragma zp_reserve(" + String.join(",", zp) + ")\n");
// Generate the procedure headers.
for(String procedureName: this.getProcedures()) {
for(String procedureName: this.getSymbols()) {
Procedure procedure = program.getScope().getProcedure(new ProcedureRef(procedureName));
if(procedure != null) {
if(procedure.isAsmExportLibrary())
@ -360,7 +360,7 @@ public class AsmLibrary extends AsmLine {
StringBuilder asm = new StringBuilder();
asm.append(".export ").append(" [ ");
asm.append("name=\"").append(asmLibraryName).append("\"");
for(String procedureName : procedures.keySet()) {
for(String procedureName : symbols.keySet()) {
asm.append(",");
asm.append(procedureName);
}

View File

@ -133,12 +133,12 @@ public class Program {
/**
* Defines the asm source to be imported with the defined procedures.
*/
private Map<String, AsmImportLibrary> asmImports;
private Map<String, AsmImportLibrary> asmImportLibraries;
/**
* Defines the asm source to be exported with the defined procedures.
*/
private final Map<String, AsmExportLibrary> asmExports;
private final Map<String, AsmExportLibrary> asmExportLibraries;
/** All #pragma code segments. Collected during parsing. These are used by the bank() pragmas to validate if the code segment exists during compilation.*/
@ -154,8 +154,8 @@ public class Program {
this.asmResourceFiles = new ArrayList<>();
this.reservedZps = new ArrayList<>();
this.procedureCompilations = new ArrayList<>();
this.asmImports = new LinkedHashMap<>();
this.asmExports = new LinkedHashMap<>();
this.asmImportLibraries = new LinkedHashMap<>();
this.asmExportLibraries = new LinkedHashMap<>();
this.currentPath = new File(".").toPath();
this.asmLibraryNamespace = false;
this.asmLibraryNamespaceSymbols = new HashMap<>();
@ -674,12 +674,12 @@ public class Program {
return entryPointBlocks;
}
public Map<String, AsmImportLibrary> getAsmImports() {
return asmImports;
public Map<String, AsmImportLibrary> getAsmImportLibraries() {
return asmImportLibraries;
}
public void setAsmImports(Map<String, AsmImportLibrary> asmImports) {
this.asmImports = asmImports;
public void setAsmImportLibraries(Map<String, AsmImportLibrary> asmImports) {
this.asmImportLibraries = asmImports;
}
/**
@ -688,7 +688,7 @@ public class Program {
* @return true if there is an .asm import library with the given base name.
*/
public boolean hasAsmImportLibrary(String asmImportLibraryName) {
return asmImports.get(asmImportLibraryName) != null;
return asmImportLibraries.get(asmImportLibraryName) != null;
}
/**
@ -697,7 +697,7 @@ public class Program {
* @return The .asm import library.
*/
public AsmImportLibrary getAsmImportLibrary(String asmImportLibraryName) {
return asmImports.get(asmImportLibraryName);
return asmImportLibraries.get(asmImportLibraryName);
}
/**
@ -718,7 +718,7 @@ public class Program {
File asmImportResource = SourceLoader.loadFile(asmImportResourceName, getCurrentPath(), getAsmLibraryPaths());
if(asmImportResource != null) {
AsmImportLibrary asmLibrary = new AsmImportLibrary(asmImportLibraryName, asmImportResource.toPath());
this.asmImports.putIfAbsent(asmImportLibraryName, asmLibrary);
this.asmImportLibraries.putIfAbsent(asmImportLibraryName, asmLibrary);
if (!this.getAsmResourceFiles().contains(asmImportResource.toPath()))
this.addAsmResourceFile(asmImportResource.toPath()); // #820/20 here ...
return asmLibrary;
@ -733,7 +733,7 @@ public class Program {
public void addAsmImportProcedures(AsmImportLibrary asmImportLibrary, Procedure.CallingConvention callingConvention, List<String> procedures) {
for(String procedureName : procedures) {
asmImportLibrary.addProcedure(procedureName, callingConvention);
asmImportLibrary.addSymbol(procedureName, callingConvention);
this.getLog().append("Procedure " + procedureName + " imported from .asm library " + asmImportLibrary.getAsmLibraryName() );
}
}
@ -742,10 +742,10 @@ public class Program {
* 820/20 - Get the .asm import library of the procedure.
*/
public AsmImportLibrary getProcedureAsmImportLibrary(String procedureName) {
Map<String, AsmImportLibrary> asmImports = this.getAsmImports();
Map<String, AsmImportLibrary> asmImports = this.getAsmImportLibraries();
for (String asmImportKey : asmImports.keySet()) {
AsmImportLibrary library = asmImports.get(asmImportKey);
if (library.hasProcedure(procedureName)) {
if (library.hasSymbol(procedureName)) {
return library;
}
}
@ -778,8 +778,8 @@ public class Program {
*
* @return All .asm export libraries!
*/
public Map<String, AsmExportLibrary> getAsmExports() {
return asmExports;
public Map<String, AsmExportLibrary> getAsmExportLibraries() {
return asmExportLibraries;
}
/**
@ -795,10 +795,10 @@ public class Program {
// Only calculate the .asm export library when the .asm library is declared in the main program.
// Otherwise ignore. This is important for .asm library imports, where library sources are
// imported that contain the #pragma asm_export pro-processor statements.
asmLibrary = asmExports.get(asmExportLibraryName);
asmLibrary = asmExportLibraries.get(asmExportLibraryName);
if (asmLibrary == null) {
asmLibrary = new AsmExportLibrary(asmExportLibraryName, asmExportResource, exportAll);
asmExports.put(asmExportLibraryName, asmLibrary);
asmExportLibraries.put(asmExportLibraryName, asmLibrary);
} else {
asmLibrary.setExportAll(exportAll);
}
@ -816,7 +816,7 @@ public class Program {
* @param procedureName The procedure to be added.
*/
public void addAsmExportProcedure(AsmExportLibrary asmExportLibrary, Procedure.CallingConvention callingConvention, String procedureName) {
this.asmExports.get(asmExportLibrary.getAsmLibraryName()).addProcedure(procedureName, callingConvention);
this.asmExportLibraries.get(asmExportLibrary.getAsmLibraryName()).addSymbol(procedureName, callingConvention);
this.getLog().append("Procedure " + procedureName + " exported to .asm library " + asmExportLibrary.getAsmLibraryName() );
}
@ -841,10 +841,10 @@ public class Program {
* @return true if the procedure is part of an .asm export library.
*/
public boolean isProcedureAsmExport(String procedureName) {
Map<String, AsmExportLibrary> asmExports = this.getAsmExports();
Map<String, AsmExportLibrary> asmExports = this.getAsmExportLibraries();
for (String asmExportKey : asmExports.keySet()) {
AsmExportLibrary library = asmExports.get(asmExportKey);
if (library.hasProcedure(procedureName)) {
if (library.hasSymbol(procedureName)) {
return true;
}
}
@ -852,22 +852,31 @@ public class Program {
}
/**
* 820/20 - Retrieve the .asm export library (AsmLibrary) object from a given Procedure object.
* 820/20 - Retrieve the .asm export library (AsmLibrary) object from a given Symbol object.
*
* @param procedure The Procedure object.
* @param symbol The Symbol object.
* @return The AsmLibrary object that is an .asm export library.
*/
public AsmExportLibrary getAsmExportLibrary(Procedure procedure) {
Map<String, AsmExportLibrary> asmExports = this.getAsmExports();
public AsmExportLibrary getAsmExportLibraryFromSymbol(Symbol symbol) {
Map<String, AsmExportLibrary> asmExports = this.getAsmExportLibraries();
for (String asmExportKey : asmExports.keySet()) {
AsmExportLibrary library = asmExports.get(asmExportKey);
if(library.isExportAll(procedure) || library.hasProcedure(procedure.getFullName())) {
return library;
if(symbol instanceof Procedure procedure) {
if (library.isExportAll((Procedure) procedure) || library.hasSymbol(procedure.getFullName())) {
return library;
}
}
if(symbol instanceof Variable variable) {
if (library.hasSymbol(variable.getFullName())) {
return library;
}
}
}
return null;
}
/**
* #820/20 - Configure the Procedure object as an .asm import library,
* and set the relevant properties!

View File

@ -1,6 +1,6 @@
package dk.camelot64.kickc.model;
import dk.camelot64.kickc.asm.AsmIdentifier;
import dk.camelot64.kickc.asm.AsmExportLibrary;
import dk.camelot64.kickc.model.symbols.*;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
@ -10,6 +10,7 @@ import dk.camelot64.kickc.model.values.ConstantValue;
import dk.camelot64.kickc.model.values.ScopeRef;
import java.util.List;
import java.util.Map;
/**
* Used for creating a {@link Variable} with the right properties based on the declaration incl. all directives and configuration.
@ -42,7 +43,10 @@ public class VariableBuilder {
/** Configuration of how to setup optimization/memory area for variables. */
private VariableBuilderConfig config;
public VariableBuilder(String varName, Scope scope, boolean isParameter, boolean isIntermediate, SymbolType type, List<Directive> directives, String dataSegment, VariableBuilderConfig config) {
/** Reference to the program, to capture program-level configurations */
private Program program;
public VariableBuilder(String varName, Scope scope, boolean isParameter, boolean isIntermediate, SymbolType type, List<Directive> directives, String dataSegment, VariableBuilderConfig config, Program program) {
this.varName = varName;
this.scope = scope;
this.isIntermediate = isIntermediate;
@ -51,6 +55,7 @@ public class VariableBuilder {
this.directives = directives;
this.dataSegment = dataSegment;
this.config = config;
this.program = program;
}
/**
@ -63,7 +68,7 @@ public class VariableBuilder {
* @return The new intermediate variable
*/
public static Variable createIntermediate(Scope scope, SymbolType type, Program program) {
VariableBuilder builder = new VariableBuilder(scope.allocateIntermediateVariableName(), scope, false, true, type, null, scope.getSegmentData(), program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder builder = new VariableBuilder(scope.allocateIntermediateVariableName(), scope, false, true, type, null, scope.getSegmentData(), program.getTargetPlatform().getVariableBuilderConfig(), program);
return builder.build();
}
@ -90,7 +95,7 @@ public class VariableBuilder {
// Set the Export and Import and associated variable flags.
// (note that these are set inside these procedures).
variable.setAsmExportLibrary(this.getAsmExportLibrary());
variable.setAsmExportLibrary(this.getAsmExportLibrary(variable));
variable.setAsmImportLibrary(this.getAsmImportLibrary());
// Check if the symbol has already been declared
@ -116,6 +121,7 @@ public class VariableBuilder {
}
throw new CompileError("Error! Redefinition of variable: " + variable.getFullName());
}
// TODO: Sven to check if this condition does not need rework.
if(!SymbolTypeConversion.variableDeclarationMatch(declaredVar, variable) && !variable.isAsmExportLibraryGlobal())
throw new CompileError("Error! Conflicting declarations for: " + variable.getFullName());
@ -460,11 +466,15 @@ public class VariableBuilder {
*
* @return The .asm export library
*/
public String getAsmExportLibrary() {
public String getAsmExportLibrary(Variable variable) {
Directive.AsmExportDirective asmLibraryDirective = findDirective(Directive.AsmExportDirective.class, directives);
if(asmLibraryDirective != null) {
return asmLibraryDirective.getAsmLibrary();
}
AsmExportLibrary asmExportLibrary = this.program.getAsmExportLibraryFromSymbol(variable);
if(asmExportLibrary != null) {
return asmExportLibrary.getAsmLibraryName();
}
return null;
}

View File

@ -215,7 +215,7 @@ public class Variable implements Symbol {
constVar.setComments(variable.getComments());
constVar.setStructUnwind(variable.isStructUnwind());
constVar.setAsmImportLibrary(variable.getImportAsmLibrary());
constVar.setAsmExportLibrary(variable.getExportAsmLibrary());
// constVar.setAsmExportLibrary(variable.getExportAsmLibrary());
return constVar;
}

View File

@ -176,7 +176,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
// Mark the constructor procedure
constructorProc.setConstructor(true);
// #820/41 - Export the constructor_for procedure(s) so that when imported, they are not generated.
AsmExportLibrary asmExportLibrary = program.getAsmExports().get(program.getAsmLibraryName());
AsmExportLibrary asmExportLibrary = program.getAsmExportLibraries().get(program.getAsmLibraryName());
if(asmExportLibrary != null) {
program.addAsmExportProcedure(asmExportLibrary, Procedure.CallingConvention.VAR_CALL, constructorProc.getLocalName());
constructorProc.setAsmExportLibrary(program.getAsmLibraryName());
@ -208,7 +208,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
program.getScope().add(startProcedure);
final ProcedureCompilation startProcedureCompilation = program.createProcedureCompilation(startProcedure.getRef());
if(program.getAsmLibraryName() != null) {
AsmExportLibrary asmExportLibrary = program.getAsmExports().get(program.getAsmLibraryName());
AsmExportLibrary asmExportLibrary = program.getAsmExportLibraries().get(program.getAsmLibraryName());
program.addAsmExportProcedure(asmExportLibrary, Procedure.CallingConvention.VAR_CALL, startProcedureName);
startProcedure.setAsmExportLibrary(program.getAsmLibraryName());
}
@ -221,7 +221,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
// Libraries are activated using the #pragma library( library_name ) option.
if (program.getAsmLibraryName() == null) {
// 820/17 - For each imported library, call the start procedure of the library.
for(AsmLibrary importedLibrary: program.getAsmImports().values()) {
for(AsmLibrary importedLibrary: program.getAsmImportLibraries().values()) {
String procedureStartName = "__" + importedLibrary.getAsmLibraryIdentifier() + "_start";
Procedure procedureStart = this.program.getScope().getProcedure(new ProcedureRef(procedureStartName));
if(procedureStart != null) {
@ -721,7 +721,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if (parameter.name == null)
throw new CompileError("Illegal unnamed parameter.", statementSource);
VariableBuilder varBuilder = new VariableBuilder(parameter.name, getCurrentScope(), true, false, parameter.type, parameter.directives, currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(parameter.name, getCurrentScope(), true, false, parameter.type, parameter.directives, currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig(), program);
final Variable paramVar = varBuilder.build();
parameterList.add(paramVar);
}
@ -733,7 +733,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
// Add return variable
if(!SymbolType.VOID.equals(procedure.getReturnType())) {
final VariableBuilder builder = new VariableBuilder("return", procedure, false, false, procedure.getReturnType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig());
final VariableBuilder builder = new VariableBuilder("return", procedure, false, false, procedure.getReturnType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig(), program);
builder.build();
}
@ -780,7 +780,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
// Export the procedure to an .asm export library when either the source is flagged as a library
// and/or specific procedures are flagged as a library.
// TODO: remove the library dependency and rework to one routine call.
AsmExportLibrary asmExport = this.program.getAsmExportLibrary(procedure);
AsmExportLibrary asmExport = this.program.getAsmExportLibraryFromSymbol(procedure);
if(asmExport != null) {
if(!program.isProcedureAsmExport(procedure.getFullName()) && asmExport.isExportAll()) {
program.addAsmExportProcedure(asmExport, currentCallingConvention, procedure.getFullName());
@ -810,7 +810,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(parameter.name == null)
throw new CompileError("Illegal unnamed parameter.", statementSource);
VariableBuilder varBuilder = new VariableBuilder(parameter.name, getCurrentScope(), true, false, parameter.type, null, currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(parameter.name, getCurrentScope(), true, false, parameter.type, null, currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig(), program);
final Variable paramVar = varBuilder.build();
parameterList.add(paramVar);
}
@ -822,7 +822,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
// Add return variable
if(!SymbolType.VOID.equals(procedure.getReturnType())) {
final VariableBuilder builder = new VariableBuilder("return", procedure, false, false, procedure.getReturnType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig());
final VariableBuilder builder = new VariableBuilder("return", procedure, false, false, procedure.getReturnType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig(), program);
builder.build();
}
// exit the procedure
@ -1167,11 +1167,11 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
} else if(directive instanceof Directive.AsmExportDirective) {
// Type-qualifier directive volatile
this.declDirectives.add(directive);
this.declType = this.declType.getQualified(true, this.declType.isNomodify());
this.declType = this.declType.getQualified(false, this.declType.isNomodify());
} else if(directive instanceof Directive.AsmImportDirective) {
// Type-qualifier directive volatile
this.declDirectives.add(directive);
this.declType = this.declType.getQualified(true, this.declType.isNomodify());
this.declType = this.declType.getQualified(false, this.declType.isNomodify());
} else {
// variable directive
if(!this.declDirectives.contains(directive))
@ -1307,7 +1307,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
final List<Directive> effectiveDirectives = varDecl.getDeclDirectives();
final List<Comment> declComments = varDecl.getDeclComments();
varDecl.exitVar();
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, false, effectiveType, effectiveDirectives, currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, false, effectiveType, effectiveDirectives, currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig(), program);
Variable variable = varBuilder.build();
if(isStructMember && (initializer != null))
throw new CompileError("Initializer not supported inside structs " + effectiveType.toCDecl(), declSource);
@ -1416,7 +1416,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
ConstantArrayKickAsm constantArrayKickAsm = new ConstantArrayKickAsm(((SymbolTypePointer) varDecl.getEffectiveType()).getElementType(), kasm.kickAsmCode, kasm.uses, ((SymbolTypePointer) effectiveType).getArraySpec().getArraySize());
// Add a constant variable
Scope scope = getCurrentScope();
VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig(), program);
Variable variable = varBuilder.build();
// Set constant value
variable.setInitValue(getConstInitValue(constantArrayKickAsm, null, statementSource));
@ -1998,7 +1998,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
String varName = varDecl.getVarName();
Variable lValue;
if(varType != null) {
VariableBuilder varBuilder = new VariableBuilder(varName, blockScope, false, false, varType, varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(varName, blockScope, false, false, varType, varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig(), program);
lValue = varBuilder.build();
} else {
lValue = getCurrentScope().findVariable(varName);
@ -2563,7 +2563,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.visit(ctx.declType());
this.visit(ctx.declarator());
String typedefName = varDecl.getVarName();
VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig(), program);
varBuilder.build();
if(typedefName != null) {
// #820/50 - Define the name of structures, based on the typedef name, if any.

View File

@ -39,7 +39,7 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
if(variable.getRegister()!=null && variable.getRegister().isMem())
// Skip variables allocated into memory
continue;
if(variable.isAsmExportLibraryGlobal()) continue; // Don't converted exported constant global variables.
if(variable.isAsmExportLibraryGlobal()) continue; // Don't convert exported constant global variables.
if(!isParameter(variableRef)) {
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(variableRef, getGraph(), getProgramScope());
if(varAssignments.size() == 1) {

View File

@ -102,8 +102,6 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
final long stringLength = constantString.getStringLength();
final ConstantInteger arraySize = new ConstantInteger(stringLength, stringLength<256?SymbolType.BYTE : SymbolType.WORD);
Variable strConst = Variable.createConstant(name, new SymbolTypePointer(SymbolType.BYTE, new ArraySpec(arraySize), false, false), blockScope, constantString, blockScope.getSegmentData());
// #820 - Set the library for string constant pointers.
strConst.setAsmExportLibrary(getProgram().getAsmLibraryName());
blockScope.add(strConst);
if(getLog().isVerbosePass1CreateSsa()) {
getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\"");

View File

@ -390,7 +390,7 @@ public class Pass4CodeGeneration {
* @param program The main program.
*/
private void generateImportAsmLibraries(AsmProgram asm, Program program) {
for (AsmImportLibrary asmImportLibrary : program.getAsmImports().values()) {
for (AsmImportLibrary asmImportLibrary : program.getAsmImportLibraries().values()) {
asm.addAsmImportLibrary(asmImportLibrary);
}
}

View File

@ -1,43 +0,0 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Directive;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.VariableReferenceInfos;
import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.*;
import dk.camelot64.kickc.model.values.LValue;
import dk.camelot64.kickc.model.values.ScopeRef;
import dk.camelot64.kickc.model.values.StructUnwoundPlaceholder;
import dk.camelot64.kickc.model.values.VariableRef;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.ListIterator;
import java.util.Set;
/**
* Declare all global variables in a library as exported. But only in a library!
*/
public class PassNAsmLibraryGlobalVarsExport extends Pass2SsaOptimization {
public PassNAsmLibraryGlobalVarsExport(Program program) {
super(program);
}
@Override
public boolean step() {
boolean modified = false;
Scope scope = getProgram().getScope().getScope(ScopeRef.ROOT); //
Collection<Variable> scopeConstants = scope.getAllVars(false);
String asmLibraryName = getProgram().getAsmLibraryName();
if(asmLibraryName != null) {
for (Variable constantVar : scopeConstants) {
if(constantVar.isKindLoadStore()) {
constantVar.setAsmExportLibrary(asmLibraryName);
}
}
}
return modified;
}
}

View File

@ -20,7 +20,7 @@ public class PassNFixIntermediateMemoryArea extends Pass2SsaOptimization {
final VariableBuilderConfig variableBuilderConfig = getProgram().getTargetPlatform().getVariableBuilderConfig();
for(Variable var : getProgramScope().getAllVars(true)) {
if(var.isKindIntermediate()) {
final VariableBuilder builder = new VariableBuilder(var.getLocalName(), var.getScope(), false, true, var.getType(), null, var.getDataSegment(), variableBuilderConfig);
final VariableBuilder builder = new VariableBuilder(var.getLocalName(), var.getScope(), false, true, var.getType(), null, var.getDataSegment(), variableBuilderConfig, getProgram());
final Variable.MemoryArea memoryArea = builder.getMemoryArea();
if(!memoryArea.equals(var.getMemoryArea())) {
// Update the variable memory area

View File

@ -12,24 +12,24 @@
#define CONIO_BYTES CONIO_HEIGHT*CONIO_WIDTH
// The current cursor x-position
__ma char conio_cursor_x = 0;
__ma __asm_export char conio_cursor_x = 0;
// The current cursor y-position
__ma char conio_cursor_y = 0;
__ma __asm_export char conio_cursor_y = 0;
// The current text cursor line start
__ma char *conio_line_text = CONIO_SCREEN_TEXT;
__ma __asm_export char *conio_line_text = CONIO_SCREEN_TEXT;
#ifndef __PET8032__
// The current color cursor line start
__ma char *conio_line_color = CONIO_SCREEN_COLORS;
__ma __asm_export char *conio_line_color = CONIO_SCREEN_COLORS;
#endif
// The current text color
__ma char conio_textcolor = CONIO_TEXTCOLOR_DEFAULT;
__ma __asm_export char conio_textcolor = CONIO_TEXTCOLOR_DEFAULT;
// Is a cursor whown when waiting for input (0: no, other: yes)
__ma char conio_display_cursor = 0;
__ma __asm_export char conio_display_cursor = 0;
// Is scrolling enabled when outputting beyond the end of the screen (1: yes, 0: no).
// If disabled the cursor just moves back to (0,0) instead
__ma char conio_scroll_enable = 1;
__ma __asm_export char conio_scroll_enable = 1;
// clears the screen and moves the cursor to the upper left-hand corner of the screen.
void clrscr(void) {

View File

@ -26,7 +26,7 @@
#define CONIO_TEXTCOLOR_DEFAULT WHITE // The default text color
#define CONIO_BACKCOLOR_DEFAULT BLUE // The default back color
typedef struct {
struct cx16_conio_s {
unsigned char cursor_x; ///< current cursor x-position
unsigned char cursor_y; ///< current cursor y-position
unsigned char layer;
@ -47,9 +47,9 @@ typedef struct {
unsigned char hscroll[2];
unsigned int offset; ///< The current offset
unsigned int offsets[61]; ///< Calculated offsets per line according the mapbase and the row width (scale).
} cx16_conio_t;
};
cx16_conio_t __conio;
__mem __asm_export struct cx16_conio_s __conio;
/// Initializer for conio.h on X16 Commander.
@ -95,7 +95,7 @@ void clrscr(void)
*VERA_ADDRX_L = BYTE0(ch);
*VERA_ADDRX_M = BYTE1(ch);
unsigned char c = __conio.mapwidth;
unsigned char c = __conio.mapwidth+1;
do{
*VERA_DATA0 = ' ';
*VERA_DATA0 = __conio.color;
@ -187,10 +187,11 @@ void cputc(char c) {
} else {
if(__conio.cursor_x >= __conio.mapwidth)
cputln();
else
else {
__conio.cursor_x++;
__conio.offset++;
__conio.offset++;
}
}
}
}

View File

@ -4,7 +4,7 @@
#include <printf.h>
// Buffer used for stringified number being printed
struct printf_buffer_number printf_buffer;
__asm_export struct printf_buffer_number printf_buffer;
// Print a formatted string.
// https://en.wikipedia.org/wiki/Printf_format_string

View File

@ -4,6 +4,8 @@
#pragma asm_library
#pragma calling(__varcall)
#pragma asm_export(global1d)
#pragma var_model(zp)
__export const char CONST1 = 20;
@ -24,6 +26,6 @@ __export volatile long global3b[256];
__export volatile char global1c[3] = {1,2,3};
__export volatile char global2c[3] = {CONST1, CONST2, CONST3};
__export volatile char global1d[3] = {&global1a, &global2a, &global3a};
__export char global1d[3] = {&global1a, &global2a, &global3a};
__export volatile char global2d[3] = {(char*)0x4000, (char*)0x5000, (char*)0x6000};
//__export char* global3d[3] = {"test1", "test2", "test3"};
__export char* global3d[3] = {"test1", "test2", "test3"};