Member access (no writing yet)

This commit is contained in:
2026-01-27 21:12:09 +11:00
parent e285b2c59f
commit 59e273b26e
4 changed files with 115 additions and 8 deletions

View File

@@ -6,6 +6,7 @@
#include <groundvm.h>
#include <cstring>
#include <string>
#include <regex>
#include <cstdlib>
#define parseOneToken(token) Parser({token}).parse().children[0]
@@ -267,6 +268,81 @@ namespace Solstice {
code = parsedStdlib.generateCode();
}
}
// Process object member access
for (size_t i = 0; i < children.size(); i++) {
SolNode& child = children[i];
if (child.nodeType == SolNodeType::In) {
if (variables.find(child.outputId) == variables.end()) {
Error::syntaxError(child.outputId + " could not be found", child.line, child.lineContent);
}
std::string type = variables[child.outputId];
if (type.substr(0, 7) != "object(") {
Error::typingError(child.outputId + " is not an object", child.line, child.lineContent);
}
std::regex pattern("([a-zA-Z0-9_:<>*&]+)\\s+\\b" + child.children[0].outputId + "\\b");
std::smatch match;
if (std::regex_search(type, match, pattern)) {
if (i + 1 < children.size() && children[i + 1].nodeType == SolNodeType::Set) {
// handle stuff in the equals
} else {
SolGroundCodeBlock codeBlock;
GroundInstruction gi = groundCreateInstruction(GETFIELD);
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(child.outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(child.children[0].outputId)));
child.outputId = "obj_access_" + std::to_string(tmpIdIterator++);
variables[child.outputId] = match[1];
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(child.outputId)));
codeBlock.code.push_back(gi);
code.push_back(codeBlock);
}
} else {
Error::typingError("Couldn't find field " + child.children[0].outputId + " in " + child.outputId, child.line, child.lineContent);
}
}
}
/*
// Process object member access
for (size_t i = 0; i < children.size(); i++) {
SolNode& child = children[i];
if (child.nodeType == SolNodeType::In) {
if (variables.find(outputId) == variables.end()) {
Error::syntaxError(child.outputId + " could not be found", child.line, child.lineContent);
break;
}
std::string type = variables[outputId];
if (type.substr(0, 7) != "object(") {
Error::typingError(child.outputId + " is not an object", child.line, child.lineContent);
break;
}
std::regex pattern("([a-zA-Z0-9_:<>*&]+)\\s+\\b" + child.children[0].outputId + "\\b");
std::smatch match;
if (std::regex_search(type, match, pattern)) {
if (i + 1 < children.size() && children[i + 1].nodeType == SolNodeType::Set) {
// handle stuff in the equals
} else {
SolGroundCodeBlock codeBlock;
GroundInstruction gi = groundCreateInstruction(GETFIELD);
groundAddReferenceToInstruction(&gi, groundCreateReference(VALREF, copyString(outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(children[0].outputId)));
outputId = "obj_access_" + std::to_string(tmpIdIterator++);
variables[outputId] = match[1];
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
codeBlock.code.push_back(gi);
code.push_back(codeBlock);
}
} else {
Error::typingError("Couldn't find field " + child.children[0].outputId + " in " + outputId, child.line, child.lineContent);
break;
}
}
}
*/
// Process other stuff
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());
@@ -897,17 +973,22 @@ namespace Solstice {
return true;
}
bool Parser::isDouble(std::string in) {
if (in.empty()) return false;
bool foundDot = false;
bool foundDigit = false;
for (const char& c : in) {
if (!std::isdigit(c)) {
if (!foundDot && c == '.') {
foundDot = true;
continue;
}
if (std::isdigit(c)) {
foundDigit = true;
} else if (c == '.' && !foundDot) {
foundDot = true;
} else {
return false;
}
}
return true;
return foundDot && foundDigit;
}
bool Parser::isString(std::string in) {
if (in.size() > 1 && in[0] == '"' && in.back() == '"') {
@@ -1020,6 +1101,9 @@ namespace Solstice {
if (in == ")") {
return SolNodeType::BracketEnd;
}
if (in == ".") {
return SolNodeType::In;
}
return SolNodeType::Identifier;
}
@@ -1690,6 +1774,25 @@ namespace Solstice {
rootNode.addNode(newNode);
break;
}
case SolNodeType::In: {
SolNode inNode(SolNodeType::In);
inNode.line = tokenObj.line;
inNode.lineContent = tokenObj.lineContent;
inNode.outputId = rootNode.children.back().outputId;
rootNode.children.pop_back();
auto accessopt = consume();
if (accessopt) {
SolNode accessNode(SolNodeType::Identifier);
accessNode.outputId = accessopt.value().value;
accessNode.line = accessopt.value().line;
accessNode.lineContent = accessopt.value().lineContent;
inNode.addNode(accessNode);
} else {
Error::syntaxError("Expected identifier after '.'", tokenObj.line, tokenObj.lineContent);
}
rootNode.addNode(inNode);
break;
}
}
}
return rootNode;