Added unary expressions

This commit is contained in:
Rafał Grodziński
2025-07-31 23:28:33 +09:00
parent c75052e35f
commit 7dfa6bcffe
10 changed files with 80 additions and 8 deletions

View File

@@ -49,10 +49,10 @@ i u32 <- 0, rep text[i] != 0:
;*/ ;*/
main fun -> u32 main fun -> u32
num1 u8 <- 42 /*num1 u8 <- 42
num2 s8 <- -15 num2 s8 <- 3 - +15
num3 u32 <- 1234123 num3 u32 <- 1234123
num4 s32 <- -345345 num4 s32 <- -345345*/
num5 r32 <- -42.58 num5 r32 <- -42.58
ret 0 ret 0

View File

@@ -11,6 +11,7 @@
#include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionCall.h"
#include "Parser/Expression/ExpressionIfElse.h" #include "Parser/Expression/ExpressionIfElse.h"
#include "Parser/Expression/ExpressionBinary.h" #include "Parser/Expression/ExpressionBinary.h"
#include "Parser/Expression/ExpressionUnary.h"
#include "Parser/Expression/ExpressionBlock.h" #include "Parser/Expression/ExpressionBlock.h"
#include "Parser/Statement/StatementFunction.h" #include "Parser/Statement/StatementFunction.h"
@@ -172,6 +173,8 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement)
} }
} else { } else {
llvm::Value *value = valueForExpression(statement->getExpression()); llvm::Value *value = valueForExpression(statement->getExpression());
if (value == nullptr)
return;
llvm::AllocaInst *alloca = builder->CreateAlloca(typeForValueType(statement->getValueType(), 0), nullptr, statement->getName()); llvm::AllocaInst *alloca = builder->CreateAlloca(typeForValueType(statement->getValueType(), 0), nullptr, statement->getName());
if (!setAlloca(statement->getName(), alloca)) if (!setAlloca(statement->getName(), alloca))
@@ -297,6 +300,8 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression
return valueForExpression(dynamic_pointer_cast<ExpressionGrouping>(expression)->getExpression()); return valueForExpression(dynamic_pointer_cast<ExpressionGrouping>(expression)->getExpression());
case ExpressionKind::BINARY: case ExpressionKind::BINARY:
return valueForBinary(dynamic_pointer_cast<ExpressionBinary>(expression)); return valueForBinary(dynamic_pointer_cast<ExpressionBinary>(expression));
case ExpressionKind::UNARY:
return valueForUnary(dynamic_pointer_cast<ExpressionUnary>(expression));
case ExpressionKind::IF_ELSE: case ExpressionKind::IF_ELSE:
return valueForIfElse(dynamic_pointer_cast<ExpressionIfElse>(expression)); return valueForIfElse(dynamic_pointer_cast<ExpressionIfElse>(expression));
case ExpressionKind::VAR: case ExpressionKind::VAR:
@@ -337,7 +342,7 @@ llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr<ExpressionLiteral> expres
case ValueTypeKind::S32: case ValueTypeKind::S32:
return llvm::ConstantInt::get(typeS32, expression->getS32Value(), true); return llvm::ConstantInt::get(typeS32, expression->getS32Value(), true);
case ValueTypeKind::R32: case ValueTypeKind::R32:
return llvm::ConstantInt::get(typeR32, expression->getR32Value(), true); return llvm::ConstantFP::get(typeR32, expression->getR32Value());
} }
} }
@@ -383,7 +388,7 @@ llvm::Value *ModuleBuilder::valueForBinaryBool(ExpressionBinaryOperation operati
case ExpressionBinaryOperation::NOT_EQUAL: case ExpressionBinaryOperation::NOT_EQUAL:
return builder->CreateICmpNE(leftValue, rightValue); return builder->CreateICmpNE(leftValue, rightValue);
default: default:
markError(0, 0, "Unexpecgted operation for boolean operands"); markError(0, 0, "Unexpected operation for boolean operands");
return nullptr; return nullptr;
} }
} }
@@ -469,6 +474,26 @@ llvm::Value *ModuleBuilder::valueForBinaryReal(ExpressionBinaryOperation operati
} }
} }
llvm::Value *ModuleBuilder::valueForUnary(shared_ptr<ExpressionUnary> expression) {
llvm::Value *value = valueForExpression(expression->getExpression());
llvm::Type *type = value->getType();
// do nothing for plus
if (expression->getOperation() == ExpressionUnaryOperation::PLUS)
return value;
if (type == typeU8 || type == typeU32) {
return builder->CreateNeg(value);
} else if (type == typeS8 || type == typeS32) {
return builder->CreateNSWNeg(value);
} else if (type == typeR32) {
return builder->CreateFNeg(value);
}
markError(0, 0, "Unexpected operation");
return nullptr;
}
llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr<ExpressionIfElse> expression) { llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr<ExpressionIfElse> expression) {
shared_ptr<Expression> conditionExpression = expression->getCondition(); shared_ptr<Expression> conditionExpression = expression->getCondition();

View File

@@ -23,6 +23,7 @@ class ExpressionVariable;
class ExpressionCall; class ExpressionCall;
class ExpressionIfElse; class ExpressionIfElse;
class ExpressionBinary; class ExpressionBinary;
class ExpressionUnary;
enum class ExpressionBinaryOperation; enum class ExpressionBinaryOperation;
class Statement; class Statement;
@@ -86,6 +87,7 @@ private:
llvm::Value *valueForBinaryUnsignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForBinaryUnsignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue);
llvm::Value *valueForBinarySignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForBinarySignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue);
llvm::Value *valueForBinaryReal(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); 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 *valueForIfElse(shared_ptr<ExpressionIfElse> expression);
llvm::Value *valueForVar(shared_ptr<ExpressionVariable> expression); llvm::Value *valueForVar(shared_ptr<ExpressionVariable> expression);
llvm::Value *valueForCall(shared_ptr<ExpressionCall> expression); llvm::Value *valueForCall(shared_ptr<ExpressionCall> expression);

