forked from solstice/solstice
Start work on structs
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
solstice
|
||||
build
|
||||
.*_solsbuild
|
||||
|
||||
@@ -100,6 +100,7 @@ namespace Solstice {
|
||||
}
|
||||
// tokens which are not followed by anything
|
||||
case '\n':
|
||||
case ':':
|
||||
{
|
||||
if (!buf.empty()) {
|
||||
addToken(buf);
|
||||
|
||||
171
src/parser.cpp
171
src/parser.cpp
@@ -216,7 +216,7 @@ namespace Solstice {
|
||||
code = parsedStdlib.generateCode();
|
||||
}
|
||||
}
|
||||
if (nodeType != SolNodeType::If && nodeType != SolNodeType::While) for (auto& child : children) {
|
||||
if (nodeType != SolNodeType::If && nodeType != SolNodeType::While && nodeType != SolNodeType::Struct) for (auto& child : children) {
|
||||
auto childCode = child.generateCode();
|
||||
code.insert(code.end(), childCode.begin(), childCode.end());
|
||||
}
|
||||
@@ -749,6 +749,51 @@ namespace Solstice {
|
||||
code.push_back(codeBlock);
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Struct: {
|
||||
//SolGroundCodeBlock preProcessCodeBlock;
|
||||
SolGroundCodeBlock codeBlock;
|
||||
GroundInstruction gi = groundCreateInstruction(STRUCT);
|
||||
|
||||
// struct -name
|
||||
groundAddReferenceToInstruction(&gi, groundCreateReference(TYPEREF, copyString(outputId)));
|
||||
codeBlock.code.push_back(gi);
|
||||
|
||||
// contents of struct
|
||||
for (SolNode& child : children) {
|
||||
if (child.nodeType == SolNodeType::Identifier) {
|
||||
gi = groundCreateInstruction(SET);
|
||||
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(child.outputId)));
|
||||
|
||||
SolNode& valNode = child.children[0];
|
||||
if (valNode.nodeType == SolNodeType::Value) {
|
||||
GroundValue gv;
|
||||
switch (valNode.data.type) {
|
||||
case SolDataType::String: gv = groundCreateValue(STRING, copyString(valNode.data.getString().value())); break;
|
||||
case SolDataType::Int: gv = groundCreateValue(INT, valNode.data.getInt().value()); break;
|
||||
case SolDataType::Double: gv = groundCreateValue(DOUBLE, valNode.data.getDouble().value()); break;
|
||||
case SolDataType::Char: gv = groundCreateValue(CHAR, valNode.data.getChar().value()); break;
|
||||
case SolDataType::Bool: gv = groundCreateValue(BOOL, valNode.data.getBool().value()); break;
|
||||
default: Error::syntaxError("Struct member must be assigned a value or identifier", valNode.line, valNode.lineContent); break;
|
||||
}
|
||||
groundAddValueToInstruction(&gi, gv);
|
||||
} else if (child.nodeType == SolNodeType::Identifier) {
|
||||
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(valNode.outputId)));
|
||||
} else {
|
||||
Error::syntaxError("Struct member must be assigned a value or identifier", valNode.line, valNode.lineContent);
|
||||
}
|
||||
codeBlock.code.push_back(gi);
|
||||
}
|
||||
if (child.nodeType == SolNodeType::FunctionDef) {
|
||||
auto fnBlock = child.generateCode();
|
||||
for (const auto& code : fnBlock) {
|
||||
codeBlock.code.insert(codeBlock.code.end(), code.code.begin(), code.code.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
codeBlock.code.push_back(groundCreateInstruction(ENDSTRUCT));
|
||||
code.push_back(codeBlock);
|
||||
break;
|
||||
}
|
||||
default: {}
|
||||
}
|
||||
return code;
|
||||
@@ -849,7 +894,7 @@ namespace Solstice {
|
||||
if (in == "/") {
|
||||
return SolNodeType::Divide;
|
||||
}
|
||||
if (in == "=") {
|
||||
if (in == "=" || in == ":") {
|
||||
return SolNodeType::Set;
|
||||
}
|
||||
if (in == "==") {
|
||||
@@ -888,6 +933,12 @@ namespace Solstice {
|
||||
if (in == "ground") {
|
||||
return SolNodeType::InlineGround;
|
||||
}
|
||||
if (in == "struct") {
|
||||
return SolNodeType::Struct;
|
||||
}
|
||||
if (in == "new") {
|
||||
return SolNodeType::New;
|
||||
}
|
||||
if (in == "{") {
|
||||
return SolNodeType::CodeBlockStart;
|
||||
}
|
||||
@@ -1437,7 +1488,6 @@ namespace Solstice {
|
||||
SolNode groundNode(SolNodeType::InlineGround);
|
||||
consume(); // some funny token
|
||||
consume(); // {
|
||||
consume(); // new line token
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value().value == "}") {
|
||||
break;
|
||||
@@ -1447,6 +1497,121 @@ namespace Solstice {
|
||||
rootNode.addNode(groundNode);
|
||||
break;
|
||||
}
|
||||
case SolNodeType::Struct: {
|
||||
SolNode structNode(SolNodeType::Struct);
|
||||
structNode.line = tokenObj.line;
|
||||
structNode.lineContent = tokenObj.lineContent;
|
||||
|
||||
auto nameopt = consume();
|
||||
if (nameopt) {
|
||||
structNode.outputId = nameopt.value().value;
|
||||
}
|
||||
|
||||
while (peek() && peek().value().value == "\n") {
|
||||
consume();
|
||||
}
|
||||
|
||||
auto openBrace = consume();
|
||||
if (!openBrace || openBrace.value().value != "{") {
|
||||
Error::syntaxError("Expected '{' after struct name", tokenObj.line, tokenObj.lineContent);
|
||||
}
|
||||
|
||||
std::vector<Token> tokens;
|
||||
int count = 1;
|
||||
while (auto tokenopt = consume()) {
|
||||
if (tokenopt.value().value == "{") {
|
||||
count++;
|
||||
}
|
||||
if (tokenopt.value().value == "}") {
|
||||
count--;
|
||||
}
|
||||
if (count < 1) {
|
||||
break;
|
||||
}
|
||||
tokens.push_back(tokenopt.value());
|
||||
}
|
||||
|
||||
if (count != 0) {
|
||||
Error::syntaxError("Unclosed struct body", tokenObj.line, tokenObj.lineContent);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < tokens.size(); i++) {
|
||||
Token token = tokens[i];
|
||||
|
||||
if (token.value == "\n") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getNodeType(token.value) == SolNodeType::Identifier) {
|
||||
if (i + 2 >= tokens.size()) {
|
||||
Error::syntaxError("Expecting a value after the identifier", token.line, token.lineContent);
|
||||
continue;
|
||||
}
|
||||
if (getNodeType(tokens[i + 1].value) != SolNodeType::Set) {
|
||||
Error::syntaxError("Expected a set keyword ('=' or ':')", token.line, token.lineContent);
|
||||
continue;
|
||||
}
|
||||
if (getNodeType(tokens[i + 2].value) != SolNodeType::Identifier &&
|
||||
getNodeType(tokens[i + 2].value) != SolNodeType::Value) {
|
||||
Error::syntaxError("Expected a value or identifier for default value", token.line, token.lineContent);
|
||||
continue;
|
||||
}
|
||||
|
||||
SolNode idNode(SolNodeType::Identifier);
|
||||
idNode.outputId = token.value;
|
||||
idNode.line = token.line;
|
||||
idNode.lineContent = token.lineContent;
|
||||
SolNode valueNode = Parser({tokens[i + 2]}).parse().children[0];
|
||||
idNode.addNode(valueNode);
|
||||
structNode.addNode(idNode);
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (getNodeType(token.value) == SolNodeType::FunctionDef) {
|
||||
std::vector<Token> functionTokens;
|
||||
functionTokens.push_back(token);
|
||||
int funcCount = 0;
|
||||
i++;
|
||||
|
||||
while (i < tokens.size()) {
|
||||
functionTokens.push_back(tokens[i]);
|
||||
|
||||
if (tokens[i].value == "{") {
|
||||
funcCount++;
|
||||
}
|
||||
if (tokens[i].value == "}") {
|
||||
funcCount--;
|
||||
if (funcCount == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (funcCount != 0) {
|
||||
Error::syntaxError("Unclosed function in struct", token.line, token.lineContent);
|
||||
}
|
||||
|
||||
SolNode functionNode = Parser(functionTokens).parse().children[0];
|
||||
structNode.addNode(functionNode);
|
||||
} else {
|
||||
Error::syntaxError("Structs only support set statements and function definition", token.line, token.lineContent);
|
||||
}
|
||||
}
|
||||
|
||||
rootNode.addNode(structNode);
|
||||
break;
|
||||
}
|
||||
|
||||
case SolNodeType::New: {
|
||||
SolNode putsNode(SolNodeType::New);
|
||||
putsNode.line = tokenObj.line;
|
||||
putsNode.lineContent = tokenObj.lineContent;
|
||||
auto typeopt = consume();
|
||||
rootNode.addNode(putsNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rootNode;
|
||||
|
||||
@@ -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
|
||||
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
|
||||
};
|
||||
|
||||
enum class SolDataType {
|
||||
|
||||
3
tests/struct.sols
Normal file
3
tests/struct.sols
Normal file
@@ -0,0 +1,3 @@
|
||||
struct dingus {
|
||||
x = 5
|
||||
}
|
||||
Reference in New Issue
Block a user