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 main fun -> u32
us User us User
us<- 5 us.num1 <- 5
us.num2 <- 4
ret 0 ret 0
; ;

View File

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

View File

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

View File

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

View File

@@ -74,6 +74,8 @@ string Logger::toString(shared_ptr<Token> token) {
return ""; return "";
case TokenKind::RIGHT_ARROW: case TokenKind::RIGHT_ARROW:
return ""; return "";
case TokenKind::DOT:
return ".";
case TokenKind::BOOL: case TokenKind::BOOL:
return "BOOL(" + token->getLexme() + ")"; return "BOOL(" + token->getLexme() + ")";
@@ -165,6 +167,8 @@ string Logger::toString(TokenKind tokenKind) {
return ""; return "";
case TokenKind::RIGHT_ARROW: case TokenKind::RIGHT_ARROW:
return ""; return "";
case TokenKind::DOT:
return ".";
case TokenKind::BOOL: case TokenKind::BOOL:
return "LITERAL(BOOLEAN)"; return "LITERAL(BOOLEAN)";
@@ -329,10 +333,14 @@ string Logger::toString(shared_ptr<StatementBlock> statement) {
} }
string Logger::toString(shared_ptr<StatementAssignment> statement) { string Logger::toString(shared_ptr<StatementAssignment> statement) {
if (statement->getIndexExpression() != nullptr) switch (statement->getAssignmentKind()) {
return format("{}[{}] <- {}", statement->getName(), toString(statement->getIndexExpression()), toString(statement->getExpression())); case StatementAssignmentKind::VARIABLE:
else return format("{} <- {}", statement->getIdentifier(), toString(statement->getValueExpression()));
return format("{} <- {}", statement->getName(), toString(statement->getExpression())); 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) { 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() { shared_ptr<Statement> Parser::matchStatementAssignment() {
string identifier; ParseeResultsGroup resultsGroup;
shared_ptr<Expression> indexExpression;
shared_ptr<Expression> expression;
ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( // variable
resultsGroup = parseeResultsGroupForParseeGroup(
ParseeGroup( ParseeGroup(
{ {
// identifier // identifier
Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), 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 // expression
Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false), Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false),
Parsee::expressionParsee(true, true, true) Parsee::expressionParsee(true, true, true)
@@ -502,19 +491,78 @@ shared_ptr<Statement> Parser::matchStatementAssignment() {
) )
); );
if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS) switch (resultsGroup.getKind()) {
return nullptr; 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; // data
// identifier resultsGroup = parseeResultsGroupForParseeGroup(
identifier = resultsGroup.getResults().at(i++).getToken()->getLexme(); ParseeGroup(
// index expression {
if (i < resultsGroup.getResults().size()-1) // identifier
indexExpression = resultsGroup.getResults().at(i++).getExpression(); Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false),
// expression // index expression
expression = resultsGroup.getResults().at(i).getExpression(); 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() { shared_ptr<Statement> Parser::matchStatementReturn() {

View File

@@ -1,24 +1,50 @@
#include "StatementAssignment.h" #include "StatementAssignment.h"
StatementAssignment::StatementAssignment(string name, shared_ptr<Expression> indexExpression, shared_ptr<Expression> expression): StatementAssignment::StatementAssignment():
Statement(StatementKind::ASSIGNMENT), name(name), indexExpression(indexExpression), expression(expression) { } 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() { StatementAssignmentKind StatementAssignment::getAssignmentKind() {
return assignmentKind; return assignmentKind;
} }
string StatementAssignment::getName() { string StatementAssignment::getIdentifier() {
return name; return identifier;
} }
shared_ptr<Expression> StatementAssignment::getIndexExpression() { shared_ptr<Expression> StatementAssignment::getIndexExpression() {
return indexExpression; return indexExpression;
} }
shared_ptr<Expression> StatementAssignment::getExpression() {
return expression;
}
string StatementAssignment::getMemberName() { string StatementAssignment::getMemberName() {
return memberName; return memberName;
} }
shared_ptr<Expression> StatementAssignment::getValueExpression() {
return valueExpression;
}

View File

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