Read member

This commit is contained in:
Rafał Grodziński
2025-08-12 13:01:48 +09:00
parent ad3c5a99f1
commit d159b81c46
8 changed files with 170 additions and 44 deletions

View File

@@ -15,5 +15,7 @@ main fun -> u32
us.num1 <- 5
us.num2 <- 4
num3 s32 <- us.num1 + 13
ret 0
;

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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();
};

View File

@@ -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() {

View File

@@ -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();