Assign struct member

This commit is contained in:
Rafał Grodziński
2025-08-11 23:08:36 +09:00
parent b8d6ba9033
commit ad3c5a99f1
8 changed files with 141 additions and 49 deletions

View File

@@ -12,7 +12,8 @@ User blob
main fun -> u32
us User
us<- 5
us.num1 <- 5
us.num2 <- 4
ret 0
;

View File

@@ -222,11 +222,11 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement)
}
void ModuleBuilder::buildAssignment(shared_ptr<StatementAssignment> statement) {
llvm::AllocaInst *alloca = getAlloca(statement->getName());
llvm::AllocaInst *alloca = getAlloca(statement->getIdentifier());
if (alloca == nullptr)
return;
llvm::Value *value = valueForExpression(statement->getExpression());
llvm::Value *value = valueForExpression(statement->getValueExpression());
switch (statement->getAssignmentKind()) {
case StatementAssignmentKind::VARIABLE: {
@@ -240,7 +240,7 @@ void ModuleBuilder::buildAssignment(shared_ptr<StatementAssignment> statement) {
indexValue
};
llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType();
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", statement->getName()));
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", statement->getIdentifier()));
builder->CreateStore(value, elementPtr);
break;
@@ -255,7 +255,7 @@ void ModuleBuilder::buildAssignment(shared_ptr<StatementAssignment> statement) {
builder->getInt32(0),
builder->getInt32(*memberIndex)
};
llvm::Value *elementPtr = builder->CreateGEP(structType, alloca, index);
llvm::Value *elementPtr = builder->CreateGEP(structType, alloca, index, format("{}.{}", statement->getIdentifier(), statement->getMemberName()));
builder->CreateStore(value, elementPtr);
break;
}

View File

@@ -161,6 +161,10 @@ shared_ptr<Token> Lexer::nextToken() {
if (token != nullptr)
return token;
token = match(TokenKind::DOT, ".", false);
if (token != nullptr)
return token;
// arithmetic
token = match(TokenKind::PLUS, "+", false);
if (token != nullptr)
@@ -573,6 +577,7 @@ bool Lexer::isSeparator(int index) {
case ' ':
case '\t':
case '\n':
case '.':
return true;
default:
return false;

View File

@@ -28,6 +28,7 @@ enum class TokenKind {
SEMICOLON,
LEFT_ARROW,
RIGHT_ARROW,
DOT,
FUNCTION,
RAW_FUNCTION,

View File

@@ -74,6 +74,8 @@ string Logger::toString(shared_ptr<Token> token) {
return "";
case TokenKind::RIGHT_ARROW:
return "";
case TokenKind::DOT:
return ".";
case TokenKind::BOOL:
return "BOOL(" + token->getLexme() + ")";
@@ -165,6 +167,8 @@ string Logger::toString(TokenKind tokenKind) {
return "";
case TokenKind::RIGHT_ARROW:
return "";
case TokenKind::DOT:
return ".";
case TokenKind::BOOL:
return "LITERAL(BOOLEAN)";
@@ -329,10 +333,14 @@ string Logger::toString(shared_ptr<StatementBlock> statement) {
}
string Logger::toString(shared_ptr<StatementAssignment> statement) {
if (statement->getIndexExpression() != nullptr)
return format("{}[{}] <- {}", statement->getName(), toString(statement->getIndexExpression()), toString(statement->getExpression()));
else
return format("{} <- {}", statement->getName(), toString(statement->getExpression()));
switch (statement->getAssignmentKind()) {
case StatementAssignmentKind::VARIABLE:
return format("{} <- {}", statement->getIdentifier(), toString(statement->getValueExpression()));
case StatementAssignmentKind::DATA:
return format("{}[{}] <- {}", statement->getIdentifier(), toString(statement->getIndexExpression()), toString(statement->getValueExpression()));
case StatementAssignmentKind::BLOB:
return format("{}.{} <- {}", statement->getIdentifier(), statement->getMemberName(), toString(statement->getValueExpression()));
}
}
string Logger::toString(shared_ptr<StatementReturn> statement) {

View File

@@ -476,25 +476,14 @@ shared_ptr<Statement> Parser::matchStatementBlock(vector<TokenKind> terminalToke
}
shared_ptr<Statement> Parser::matchStatementAssignment() {
string identifier;
shared_ptr<Expression> indexExpression;
shared_ptr<Expression> expression;
ParseeResultsGroup resultsGroup;
ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup(
// variable
resultsGroup = parseeResultsGroupForParseeGroup(
ParseeGroup(
{
// identifier
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false),
// index expression
Parsee::groupParsee(
ParseeGroup(
{
Parsee::tokenParsee(TokenKind::LEFT_SQUARE_BRACKET, true, false, false),
Parsee::expressionParsee(true, true, true),
Parsee::tokenParsee(TokenKind::RIGHT_SQUARE_BRACKET, true, false, true)
}
), false, true, false
),
// expression
Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false),
Parsee::expressionParsee(true, true, true)
@@ -502,19 +491,78 @@ shared_ptr<Statement> Parser::matchStatementAssignment() {
)
);
if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS)
return nullptr;
switch (resultsGroup.getKind()) {
case ParseeResultsGroupKind::SUCCESS: {
string identifier = resultsGroup.getResults().at(0).getToken()->getLexme();
shared_ptr<Expression> valueExpression = resultsGroup.getResults().at(1).getExpression();
return StatementAssignment::variableAssignment(identifier, valueExpression);
}
case ParseeResultsGroupKind::NO_MATCH:
break;
case ParseeResultsGroupKind::FAILURE:
return nullptr;
}
int i = 0;
// identifier
identifier = resultsGroup.getResults().at(i++).getToken()->getLexme();
// index expression
if (i < resultsGroup.getResults().size()-1)
indexExpression = resultsGroup.getResults().at(i++).getExpression();
// expression
expression = resultsGroup.getResults().at(i).getExpression();
// 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),
// expression
Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false),
Parsee::expressionParsee(true, true, true)
}
)
);
return make_shared<StatementAssignment>(identifier, indexExpression, expression);
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> valueExpression = resultsGroup.getResults().at(2).getExpression();
return StatementAssignment::dataAssignment(identifier, indexExpression, valueExpression);
}
case ParseeResultsGroupKind::NO_MATCH:
break;
case ParseeResultsGroupKind::FAILURE:
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),
// expression
Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false),
Parsee::expressionParsee(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();
shared_ptr<Expression> valueExpression = resultsGroup.getResults().at(2).getExpression();
return StatementAssignment::blobAssignment(identifier, memberName, valueExpression);
}
case ParseeResultsGroupKind::NO_MATCH:
break;
case ParseeResultsGroupKind::FAILURE:
return nullptr;
}
return nullptr;
}
shared_ptr<Statement> Parser::matchStatementReturn() {

View File

@@ -1,24 +1,50 @@
#include "StatementAssignment.h"
StatementAssignment::StatementAssignment(string name, shared_ptr<Expression> indexExpression, shared_ptr<Expression> expression):
Statement(StatementKind::ASSIGNMENT), name(name), indexExpression(indexExpression), expression(expression) { }
StatementAssignment::StatementAssignment():
Statement(StatementKind::ASSIGNMENT) { }
shared_ptr<StatementAssignment> StatementAssignment::variableAssignment(string identifier, shared_ptr<Expression> valueExpression) {
shared_ptr<StatementAssignment> statement = make_shared<StatementAssignment>();
statement->assignmentKind = StatementAssignmentKind::VARIABLE;
statement->identifier = identifier;
statement->valueExpression = valueExpression;
return statement;
}
shared_ptr<StatementAssignment> StatementAssignment::dataAssignment(string identifier, shared_ptr<Expression> indexExpression, shared_ptr<Expression> valueExpression) {
shared_ptr<StatementAssignment> statement = make_shared<StatementAssignment>();
statement->assignmentKind = StatementAssignmentKind::DATA;
statement->identifier = identifier;
statement->indexExpression = indexExpression;
statement->valueExpression = valueExpression;
return statement;
}
shared_ptr<StatementAssignment> StatementAssignment::blobAssignment(string identifier, string memberName, shared_ptr<Expression> valueExpression) {
shared_ptr<StatementAssignment> statement = make_shared<StatementAssignment>();
statement->assignmentKind = StatementAssignmentKind::BLOB;
statement->identifier = identifier;
statement->memberName = memberName;
statement->valueExpression = valueExpression;
return statement;
}
StatementAssignmentKind StatementAssignment::getAssignmentKind() {
return assignmentKind;
}
string StatementAssignment::getName() {
return name;
string StatementAssignment::getIdentifier() {
return identifier;
}
shared_ptr<Expression> StatementAssignment::getIndexExpression() {
return indexExpression;
}
shared_ptr<Expression> StatementAssignment::getExpression() {
return expression;
}
string StatementAssignment::getMemberName() {
return memberName;
}
shared_ptr<Expression> StatementAssignment::getValueExpression() {
return valueExpression;
}

View File

@@ -11,16 +11,19 @@ enum class StatementAssignmentKind {
class StatementAssignment: public Statement {
private:
StatementAssignmentKind assignmentKind;
string name;
string identifier;
shared_ptr<Expression> indexExpression;
shared_ptr<Expression> expression;
string memberName;
public:
StatementAssignment(string name, shared_ptr<Expression> indexExpressio, shared_ptr<Expression> expression);
shared_ptr<Expression> valueExpression;
public:
StatementAssignment();
static shared_ptr<StatementAssignment> variableAssignment(string identifier, shared_ptr<Expression> expression);
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();
string getName();
string getIdentifier();
shared_ptr<Expression> getIndexExpression();
shared_ptr<Expression> getExpression();
string getMemberName();
shared_ptr<Expression> getValueExpression();
};