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

@@ -100,7 +100,6 @@ namespace Solstice {
}
// tokens which are not followed by anything
case '\n':
case ':':
{
if (!buf.empty()) {
addToken(buf);
@@ -114,6 +113,8 @@ namespace Solstice {
case ')':
case '}':
case ',':
case ':':
case '.':
{
if (!buf.empty()) {
addToken(buf);

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;

View File

@@ -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
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
};
enum class SolDataType {

View File

@@ -6,3 +6,6 @@ struct dingus {
e = new dingus
puts e
puts dingus
puts e.x
puts e.y