forked from solstice/solstice
Compilation with ground->asm
This commit is contained in:
@@ -5,6 +5,8 @@
|
|||||||
#include "argparser.h"
|
#include "argparser.h"
|
||||||
|
|
||||||
namespace ArgParser {
|
namespace ArgParser {
|
||||||
|
|
||||||
|
bool nostdlib = false;
|
||||||
|
|
||||||
void printHelp() {
|
void printHelp() {
|
||||||
std::cout << "Solstice compiler\n";
|
std::cout << "Solstice compiler\n";
|
||||||
@@ -20,7 +22,14 @@ namespace ArgParser {
|
|||||||
std::cout << " -t type or --type type\n";
|
std::cout << " -t type or --type type\n";
|
||||||
std::cout << " Specifies the type of output.\n";
|
std::cout << " Specifies the type of output.\n";
|
||||||
std::cout << " Currently supported options:\n";
|
std::cout << " Currently supported options:\n";
|
||||||
std::cout << " text\n";
|
std::cout << " ground, native (BETA) (Requires --nostdlib)\n";
|
||||||
|
std::cout << " Choosing the 'ground' option outputs the compiled program as a .grnd textual representation file.\n";
|
||||||
|
std::cout << " Choosing the 'native' option uses Ground's ground->asm compiler to create a native executable.\n";
|
||||||
|
std::cout << " This feature is currently in beta, as Ground's ground->asm compiler is not fully complete.\n";
|
||||||
|
std::cout << " This feature requires the '--nostdlib' flag as Ground's ground->asm compiler does not support functions.\n";
|
||||||
|
std::cout << " See https://sols.dev/docs#nativecompiler for more details\n";
|
||||||
|
std::cout << " --nostdlib\n";
|
||||||
|
std::cout << " Excludes the Solstice stdlib from compilation.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
Args parseArgs(int argc, char** argv) {
|
Args parseArgs(int argc, char** argv) {
|
||||||
@@ -35,13 +44,12 @@ namespace ArgParser {
|
|||||||
printHelp();
|
printHelp();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--output") == 0) {
|
else if (strcmp(argv[i], "--nostdlib") == 0) {
|
||||||
|
nostdlib = true;
|
||||||
|
}
|
||||||
|
else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--output") == 0) {
|
||||||
i++;
|
i++;
|
||||||
if (i < argc) {
|
if (i < argc) {
|
||||||
if (args.output.has_value()) {
|
|
||||||
std::cout << "(error) Multiple output values provided\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
args.output = Argument(ArgType::OUTPUT, std::string(argv[i]));
|
args.output = Argument(ArgType::OUTPUT, std::string(argv[i]));
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@@ -52,10 +60,6 @@ namespace ArgParser {
|
|||||||
else if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--type") == 0) {
|
else if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--type") == 0) {
|
||||||
i++;
|
i++;
|
||||||
if (i < argc) {
|
if (i < argc) {
|
||||||
if (args.output.has_value()) {
|
|
||||||
std::cout << "(error) Multiple type values provided\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
args.outputtype = Argument(ArgType::OUTPUTTYPE, std::string(argv[i]));
|
args.outputtype = Argument(ArgType::OUTPUTTYPE, std::string(argv[i]));
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace ArgParser {
|
namespace ArgParser {
|
||||||
|
|
||||||
|
extern bool nostdlib;
|
||||||
|
|
||||||
enum class ArgType {
|
enum class ArgType {
|
||||||
FILE, OUTPUT, OUTPUTTYPE
|
FILE, OUTPUT, OUTPUTTYPE
|
||||||
|
|||||||
66
src/main.cpp
66
src/main.cpp
@@ -4,6 +4,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
@@ -31,32 +32,51 @@ int main(int argc, char** argv) {
|
|||||||
GroundProgram program = Solstice::Parser::assembleProgram(parsed);
|
GroundProgram program = Solstice::Parser::assembleProgram(parsed);
|
||||||
Solstice::Error::summariseErrors();
|
Solstice::Error::summariseErrors();
|
||||||
if (args.output.has_value()) {
|
if (args.output.has_value()) {
|
||||||
std::FILE* originalStdout = stdout;
|
if (!args.outputtype.has_value() || args.outputtype.value().value == "ground") {
|
||||||
std::FILE* tmp = std::tmpfile();
|
std::FILE* originalStdout = stdout;
|
||||||
if (!tmp) {
|
std::FILE* tmp = std::tmpfile();
|
||||||
std::cout << "Failed to create tmp file\n";
|
if (!tmp) {
|
||||||
exit(1);
|
std::cout << "Failed to create tmp file\n";
|
||||||
}
|
exit(1);
|
||||||
stdout = tmp;
|
}
|
||||||
groundPrintProgram(&program);
|
stdout = tmp;
|
||||||
std::fflush(tmp);
|
groundPrintProgram(&program);
|
||||||
std::fseek(tmp, 0, SEEK_END);
|
std::fflush(tmp);
|
||||||
long size = std::ftell(tmp);
|
std::fseek(tmp, 0, SEEK_END);
|
||||||
std::fseek(tmp, 0, SEEK_SET);
|
long size = std::ftell(tmp);
|
||||||
|
std::fseek(tmp, 0, SEEK_SET);
|
||||||
std::string result(size, '\0');
|
|
||||||
std::fread(&result[0], 1, size, tmp);
|
std::string result(size, '\0');
|
||||||
|
std::fread(&result[0], 1, size, tmp);
|
||||||
|
|
||||||
stdout = originalStdout;
|
stdout = originalStdout;
|
||||||
std::fclose(tmp);
|
std::fclose(tmp);
|
||||||
|
|
||||||
std::ofstream outputFile(args.output.value().value);
|
std::ofstream outputFile(args.output.value().value);
|
||||||
if (!outputFile) {
|
if (!outputFile) {
|
||||||
std::cout << "Failed to write to " << args.output.value().value << "\n";
|
std::cout << "Failed to write to " << args.output.value().value << "\n";
|
||||||
|
}
|
||||||
|
outputFile << result;
|
||||||
|
outputFile.close();
|
||||||
|
exit(0);
|
||||||
|
} else if (args.outputtype.value().value == "native") {
|
||||||
|
std::string assembly(groundCompileProgram(&program));
|
||||||
|
std::string folder = "." + args.output.value().value + "_solsbuild";
|
||||||
|
std::filesystem::create_directory(folder);
|
||||||
|
std::ofstream asmfile(folder + "/program.s");
|
||||||
|
if (asmfile) {
|
||||||
|
asmfile << assembly;
|
||||||
|
asmfile.close();
|
||||||
|
} else {
|
||||||
|
std::cout << "Failed to create temporary file for assembly\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
std::string command = "nasm -f elf64 -o " + folder + "/program.o " + folder + "/program.s";
|
||||||
|
std::system(command.c_str());
|
||||||
|
command = "ld -o " + args.output.value().value + " " + folder + "/program.o";
|
||||||
|
std::system(command.c_str());
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
outputFile << result;
|
|
||||||
outputFile.close();
|
|
||||||
exit(0);
|
|
||||||
} else {
|
} else {
|
||||||
GroundValue gv = groundRunProgram(&program);
|
GroundValue gv = groundRunProgram(&program);
|
||||||
if (gv.type == INT) {
|
if (gv.type == INT) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "solstice_stdlib.h"
|
#include "solstice_stdlib.h"
|
||||||
|
#include "argparser.h"
|
||||||
#include <groundvm.h>
|
#include <groundvm.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -209,9 +210,11 @@ namespace Solstice {
|
|||||||
std::vector<SolGroundCodeBlock> code;
|
std::vector<SolGroundCodeBlock> code;
|
||||||
if (nodeType == SolNodeType::Root) {
|
if (nodeType == SolNodeType::Root) {
|
||||||
// Compile and insert standard library
|
// Compile and insert standard library
|
||||||
auto parsedStdlib = Parser(Lexer(getStdLib()).lex()).parse();
|
if (!ArgParser::nostdlib) {
|
||||||
parsedStdlib.nodeType = SolNodeType::None;
|
auto parsedStdlib = Parser(Lexer(getStdLib()).lex()).parse();
|
||||||
code = parsedStdlib.generateCode();
|
parsedStdlib.nodeType = SolNodeType::None;
|
||||||
|
code = parsedStdlib.generateCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (nodeType != SolNodeType::If && nodeType != SolNodeType::While) for (auto& child : children) {
|
if (nodeType != SolNodeType::If && nodeType != SolNodeType::While) for (auto& child : children) {
|
||||||
auto childCode = child.generateCode();
|
auto childCode = child.generateCode();
|
||||||
|
|||||||
Reference in New Issue
Block a user