forked from solstice/solstice
Use new to create an object from a struct
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
10
src/parser.h
10
src/parser.h
@@ -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;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
struct dingus {
|
||||
x = 5
|
||||
y = "dingus"
|
||||
}
|
||||
|
||||
e = new dingus
|
||||
puts e
|
||||
puts dingus
|
||||
|
||||
Reference in New Issue
Block a user