Skip to content

Commit

Permalink
[bootstrap] Start bootstrapping process (#196)
Browse files Browse the repository at this point in the history
* Add first files for bootstrapping the compiler

* Extend reader

* Remove error factory

* Extend bootstrapped compiler
  • Loading branch information
marcauberer authored Sep 1, 2022
1 parent 3990726 commit 6f9191e
Show file tree
Hide file tree
Showing 50 changed files with 1,021 additions and 419 deletions.
2 changes: 1 addition & 1 deletion .run/Spice_run.run.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Spice_run" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O2 -ir ../../media/test-project/os-test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="Spice_run" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="Spice_run">
<configuration default="false" name="Spice_run" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O2 ../../src-bootstrap/main.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="Spice_run" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="Spice_run">
<envs>
<env name="RUN_TESTS" value="OFF" />
<env name="SPICE_STD_DIR" value="$PROJECT_DIR$/std" />
Expand Down
14 changes: 1 addition & 13 deletions media/test-project/os-test.spice
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,9 @@ f<int> main() {
printf("Hello %s!", p1.getSecond());
}*/

/*import "std/net/http" as http;
import "std/net/http" as http;

f<int> main() {
http::HttpServer server = http::HttpServer();
server.serve("/test", "Hello World!");
}*/

type TokenType enum {
IDENTIFIER,
DOT = 12,
COMMA,
SIZEOF = 0,
WS
}

f<int> main() {
printf("%d\n", TokenType.DOT);
}
153 changes: 153 additions & 0 deletions src-bootstrap/CliInterface.spice
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Imports
import "std/text/print" as print;
import "std/os/cmd" as cmd;

/**
* Representation of the various cli options
*/
public type CliOptions struct {
string mainSourceFile // e.g. main.spice
string targetTriple // In format: <arch><sub>-<vendor>-<sys>-<abi>
string targetArch
string targetVendor
string targetOs
string outputDir // Where the object files go. Should always be a temp directory
string outputPath // Where the output binary goes.
bool printDebugInfo
bool dumpCST
bool dumpAST
bool dumpIR
bool dumpAssembly
bool dumpSymbolTables
short optLevel // -O0 = 0, -O1 = 1, -O2 = 2, -O3 = 3, -Os = 4, -Oz = 5
bool generateDebugInfo
bool disableVerifier
bool testMode
}

/**
* Helper class to setup the cli interface and command line parser
*/
public type CliInterface struct {
//CliApp cliApp
CliOptions cliOptions
bool compile
bool install
bool run
}

public p CliInterface.ctor() {
// Initialize cli object
this.cliOptions = CliOptions{/* mainSourceFile */ "", /* targetTriple */ "", /* targetArch */ "", /* targetVendor */ "",
/* targetOs */ "", /* outputDir */ "", /* outputPath */ "", /* printDebugInfo */ false, /* dumpCST */ false,
/* dumpAST */ false, /* dumpIR */ false, /* dumpAssembly */ false, /* dumpSymbolTables */ false, /* optLevel */ 2s,
/* generateDebugInfo */ false, /* disableVerifier */ false, /* testMode */ false };
this.compile = false;
this.install = false;
this.run = false;
}

p CliInterface.createInterface() {
// ToDo: Extend
}

/**
* Validates if all necessary cli options were provided.
*
* @throws InvalidCliOptionsException if there were an invalid combination of cli options provided
*/
p CliInterface.validate() {
// ToDo: Extend
}

/**
* Initialize the cli options based on the input of the user
*/
p CliInterface.enrich() {
// Propagate target information
if this.cliOptions.targetTriple.empty() {
// ToDo: Extend
}

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

/**
* Add build subcommand to cli interface
*/
p CliInterface.addBuildSubcommand() {
// Create sub-command itself
// ToDo: Extend
}

/**
* Add run subcommand to cli interface
*/
p CliInterface.addRunSubcommand() {
// Create sub-command itself
// ToDo: Extend
}

/**
* Add install subcommand to cli interface
*/
p CliInterface.addInstallSubcommand() {
// Create sub-command itself
// ToDo: Extend
}

/**
* Add uninstall subcommand to cli interface
*/
p CliInterface.addUninstallSubcommand() {
// Create sub-command itself
// ToDo: Extend
}

/**
* Checks if compiling is necessary
*
* @return Compile or not
*/
f<bool> CliInterface.shouldCompile() {
return this.compile;
}

/**
* Checks if running is necessary
*
* @return Run or not
*/
f<bool> CliInterface.shoudRun() {
return this.run;
}

/**
* Start the parsing process
*
* @param argc Argument count
* @param argv Argument vector
* @return Return code
*/
f<int> CliInterface.parse(int argc, string[] argv) {
// ToDo: Extend
return 0;
}

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

// Run executable
cmd.execCmd(this.cliOptions.outputPath);
}
156 changes: 156 additions & 0 deletions src-bootstrap/SourceFile.spice
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// Imports
import "std/text/print" as print;
import "CliInterface" as cli;
import "ast/AstNodes" as ast;
import "symbol/SymbolTable" as st;
import "analyzer/Analyzer" as alzr;
import "generator/Generator" as gen;

/**
* Collects the output of the compiler for debugging
*/
type CompilerOutput struct {
string cstString
string astString
string symbolTableString
string irString
string irOptString
}

/**
* Represents a single source file
*/
public type SourceFile struct {
string name
string fileName
string filePath
string fileDir
string objectFilePath
bool stdFile
CompilerOutput compilerOutput
SourceFile* parent
cli::CliOptions* cliOptions
ast::EntryNode* ast
st::SymbolTable* symbolTable
alzr::Analyzer* analyzer
gen::Generator* generator
map::Map<string, pair::Pair<SourceFile*, CodeLoc*>> dependencies
}

public p SourceFile.ctor(CliOptions* cliOptions, SourceFile* parent, string name, string filePath, bool stdFile) {
// Copy data
this.cliOptions = cliOptions;
this.parent = parent;
this.name = name;
this.filePath = filePath;
this.stdFile = stdFile;

// Deduce fileName and fileDir
/*this.fileName = ;
this.fileDir = ;*/
}

p SourceFile.runLexer() {
// Lex this source file
}

p SourceFile.runParser() {
// Parse this source file
}

p SourceFile.visualizeCST(string* output) {
// Only execute if enabled
if !cliOptions.dumpCST && !cliOptions.testMode { return; }

// ToDo: Extend
}

p SourceFile.buildAST() {
// Transform the imported source files
// ToDo: Extend
}

p SourceFile.visualizeAST(string* output) {
// Only execute if enabled
if !cliOptions.dumpAST && !cliOptions.testMode { return; }

// ToDo: Extend
}

p SourceFile.preAnalyze() {
// Pre-analyze this source file
// ToDo: Extend

// Pre-analyze this source file
foreach dyn dependencyPair : this.dependencies {
SourceFile dependencyFile = dependencyPair.getSecond();
dependencyFile.runLexer();
dependencyFile.runParser();
dependencyFile.buildAST();
dependencyFile.preAnalyze();
}
}

p SourceFile.analyze() {
// Analyze the imported source files first
// ToDo: Extend

// Analyze this source file
}

p SourceFile.reAnalyze() {
// Re-Analyze this source file

// Analyze the imported source files first
// ToDo: Extend

// Save the JSON version in the compiler output

// Dump symbolTable
if cliOptions.dumpSymbolTable {
printf("\nSymbol table of file %s:\n\n", filePath);
printf("%s\n", compilerOutput.symbolTableString);
}
}

p SourceFile.generate() {
// Generate the imported source files

// Generate this source file

// Save the JSON version in the compiler output

// Dump unoptimized IR code

// Optimize IR code

// Dump assembly code

// Emit object file

// Add object file to the linker interface

// Print warning if verifier is disabled
if parent == nil<SymbolTable*> && cliOptions.disableVerifier {
print.emptyLine();
// ToDo
print.emptyLine();
}
}

p SourceFile.addDependency(const CodeLoc codeLoc, const string name, const string stringFilePath, bool stdFile) {
// Check if this would cause a circular dependency
if isAlreadyImported(filePath) {
// ToDo: Error out
}

// Add the dependency
// ToDo
}

f<bool> SourceFile.isAlreadyImported(const string filePathSearch) {
// Check if the current source file corresponds to the path to search
if filePath == filePathSearch { return true; }
// Check parent recursively
return parent != nil<SourceFile*> && parent.isAlreadyImported(filePathSearch);
}
5 changes: 5 additions & 0 deletions src-bootstrap/analyzer/analyzer.spice
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Imports

public type Analyzer struct {

}
5 changes: 5 additions & 0 deletions src-bootstrap/ast/AstNodes.spice
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Imports

public type EntryNode struct {

}
Loading

0 comments on commit 6f9191e

Please sign in to comment.