diff --git a/src/parser.cpp b/src/parser.cpp index 6e0b250..df6f67e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -274,6 +274,7 @@ namespace Solstice { for (size_t i = 0; i < children.size(); i++) { SolNode& child = children[i]; if (child.nodeType == SolNodeType::In) { + if (nodeType == SolNodeType::Set && i == 0) continue; if (variables.find(child.outputId) == variables.end()) { Error::syntaxError(child.outputId + " could not be found", child.line, child.lineContent); } @@ -304,45 +305,6 @@ namespace Solstice { } } - /* - // 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(); @@ -780,21 +742,51 @@ namespace Solstice { break; } case SolNodeType::Set: { - if (variables.find(children[0].outputId) != variables.end()) { - if (variables[children[0].outputId] != checkNodeReturnType(children[1])) { - Error::typingError("Cannot change type of this variable", children[0].line, children[0].lineContent); + if (children[0].nodeType == SolNodeType::In) { + if (variables.find(children[0].outputId) == variables.end()) { + Error::syntaxError(children[0].outputId + " could not be found", children[0].line, children[0].lineContent); } + std::string type = variables[children[0].outputId]; + if (type.substr(0, 7) != "object(") { + Error::typingError(children[0].outputId + " is not an object", children[0].line, children[0].lineContent); + } + std::regex pattern("([a-zA-Z0-9_:<>*&]+)\\s+\\b" + children[0].children[0].outputId + "\\b"); + std::smatch match; + + if (!std::regex_search(type, match, pattern)) { + Error::typingError("Couldn't find field " + children[0].children[0].outputId + " in " + children[0].outputId, children[0].line, children[0].lineContent); + } + std::string fieldType = match[1]; + if (fieldType != checkNodeReturnType(children[1])) { + Error::typingError("Cannot assign type " + checkNodeReturnType(children[1]) + " to field of type " + fieldType, children[0].line, children[0].lineContent); + } + + exists(children[1]); + SolGroundCodeBlock codeBlock; + GroundInstruction setInstruction = groundCreateInstruction(SETFIELD); + groundAddReferenceToInstruction(&setInstruction, groundCreateReference(DIRREF, copyString(children[0].outputId))); + groundAddReferenceToInstruction(&setInstruction, groundCreateReference(DIRREF, copyString(children[0].children[0].outputId))); + groundAddReferenceToInstruction(&setInstruction, groundCreateReference(VALREF, copyString(children[1].outputId))); + codeBlock.code.push_back(setInstruction); + if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); + code.push_back(codeBlock); + } else { + if (variables.find(children[0].outputId) != variables.end()) { + if (variables[children[0].outputId] != checkNodeReturnType(children[1])) { + Error::typingError("Cannot change type of this variable", children[0].line, children[0].lineContent); + } + } + exists(children[1]); + SolGroundCodeBlock codeBlock; + GroundInstruction setInstruction = groundCreateInstruction(SET); + groundAddReferenceToInstruction(&setInstruction, groundCreateReference(DIRREF, copyString(children[0].outputId))); + groundAddReferenceToInstruction(&setInstruction, groundCreateReference(VALREF, copyString(children[1].outputId))); + codeBlock.code.push_back(setInstruction); + if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); + code.push_back(codeBlock); + // Make sure we know what the variable type is + variables[children[0].outputId] = checkNodeReturnType(children[1]); } - exists(children[1]); - SolGroundCodeBlock codeBlock; - GroundInstruction setInstruction = groundCreateInstruction(SET); - groundAddReferenceToInstruction(&setInstruction, groundCreateReference(DIRREF, copyString(children[0].outputId))); - groundAddReferenceToInstruction(&setInstruction, groundCreateReference(VALREF, copyString(children[1].outputId))); - codeBlock.code.push_back(setInstruction); - if (isTemp(children[1].outputId)) codeBlock.toBeDropped.push_back(children[1].outputId); - code.push_back(codeBlock); - // Make sure we know what the variable type is - variables[children[0].outputId] = checkNodeReturnType(children[1]); break; } case SolNodeType::FunctionCall: { diff --git a/tests/struct.sols b/tests/struct.sols index 51eb184..c8b37f8 100644 --- a/tests/struct.sols +++ b/tests/struct.sols @@ -9,3 +9,8 @@ puts dingus puts e.x println(e.y) + +e.x = 7 +e.y = "heheheha" +puts e.x +println(e.y)