(BREAKING) "use" keyword, stdlib seperate

This commit is contained in:
2026-01-28 17:03:40 +11:00
parent 4b86fee7b5
commit 6002bd922b
14 changed files with 97 additions and 76 deletions

View File

@@ -5,7 +5,7 @@ LDFLAGS = -lgroundvm
BUILD_DIR = build BUILD_DIR = build
SRC_DIR = src 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)) OBJS = $(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(SRCS))
TARGET = solstice TARGET = solstice

15
libs/conversions.sols Normal file
View File

@@ -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
}

23
libs/io.sols Normal file
View File

@@ -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
}

View File

@@ -22,14 +22,11 @@ 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 << " 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 '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 << " 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 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 << " 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) {
@@ -44,9 +41,6 @@ namespace ArgParser {
printHelp(); printHelp();
exit(1); exit(1);
} }
else if (strcmp(argv[i], "--nostdlib") == 0) {
nostdlib = true;
}
else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--output") == 0) { else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--output") == 0) {
i++; i++;
if (i < argc) { if (i < argc) {

View File

@@ -4,9 +4,6 @@
#include <cstring> #include <cstring>
namespace ArgParser { namespace ArgParser {
extern bool nostdlib;
enum class ArgType { enum class ArgType {
FILE, OUTPUT, OUTPUTTYPE FILE, OUTPUT, OUTPUTTYPE
}; };

View File

@@ -1,13 +1,13 @@
#include "parser.h" #include "parser.h"
#include "error.h" #include "error.h"
#include "lexer.h" #include "lexer.h"
#include "solstice_stdlib.h"
#include "argparser.h" #include "argparser.h"
#include <groundvm.h> #include <groundvm.h>
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <regex> #include <regex>
#include <cstdlib> #include <cstdlib>
#include <fstream>
#define parseOneToken(token) Parser({token}).parse().children[0] #define parseOneToken(token) Parser({token}).parse().children[0]
@@ -261,15 +261,6 @@ namespace Solstice {
const std::vector<SolGroundCodeBlock> SolNode::generateCode() { const std::vector<SolGroundCodeBlock> SolNode::generateCode() {
std::vector<SolGroundCodeBlock> code; std::vector<SolGroundCodeBlock> 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 // Process object member access
for (size_t i = 0; i < children.size(); i++) { for (size_t i = 0; i < children.size(); i++) {
SolNode& child = children[i]; SolNode& child = children[i];
@@ -932,6 +923,31 @@ namespace Solstice {
code.push_back(codeBlock); code.push_back(codeBlock);
break; 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: {} default: {}
} }
return code; return code;
@@ -1082,6 +1098,9 @@ namespace Solstice {
if (in == "new") { if (in == "new") {
return SolNodeType::New; return SolNodeType::New;
} }
if (in == "use") {
return SolNodeType::Use;
}
if (in == "{") { if (in == "{") {
return SolNodeType::CodeBlockStart; return SolNodeType::CodeBlockStart;
} }
@@ -1786,6 +1805,23 @@ namespace Solstice {
rootNode.addNode(inNode); rootNode.addNode(inNode);
break; 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; return rootNode;

View File

@@ -57,7 +57,7 @@ namespace Solstice {
enum class SolNodeType { 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 { enum class SolDataType {

View File

@@ -1,50 +0,0 @@
#include <string>
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
)";
}

View File

@@ -1,3 +0,0 @@
#include <string>
std::string getStdLib();

View File

@@ -1,3 +1,6 @@
use conversions
use io
myString = "312" myString = "312"
myInt = 435 myInt = 435

View File

@@ -1,3 +1,5 @@
use io
accessNotGranted = true accessNotGranted = true
while accessNotGranted { while accessNotGranted {

View File

@@ -1 +1,3 @@
use io
println("dingus") println("dingus")

View File

@@ -1,3 +1,5 @@
use io
struct dingus { struct dingus {
x = 5 x = 5
y = "dingus" y = "dingus"

View File

@@ -7,7 +7,7 @@ endif
" Keywords " Keywords
syn keyword solsticeConditional if syn keyword solsticeConditional if
syn keyword solsticeRepeat while 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 solsticeType int string bool double char
syn keyword solsticeBoolean true false syn keyword solsticeBoolean true false