From 7d141bec14976ec0caedd29f61c8253d3124fd81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Mon, 9 Jun 2025 21:41:55 +0900 Subject: [PATCH] Variable loading seems to be working --- src/Expression.cpp | 24 +++++++++++++++++++----- src/Expression.h | 12 ++++++++++++ src/ModuleBuilder.cpp | 11 +++++++++++ src/ModuleBuilder.h | 4 ++++ src/Parser.cpp | 25 ++++++++++++++++++++++--- src/Parser.h | 1 + src/Types.h | 1 + 7 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/Expression.cpp b/src/Expression.cpp index 971dc9a..d22840f 100644 --- a/src/Expression.cpp +++ b/src/Expression.cpp @@ -23,7 +23,7 @@ string Expression::toString(int indent) { // // ExpressionBinary ExpressionBinary::ExpressionBinary(shared_ptr token, shared_ptr left, shared_ptr right): - Expression(ExpressionKind::BINARY, ValueType::VOID), left(left), right(right) { +Expression(ExpressionKind::BINARY, ValueType::VOID), left(left), right(right) { // Types must match if (left->getValueType() != right->getValueType()) exit(1); @@ -124,7 +124,7 @@ string ExpressionBinary::toString(int indent) { // // ExpressionLiteral ExpressionLiteral::ExpressionLiteral(shared_ptr token): - Expression(ExpressionKind::LITERAL, ValueType::VOID) { +Expression(ExpressionKind::LITERAL, ValueType::VOID) { switch (token->getKind()) { case TokenKind::BOOL: boolValue = token->getLexme().compare("true") == 0; @@ -171,7 +171,7 @@ string ExpressionLiteral::toString(int indent) { // // ExpressionGrouping ExpressionGrouping::ExpressionGrouping(shared_ptr expression): - Expression(ExpressionKind::GROUPING, expression->getValueType()), expression(expression) { +Expression(ExpressionKind::GROUPING, expression->getValueType()), expression(expression) { } shared_ptr ExpressionGrouping::getExpression() { @@ -185,7 +185,7 @@ string ExpressionGrouping::toString(int indent) { // // ExpressionIfElse ExpressionIfElse::ExpressionIfElse(shared_ptr condition, shared_ptr thenBlock, shared_ptr elseBlock): - Expression(ExpressionKind::IF_ELSE, ValueType::VOID), condition(condition), thenBlock(thenBlock), elseBlock(elseBlock) { +Expression(ExpressionKind::IF_ELSE, ValueType::VOID), condition(condition), thenBlock(thenBlock), elseBlock(elseBlock) { // Condition must evaluate to bool if (condition->getValueType() != ValueType::BOOL) exit(1); @@ -232,10 +232,24 @@ string ExpressionIfElse::toString(int indent) { return value; } +// +// ExpressionVar +ExpressionVar::ExpressionVar(string name): +Expression(ExpressionKind::VAR, ValueType::VOID), name(name) { +} + +string ExpressionVar::getName() { + return name; +} + +string ExpressionVar::toString(int indent) { + return "VAR(" + name + ")"; +} + // // ExpressionInvalid ExpressionInvalid::ExpressionInvalid(shared_ptr token): - Expression(ExpressionKind::INVALID, ValueType::VOID), token(token) { +Expression(ExpressionKind::INVALID, ValueType::VOID), token(token) { } shared_ptr ExpressionInvalid::getToken() { diff --git a/src/Expression.h b/src/Expression.h index eb7b3b7..9100629 100644 --- a/src/Expression.h +++ b/src/Expression.h @@ -102,6 +102,18 @@ public: string toString(int indent) override; }; +// +// ExpressionVar +class ExpressionVar: public Expression { +private: + string name; + +public: + ExpressionVar(string name); + string getName(); + string toString(int indent) override; +}; + // // ExpressionInvalid class ExpressionInvalid: public Expression { diff --git a/src/ModuleBuilder.cpp b/src/ModuleBuilder.cpp index c1adf9e..6a6cc58 100644 --- a/src/ModuleBuilder.cpp +++ b/src/ModuleBuilder.cpp @@ -51,6 +51,7 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr statement) { llvm::Value *value = valueForExpression(statement->getExpression()); llvm::AllocaInst *alloca = builder->CreateAlloca(typeForValueType(statement->getValueType()), nullptr, statement->getName()); + allocaMap[statement->getName()] = alloca; builder->CreateStore(value, alloca); } @@ -85,6 +86,8 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr expression return valueForBinary(dynamic_pointer_cast(expression)); case ExpressionKind::IF_ELSE: return valueForIfElse(dynamic_pointer_cast(expression)); + case ExpressionKind::VAR: + return valueForVar(dynamic_pointer_cast(expression)); default: exit(1); } @@ -242,6 +245,14 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expressi return phi; } +llvm::Value *ModuleBuilder::valueForVar(shared_ptr expression) { + llvm::AllocaInst *alloca = allocaMap[expression->getName()]; + if (alloca == nullptr) + exit(1); + + return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName()); +} + llvm::Type *ModuleBuilder::typeForValueType(ValueType valueType) { switch (valueType) { case ValueType::VOID: diff --git a/src/ModuleBuilder.h b/src/ModuleBuilder.h index fa34581..7369986 100644 --- a/src/ModuleBuilder.h +++ b/src/ModuleBuilder.h @@ -1,6 +1,8 @@ #ifndef MODULE_BUILDER_H #define MODULE_BUILDER_H +#include + #include "llvm/IR/Module.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" @@ -24,6 +26,7 @@ private: llvm::Type *typeReal32; vector> statements; + map allocaMap; void buildStatement(shared_ptr statement); void buildFunctionDeclaration(shared_ptr statement); @@ -40,6 +43,7 @@ private: llvm::Value *valueForBinaryInteger(shared_ptr expression); llvm::Value *valueForBinaryReal(shared_ptr expression); llvm::Value *valueForIfElse(shared_ptr expression); + llvm::Value *valueForVar(shared_ptr expression); llvm::Type *typeForValueType(ValueType valueType); diff --git a/src/Parser.cpp b/src/Parser.cpp index 5acccd9..0e848cc 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -97,10 +97,11 @@ shared_ptr Parser::matchStatementVarDeclaration() { else return matchStatementInvalid(); - //if (tokens.at(currentIndex)->getKind() != TokenKind::NEW_LINE) - // return matchStatementInvalid(); + // Expect new line + if (tokens.at(currentIndex)->getKind() != TokenKind::NEW_LINE) + return matchStatementInvalid(); - //currentIndex++; + currentIndex++; return make_shared(identifierToken->getLexme(), valueType, expression); } @@ -182,6 +183,10 @@ shared_ptr Parser::nextExpression() { expression = matchExpressionIfElse(); if (expression != nullptr) return expression; + + expression = matchExpressionVar(); + if (expression != nullptr) + return expression; return nullptr; } @@ -346,11 +351,25 @@ shared_ptr Parser::matchExpressionIfElse() { return matchExpressionInvalid(); else if (!elseBlock->isValid()) return matchExpressionInvalid(); // FIXME + + // hack to treat statement as an expression + if (tokens.at(currentIndex-1)->getKind() == TokenKind::NEW_LINE) + currentIndex--; } return make_shared(condition, dynamic_pointer_cast(thenBlock), dynamic_pointer_cast(elseBlock)); } +shared_ptr Parser::matchExpressionVar() { + shared_ptr token = tokens.at(currentIndex); + if (token->isOfKind({TokenKind::IDENTIFIER})) { + currentIndex++; + return make_shared(token->getLexme()); + } + + return nullptr; +} + shared_ptr Parser::matchExpressionInvalid() { return make_shared(tokens.at(currentIndex)); } diff --git a/src/Parser.h b/src/Parser.h index d1fcaba..c73b776 100644 --- a/src/Parser.h +++ b/src/Parser.h @@ -33,6 +33,7 @@ private: shared_ptr matchExpressionGrouping(); shared_ptr matchExpressionBinary(shared_ptr left); shared_ptr matchExpressionIfElse(); + shared_ptr matchExpressionVar(); shared_ptr matchExpressionInvalid(); bool matchesTokenKinds(vector kinds); diff --git a/src/Types.h b/src/Types.h index 7cd06d9..9169ef0 100644 --- a/src/Types.h +++ b/src/Types.h @@ -44,6 +44,7 @@ enum class ExpressionKind { GROUPING, BINARY, IF_ELSE, + VAR, INVALID };