mirror of https://gitlab.com/camelot/kickc.git
- 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:
parent
00df07b7bf
commit
1a53d6a913
|
@ -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(() -> {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() + "\"");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"};
|
||||
|
|
Loading…
Reference in New Issue