Use new to create an object from a struct

This commit is contained in:
2026-01-27 14:10:57 +11:00
parent e3abe07f4b
commit e285b2c59f
3 changed files with 97 additions and 4 deletions

View File

@@ -13,6 +13,46 @@
namespace Solstice {
namespace Parser {
bool operator==(const SolStruct& left, const SolStruct& right) {
return left.signature == right.signature;
}
SolStruct::SolStruct(SolNode in) {
signature = "template(";
genSignature = "object(";
bool first = true;
for (auto& node : in.children) {
if (!first) {
signature += ", ";
genSignature += ", ";
} else {
first = false;
}
if (node.nodeType == SolNodeType::FunctionDef) {
// FIXME do this later
}
if (node.nodeType == SolNodeType::Identifier) {
if (node.children[0].nodeType == SolNodeType::Value) {
signature += node.children[0].data.getTypeString();
genSignature += node.children[0].data.getTypeString();
} else if (node.children[0].nodeType == SolNodeType::Identifier) {
if (variables.find(node.children[0].outputId) != variables.end()) {
signature += variables[node.children[0].outputId];
genSignature += variables[node.children[0].outputId];
} else {
return;
}
} else {
return;
}
signature += " " + node.outputId;
genSignature += " " + node.outputId;
}
}
signature += ")";
genSignature += ")";
}
char* copyString(std::string s) {
char* str = (char*) malloc(s.size() + 1);
strcpy(str, s.c_str());
@@ -23,8 +63,13 @@ namespace Solstice {
return id.rfind("tmp_", 0) == 0;
}
// Contains the type information for all variables.
// The first string is the variable name, the second is the type.
std::map<std::string, std::string> variables;
// Contains type information for all templates.
std::map<std::string, SolStruct> templates;
std::string checkNodeReturnType(SolNode i) {
switch (i.nodeType) {
case SolNodeType::Identifier: {
@@ -115,6 +160,12 @@ namespace Solstice {
return retType;
break;
}
case SolNodeType::New: {
if (templates.find(i.children[0].outputId) == templates.end()) {
Error::typingError("Cannot find template " + i.children[0].outputId, i.line, i.lineContent);
}
return templates[i.children[0].outputId].genSignature;
}
case SolNodeType::Puts:
case SolNodeType::If:
case SolNodeType::While:
@@ -754,6 +805,11 @@ namespace Solstice {
SolGroundCodeBlock codeBlock;
GroundInstruction gi = groundCreateInstruction(STRUCT);
SolStruct newStruct(*this);
variables[outputId] = newStruct.signature;
templates[outputId] = newStruct;
// struct -name
groundAddReferenceToInstruction(&gi, groundCreateReference(TYPEREF, copyString(outputId)));
codeBlock.code.push_back(gi);
@@ -794,6 +850,19 @@ namespace Solstice {
code.push_back(codeBlock);
break;
}
case SolNodeType::New: {
SolGroundCodeBlock codeBlock;
GroundInstruction gi = groundCreateInstruction(INIT);
if (templates.find(children[0].outputId) == templates.end()) {
Error::typingError("Unknown template " + children[0].outputId, line, lineContent);
}
outputId = "tmp_" + std::to_string(tmpIdIterator);
groundAddReferenceToInstruction(&gi, groundCreateReference(DIRREF, copyString(outputId)));
groundAddReferenceToInstruction(&gi, groundCreateReference(TYPEREF, copyString(children[0].outputId)));
codeBlock.code.push_back(gi);
code.push_back(codeBlock);
break;
}
default: {}
}
return code;
@@ -1605,11 +1674,20 @@ namespace Solstice {
}
case SolNodeType::New: {
SolNode putsNode(SolNodeType::New);
putsNode.line = tokenObj.line;
putsNode.lineContent = tokenObj.lineContent;
SolNode newNode(SolNodeType::New);
newNode.line = tokenObj.line;
newNode.lineContent = tokenObj.lineContent;
auto typeopt = consume();
rootNode.addNode(putsNode);
if (typeopt) {
SolNode typeNode(SolNodeType::Identifier);
typeNode.outputId = typeopt.value().value;
typeNode.line = typeopt.value().line;
typeNode.lineContent = typeopt.value().lineContent;
newNode.addNode(typeNode);
} else {
Error::syntaxError("Expected type name after 'new'", tokenObj.line, tokenObj.lineContent);
}
rootNode.addNode(newNode);
break;
}
}

View File

@@ -124,6 +124,16 @@ namespace Solstice {
const std::vector<SolGroundCodeBlock> generateCode();
};
class SolStruct {
std::map<std::string, std::string> fields;
public:
std::string signature; // template(...)
std::string genSignature; // object(...)
SolStruct() = default;
friend bool operator==(const SolStruct& left, const SolStruct& right);
SolStruct(SolNode in);
};
class Parser {
std::vector<Token> tokensToParse;
size_t current;

View File

@@ -1,3 +1,8 @@
struct dingus {
x = 5
y = "dingus"
}
e = new dingus
puts e
puts dingus