forked from solstice/solstice
Start work on structs
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
solstice
|
solstice
|
||||||
build
|
build
|
||||||
|
.*_solsbuild
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ namespace Solstice {
|
|||||||
}
|
}
|
||||||
// tokens which are not followed by anything
|
// tokens which are not followed by anything
|
||||||
case '\n':
|
case '\n':
|
||||||
|
case ':':
|
||||||
{
|
{
|
||||||
if (!buf.empty()) {
|
if (!buf.empty()) {
|
||||||
addToken(buf);
|
addToken(buf);
|
||||||
|
|||||||
171
src/parser.cpp
171
src/parser.cpp
@@ -216,7 +216,7 @@ namespace Solstice {
|
|||||||
code = parsedStdlib.generateCode();
|
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();
|
auto childCode = child.generateCode();
|
||||||
code.insert(code.end(), childCode.begin(), childCode.end());
|
code.insert(code.end(), childCode.begin(), childCode.end());
|
||||||
}
|
}
|
||||||
@@ -749,6 +749,51 @@ namespace Solstice {
|
|||||||
code.push_back(codeBlock);
|
code.push_back(codeBlock);
|
||||||
break;
|
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: {}
|
default: {}
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
@@ -849,7 +894,7 @@ namespace Solstice {
|
|||||||
if (in == "/") {
|
if (in == "/") {
|
||||||
return SolNodeType::Divide;
|
return SolNodeType::Divide;
|
||||||
}
|
}
|
||||||
if (in == "=") {
|
if (in == "=" || in == ":") {
|
||||||
return SolNodeType::Set;
|
return SolNodeType::Set;
|
||||||
}
|
}
|
||||||
if (in == "==") {
|
if (in == "==") {
|
||||||
@@ -888,6 +933,12 @@ namespace Solstice {
|
|||||||
if (in == "ground") {
|
if (in == "ground") {
|
||||||
return SolNodeType::InlineGround;
|
return SolNodeType::InlineGround;
|
||||||
}
|
}
|
||||||
|
if (in == "struct") {
|
||||||
|
return SolNodeType::Struct;
|
||||||
|
}
|
||||||
|
if (in == "new") {
|
||||||
|
return SolNodeType::New;
|
||||||
|
}
|
||||||
if (in == "{") {
|
if (in == "{") {
|
||||||
return SolNodeType::CodeBlockStart;
|
return SolNodeType::CodeBlockStart;
|
||||||
}
|
}
|
||||||
@@ -1437,7 +1488,6 @@ namespace Solstice {
|
|||||||
SolNode groundNode(SolNodeType::InlineGround);
|
SolNode groundNode(SolNodeType::InlineGround);
|
||||||
consume(); // some funny token
|
consume(); // some funny token
|
||||||
consume(); // {
|
consume(); // {
|
||||||
consume(); // new line token
|
|
||||||
while (auto tokenopt = consume()) {
|
while (auto tokenopt = consume()) {
|
||||||
if (tokenopt.value().value == "}") {
|
if (tokenopt.value().value == "}") {
|
||||||
break;
|
break;
|
||||||
@@ -1447,6 +1497,121 @@ namespace Solstice {
|
|||||||
rootNode.addNode(groundNode);
|
rootNode.addNode(groundNode);
|
||||||
break;
|
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;
|
return rootNode;
|
||||||
|
|||||||
@@ -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
|
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 {
|
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