Generate code for custom type
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
User type
|
||||
User pack
|
||||
;
|
||||
|
||||
main fun -> u32
|
||||
//user User
|
||||
user User <- 0
|
||||
|
||||
ret 0
|
||||
;
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "Parser/Statement/StatementFunction.h"
|
||||
#include "Parser/Statement/StatementRawFunction.h"
|
||||
#include "Parser/Statement/StatementType.h"
|
||||
#include "Parser/Statement/StatementVariable.h"
|
||||
#include "Parser/Statement/StatementAssignment.h"
|
||||
#include "Parser/Statement/StatementReturn.h"
|
||||
@@ -68,6 +69,9 @@ void ModuleBuilder::buildStatement(shared_ptr<Statement> statement) {
|
||||
case StatementKind::RAW_FUNCTION:
|
||||
buildRawFunction(dynamic_pointer_cast<StatementRawFunction>(statement));
|
||||
break;
|
||||
case StatementKind::TYPE:
|
||||
buildType(dynamic_pointer_cast<StatementType>(statement));
|
||||
break;
|
||||
case StatementKind::VARIABLE:
|
||||
buildVarDeclaration(dynamic_pointer_cast<StatementVariable>(statement));
|
||||
break;
|
||||
@@ -160,6 +164,14 @@ void ModuleBuilder::buildRawFunction(shared_ptr<StatementRawFunction> statement)
|
||||
return;
|
||||
}
|
||||
|
||||
void ModuleBuilder::buildType(shared_ptr<StatementType> statement) {
|
||||
llvm::StructType *structType = llvm::StructType::create(*context, statement->getIdentifier());
|
||||
vector<llvm::Type *> elements;
|
||||
structType->setBody(elements, false);
|
||||
if (!setStruct(statement->getIdentifier(), structType))
|
||||
return;
|
||||
}
|
||||
|
||||
void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement) {
|
||||
if (statement->getValueType()->getKind() == ValueTypeKind::DATA) {
|
||||
vector<llvm::Value *> values = valuesForExpression(statement->getExpression());
|
||||
@@ -177,6 +189,11 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement)
|
||||
|
||||
builder->CreateStore(values[i], elementPtr);
|
||||
}
|
||||
} else if (statement->getValueType()->getKind() == ValueTypeKind::TYPE) {
|
||||
llvm::StructType *type = (llvm::StructType *)typeForValueType(statement->getValueType(), 0);
|
||||
llvm::AllocaInst *alloca = builder->CreateAlloca(type, nullptr, statement->getName());
|
||||
if (!setAlloca(statement->getName(), alloca))
|
||||
return;
|
||||
} else {
|
||||
llvm::Value *value = valueForExpression(statement->getExpression());
|
||||
if (value == nullptr)
|
||||
@@ -671,6 +688,29 @@ llvm::InlineAsm *ModuleBuilder::getRawFun(string name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ModuleBuilder::setStruct(string name, llvm::StructType *structType) {
|
||||
if (scopes.top().structTypeMap[name] != nullptr) {
|
||||
markError(0, 0, format("Type \"{}\" already defined in scope", name));
|
||||
return false;
|
||||
}
|
||||
|
||||
scopes.top().structTypeMap[name] = structType;
|
||||
return true;
|
||||
}
|
||||
|
||||
llvm::StructType *ModuleBuilder::getStructType(string name) {
|
||||
stack<Scope> scopes = this->scopes;
|
||||
|
||||
while (!scopes.empty()) {
|
||||
llvm::StructType *structType = scopes.top().structTypeMap[name];
|
||||
if (structType != nullptr)
|
||||
return structType;
|
||||
scopes.pop();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int count) {
|
||||
if (valueType == nullptr) {
|
||||
markError(0, 0, "Missing type");
|
||||
@@ -699,6 +739,8 @@ llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int
|
||||
count = valueType->getValueArg();
|
||||
return llvm::ArrayType::get(typeForValueType(valueType->getSubType(), count), count);
|
||||
}
|
||||
case ValueTypeKind::TYPE:
|
||||
return getStructType(valueType->getTypeName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ enum class ExpressionBinaryOperation;
|
||||
class Statement;
|
||||
class StatementFunction;
|
||||
class StatementRawFunction;
|
||||
class StatementType;
|
||||
class StatementVariable;
|
||||
class StatementAssignment;
|
||||
class StatementReturn;
|
||||
@@ -43,6 +44,7 @@ typedef struct {
|
||||
map<string, llvm::AllocaInst*> allocaMap;
|
||||
map<string, llvm::Function*> funMap;
|
||||
map<string, llvm::InlineAsm*> rawFunMap;
|
||||
map<string, llvm::StructType*> structTypeMap;
|
||||
} Scope;
|
||||
|
||||
class ModuleBuilder {
|
||||
@@ -69,6 +71,7 @@ private:
|
||||
void buildStatement(shared_ptr<Statement> statement);
|
||||
void buildFunction(shared_ptr<StatementFunction> statement);
|
||||
void buildRawFunction(shared_ptr<StatementRawFunction> statement);
|
||||
void buildType(shared_ptr<StatementType> statement);
|
||||
void buildVarDeclaration(shared_ptr<StatementVariable> statement);
|
||||
void buildAssignment(shared_ptr<StatementAssignment> statement);
|
||||
void buildBlock(shared_ptr<StatementBlock> statement);
|
||||
@@ -101,6 +104,9 @@ private:
|
||||
bool setRawFun(string name, llvm::InlineAsm *rawFun);
|
||||
llvm::InlineAsm *getRawFun(string name);
|
||||
|
||||
bool setStruct(string name, llvm::StructType *structType);
|
||||
llvm::StructType *getStructType(string name);
|
||||
|
||||
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType, int count = 0);
|
||||
|
||||
void markError(int line, int column, string message);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Parser/Statement/StatementVariable.h"
|
||||
#include "Parser/Statement/StatementFunction.h"
|
||||
#include "Parser/Statement/StatementRawFunction.h"
|
||||
#include "Parser/Statement/StatementType.h"
|
||||
#include "Parser/Statement/StatementBlock.h"
|
||||
#include "Parser/Statement/StatementAssignment.h"
|
||||
#include "Parser/Statement/StatementReturn.h"
|
||||
@@ -223,6 +224,8 @@ string Logger::toString(shared_ptr<ValueType> valueType) {
|
||||
return "R32";
|
||||
case ValueTypeKind::DATA:
|
||||
return "[]";
|
||||
case ValueTypeKind::TYPE:
|
||||
return format("TYPE({})", valueType->getTypeName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,6 +239,8 @@ string Logger::toString(shared_ptr<Statement> statement) {
|
||||
return toString(dynamic_pointer_cast<StatementFunction>(statement));
|
||||
case StatementKind::RAW_FUNCTION:
|
||||
return toString(dynamic_pointer_cast<StatementRawFunction>(statement));
|
||||
case StatementKind::TYPE:
|
||||
return toString(dynamic_pointer_cast<StatementType>(statement));
|
||||
case StatementKind::BLOCK:
|
||||
return toString(dynamic_pointer_cast<StatementBlock>(statement));
|
||||
case StatementKind::ASSIGNMENT:
|
||||
@@ -296,6 +301,14 @@ string Logger::toString(shared_ptr<StatementRawFunction> statement) {
|
||||
return text;
|
||||
}
|
||||
|
||||
string Logger::toString(shared_ptr<StatementType> statement) {
|
||||
string text;
|
||||
|
||||
text += format("TYPE(\"{}\"):\n", statement->getIdentifier());
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
string Logger::toString(shared_ptr<StatementBlock> statement) {
|
||||
string text;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ class StatementMetaExternFunction;
|
||||
class StatementVariable;
|
||||
class StatementFunction;
|
||||
class StatementRawFunction;
|
||||
class StatementType;
|
||||
class StatementBlock;
|
||||
class StatementAssignment;
|
||||
class StatementReturn;
|
||||
@@ -44,6 +45,7 @@ private:
|
||||
static string toString(shared_ptr<StatementVariable> statement);
|
||||
static string toString(shared_ptr<StatementFunction> statement);
|
||||
static string toString(shared_ptr<StatementRawFunction> statement);
|
||||
static string toString(shared_ptr<StatementType> statement);
|
||||
static string toString(shared_ptr<StatementBlock> statement);
|
||||
static string toString(shared_ptr<StatementAssignment> statement);
|
||||
static string toString(shared_ptr<StatementReturn> statement);
|
||||
|
||||
@@ -503,31 +503,38 @@ shared_ptr<Statement> Parser::matchStatementType() {
|
||||
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true),
|
||||
Parsee::tokenParsee(TokenKind::TYPE, true, false)
|
||||
},
|
||||
ParseeGroup(
|
||||
{
|
||||
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true),
|
||||
Parsee::valueTypeParsee(true)
|
||||
},
|
||||
{}
|
||||
)
|
||||
{}
|
||||
)
|
||||
);
|
||||
|
||||
switch (resultsGroup.getKind()) {
|
||||
case ParseeResultsGroupKind::SUCCESS:
|
||||
identifier = resultsGroup.getResults().at(0).getToken()->getLexme();
|
||||
for (int i=1; i<resultsGroup.getResults().size(); i+=2) {
|
||||
pair<string, shared_ptr<ValueType>> arg;
|
||||
arg.first = resultsGroup.getResults().at(i).getToken()->getLexme();
|
||||
arg.second = resultsGroup.getResults().at(i+1).getValueType();
|
||||
variables.push_back(arg);
|
||||
}
|
||||
/*for (int i=1; i<resultsGroup.getResults().size(); i+=2) {
|
||||
pair<string, shared_ptr<ValueType>> arg;
|
||||
arg.first = resultsGroup.getResults().at(i).getToken()->getLexme();
|
||||
arg.second = resultsGroup.getResults().at(i+1).getValueType();
|
||||
variables.push_back(arg);
|
||||
}*/
|
||||
break;
|
||||
case ParseeResultsGroupKind::NO_MATCH:
|
||||
case ParseeResultsGroupKind::FAILURE:
|
||||
return nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
// consume new line
|
||||
if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) {
|
||||
markError(TokenKind::NEW_LINE, {});
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// closing semicolon
|
||||
if(!tryMatchingTokenKinds({TokenKind::SEMICOLON}, false, true)) {
|
||||
markError(TokenKind::SEMICOLON, {});
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return make_shared<StatementType>(identifier, variables);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,27 +10,38 @@ shared_ptr<ValueType> ValueType::S8 = make_shared<ValueType>(ValueTypeKind::S8,
|
||||
shared_ptr<ValueType> ValueType::S32 = make_shared<ValueType>(ValueTypeKind::S32, nullptr, 0);
|
||||
shared_ptr<ValueType> ValueType::R32 = make_shared<ValueType>(ValueTypeKind::R32, nullptr, 0);
|
||||
|
||||
ValueType::ValueType() { }
|
||||
|
||||
ValueType::ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg):
|
||||
kind(kind), subType(subType), valueArg(valueArg) { }
|
||||
|
||||
shared_ptr<ValueType> ValueType::type(string typeName) {
|
||||
shared_ptr<ValueType> valueType = make_shared<ValueType>();
|
||||
valueType->kind = ValueTypeKind::TYPE;
|
||||
valueType->typeName = typeName;
|
||||
return valueType;
|
||||
}
|
||||
|
||||
shared_ptr<ValueType> ValueType::valueTypeForToken(shared_ptr<Token> token, shared_ptr<ValueType> subType, int valueArg) {
|
||||
switch (token->getKind()) {
|
||||
case TokenKind::TYPE: {
|
||||
string lexme = token->getLexme();
|
||||
if (lexme.compare("bool") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::BOOL, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0);
|
||||
else if (lexme.compare("u8") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::U8, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::U8, nullptr, 0);
|
||||
else if (lexme.compare("u32") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::U32, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::U32, nullptr, 0);
|
||||
else if (lexme.compare("s8") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::S8, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::S8, nullptr, 0);
|
||||
else if (lexme.compare("s32") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::S32, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::S32, nullptr, 0);
|
||||
else if (lexme.compare("r32") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::R32, subType, valueArg);
|
||||
return make_shared<ValueType>(ValueTypeKind::R32, nullptr, 0);
|
||||
else if (lexme.compare("data") == 0)
|
||||
return make_shared<ValueType>(ValueTypeKind::DATA, subType, valueArg);
|
||||
else if (lexme.compare("type") != 0)
|
||||
return ValueType::type(token->getLexme());
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
@@ -59,4 +70,8 @@ shared_ptr<ValueType> ValueType::getSubType() {
|
||||
|
||||
int ValueType::getValueArg() {
|
||||
return valueArg;
|
||||
}
|
||||
|
||||
string ValueType::getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
#define VALUE_TYPE_H
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
class Token;
|
||||
|
||||
@@ -15,7 +16,8 @@ enum class ValueTypeKind {
|
||||
S8,
|
||||
S32,
|
||||
R32,
|
||||
DATA
|
||||
DATA,
|
||||
TYPE
|
||||
};
|
||||
|
||||
class ValueType {
|
||||
@@ -23,6 +25,7 @@ private:
|
||||
ValueTypeKind kind;
|
||||
shared_ptr<ValueType> subType;
|
||||
int valueArg;
|
||||
string typeName;
|
||||
|
||||
public:
|
||||
static shared_ptr<ValueType> NONE;
|
||||
@@ -34,10 +37,13 @@ public:
|
||||
static shared_ptr<ValueType> R32;
|
||||
static shared_ptr<ValueType> valueTypeForToken(shared_ptr<Token> token, shared_ptr<ValueType> subType, int valueArg);
|
||||
|
||||
ValueType();
|
||||
ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg);
|
||||
static shared_ptr<ValueType> type(string typeName);
|
||||
ValueTypeKind getKind();
|
||||
shared_ptr<ValueType> getSubType();
|
||||
int getValueArg();
|
||||
string getTypeName();
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user