Skip to content

Commit

Permalink
Improve driver of bootstrap compiler (#588)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer authored Jun 14, 2024
1 parent cffb512 commit 62beaa9
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 64 deletions.
2 changes: 1 addition & 1 deletion .run/spice.run.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O0 -d ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="build -O0 -d ../../src-bootstrap/main.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<envs>
<env name="LLVM_ADDITIONAL_FLAGS" value="-lole32 -lws2_32" />
<env name="LLVM_BUILD_INCLUDE_DIR" value="$PROJECT_DIR$/../llvm-project-latest/build/include" />
Expand Down
31 changes: 0 additions & 31 deletions media/test-project/test.spice
Original file line number Diff line number Diff line change
@@ -1,35 +1,4 @@
type TestStruct struct {
int a
}

p TestStruct.unusedProcedure() {
printf("Hello World: %d", this.a);
}

f<string> TestStruct.unusedFunction() {
printf("%d", this.a);
return "Hello World";
}

f<int> main() {
TestStruct _ts;
}

/*type Parent struct {
int i
}

type Child struct {
compose Parent parent
int j
int k
}

f<int> main() {
Child child;
child.i = 3;
child.j = 5;
}*/

/*import "std/os/env";
import "std/io/filepath";
Expand Down
50 changes: 34 additions & 16 deletions src-bootstrap/driver.spice
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,27 @@ public p Driver.enrich() {

// Dump AST, IR and symbol table if all debug output is enabled
if this.cliOptions.printDebugOutput {
this.cliOptions.dumpAST = true;
this.cliOptions.dumpIR = true;
this.cliOptions.dumpSymbolTable = true;
this.cliOptions.dumpSettings.dumpAST = true;
this.cliOptions.dumpSettings.dumpIR = true;
this.cliOptions.dumpSettings.dumpSymbolTable = true;
}
}

/**
* Executes the built executable
*/
public p Driver.runBinary() {
// Print status message
if this.cliOptions.printDebugOutput {
print("Running executable ...\n\n");
}

// Run executable
FilePath executablePath = this.cliOptions.outputPath;
executablePath.makeNative();
const int exitCode = execCmd(executablePath.toString());
if exitCode != 0 {
panic(Error("Your Spice executable exited with non-zero exit code"));
}
}

Expand All @@ -131,10 +149,10 @@ public p Driver.enrich() {
*/
p Driver.addBuildSubcommand() {
// Create sub-command itself
CliSubcommand& subCmd = this.cliParser.createSubcommand("build", "Builds your Spice program and emits an executable");
CliSubcommand& subCmd = this.cliParser.addSubcommand("build", "Builds your Spice program and emits an executable");
subCmd.addAlias("b");

addCompileSubcommandOptions(subCmd);
this.addCompileSubcommandOptions(subCmd);

// --target-triple
CliOption<string>& targetOption = subCmd.addOption("--target", this.cliOptions.targetTriple, "Target triple for the emitted executable (for cross-compiling)");
Expand Down Expand Up @@ -162,10 +180,10 @@ p Driver.addBuildSubcommand() {
*/
p Driver.addRunSubcommand() {
// Create sub-command itself
CliSubcommand& subCmd = this.cliParser.createSubcommand("run", "Builds your Spice program and runs it immediately");
CliSubcommand& subCmd = this.cliParser.addSubcommand("run", "Builds your Spice program and runs it immediately");
subCmd.addAlias("r");

addCompileSubcommandOptions(subCmd);
this.addCompileSubcommandOptions(subCmd);

// --output
CliOption<string>& outputOption = subCmd.addOption("--output", this.cliOptions.outputPath, "Set the output file path");
Expand All @@ -182,41 +200,41 @@ p Driver.addRunSubcommand() {
*/
p Driver.addInstallSubcommand() {
// Create sub-command itself
CliSubcommand& subCmd = this.cliParser.createSubcommand("install", "Builds your Spice program and installs it to a directory in the PATH variable");
CliSubcommand& subCmd = this.cliParser.addSubcommand("install", "Builds your Spice program and installs it to a directory in the PATH variable");
subCmd.addAlias("i");

addCompileSubcommandOptions(subCmd);
this.addCompileSubcommandOptions(subCmd);
}

/**
* Add uninstall subcommand to cli interface
*/
p Driver.addUninstallSubcommand() {
// Create sub-command itself
CliSubcommand& subCmd = this.cliParser.createSubcommand("uninstall", "Builds your Spice program and runs it immediately");
CliSubcommand& subCmd = this.cliParser.addSubcommand("uninstall", "Builds your Spice program and runs it immediately");
subCmd.addAlias("u");

addCompileSubcommandOptions(subCmd);
this.addCompileSubcommandOptions(subCmd);
}

p Driver.addCompileSubcommandOptions(CliSubcommand& subCmd) {
// --debug-output
CliOption<bool>& debugOutputFlag = subCmd.addFlag("--debug-output", this.cliOptions.printDebugOutput, "Enable debug output");
debugOutputFlag.addAlias("-d");
// --dump-cst
CliOption<bool>& dumpCstFlag = subCmd.addFlag("--dump-cst", this.cliOptions.dumpCST, "Dump CSTs as serialized string and SVG image");
CliOption<bool>& dumpCstFlag = subCmd.addFlag("--dump-cst", this.cliOptions.dumpSettings.dumpCST, "Dump CSTs as serialized string and SVG image");
dumpCstFlag.addAlias("-cst");
// --dump-ast
CliOption<bool>& dumpAstFlag = subCmd.addFlag("--dump-ast", this.cliOptions.dumpAST, "Dump ASTs as serialized string and SVG image");
CliOption<bool>& dumpAstFlag = subCmd.addFlag("--dump-ast", this.cliOptions.dumpSettings.dumpAST, "Dump ASTs as serialized string and SVG image");
dumpAstFlag.addAlias("-ast");
// --dump-symtab
CliOption<bool>& dumpSymtabFlag = subCmd.addFlag("--dump-symtab", this.cliOptions.dumpSymbolTable, "Dump serialized symbol tables");
CliOption<bool>& dumpSymtabFlag = subCmd.addFlag("--dump-symtab", this.cliOptions.dumpSettings.dumpSymbolTable, "Dump serialized symbol tables");
dumpSymtabFlag.addAlias("-symtab");
// --dump-ir
CliOption<bool>& dumpIrFlag = subCmd.addFlag("--dump-ir", this.cliOptions.dumpIR, "Dump LLVM-IR");
CliOption<bool>& dumpIrFlag = subCmd.addFlag("--dump-ir", this.cliOptions.dumpSettings.dumpIR, "Dump LLVM-IR");
dumpIrFlag.addAlias("-ir");
// --dump-assembly
CliOption<bool>& dumpAsmFlag = subCmd.addFlag("--dump-assembly", this.cliOptions.dumpAssembly, "Dump assembly code");
CliOption<bool>& dumpAsmFlag = subCmd.addFlag("--dump-assembly", this.cliOptions.dumpSettings.dumpAssembly, "Dump assembly code");
dumpAsmFlag.addAlias("-asm");
dumpAsmFlag.addAlias("-s");

Expand Down
27 changes: 12 additions & 15 deletions src-bootstrap/main.spice
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import "std/os/os";

// Own imports
import "./source-file";
import "./driver";
import "./global/global-resource-manager";
//import "bootstrap/source-file";
import "bootstrap/driver";
//import "bootstrap/global/global-resource-manager";

/**
* Compile main source file. All files, that are included by the main source file will be resolved recursively.
Expand All @@ -14,10 +14,10 @@ import "./global/global-resource-manager";
*/
f<bool> compileProject(const CliOptions& cliOptions) {
// Instantiate GlobalResourceManager
dyn resourceManager = GlobalResourceManager(options);
/*dyn resourceManager = GlobalResourceManager(cliOptions);

// Create source file instance for main source file
SourceFile* mainSourceFile = resourceManager.createSourceFile(nullptr, MAIN_FILE_NAME, cliOptions.mainSourceFile, false);
heap SourceFile* mainSourceFile = resourceManager.createSourceFile(nil<SourceFile*>, String(MAIN_FILE_NAME), cliOptions.mainSourceFile, false);

// Run compile pipeline for main source file. All dependent source files are triggered by their parents
mainSourceFile.runFrontEnd();
Expand All @@ -29,10 +29,7 @@ f<bool> compileProject(const CliOptions& cliOptions) {
resourceManager.linker.link();

// Print compiler warnings
mainSourceFile.collectAndPrintWarnings();

// Print compiler warnings
mainSourceFile.collectAndPrintWarnings();
mainSourceFile.collectAndPrintWarnings();*/

return true;
}
Expand All @@ -47,28 +44,28 @@ f<bool> compileProject(const CliOptions& cliOptions) {
f<int> main(int argc, string[] argv) {
// Initialize command line parser
Driver driver;
driver.create();
driver.init();
const int exitCode = driver.parse(argc, argv);
if exitCode != EXIT_SUCCESS {
if exitCode != EXIT_CODE_SUCCESS {
return exitCode;
}

// Cancel here if we do not have to compile
if !driver.shouldCompile {
return EXIT_SUCCESS;
return EXIT_CODE_SUCCESS;
}

driver.enrich(); // Prepare the cli options

// Kick off the compiling process
if !compileProject(driver.cliOptions) {
return EXIT_FAILURE;
return EXIT_CODE_ERROR;
}

// Execute
if driver.cliOptions.execute {
driver.runBinary();
}

return EXIT_SUCCESS;
}
return EXIT_CODE_SUCCESS;
}
44 changes: 44 additions & 0 deletions src-bootstrap/source-file.spice
Original file line number Diff line number Diff line change
Expand Up @@ -591,3 +591,47 @@ public f<const NameRegistryEntry*> SourceFile.getNameRegistryEntry(const String&

return entry;
}

public p SourceFile.checkForSoftErrors() {
// Check if there are any soft errors and if so, print them
if !this.resourceManager.errorManager.softErrors.isEmpty() {
String errorMessage = String("There are unresolved errors. Please fix them and recompile.");
foreach dyn error : this.resourceManager.errorManager.softErrors {
errorMessage += "\n\n";
errorMessage += error.toString();
}
panic(Error("Compilation aborted due to unresolved errors."));
}
}

public p SourceFile.collectAndPrintWarnings() {
// Print warnings for all dependencies
foreach dyn dependency : this.dependencies {
SourceFile* sourceFile = dependency.getSecond();
if !sourceFile.isStdFile {
sourceFile.collectAndPrintWarnings();
}
}
// Collect warnings for this file
if !ignoreWarnings {
this.globalScope.collectWarnings(this.compilerOutput.warnings);
}
// Print warnings for this file
foreach dyn warning : this.compilerOutput.warnings {
warning.print();
}
}

public f<const SourceFile*> SourceFile.getRootSourceFile() {
return this.isMainFile ? this : this.parent.getRootSourceFile();
}

/*public f<bool> SourceFile.isRT(RuntimeModule runtimeModule) {
assert IDENTIFIER_RUNTIME_MODULES.contains(runtimeModule);
const string topLevelName = IDENTIFIER_RUNTIME_MODULES.at(runtimeModule);
if !this.exportedNameRegistry.contains(topLevelName) {
return false;
}
dyn entry = this.exportedNameRegistry.get(topLevelName);
return entry.targetEntry.scope == this.globalScope;
}*/
5 changes: 4 additions & 1 deletion src/typechecker/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1776,7 +1776,10 @@ std::any TypeChecker::visitFctCall(FctCallNode *node) {
Scope *matchScope = returnBaseType.getBodyScope()->parent;
assert(matchScope != nullptr);
Struct *spiceStruct = StructManager::matchStruct(matchScope, structName, returnBaseType.getTemplateTypes(), node);
assert(spiceStruct != nullptr);
if (!spiceStruct) {
const std::string signature = Struct::getSignature(structName, returnBaseType.getTemplateTypes());
SOFT_ERROR_ER(node, UNKNOWN_DATATYPE, "Could not find struct candidate for struct '" + signature + "'. Do the template types match?")
}
returnType = returnType.getWithBodyScope(spiceStruct->scope).replaceBaseType(returnBaseType);

returnType = mapImportedScopeTypeToLocalType(returnType.getBase().getBodyScope(), returnType);
Expand Down
9 changes: 9 additions & 0 deletions std/os/cmd.spice
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,13 @@ public f<int> getPID() {
*/
public f<int> execCmd(string cmd) {
return system(cmd);
}

/**
* Executes a shell command by creating a new process.
*
* @return Return code of the shell comand
*/
public f<int> execCmd(const String& cmd) {
return system(cmd.getRaw());
}

0 comments on commit 62beaa9

Please sign in to comment.