View File

@@ -4,21 +4,30 @@ vector<TokenKind> Token::tokensEquality = {
TokenKind::EQUAL, TokenKind::EQUAL,
TokenKind::NOT_EQUAL TokenKind::NOT_EQUAL
}; };
vector<TokenKind> Token::tokensComparison = { vector<TokenKind> Token::tokensComparison = {
TokenKind::LESS, TokenKind::LESS,
TokenKind::LESS_EQUAL, TokenKind::LESS_EQUAL,
TokenKind::GREATER, TokenKind::GREATER,
TokenKind::GREATER_EQUAL TokenKind::GREATER_EQUAL
}; };
vector<TokenKind> Token::tokensTerm = { vector<TokenKind> Token::tokensTerm = {
TokenKind::PLUS, TokenKind::PLUS,
TokenKind::MINUS TokenKind::MINUS
}; };
vector<TokenKind> Token::tokensFactor = { vector<TokenKind> Token::tokensFactor = {
TokenKind::STAR, TokenKind::STAR,
TokenKind::SLASH, TokenKind::SLASH,
TokenKind::PERCENT TokenKind::PERCENT
}; };
vector<TokenKind> Token::tokensUnary = {
TokenKind::PLUS,
TokenKind::MINUS
};
vector<TokenKind> Token::tokensBinary = { vector<TokenKind> Token::tokensBinary = {
TokenKind::EQUAL, TokenKind::EQUAL,
TokenKind::NOT_EQUAL, TokenKind::NOT_EQUAL,
@@ -35,6 +44,7 @@ vector<TokenKind> Token::tokensBinary = {
TokenKind::SLASH, TokenKind::SLASH,
TokenKind::PERCENT TokenKind::PERCENT
}; };
vector<TokenKind> Token::tokensLiteral = { vector<TokenKind> Token::tokensLiteral = {
TokenKind::BOOL, TokenKind::BOOL,
TokenKind::INTEGER_DEC, TokenKind::INTEGER_DEC,

View File

@@ -65,6 +65,7 @@ public:
static vector<TokenKind> tokensComparison; static vector<TokenKind> tokensComparison;
static vector<TokenKind> tokensTerm; static vector<TokenKind> tokensTerm;
static vector<TokenKind> tokensFactor; static vector<TokenKind> tokensFactor;
static vector<TokenKind> tokensUnary;
static vector<TokenKind> tokensBinary; static vector<TokenKind> tokensBinary;
static vector<TokenKind> tokensLiteral; static vector<TokenKind> tokensLiteral;

View File

@@ -20,6 +20,7 @@
#include "Parser/Expression/Expression.h" #include "Parser/Expression/Expression.h"
#include "Parser/Expression/ExpressionBinary.h" #include "Parser/Expression/ExpressionBinary.h"
#include "Parser/Expression/ExpressionUnary.h"
#include "Parser/Expression/ExpressionIfElse.h" #include "Parser/Expression/ExpressionIfElse.h"
#include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionVariable.h"
#include "Parser/Expression/ExpressionGrouping.h" #include "Parser/Expression/ExpressionGrouping.h"
@@ -344,7 +345,9 @@ string Logger::toString(shared_ptr<StatementExpression> statement) {
string Logger::toString(shared_ptr<Expression> expression) { string Logger::toString(shared_ptr<Expression> expression) {
switch (expression->getKind()) { switch (expression->getKind()) {
case ExpressionKind::BINARY: case ExpressionKind::BINARY:
return toString(dynamic_pointer_cast<ExpressionBinary>(expression)); return toString(dynamic_pointer_cast<ExpressionBinary>(expression));
case ExpressionKind::UNARY:
return toString(dynamic_pointer_cast<ExpressionUnary>(expression));
case ExpressionKind::IF_ELSE: case ExpressionKind::IF_ELSE:
return toString(dynamic_pointer_cast<ExpressionIfElse>(expression)); return toString(dynamic_pointer_cast<ExpressionIfElse>(expression));
case ExpressionKind::VAR: case ExpressionKind::VAR:
@@ -391,6 +394,17 @@ string Logger::toString(shared_ptr<ExpressionBinary> expression) {
} }
} }
string Logger::toString(shared_ptr<ExpressionUnary> expression) {
switch (expression->getOperation()) {
case ExpressionUnaryOperation::PLUS:
return "+" + toString(expression->getExpression());
case ExpressionUnaryOperation::MINUS:
return "-" + toString(expression->getExpression());
case ExpressionUnaryOperation::INVALID:
return "{INVALID}";
}
}
string Logger::toString(shared_ptr<ExpressionIfElse> expression) { string Logger::toString(shared_ptr<ExpressionIfElse> expression) {
string text; string text;

View File

@@ -20,6 +20,7 @@ class StatementExpression;
class Expression; class Expression;
class ExpressionBinary; class ExpressionBinary;
class ExpressionUnary;
class ExpressionIfElse; class ExpressionIfElse;
class ExpressionVariable; class ExpressionVariable;
class ExpressionGrouping; class ExpressionGrouping;
@@ -51,6 +52,7 @@ private:
static string toString(shared_ptr<Expression> expression); static string toString(shared_ptr<Expression> expression);
static string toString(shared_ptr<ExpressionBinary> expression); static string toString(shared_ptr<ExpressionBinary> expression);
static string toString(shared_ptr<ExpressionUnary> expression);
static string toString(shared_ptr<ExpressionIfElse> expression); static string toString(shared_ptr<ExpressionIfElse> expression);
static string toString(shared_ptr<ExpressionVariable> expression); static string toString(shared_ptr<ExpressionVariable> expression);
static string toString(shared_ptr<ExpressionGrouping> expression); static string toString(shared_ptr<ExpressionGrouping> expression);

View File

@@ -7,12 +7,15 @@ Expression(ExpressionKind::UNARY, nullptr), expression(expression) {
switch (token->getKind()) { switch (token->getKind()) {
case TokenKind::PLUS: case TokenKind::PLUS:
operation = ExpressionUnaryOperation::PLUS; operation = ExpressionUnaryOperation::PLUS;
valueType = expression->getValueType();
break; break;
case TokenKind::MINUS: case TokenKind::MINUS:
operation = ExpressionUnaryOperation::MINUS; operation = ExpressionUnaryOperation::MINUS;
valueType = expression->getValueType();
break; break;
default: default:
operation = ExpressionUnaryOperation::INVALID; operation = ExpressionUnaryOperation::INVALID;
valueType = nullptr;
break; break;
} }
} }

View File

@@ -12,6 +12,7 @@
#include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionVariable.h"
#include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionCall.h"
#include "Parser/Expression/ExpressionIfElse.h" #include "Parser/Expression/ExpressionIfElse.h"
#include "Parser/Expression/ExpressionUnary.h"
#include "Parser/Expression/ExpressionBinary.h" #include "Parser/Expression/ExpressionBinary.h"
#include "Parser/Expression/ExpressionBlock.h" #include "Parser/Expression/ExpressionBlock.h"
@@ -723,7 +724,7 @@ shared_ptr<Expression> Parser::matchTerm() {
} }
shared_ptr<Expression> Parser::matchFactor() { shared_ptr<Expression> Parser::matchFactor() {
shared_ptr<Expression> expression = matchPrimary(); shared_ptr<Expression> expression = matchUnary();
if (expression == nullptr) if (expression == nullptr)
return nullptr; return nullptr;
@@ -733,6 +734,19 @@ shared_ptr<Expression> Parser::matchFactor() {
return expression; return expression;
} }
shared_ptr<Expression> Parser::matchUnary() {
shared_ptr<Token> token = tokens.at(currentIndex);
if (tryMatchingTokenKinds(Token::tokensUnary, false, true)) {
shared_ptr<Expression> expression = matchPrimary();
if (expression == nullptr)
return nullptr;
return make_shared<ExpressionUnary>(token, expression);
}
return matchPrimary();
}
shared_ptr<Expression> Parser::matchPrimary() { shared_ptr<Expression> Parser::matchPrimary() {
shared_ptr<Expression> expression; shared_ptr<Expression> expression;
int errorsCount = errors.size(); int errorsCount = errors.size();

View File

@@ -43,7 +43,8 @@ private:
shared_ptr<Expression> matchComparison(); // <, <=, >, >= shared_ptr<Expression> matchComparison(); // <, <=, >, >=
shared_ptr<Expression> matchTerm(); // +, - shared_ptr<Expression> matchTerm(); // +, -
shared_ptr<Expression> matchFactor(); // *, /, % shared_ptr<Expression> matchFactor(); // *, /, %
shared_ptr<Expression> matchPrimary(); // integer, () shared_ptr<Expression> matchUnary(); // +, -
shared_ptr<Expression> matchPrimary(); // literal, ()
shared_ptr<Expression> matchExpressionGrouping(); shared_ptr<Expression> matchExpressionGrouping();
shared_ptr<Expression> matchExpressionLiteral(); shared_ptr<Expression> matchExpressionLiteral();