1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-18 08:30:18 +00:00

Improved commandline to include output-directory, compilation & execution.

This commit is contained in:
jespergravgaard 2018-08-27 01:03:15 +02:00
parent 7b940014a2
commit 7f29a344ae
3 changed files with 92 additions and 42 deletions

View File

@ -20,7 +20,7 @@
<groupId>dk.camelot64.kickc</groupId> <groupId>dk.camelot64.kickc</groupId>
<artifactId>kickc</artifactId> <artifactId>kickc</artifactId>
<version>0.7-SNAPSHOT</version> <version>0.5-SNAPSHOT</version>
<dependencies> <dependencies>
<dependency> <dependency>

View File

@ -5,87 +5,137 @@ import kickass.KickAssembler;
import picocli.CommandLine; import picocli.CommandLine;
import java.io.*; import java.io.*;
import java.nio.file.*;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import static junit.framework.TestCase.fail; import static junit.framework.TestCase.fail;
/** KickC Commandline */ /** KickC Commandline */
@CommandLine.Command(description = "Compiles KickC source files to KickAssembler.", @CommandLine.Command(description = "Compiles KickC source files to KickAssembler.",
name = "kickc", mixinStandardHelpOptions = true, version = "KickC 0.7") name = "kickc", mixinStandardHelpOptions = true, version = "KickC 0.5 SNAPSHOT")
public class KickC implements Callable<Void> { public class KickC implements Callable<Void> {
@CommandLine.Parameters(index = "0", description = "The KickC file to compile.") @CommandLine.Parameters(index = "0", description = "The KickC file to compile.")
private File kcFile = null; private Path kcFile = null;
@CommandLine.Option(names = {"-libdir", "-I"}, description = "Path to a library folder, where the compiler looks for included files.") @CommandLine.Option(names = {"-I", "-libdir" }, description = "Path to a library folder, where the compiler looks for included files.")
private File libdir = null; private Path libDir = null;
@CommandLine.Option(names = {"-o"}, description = "Name of the output file. By default it is the same as the input file with extension .asm") @CommandLine.Option(names = {"-o"}, description = "Name of the output file. By default it is the same as the input file with extension .asm")
private String asmFileName = null; private String asmFileName = null;
@CommandLine.Option(names = {"-odir" }, description = "Path to the output folder, where the compiler places all generated files. By default the folder of the output file is used.")
private Path outputDir = null;
@CommandLine.Option(names = {"-a"}, description = "Assemble the output file using KickAssembler. Produces a .prg file.") @CommandLine.Option(names = {"-a"}, description = "Assemble the output file using KickAssembler. Produces a .prg file.")
private boolean assemble = false; private boolean assemble = false;
@CommandLine.Option(names = {"-e"}, description = "Execute the assembled prg file using VICE. Implicitly assembles the output.")
private boolean execute = false;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
CommandLine.call(new KickC(), args); CommandLine.call(new KickC(), args);
} }
@Override @Override
public Void call() throws Exception { public Void call() throws Exception {
System.out.println("//------------------------------------"); System.out.println("//-------------------------------------");
System.out.println("// KickC v0.7 by Jesper Gravgaard "); System.out.println("// " + getVersion() + " by Jesper Gravgaard ");
System.out.println("//------------------------------------"); System.out.println("//-------------------------------------");
Compiler compiler = new Compiler(); Compiler compiler = new Compiler();
if(libdir != null) {
compiler.addImportPath(libdir.getPath()); compiler.addImportPath(".");
if(libDir != null) {
compiler.addImportPath(libDir.toString());
} }
String outDirName = kcFile.getParent(); String fileBaseName = getFileBaseName(kcFile);
File outDir = new File(".");
Path kcFileDir = kcFile.getParent();
if(kcFileDir==null) {
kcFileDir = FileSystems.getDefault().getPath(".");
}
if(outputDir==null) {
outputDir = kcFileDir;
}
if(!Files.exists(outputDir)) {
Files.createDirectory(outputDir);
}
if(asmFileName == null) { if(asmFileName == null) {
asmFileName = getFileBaseName(kcFile) + ".asm"; asmFileName = fileBaseName + ".asm";
} }
File asmFile = new File(asmFileName);
System.out.println("Compiling "+ kcFile.getPath());
Program program = compiler.compile(kcFile.getName());
System.out.println("Writing asm file "+ asmFileName);
FileOutputStream outputStream = new FileOutputStream(asmFileName);
OutputStreamWriter writer = new OutputStreamWriter(outputStream);
String assembler = program.getAsm().toString(false);
writer.write(assembler);
writer.close();
outputStream.close();
// Copy Resource Files (if out-dir is different from current dir) System.out.println("Compiling " + kcFile);
Program program = compiler.compile(kcFile.toString());
if(assemble) { Path asmPath = outputDir.resolve(asmFileName);
File asmPrgFile = new File(getFileBaseName(kcFile)+ ".prg"); System.out.println("Writing asm file " + asmPath);
File asmLogFile = new File(getFileBaseName(kcFile)+ ".klog"); FileOutputStream asmOutputStream = new FileOutputStream(asmPath.toFile());
System.out.println("Assembling to "+ asmPrgFile.getPath()); OutputStreamWriter asmWriter = new OutputStreamWriter(asmOutputStream);
ByteArrayOutputStream kickAssOut = new ByteArrayOutputStream(); String asmCodeString = program.getAsm().toString(false);
System.setOut(new PrintStream(kickAssOut)); asmWriter.write(asmCodeString);
int asmRes = KickAssembler.main2(new String[]{asmFile.getAbsolutePath(), "-log", asmLogFile.getAbsolutePath(), "-o", asmPrgFile.getAbsolutePath(), "-vicesymbols", "-showmem"}); asmWriter.close();
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); asmOutputStream.close();
if(asmRes != 0) {
fail("KickAssembling file failed! " + kickAssOut.toString()); // Copy Resource Files (if out-dir is different from in-dir)
if(!kcFileDir.toAbsolutePath().equals(outputDir.toAbsolutePath())) {
for(Path resourcePath : program.getAsmResourceFiles()) {
Path outResourcePath = outputDir.resolve(resourcePath.getFileName().toString());
System.out.println("Copying resource " + outResourcePath);
try {
Files.copy(resourcePath, outResourcePath);
} catch(FileAlreadyExistsException e) {
// Ignore this
}
} }
} }
// Assemble the asm-file if instructed
Path prgPath = outputDir.resolve(fileBaseName + ".prg");
if(assemble || execute) {
Path kasmLogPath = outputDir.resolve(fileBaseName+".klog");
System.out.println("Assembling to " + prgPath.toString());
ByteArrayOutputStream kasmLogOutputStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(kasmLogOutputStream));
int kasmResult = KickAssembler.main2(new String[]{asmPath.toString(), "-log", kasmLogPath.toString(), "-o", prgPath.toString(), "-vicesymbols", "-showmem"});
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
if(kasmResult != 0) {
fail("KickAssembling file failed! " + kasmLogOutputStream.toString());
}
}
// Execute the prg-file if instructed
if(execute) {
System.out.println("Executing " + prgPath);
Process process = Runtime.getRuntime().exec("x64 " + prgPath.toString() );
process.waitFor();
}
return null; return null;
} }
String getFileBaseName(File file) { /**
String name = file.getName(); * Get the current version of KickC
* @return The name and version (eg "KickC 0.5")
*/
private String getVersion() {
return new CommandLine(new KickC()).getCommandSpec().version()[0];
}
String getFileBaseName(Path file) {
String name = file.getFileName().toString();
int i = name.lastIndexOf('.'); int i = name.lastIndexOf('.');
return i > 0 ? name.substring(0, i) : name; return i > 0 ? name.substring(0, i) : name;
} }
String getFileExtension(File file) { String getFileExtension(Path file) {
if(file == null) { if(file == null) {
return ""; return "";
} }
String name = file.getName(); String name = file.getFileName().toString();
int i = name.lastIndexOf('.'); int i = name.lastIndexOf('.');
return i > 0 ? name.substring(i + 1) : ""; return i > 0 ? name.substring(i + 1) : "";
} }

View File

@ -6,8 +6,7 @@ import dk.camelot64.kickc.model.Program;
import kickass.KickAssembler; import kickass.KickAssembler;
import java.io.*; import java.io.*;
import java.nio.file.Files; import java.nio.file.*;
import java.nio.file.Path;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -177,12 +176,13 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization {
writer.write(outputString); writer.write(outputString);
writer.close(); writer.close();
outputStream.close(); outputStream.close();
//System.out.println("ASM generated to " + file.getAbsolutePath()); //System.out.println("Long Branch ASM generated to " + file.getAbsolutePath());
return file; return file;
} }
public File getTmpFile(String fileName, String extension) { public File getTmpFile(String fileName, String extension) {
return new File(tmpDir.toFile(), fileName + extension); Path kcPath = FileSystems.getDefault().getPath(fileName);
return new File(tmpDir.toFile(), kcPath.getFileName().toString() + extension);
} }
public File getTmpFile(String fileName) { public File getTmpFile(String fileName) {