Build struct member assignment
This commit is contained in:
@@ -12,6 +12,7 @@ User blob
|
|||||||
|
|
||||||
main fun -> u32
|
main fun -> u32
|
||||||
us User
|
us User
|
||||||
|
us<- 5
|
||||||
|
|
||||||
ret 0
|
ret 0
|
||||||
;
|
;
|
||||||
@@ -168,15 +168,17 @@ void ModuleBuilder::buildBlob(shared_ptr<StatementBlob> statement) {
|
|||||||
llvm::StructType *structType = llvm::StructType::create(*context, statement->getIdentifier());
|
llvm::StructType *structType = llvm::StructType::create(*context, statement->getIdentifier());
|
||||||
|
|
||||||
// Generate types for body
|
// Generate types for body
|
||||||
|
vector<string> memberNames;
|
||||||
vector<llvm::Type *> types;
|
vector<llvm::Type *> types;
|
||||||
for (pair<string, shared_ptr<ValueType>> &variable: statement->getVariables()) {
|
for (pair<string, shared_ptr<ValueType>> &variable: statement->getVariables()) {
|
||||||
|
memberNames.push_back(variable.first);
|
||||||
llvm::Type *type = typeForValueType(variable.second);
|
llvm::Type *type = typeForValueType(variable.second);
|
||||||
if (type == nullptr)
|
if (type == nullptr)
|
||||||
return;
|
return;
|
||||||
types.push_back(type);
|
types.push_back(type);
|
||||||
}
|
}
|
||||||
structType->setBody(types, false);
|
structType->setBody(types, false);
|
||||||
if (!setStruct(statement->getIdentifier(), structType))
|
if (!registerStruct(statement->getIdentifier(), structType, memberNames))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,18 +228,37 @@ void ModuleBuilder::buildAssignment(shared_ptr<StatementAssignment> statement) {
|
|||||||
|
|
||||||
llvm::Value *value = valueForExpression(statement->getExpression());
|
llvm::Value *value = valueForExpression(statement->getExpression());
|
||||||
|
|
||||||
if (statement->getIndexExpression()) {
|
switch (statement->getAssignmentKind()) {
|
||||||
llvm::Value *indexValue = valueForExpression(statement->getIndexExpression());
|
case StatementAssignmentKind::VARIABLE: {
|
||||||
llvm::Value *index[] = {
|
builder->CreateStore(value, alloca);
|
||||||
builder->getInt32(0),
|
break;
|
||||||
indexValue
|
}
|
||||||
};
|
case StatementAssignmentKind::DATA: {
|
||||||
llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType();
|
llvm::Value *indexValue = valueForExpression(statement->getIndexExpression());
|
||||||
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", statement->getName()));
|
llvm::Value *index[] = {
|
||||||
|
builder->getInt32(0),
|
||||||
|
indexValue
|
||||||
|
};
|
||||||
|
llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType();
|
||||||
|
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", statement->getName()));
|
||||||
|
|
||||||
builder->CreateStore(value, elementPtr);
|
builder->CreateStore(value, elementPtr);
|
||||||
} else {
|
break;
|
||||||
builder->CreateStore(value, alloca);
|
}
|
||||||
|
case StatementAssignmentKind::BLOB: {
|
||||||
|
llvm::StructType *structType = (llvm::StructType *)alloca->getAllocatedType();
|
||||||
|
string structName = string(structType->getName());
|
||||||
|
optional<int> memberIndex = getMemberIndex(structName, statement->getMemberName());
|
||||||
|
if (!memberIndex)
|
||||||
|
return;
|
||||||
|
llvm::Value *index[] = {
|
||||||
|
builder->getInt32(0),
|
||||||
|
builder->getInt32(*memberIndex)
|
||||||
|
};
|
||||||
|
llvm::Value *elementPtr = builder->CreateGEP(structType, alloca, index);
|
||||||
|
builder->CreateStore(value, elementPtr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,21 +722,23 @@ llvm::InlineAsm *ModuleBuilder::getRawFun(string name) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModuleBuilder::setStruct(string name, llvm::StructType *structType) {
|
bool ModuleBuilder::registerStruct(string structName, llvm::StructType *structType, vector<string> memberNames) {
|
||||||
if (scopes.top().structTypeMap[name] != nullptr) {
|
if (scopes.top().structTypeMap[structName] != nullptr) {
|
||||||
markError(0, 0, format("Type \"{}\" already defined in scope", name));
|
markError(0, 0, format("Blob \"{}\" already defined in scope",structName));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
scopes.top().structTypeMap[name] = structType;
|
scopes.top().structTypeMap[structName] = structType;
|
||||||
|
scopes.top().structMembersMap[structName] = memberNames;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::StructType *ModuleBuilder::getStructType(string name) {
|
llvm::StructType *ModuleBuilder::getStructType(string structName) {
|
||||||
stack<Scope> scopes = this->scopes;
|
stack<Scope> scopes = this->scopes;
|
||||||
|
|
||||||
while (!scopes.empty()) {
|
while (!scopes.empty()) {
|
||||||
llvm::StructType *structType = scopes.top().structTypeMap[name];
|
llvm::StructType *structType = scopes.top().structTypeMap[structName];
|
||||||
if (structType != nullptr)
|
if (structType != nullptr)
|
||||||
return structType;
|
return structType;
|
||||||
scopes.pop();
|
scopes.pop();
|
||||||
@@ -724,6 +747,23 @@ llvm::StructType *ModuleBuilder::getStructType(string name) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optional<int> ModuleBuilder::getMemberIndex(string structName, string memberName) {
|
||||||
|
stack<Scope> scopes = this->scopes;
|
||||||
|
|
||||||
|
while (!scopes.empty()) {
|
||||||
|
if (scopes.top().structMembersMap.contains(structName)) {
|
||||||
|
vector<string> memberNames = scopes.top().structMembersMap[structName];
|
||||||
|
for (int i=0; i<memberNames.size(); i++) {
|
||||||
|
if (memberNames[i].compare(memberName) == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scopes.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int count) {
|
llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int count) {
|
||||||
if (valueType == nullptr) {
|
if (valueType == nullptr) {
|
||||||
markError(0, 0, "Missing type");
|
markError(0, 0, "Missing type");
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ typedef struct {
|
|||||||
map<string, llvm::Function*> funMap;
|
map<string, llvm::Function*> funMap;
|
||||||
map<string, llvm::InlineAsm*> rawFunMap;
|
map<string, llvm::InlineAsm*> rawFunMap;
|
||||||
map<string, llvm::StructType*> structTypeMap;
|
map<string, llvm::StructType*> structTypeMap;
|
||||||
|
map<string, vector<string>> structMembersMap;
|
||||||
} Scope;
|
} Scope;
|
||||||
|
|
||||||
class ModuleBuilder {
|
class ModuleBuilder {
|
||||||
@@ -104,8 +105,9 @@ private:
|
|||||||
bool setRawFun(string name, llvm::InlineAsm *rawFun);
|
bool setRawFun(string name, llvm::InlineAsm *rawFun);
|
||||||
llvm::InlineAsm *getRawFun(string name);
|
llvm::InlineAsm *getRawFun(string name);
|
||||||
|
|
||||||
bool setStruct(string name, llvm::StructType *structType);
|
bool registerStruct(string structName, llvm::StructType *structType, vector<string> memberNames);
|
||||||
llvm::StructType *getStructType(string name);
|
llvm::StructType *getStructType(string structName);
|
||||||
|
optional<int> getMemberIndex(string structName, string memberName);
|
||||||
|
|
||||||
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType, int count = 0);
|
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType, int count = 0);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
StatementAssignment::StatementAssignment(string name, shared_ptr<Expression> indexExpression, shared_ptr<Expression> expression):
|
StatementAssignment::StatementAssignment(string name, shared_ptr<Expression> indexExpression, shared_ptr<Expression> expression):
|
||||||
Statement(StatementKind::ASSIGNMENT), name(name), indexExpression(indexExpression), expression(expression) { }
|
Statement(StatementKind::ASSIGNMENT), name(name), indexExpression(indexExpression), expression(expression) { }
|
||||||
|
|
||||||
|
StatementAssignmentKind StatementAssignment::getAssignmentKind() {
|
||||||
|
return assignmentKind;
|
||||||
|
}
|
||||||
|
|
||||||
string StatementAssignment::getName() {
|
string StatementAssignment::getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@@ -14,3 +18,7 @@ shared_ptr<Expression> StatementAssignment::getIndexExpression() {
|
|||||||
shared_ptr<Expression> StatementAssignment::getExpression() {
|
shared_ptr<Expression> StatementAssignment::getExpression() {
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string StatementAssignment::getMemberName() {
|
||||||
|
return memberName;
|
||||||
|
}
|
||||||
@@ -2,15 +2,25 @@
|
|||||||
|
|
||||||
class Expression;
|
class Expression;
|
||||||
|
|
||||||
|
enum class StatementAssignmentKind {
|
||||||
|
VARIABLE,
|
||||||
|
DATA,
|
||||||
|
BLOB
|
||||||
|
};
|
||||||
|
|
||||||
class StatementAssignment: public Statement {
|
class StatementAssignment: public Statement {
|
||||||
private:
|
private:
|
||||||
|
StatementAssignmentKind assignmentKind;
|
||||||
string name;
|
string name;
|
||||||
shared_ptr<Expression> indexExpression;
|
shared_ptr<Expression> indexExpression;
|
||||||
shared_ptr<Expression> expression;
|
shared_ptr<Expression> expression;
|
||||||
|
string memberName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StatementAssignment(string name, shared_ptr<Expression> indexExpressio, shared_ptr<Expression> expression);
|
StatementAssignment(string name, shared_ptr<Expression> indexExpressio, shared_ptr<Expression> expression);
|
||||||
|
StatementAssignmentKind getAssignmentKind();
|
||||||
string getName();
|
string getName();
|
||||||
shared_ptr<Expression> getIndexExpression();
|
shared_ptr<Expression> getIndexExpression();
|
||||||
shared_ptr<Expression> getExpression();
|
shared_ptr<Expression> getExpression();
|
||||||
|
string getMemberName();
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user