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