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 Solstice {
|
||||||
namespace Parser {
|
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* copyString(std::string s) {
|
||||||
char* str = (char*) malloc(s.size() + 1);
|
char* str = (char*) malloc(s.size() + 1);
|
||||||
strcpy(str, s.c_str());
|
strcpy(str, s.c_str());
|
||||||
@@ -23,8 +63,13 @@ namespace Solstice {
|
|||||||
return id.rfind("tmp_", 0) == 0;
|
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;
|
std::map<std::string, std::string> variables;
|
||||||
|
|
||||||
|
// Contains type information for all templates.
|
||||||
|
std::map<std::string, SolStruct> templates;
|
||||||
|
|
||||||
std::string checkNodeReturnType(SolNode i) {
|
std::string checkNodeReturnType(SolNode i) {
|
||||||
switch (i.nodeType) {
|
switch (i.nodeType) {
|
||||||
case SolNodeType::Identifier: {
|
case SolNodeType::Identifier: {
|
||||||
@@ -115,6 +160,12 @@ namespace Solstice {
|
|||||||
return retType;
|
return retType;
|
||||||
break;
|
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::Puts:
|
||||||
case SolNodeType::If:
|
case SolNodeType::If:
|
||||||
case SolNodeType::While:
|
case SolNodeType::While:
|
||||||
@@ -754,6 +805,11 @@ namespace Solstice {
|
|||||||
SolGroundCodeBlock codeBlock;
|
SolGroundCodeBlock codeBlock;
|
||||||
GroundInstruction gi = groundCreateInstruction(STRUCT);
|
GroundInstruction gi = groundCreateInstruction(STRUCT);
|
||||||
|
|
||||||
|
SolStruct newStruct(*this);
|
||||||
|
|
||||||
|
variables[outputId] = newStruct.signature;
|
||||||
|
templates[outputId] = newStruct;
|
||||||
|
|
||||||
// struct -name
|
// struct -name
|
||||||
groundAddReferenceToInstruction(&gi, groundCreateReference(TYPEREF, copyString(outputId)));
|
groundAddReferenceToInstruction(&gi, groundCreateReference(TYPEREF, copyString(outputId)));
|
||||||
codeBlock.code.push_back(gi);
|
codeBlock.code.push_back(gi);
|
||||||
@@ -794,6 +850,19 @@ namespace Solstice {
|
|||||||
code.push_back(codeBlock);
|
code.push_back(codeBlock);
|
||||||
break;
|
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: {}
|
default: {}
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
@@ -1605,11 +1674,20 @@ namespace Solstice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SolNodeType::New: {
|
case SolNodeType::New: {
|
||||||
SolNode putsNode(SolNodeType::New);
|
SolNode newNode(SolNodeType::New);
|
||||||
putsNode.line = tokenObj.line;
|
newNode.line = tokenObj.line;
|
||||||
putsNode.lineContent = tokenObj.lineContent;
|
newNode.lineContent = tokenObj.lineContent;
|
||||||
auto typeopt = consume();
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/parser.h
10
src/parser.h
@@ -124,6 +124,16 @@ namespace Solstice {
|
|||||||
const std::vector<SolGroundCodeBlock> generateCode();
|
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 {
|
class Parser {
|
||||||
std::vector<Token> tokensToParse;
|
std::vector<Token> tokensToParse;
|
||||||
size_t current;
|
size_t current;
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
struct dingus {
|
struct dingus {
|
||||||
x = 5
|
x = 5
|
||||||
|
y = "dingus"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e = new dingus
|
||||||
|
puts e
|
||||||
|
puts dingus
|
||||||
|
|||||||
Reference in New Issue
Block a user