1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +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>
<artifactId>kickc</artifactId>
<version>0.7-SNAPSHOT</version>
<version>0.5-SNAPSHOT</version>
<dependencies>
<dependency>

View File

@ -5,87 +5,137 @@ import kickass.KickAssembler;
import picocli.CommandLine;
import java.io.*;
import java.nio.file.*;
import java.util.concurrent.Callable;
import static junit.framework.TestCase.fail;
/** KickC Commandline */
@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> {
@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.")
private File libdir = null;
@CommandLine.Option(names = {"-I", "-libdir" }, description = "Path to a library folder, where the compiler looks for included files.")
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")
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.")
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 {
CommandLine.call(new KickC(), args);
}
@Override
public Void call() throws Exception {
System.out.println("//------------------------------------");
System.out.println("// KickC v0.7 by Jesper Gravgaard ");
System.out.println("//------------------------------------");
System.out.println("//-------------------------------------");
System.out.println("// " + getVersion() + " by Jesper Gravgaard ");
System.out.println("//-------------------------------------");
Compiler compiler = new Compiler();
if(libdir != null) {
compiler.addImportPath(libdir.getPath());
compiler.addImportPath(".");
if(libDir != null) {
compiler.addImportPath(libDir.toString());
}
String outDirName = kcFile.getParent();
File outDir = new File(".");
String fileBaseName = getFileBaseName(kcFile);
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) {
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) {
File asmPrgFile = new File(getFileBaseName(kcFile)+ ".prg");
File asmLogFile = new File(getFileBaseName(kcFile)+ ".klog");
System.out.println("Assembling to "+ asmPrgFile.getPath());
ByteArrayOutputStream kickAssOut = new ByteArrayOutputStream();
System.setOut(new PrintStream(kickAssOut));
int asmRes = KickAssembler.main2(new String[]{asmFile.getAbsolutePath(), "-log", asmLogFile.getAbsolutePath(), "-o", asmPrgFile.getAbsolutePath(), "-vicesymbols", "-showmem"});
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
if(asmRes != 0) {
fail("KickAssembling file failed! " + kickAssOut.toString());
Path asmPath = outputDir.resolve(asmFileName);
System.out.println("Writing asm file " + asmPath);
FileOutputStream asmOutputStream = new FileOutputStream(asmPath.toFile());
OutputStreamWriter asmWriter = new OutputStreamWriter(asmOutputStream);
String asmCodeString = program.getAsm().toString(false);
asmWriter.write(asmCodeString);
asmWriter.close();
asmOutputStream.close();
// 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;
}
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('.');
return i > 0 ? name.substring(0, i) : name;
}
String getFileExtension(File file) {
String getFileExtension(Path file) {
if(file == null) {
return "";
}
String name = file.getName();
String name = file.getFileName().toString();
int i = name.lastIndexOf('.');
return i > 0 ? name.substring(i + 1) : "";
}

View File

@ -6,8 +6,7 @@ import dk.camelot64.kickc.model.Program;
import kickass.KickAssembler;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -177,12 +176,13 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization {
writer.write(outputString);
writer.close();
outputStream.close();
//System.out.println("ASM generated to " + file.getAbsolutePath());
//System.out.println("Long Branch ASM generated to " + file.getAbsolutePath());
return file;
}
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) {