Read member
This commit is contained in:
@@ -15,5 +15,7 @@ main fun -> u32
|
|||||||
us.num1 <- 5
|
us.num1 <- 5
|
||||||
us.num2 <- 4
|
us.num2 <- 4
|
||||||
|
|
||||||
|
num3 s32 <- us.num1 + 13
|
||||||
|
|
||||||
ret 0
|
ret 0
|
||||||
;
|
;
|
||||||
@@ -365,7 +365,7 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression
|
|||||||
case ExpressionKind::IF_ELSE:
|
case ExpressionKind::IF_ELSE:
|
||||||
return valueForIfElse(dynamic_pointer_cast<ExpressionIfElse>(expression));
|
return valueForIfElse(dynamic_pointer_cast<ExpressionIfElse>(expression));
|
||||||
case ExpressionKind::VAR:
|
case ExpressionKind::VAR:
|
||||||
return valueForVar(dynamic_pointer_cast<ExpressionVariable>(expression));
|
return valueForVariable(dynamic_pointer_cast<ExpressionVariable>(expression));
|
||||||
case ExpressionKind::CALL:
|
case ExpressionKind::CALL:
|
||||||
return valueForCall(dynamic_pointer_cast<ExpressionCall>(expression));
|
return valueForCall(dynamic_pointer_cast<ExpressionCall>(expression));
|
||||||
default:
|
default:
|
||||||
@@ -435,6 +435,8 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> expressi
|
|||||||
return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue);
|
return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue);
|
||||||
} else if (type == typeR32) {
|
} else if (type == typeR32) {
|
||||||
return valueForBinaryReal(expression->getOperation(), leftValue, rightValue);
|
return valueForBinaryReal(expression->getOperation(), leftValue, rightValue);
|
||||||
|
} else { // FIXME (we have missing value types)
|
||||||
|
return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
markError(0, 0, "Unexpected operation");
|
markError(0, 0, "Unexpected operation");
|
||||||
@@ -606,23 +608,39 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr<ExpressionIfElse> expressi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value *ModuleBuilder::valueForVar(shared_ptr<ExpressionVariable> expression) {
|
llvm::Value *ModuleBuilder::valueForVariable(shared_ptr<ExpressionVariable> expression) {
|
||||||
llvm::AllocaInst *alloca = getAlloca(expression->getName());
|
llvm::AllocaInst *alloca = getAlloca(expression->getIdentifier());
|
||||||
if (alloca == nullptr)
|
if (alloca == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (expression->getIndexExpression()) {
|
switch (expression->getVariableKind()) {
|
||||||
|
case ExpressionVariableKind::SIMPLE: {
|
||||||
|
return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getIdentifier());
|
||||||
|
}
|
||||||
|
case ExpressionVariableKind::DATA: {
|
||||||
llvm::Value *indexValue = valueForExpression(expression->getIndexExpression());
|
llvm::Value *indexValue = valueForExpression(expression->getIndexExpression());
|
||||||
llvm::Value *index[] = {
|
llvm::Value *index[] = {
|
||||||
builder->getInt32(0),
|
builder->getInt32(0),
|
||||||
indexValue
|
indexValue
|
||||||
};
|
};
|
||||||
llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType();
|
llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType();
|
||||||
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", expression->getName()));
|
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", expression->getIdentifier()));
|
||||||
|
|
||||||
return builder->CreateLoad(type->getArrayElementType(), elementPtr);
|
return builder->CreateLoad(type->getArrayElementType(), elementPtr);
|
||||||
} else {
|
}
|
||||||
return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName());
|
case ExpressionVariableKind::BLOB: {
|
||||||
|
llvm::StructType *structType = (llvm::StructType *)alloca->getAllocatedType();
|
||||||
|
string structName = string(structType->getName());
|
||||||
|
optional<int> memberIndex = getMemberIndex(structName, expression->getMemberName());
|
||||||
|
if (!memberIndex)
|
||||||
|
return nullptr;
|
||||||
|
llvm::Value *index[] = {
|
||||||
|
builder->getInt32(0),
|
||||||
|
builder->getInt32(*memberIndex)
|
||||||
|
};
|
||||||
|
llvm::Value *elementPtr = builder->CreateGEP(structType, alloca, index, format("{}.{}", expression->getIdentifier(), expression->getMemberName()));
|
||||||
|
return builder->CreateLoad(structType->getElementType(*memberIndex), elementPtr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ private:
|
|||||||
llvm::Value *valueForBinaryReal(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue);
|
llvm::Value *valueForBinaryReal(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue);
|
||||||
llvm::Value *valueForUnary(shared_ptr<ExpressionUnary> expression);
|
llvm::Value *valueForUnary(shared_ptr<ExpressionUnary> expression);
|
||||||
llvm::Value *valueForIfElse(shared_ptr<ExpressionIfElse> expression);
|
llvm::Value *valueForIfElse(shared_ptr<ExpressionIfElse> expression);
|
||||||
llvm::Value *valueForVar(shared_ptr<ExpressionVariable> expression);
|
llvm::Value *valueForVariable(shared_ptr<ExpressionVariable> expression);
|
||||||
llvm::Value *valueForCall(shared_ptr<ExpressionCall> expression);
|
llvm::Value *valueForCall(shared_ptr<ExpressionCall> expression);
|
||||||
|
|
||||||
bool setAlloca(string name, llvm::AllocaInst *alloca);
|
bool setAlloca(string name, llvm::AllocaInst *alloca);
|
||||||
|
|||||||
@@ -454,11 +454,14 @@ string Logger::toString(shared_ptr<ExpressionIfElse> expression) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string Logger::toString(shared_ptr<ExpressionVariable> expression) {
|
string Logger::toString(shared_ptr<ExpressionVariable> expression) {
|
||||||
string text = format("VAR({}", expression->getName());
|
switch (expression->getVariableKind()) {
|
||||||
if (expression->getIndexExpression() != nullptr)
|
case ExpressionVariableKind::SIMPLE:
|
||||||
text += format("|{}", toString(expression->getIndexExpression()));
|
return format("VAR({})", expression->getIdentifier());
|
||||||
text += ")";
|
case ExpressionVariableKind::DATA:
|
||||||
return text;
|
return format("VAR({}|{})", expression->getIdentifier(), toString(expression->getIndexExpression()));
|
||||||
|
case ExpressionVariableKind::BLOB:
|
||||||
|
return format("VAR({}.{})", expression->getIdentifier(), expression->getMemberName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string Logger::toString(shared_ptr<ExpressionGrouping> expression) {
|
string Logger::toString(shared_ptr<ExpressionGrouping> expression) {
|
||||||
|
|||||||
@@ -1,12 +1,43 @@
|
|||||||
#include "ExpressionVariable.h"
|
#include "ExpressionVariable.h"
|
||||||
|
|
||||||
ExpressionVariable::ExpressionVariable(string name, shared_ptr<Expression> indexExpression):
|
shared_ptr<ExpressionVariable> ExpressionVariable::simpleVariable(string identifier) {
|
||||||
Expression(ExpressionKind::VAR, nullptr), name(name), indexExpression(indexExpression) { }
|
shared_ptr<ExpressionVariable> expression = make_shared<ExpressionVariable>();
|
||||||
|
expression->variableKind = ExpressionVariableKind::SIMPLE;
|
||||||
|
expression->identifier = identifier;
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
string ExpressionVariable::getName() {
|
shared_ptr<ExpressionVariable> ExpressionVariable::dataVariable(string identifier, shared_ptr<Expression> indexExpression) {
|
||||||
return name;
|
shared_ptr<ExpressionVariable> expression = make_shared<ExpressionVariable>();
|
||||||
|
expression->variableKind = ExpressionVariableKind::DATA;
|
||||||
|
expression->identifier = identifier;
|
||||||
|
expression->indexExpression = indexExpression;
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ExpressionVariable> ExpressionVariable::blobVariable(string identifier, string memberName) {
|
||||||
|
shared_ptr<ExpressionVariable> expression = make_shared<ExpressionVariable>();
|
||||||
|
expression->variableKind = ExpressionVariableKind::BLOB;
|
||||||
|
expression->identifier = identifier;
|
||||||
|
expression->memberName = memberName;
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpressionVariable::ExpressionVariable():
|
||||||
|
Expression(ExpressionKind::VAR, nullptr) { }
|
||||||
|
|
||||||
|
ExpressionVariableKind ExpressionVariable::getVariableKind() {
|
||||||
|
return variableKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
string ExpressionVariable::getIdentifier() {
|
||||||
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Expression> ExpressionVariable::getIndexExpression() {
|
shared_ptr<Expression> ExpressionVariable::getIndexExpression() {
|
||||||
return indexExpression;
|
return indexExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string ExpressionVariable::getMemberName() {
|
||||||
|
return memberName;
|
||||||
|
}
|
||||||
@@ -1,12 +1,26 @@
|
|||||||
#include "Parser/Expression/Expression.h"
|
#include "Parser/Expression/Expression.h"
|
||||||
|
|
||||||
|
enum class ExpressionVariableKind {
|
||||||
|
SIMPLE,
|
||||||
|
DATA,
|
||||||
|
BLOB
|
||||||
|
};
|
||||||
|
|
||||||
class ExpressionVariable: public Expression {
|
class ExpressionVariable: public Expression {
|
||||||
private:
|
private:
|
||||||
string name;
|
ExpressionVariableKind variableKind;
|
||||||
|
string identifier;
|
||||||
shared_ptr<Expression> indexExpression;
|
shared_ptr<Expression> indexExpression;
|
||||||
|
string memberName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExpressionVariable(string name, shared_ptr<Expression> indexExpression);
|
static shared_ptr<ExpressionVariable> simpleVariable(string identifer);
|
||||||
string getName();
|
static shared_ptr<ExpressionVariable> dataVariable(string identifier, shared_ptr<Expression> indexExpression);
|
||||||
|
static shared_ptr<ExpressionVariable> blobVariable(string identifier, string memberName);
|
||||||
|
|
||||||
|
ExpressionVariable();
|
||||||
|
ExpressionVariableKind getVariableKind();
|
||||||
|
string getIdentifier();
|
||||||
shared_ptr<Expression> getIndexExpression();
|
shared_ptr<Expression> getIndexExpression();
|
||||||
|
string getMemberName();
|
||||||
};
|
};
|
||||||
@@ -478,7 +478,7 @@ shared_ptr<Statement> Parser::matchStatementBlock(vector<TokenKind> terminalToke
|
|||||||
shared_ptr<Statement> Parser::matchStatementAssignment() {
|
shared_ptr<Statement> Parser::matchStatementAssignment() {
|
||||||
ParseeResultsGroup resultsGroup;
|
ParseeResultsGroup resultsGroup;
|
||||||
|
|
||||||
// variable
|
// simple
|
||||||
resultsGroup = parseeResultsGroupForParseeGroup(
|
resultsGroup = parseeResultsGroupForParseeGroup(
|
||||||
ParseeGroup(
|
ParseeGroup(
|
||||||
{
|
{
|
||||||
@@ -523,7 +523,7 @@ shared_ptr<Statement> Parser::matchStatementAssignment() {
|
|||||||
switch (resultsGroup.getKind()) {
|
switch (resultsGroup.getKind()) {
|
||||||
case ParseeResultsGroupKind::SUCCESS: {
|
case ParseeResultsGroupKind::SUCCESS: {
|
||||||
string identifier = resultsGroup.getResults().at(0).getToken()->getLexme();
|
string identifier = resultsGroup.getResults().at(0).getToken()->getLexme();
|
||||||
shared_ptr<Expression> indexExpression = indexExpression = resultsGroup.getResults().at(1).getExpression();
|
shared_ptr<Expression> indexExpression = resultsGroup.getResults().at(1).getExpression();
|
||||||
shared_ptr<Expression> valueExpression = resultsGroup.getResults().at(2).getExpression();
|
shared_ptr<Expression> valueExpression = resultsGroup.getResults().at(2).getExpression();
|
||||||
return StatementAssignment::dataAssignment(identifier, indexExpression, valueExpression);
|
return StatementAssignment::dataAssignment(identifier, indexExpression, valueExpression);
|
||||||
}
|
}
|
||||||
@@ -813,23 +813,81 @@ shared_ptr<Expression> Parser::matchExpressionArrayLiteral() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Expression> Parser::matchExpressionVariable() {
|
shared_ptr<Expression> Parser::matchExpressionVariable() {
|
||||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, false))
|
ParseeResultsGroup resultsGroup;
|
||||||
return nullptr;
|
|
||||||
shared_ptr<Token> idToken = tokens.at(currentIndex++);
|
|
||||||
shared_ptr<Expression> indexExpression;
|
|
||||||
|
|
||||||
if (tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) {
|
// data
|
||||||
indexExpression = nextExpression();
|
resultsGroup = parseeResultsGroupForParseeGroup(
|
||||||
if (indexExpression == nullptr)
|
ParseeGroup(
|
||||||
return nullptr;
|
{
|
||||||
|
// identifier
|
||||||
|
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false),
|
||||||
|
// index expression
|
||||||
|
Parsee::tokenParsee(TokenKind::LEFT_SQUARE_BRACKET, true, false, false),
|
||||||
|
Parsee::expressionParsee(true, true, true),
|
||||||
|
Parsee::tokenParsee(TokenKind::RIGHT_SQUARE_BRACKET, true, false, true)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) {
|
switch (resultsGroup.getKind()) {
|
||||||
markError(TokenKind::RIGHT_SQUARE_BRACKET, {});
|
case ParseeResultsGroupKind::SUCCESS: {
|
||||||
|
string identifier = resultsGroup.getResults().at(0).getToken()->getLexme();
|
||||||
|
shared_ptr<Expression> indexExpression = indexExpression = resultsGroup.getResults().at(1).getExpression();
|
||||||
|
return ExpressionVariable::dataVariable(identifier, indexExpression);
|
||||||
|
}
|
||||||
|
case ParseeResultsGroupKind::NO_MATCH:
|
||||||
|
break;
|
||||||
|
case ParseeResultsGroupKind::FAILURE:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// blob
|
||||||
|
resultsGroup = parseeResultsGroupForParseeGroup(
|
||||||
|
ParseeGroup(
|
||||||
|
{
|
||||||
|
// identifier
|
||||||
|
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false),
|
||||||
|
// member name
|
||||||
|
Parsee::tokenParsee(TokenKind::DOT, true, false, false),
|
||||||
|
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, true)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (resultsGroup.getKind()) {
|
||||||
|
case ParseeResultsGroupKind::SUCCESS: {
|
||||||
|
string identifier = resultsGroup.getResults().at(0).getToken()->getLexme();
|
||||||
|
string memberName = resultsGroup.getResults().at(1).getToken()->getLexme();
|
||||||
|
return ExpressionVariable::blobVariable(identifier, memberName);
|
||||||
|
}
|
||||||
|
case ParseeResultsGroupKind::NO_MATCH:
|
||||||
|
break;
|
||||||
|
case ParseeResultsGroupKind::FAILURE:
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return make_shared<ExpressionVariable>(idToken->getLexme(), indexExpression);
|
// simple
|
||||||
|
resultsGroup = parseeResultsGroupForParseeGroup(
|
||||||
|
ParseeGroup(
|
||||||
|
{
|
||||||
|
// identifier
|
||||||
|
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (resultsGroup.getKind()) {
|
||||||
|
case ParseeResultsGroupKind::SUCCESS: {
|
||||||
|
string identifier = resultsGroup.getResults().at(0).getToken()->getLexme();
|
||||||
|
return ExpressionVariable::simpleVariable(identifier);
|
||||||
|
}
|
||||||
|
case ParseeResultsGroupKind::NO_MATCH:
|
||||||
|
break;
|
||||||
|
case ParseeResultsGroupKind::FAILURE:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Expression> Parser::matchExpressionCall() {
|
shared_ptr<Expression> Parser::matchExpressionCall() {
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ private:
|
|||||||
string memberName;
|
string memberName;
|
||||||
shared_ptr<Expression> valueExpression;
|
shared_ptr<Expression> valueExpression;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StatementAssignment();
|
StatementAssignment();
|
||||||
static shared_ptr<StatementAssignment> variableAssignment(string identifier, shared_ptr<Expression> expression);
|
static shared_ptr<StatementAssignment> variableAssignment(string identifier, shared_ptr<Expression> valueExpression);
|
||||||
static shared_ptr<StatementAssignment> dataAssignment(string identifier, shared_ptr<Expression> indexExpression, shared_ptr<Expression> valueExpression);
|
static shared_ptr<StatementAssignment> dataAssignment(string identifier, shared_ptr<Expression> indexExpression, shared_ptr<Expression> valueExpression);
|
||||||
static shared_ptr<StatementAssignment> blobAssignment(string identifier, string memberName, shared_ptr<Expression> valueExpression);
|
static shared_ptr<StatementAssignment> blobAssignment(string identifier, string memberName, shared_ptr<Expression> valueExpression);
|
||||||
StatementAssignmentKind getAssignmentKind();
|
StatementAssignmentKind getAssignmentKind();
|
||||||
|
|||||||
Reference in New Issue
Block a user