diff --git a/Makefile b/Makefile index c8af9fb..31a1664 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ LDFLAGS = -lgroundvm BUILD_DIR = build SRC_DIR = src -SRCS = $(SRC_DIR)/main.cpp $(SRC_DIR)/argparser.cpp $(SRC_DIR)/lexer.cpp $(SRC_DIR)/parser.cpp $(SRC_DIR)/error.cpp $(SRC_DIR)/solstice_stdlib.cpp +SRCS = $(SRC_DIR)/main.cpp $(SRC_DIR)/argparser.cpp $(SRC_DIR)/lexer.cpp $(SRC_DIR)/parser.cpp $(SRC_DIR)/error.cpp OBJS = $(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(SRCS)) TARGET = solstice diff --git a/libs/conversions.sols b/libs/conversions.sols new file mode 100644 index 0000000..d0536a4 --- /dev/null +++ b/libs/conversions.sols @@ -0,0 +1,15 @@ +def stringToInt(string in) int { + result = 0 + ground { + stoi $in &result + } + return result +} + +def intToString(int in) string { + result = "" + ground { + tostring $in &result + } + return result +} diff --git a/libs/io.sols b/libs/io.sols new file mode 100644 index 0000000..809c718 --- /dev/null +++ b/libs/io.sols @@ -0,0 +1,23 @@ +def input(string msg) string { + retval = "" + ground { + print $msg + input &retval + } + return retval +} + +def print(string msg) string { + ground { + print $msg + } + return msg +} + +def println(string msg) string { + ground { + println $msg + } + return msg +} + diff --git a/src/argparser.cpp b/src/argparser.cpp index 04383f1..b1a03ba 100644 --- a/src/argparser.cpp +++ b/src/argparser.cpp @@ -22,14 +22,11 @@ namespace ArgParser { std::cout << " -t type or --type type\n"; std::cout << " Specifies the type of output.\n"; std::cout << " Currently supported options:\n"; - std::cout << " ground, native (BETA) (Requires --nostdlib)\n"; + std::cout << " ground, native (BETA)\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) { @@ -44,9 +41,6 @@ namespace ArgParser { printHelp(); exit(1); } - else if (strcmp(argv[i], "--nostdlib") == 0) { - nostdlib = true; - } else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--output") == 0) { i++; if (i < argc) { diff --git a/src/argparser.h b/src/argparser.h index 6fb92c7..c910efd 100644 --- a/src/argparser.h +++ b/src/argparser.h @@ -4,9 +4,6 @@ #include namespace ArgParser { - - extern bool nostdlib; - enum class ArgType { FILE, OUTPUT, OUTPUTTYPE }; diff --git a/src/parser.cpp b/src/parser.cpp index df6f67e..3318f16 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,13 +1,13 @@ #include "parser.h" #include "error.h" #include "lexer.h" -#include "solstice_stdlib.h" #include "argparser.h" #include #include #include #include #include +#include #define parseOneToken(token) Parser({token}).parse().children[0] @@ -261,15 +261,6 @@ namespace Solstice { const std::vector SolNode::generateCode() { std::vector code; - if (nodeType == SolNodeType::Root) { - // Compile and insert standard library - if (!ArgParser::nostdlib) { - auto parsedStdlib = Parser(Lexer(getStdLib()).lex()).parse(); - parsedStdlib.nodeType = SolNodeType::None; - code = parsedStdlib.generateCode(); - } - } - // Process object member access for (size_t i = 0; i < children.size(); i++) { SolNode& child = children[i]; @@ -932,6 +923,31 @@ namespace Solstice { code.push_back(codeBlock); break; } + case SolNodeType::Use: { + SolGroundCodeBlock codeBlock; + char* solsticeLibsEnv = getenv("SOLSTICE_LIBS"); + std::string filePath; + if (solsticeLibsEnv == NULL) { + filePath = "/usr/lib/solstice/" + outputId + ".sols"; + } else { + filePath = std::string(solsticeLibsEnv) + "/" + outputId + ".sols"; + } + + std::ifstream file(filePath); + + if (file.good()) { + std::ostringstream ss; + ss << file.rdbuf(); + SolNode fileNode = Parser(Lexer(ss.str()).lex()).parse(); + fileNode.nodeType = SolNodeType::None; + auto fileCode = fileNode.generateCode(); + code.insert(code.end(), fileCode.begin(), fileCode.end()); + } else { + file.close(); + Error::syntaxError("Library " + outputId + " does not exist"); + } + break; + } default: {} } return code; @@ -1082,6 +1098,9 @@ namespace Solstice { if (in == "new") { return SolNodeType::New; } + if (in == "use") { + return SolNodeType::Use; + } if (in == "{") { return SolNodeType::CodeBlockStart; } @@ -1786,6 +1805,23 @@ namespace Solstice { rootNode.addNode(inNode); break; } + case SolNodeType::Use: { + SolNode useNode(SolNodeType::Use); + useNode.line = tokenObj.line; + useNode.lineContent = tokenObj.lineContent; + auto tokenopt = consume(); + if (tokenopt) { + Token token = tokenopt.value(); + if (getNodeType(token.value) != SolNodeType::Identifier) { + Error::syntaxError("Expected identifier after 'use'", tokenObj.line, tokenObj.lineContent); + } + useNode.outputId = token.value; + rootNode.addNode(useNode); + } else { + Error::syntaxError("Expected identifier after 'use'", tokenObj.line, tokenObj.lineContent); + } + break; + } } } return rootNode; diff --git a/src/parser.h b/src/parser.h index 793813a..0d59846 100644 --- a/src/parser.h +++ b/src/parser.h @@ -57,7 +57,7 @@ namespace Solstice { enum class SolNodeType { - Add, Subtract, Multiply, Divide, Equal, Inequal, Greater, Lesser, EqGreater, EqLesser, Set, While, If, Value, Identifier, None, Root, CodeBlock, CodeBlockStart, CodeBlockEnd, FunctionDef, FunctionCall, Expression, BracketStart, BracketEnd, Puts, Return, InlineGround, Struct, New, In + Add, Subtract, Multiply, Divide, Equal, Inequal, Greater, Lesser, EqGreater, EqLesser, Set, While, If, Value, Identifier, None, Root, CodeBlock, CodeBlockStart, CodeBlockEnd, FunctionDef, FunctionCall, Expression, BracketStart, BracketEnd, Puts, Return, InlineGround, Struct, New, In, Use }; enum class SolDataType { diff --git a/src/solstice_stdlib.cpp b/src/solstice_stdlib.cpp deleted file mode 100644 index 7fd223b..0000000 --- a/src/solstice_stdlib.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include - -std::string getStdLib() { - return R"( - -// Solstice stdlib - -def input(string msg) string { - retval = "" - ground { - print $msg - input &retval - } - return retval -} - -def print(string msg) string { - ground { - print $msg - } - return msg -} - -def println(string msg) string { - ground { - println $msg - } - return msg -} - -def stringToInt(string in) int { - result = 0 - ground { - stoi $in &result - } - return result -} - -def intToString(int in) string { - result = "" - ground { - tostring $in &result - } - return result -} - -// End Solstice stdlib - - )"; -} diff --git a/src/solstice_stdlib.h b/src/solstice_stdlib.h deleted file mode 100644 index 43361c4..0000000 --- a/src/solstice_stdlib.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -std::string getStdLib(); diff --git a/tests/convert.sols b/tests/convert.sols index c99068f..55c4d57 100644 --- a/tests/convert.sols +++ b/tests/convert.sols @@ -1,3 +1,6 @@ +use conversions +use io + myString = "312" myInt = 435 diff --git a/tests/input.sols b/tests/input.sols index 3feacfa..2a8d359 100644 --- a/tests/input.sols +++ b/tests/input.sols @@ -1,3 +1,5 @@ +use io + accessNotGranted = true while accessNotGranted { diff --git a/tests/print.sols b/tests/print.sols index 8900c63..b136818 100644 --- a/tests/print.sols +++ b/tests/print.sols @@ -1 +1,3 @@ +use io + println("dingus") diff --git a/tests/struct.sols b/tests/struct.sols index c8b37f8..5cfe973 100644 --- a/tests/struct.sols +++ b/tests/struct.sols @@ -1,3 +1,5 @@ +use io + struct dingus { x = 5 y = "dingus" diff --git a/vim/syntax/solstice.vim b/vim/syntax/solstice.vim index b642d5c..c11acd5 100644 --- a/vim/syntax/solstice.vim +++ b/vim/syntax/solstice.vim @@ -7,7 +7,7 @@ endif " Keywords syn keyword solsticeConditional if syn keyword solsticeRepeat while -syn keyword solsticeKeyword def struct return +syn keyword solsticeKeyword def struct return use syn keyword solsticeType int string bool double char syn keyword solsticeBoolean true false