Merge pull request #32 from rafalgrodzinski/24-update-types

Update types
This commit is contained in:
Rafał
2025-08-01 12:42:01 +09:00
committed by GitHub
21 changed files with 359 additions and 109 deletions

6
.gitignore vendored
View File

@@ -1,3 +1,8 @@
# ingnore files without extension
*
!*.*
!*/
.DS_Store .DS_Store
.vscode/settings.json .vscode/settings.json
@@ -7,3 +12,4 @@ build/
# brb build artifiacts # brb build artifiacts
*.o *.o
*.asm

9
.vscode/tasks.json vendored
View File

@@ -3,12 +3,17 @@
"tasks": [ "tasks": [
{ {
"label": "Build Bits Runner Builder (Debug)", "label": "Build Bits Runner Builder (Debug)",
"type": "cmake", "type": "shell",
"command": "build", "command": "cmake -B build && cmake --build build --config Debug",
"group": { "group": {
"kind": "build", "kind": "build",
"isDefault": true "isDefault": true
} }
},
{
"label": "Clean",
"type": "shell",
"command": "rm -rf build *.o *.asm; find ./ -perm +100 -type f -maxdepth 1 -delete"
} }
] ]
} }

View File

@@ -1,6 +1,6 @@
@extern putchar fun: character sint32 -> sint32 @extern putchar fun: character u32 -> u32
fib fun: number sint32 -> sint32 fib fun: number u32 -> u32
ret if number < 2: ret if number < 2:
number number
else else
@@ -8,13 +8,13 @@ fib fun: number sint32 -> sint32
; ;
; ;
printNum fun: number sint32 printNum fun: number u32
biggest sint32 <- 10 biggest u32 <- 10
rep biggest <= number: biggest <- biggest * 10 rep biggest <= number: biggest <- biggest * 10
biggest <- biggest / 10 biggest <- biggest / 10
rep biggest > 0: rep biggest > 0:
digit sint32 <- number / biggest digit u32 <- number / biggest
putchar(digit + '0') putchar(digit + '0')
number <- number % biggest number <- number % biggest
biggest <- biggest / 10 biggest <- biggest / 10
@@ -22,9 +22,9 @@ printNum fun: number sint32
; ;
// Print first 20 fibonaci numbers // Print first 20 fibonaci numbers
main fun -> sint32 main fun -> u32
rep i sint32 <- 0, i < 20: rep i u32 <- 0, i < 20:
res sint32 <- fib(i) res u32 <- fib(i)
printNum(res) printNum(res)
putchar('\n') putchar('\n')
i <- i + 1 i <- i + 1

View File

@@ -1,9 +1,9 @@
@extern putchar fun: character sint32 -> sint32 @extern putchar fun: character u32 -> u32
main fun -> sint32 main fun -> u32
text data<sint32> <- "Hello, world!\n" text data<u32> <- "Hello, world!\n"
rep i sint32 <- 0, text[i] != 0: rep i u32 <- 0, text[i] != 0:
putchar(text[i]) putchar(text[i])
i <- i + 1 i <- i + 1
; ;

View File

@@ -1,4 +1,4 @@
@extern putchar fun: character sint32 -> sint32 //@extern putchar fun: character sint32 -> sint32
// ./build/brb samples/test.brc -S -x86-asm-syntax=intel // ./build/brb samples/test.brc -S -x86-asm-syntax=intel
@@ -28,10 +28,10 @@ i u32 <- 0, rep text[i] != 0:
ret num1 + num2 ret num1 + num2
;*/ ;*/
rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 /*rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32
add $1, $2 add $1, $2
mov $0, $1 mov $0, $1
; ;*/
/*rawAdd raw: num1 sint32, num2 sint32 -> sint32 /*rawAdd raw: num1 sint32, num2 sint32 -> sint32
add $1, $2 add $1, $2
@@ -48,13 +48,14 @@ rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32
;*/ ;*/
main fun -> sint32 main fun -> u32
/*a sint32 <- 4 num1 u8 <- 42
b sint32 <- 5 num2 s8 <- 3 - +15
num3 u32 <- 1234123
num4 s32 <- -345345
num5 r32 <- -42.58
res sint32 <- rawAdd(4, 5)*/ num5 + num3
putchar('@')
putchar('\n')
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"
@@ -32,8 +33,11 @@ moduleName(moduleName), sourceFileName(sourceFileName), statements(statements) {
typeVoid = llvm::Type::getVoidTy(*context); typeVoid = llvm::Type::getVoidTy(*context);
typeBool = llvm::Type::getInt1Ty(*context); typeBool = llvm::Type::getInt1Ty(*context);
typeSint32 = llvm::Type::getInt32Ty(*context); typeU8 = llvm::Type::getInt8Ty(*context);
typeReal32 = llvm::Type::getFloatTy(*context); typeU32 = llvm::Type::getInt32Ty(*context);
typeS8 = llvm::Type::getInt8Ty(*context);
typeS32 = llvm::Type::getInt32Ty(*context);
typeR32 = llvm::Type::getFloatTy(*context);
} }
shared_ptr<llvm::Module> ModuleBuilder::getModule() { shared_ptr<llvm::Module> ModuleBuilder::getModule() {
@@ -93,9 +97,15 @@ void ModuleBuilder::buildStatement(shared_ptr<Statement> statement) {
void ModuleBuilder::buildFunction(shared_ptr<StatementFunction> statement) { void ModuleBuilder::buildFunction(shared_ptr<StatementFunction> statement) {
// function types // function types
llvm::Type *returnType = typeForValueType(statement->getReturnValueType()); llvm::Type *returnType = typeForValueType(statement->getReturnValueType());
if (returnType == nullptr)
return;
vector<llvm::Type *> argTypes; vector<llvm::Type *> argTypes;
for (pair<string, shared_ptr<ValueType>> &arg : statement->getArguments()) for (pair<string, shared_ptr<ValueType>> &arg : statement->getArguments()) {
argTypes.push_back(typeForValueType(arg.second)); llvm::Type *argType = typeForValueType(arg.second);
if (argType == nullptr)
return;
argTypes.push_back(argType);
}
// build function declaration // build function declaration
llvm::FunctionType *funType = llvm::FunctionType::get(returnType, argTypes, false); llvm::FunctionType *funType = llvm::FunctionType::get(returnType, argTypes, false);
@@ -169,6 +179,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))
@@ -268,7 +280,10 @@ void ModuleBuilder::buildMetaExternFunction(shared_ptr<StatementMetaExternFuncti
} }
// build function declaration // build function declaration
llvm::FunctionType *funType = llvm::FunctionType::get(typeForValueType(statement->getReturnValueType()), types, false); llvm::Type *returnType = typeForValueType(statement->getReturnValueType());
if (returnType == nullptr)
return;
llvm::FunctionType *funType = llvm::FunctionType::get(returnType, types, false);
llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::ExternalLinkage, statement->getName(), module.get()); llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::ExternalLinkage, statement->getName(), module.get());
if (!setFun(statement->getName(), fun)) if (!setFun(statement->getName(), fun))
return; return;
@@ -294,6 +309,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:
@@ -325,10 +342,16 @@ llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr<ExpressionLiteral> expres
return llvm::UndefValue::get(typeVoid); return llvm::UndefValue::get(typeVoid);
case ValueTypeKind::BOOL: case ValueTypeKind::BOOL:
return llvm::ConstantInt::get(typeBool, expression->getBoolValue(), true); return llvm::ConstantInt::get(typeBool, expression->getBoolValue(), true);
case ValueTypeKind::SINT32: case ValueTypeKind::U8:
return llvm::ConstantInt::get(typeSint32, expression->getSint32Value(), true); return llvm::ConstantInt::get(typeU8, expression->getU8Value(), true);
case ValueTypeKind::REAL32: case ValueTypeKind::U32:
return llvm::ConstantInt::get(typeReal32, expression->getReal32Value(), true); return llvm::ConstantInt::get(typeU32, expression->getU32Value(), true);
case ValueTypeKind::S8:
return llvm::ConstantInt::get(typeS8, expression->getS8Value(), true);
case ValueTypeKind::S32:
return llvm::ConstantInt::get(typeS32, expression->getS32Value(), true);
case ValueTypeKind::R32:
return llvm::ConstantFP::get(typeR32, expression->getR32Value());
} }
} }
@@ -355,9 +378,11 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> expressi
if (type == typeBool) { if (type == typeBool) {
return valueForBinaryBool(expression->getOperation(), leftValue, rightValue); return valueForBinaryBool(expression->getOperation(), leftValue, rightValue);
} else if (type == typeSint32 || type == typeVoid) { } else if (type == typeU8 || type == typeU32) {
return valueForBinaryInteger(expression->getOperation(), leftValue, rightValue); return valueForBinaryUnsignedInteger(expression->getOperation(), leftValue, rightValue);
} else if (type == typeReal32) { } else if (type == typeS8 || type == typeS32) {
return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue);
} else if (type == typeR32) {
return valueForBinaryReal(expression->getOperation(), leftValue, rightValue); return valueForBinaryReal(expression->getOperation(), leftValue, rightValue);
} }
@@ -372,35 +397,62 @@ 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;
} }
} }
llvm::Value *ModuleBuilder::valueForBinaryInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) { llvm::Value *ModuleBuilder::valueForBinaryUnsignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) {
switch (operation) { switch (operation) {
case ExpressionBinaryOperation::EQUAL: case ExpressionBinaryOperation::EQUAL:
return builder->CreateICmpEQ(leftValue, rightValue); return builder->CreateICmpEQ(leftValue, rightValue);
case ExpressionBinaryOperation::NOT_EQUAL: case ExpressionBinaryOperation::NOT_EQUAL:
return builder->CreateICmpNE(leftValue, rightValue); return builder->CreateICmpNE(leftValue, rightValue);
case ExpressionBinaryOperation::LESS: case ExpressionBinaryOperation::LESS:
return builder->CreateICmpSLT(leftValue, rightValue); return builder->CreateICmpSLT(leftValue, rightValue);
case ExpressionBinaryOperation::LESS_EQUAL: case ExpressionBinaryOperation::LESS_EQUAL:
return builder->CreateICmpSLE(leftValue, rightValue); return builder->CreateICmpSLE(leftValue, rightValue);
case ExpressionBinaryOperation::GREATER: case ExpressionBinaryOperation::GREATER:
return builder->CreateICmpSGT(leftValue, rightValue); return builder->CreateICmpSGT(leftValue, rightValue);
case ExpressionBinaryOperation::GREATER_EQUAL: case ExpressionBinaryOperation::GREATER_EQUAL:
return builder->CreateICmpSGE(leftValue, rightValue); return builder->CreateICmpSGE(leftValue, rightValue);
case ExpressionBinaryOperation::ADD: case ExpressionBinaryOperation::ADD:
return builder->CreateNSWAdd(leftValue, rightValue); return builder->CreateNUWAdd(leftValue, rightValue);
case ExpressionBinaryOperation::SUB: case ExpressionBinaryOperation::SUB:
return builder->CreateNSWSub(leftValue, rightValue); return builder->CreateNUWSub(leftValue, rightValue);
case ExpressionBinaryOperation::MUL: case ExpressionBinaryOperation::MUL:
return builder->CreateNSWMul(leftValue, rightValue); return builder->CreateNUWMul(leftValue, rightValue);
case ExpressionBinaryOperation::DIV: case ExpressionBinaryOperation::DIV:
return builder->CreateSDiv(leftValue, rightValue); return builder->CreateUDiv(leftValue, rightValue);
case ExpressionBinaryOperation::MOD: case ExpressionBinaryOperation::MOD:
return builder->CreateSRem(leftValue, rightValue); return builder->CreateURem(leftValue, rightValue);
}
}
llvm::Value *ModuleBuilder::valueForBinarySignedInteger(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) {
switch (operation) {
case ExpressionBinaryOperation::EQUAL:
return builder->CreateICmpEQ(leftValue, rightValue);
case ExpressionBinaryOperation::NOT_EQUAL:
return builder->CreateICmpNE(leftValue, rightValue);
case ExpressionBinaryOperation::LESS:
return builder->CreateICmpSLT(leftValue, rightValue);
case ExpressionBinaryOperation::LESS_EQUAL:
return builder->CreateICmpSLE(leftValue, rightValue);
case ExpressionBinaryOperation::GREATER:
return builder->CreateICmpSGT(leftValue, rightValue);
case ExpressionBinaryOperation::GREATER_EQUAL:
return builder->CreateICmpSGE(leftValue, rightValue);
case ExpressionBinaryOperation::ADD:
return builder->CreateNSWAdd(leftValue, rightValue);
case ExpressionBinaryOperation::SUB:
return builder->CreateNSWSub(leftValue, rightValue);
case ExpressionBinaryOperation::MUL:
return builder->CreateNSWMul(leftValue, rightValue);
case ExpressionBinaryOperation::DIV:
return builder->CreateSDiv(leftValue, rightValue);
case ExpressionBinaryOperation::MOD:
return builder->CreateSRem(leftValue, rightValue);
} }
} }
@@ -431,6 +483,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();
@@ -600,22 +672,32 @@ llvm::InlineAsm *ModuleBuilder::getRawFun(string name) {
} }
llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int count) { llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int count) {
if (valueType == nullptr) {
markError(0, 0, "Missing type");
return nullptr;
}
switch (valueType->getKind()) { switch (valueType->getKind()) {
case ValueTypeKind::NONE: case ValueTypeKind::NONE:
return typeVoid; return typeVoid;
case ValueTypeKind::BOOL: case ValueTypeKind::BOOL:
return typeBool; return typeBool;
case ValueTypeKind::SINT32: case ValueTypeKind::U8:
return typeSint32; return typeU8;
case ValueTypeKind::REAL32: case ValueTypeKind::U32:
return typeReal32; return typeU32;
case ValueTypeKind::S8:
return typeS8;
case ValueTypeKind::S32:
return typeS32;
case ValueTypeKind::R32:
return typeR32;
case ValueTypeKind::DATA: { case ValueTypeKind::DATA: {
if (valueType->getSubType() == nullptr) if (valueType->getSubType() == nullptr)
return nullptr; return nullptr;
if (valueType->getValueArg() > 0) if (valueType->getValueArg() > 0)
count = valueType->getValueArg(); count = valueType->getValueArg();
return llvm::ArrayType::get(typeForValueType(valueType->getSubType(), count), count); return llvm::ArrayType::get(typeForValueType(valueType->getSubType(), count), count);
return nullptr;
} }
} }
} }

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;
@@ -56,8 +57,11 @@ private:
llvm::Type *typeVoid; llvm::Type *typeVoid;
llvm::Type *typeBool; llvm::Type *typeBool;
llvm::IntegerType *typeSint32; llvm::IntegerType *typeU8;
llvm::Type *typeReal32; llvm::IntegerType *typeU32;
llvm::IntegerType *typeS8;
llvm::IntegerType *typeS32;
llvm::Type *typeR32;
vector<shared_ptr<Statement>> statements; vector<shared_ptr<Statement>> statements;
stack<Scope> scopes; stack<Scope> scopes;
@@ -80,8 +84,10 @@ private:
llvm::Value *valueForGrouping(shared_ptr<ExpressionGrouping> expression); llvm::Value *valueForGrouping(shared_ptr<ExpressionGrouping> expression);
llvm::Value *valueForBinary(shared_ptr<ExpressionBinary> expression); llvm::Value *valueForBinary(shared_ptr<ExpressionBinary> expression);
llvm::Value *valueForBinaryBool(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForBinaryBool(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue);
llvm::Value *valueForBinaryInteger(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 *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"
@@ -202,15 +203,24 @@ string Logger::toString(TokenKind tokenKind) {
} }
string Logger::toString(shared_ptr<ValueType> valueType) { string Logger::toString(shared_ptr<ValueType> valueType) {
if (valueType == nullptr)
return "{INVALID}";
switch (valueType->getKind()) { switch (valueType->getKind()) {
case ValueTypeKind::NONE: case ValueTypeKind::NONE:
return "NONE"; return "NONE";
case ValueTypeKind::BOOL: case ValueTypeKind::BOOL:
return "BOOL"; return "BOOL";
case ValueTypeKind::SINT32: case ValueTypeKind::U8:
return "SINT32"; return "U8";
case ValueTypeKind::REAL32: case ValueTypeKind::U32:
return "REAL32"; return "U32";
case ValueTypeKind::S8:
return "S8";
case ValueTypeKind::S32:
return "S32";
case ValueTypeKind::R32:
return "R32";
case ValueTypeKind::DATA: case ValueTypeKind::DATA:
return "[]"; return "[]";
} }
@@ -338,7 +348,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:
@@ -385,6 +397,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;
@@ -420,10 +443,16 @@ string Logger::toString(shared_ptr<ExpressionLiteral> expression) {
return "NONE"; return "NONE";
case ValueTypeKind::BOOL: case ValueTypeKind::BOOL:
return expression->getBoolValue() ? "true" : "false"; return expression->getBoolValue() ? "true" : "false";
case ValueTypeKind::SINT32: case ValueTypeKind::U8:
return to_string(expression->getSint32Value()); return to_string(expression->getU8Value());
case ValueTypeKind::REAL32: case ValueTypeKind::U32:
return to_string(expression->getReal32Value()); return to_string(expression->getU32Value());
case ValueTypeKind::S8:
return to_string(expression->getS8Value());
case ValueTypeKind::S32:
return to_string(expression->getS32Value());
case ValueTypeKind::R32:
return to_string(expression->getR32Value());
default: default:
return "?"; return "?";
} }

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

@@ -12,6 +12,7 @@ enum class ExpressionKind {
LITERAL, LITERAL,
ARRAY_LITERAL, ARRAY_LITERAL,
GROUPING, GROUPING,
UNARY,
BINARY, BINARY,
IF_ELSE, IF_ELSE,
VAR, VAR,

View File

@@ -1,4 +1,7 @@
#include "Parser/Expression/Expression.h" #ifndef EXPRESSION_BINARY_H
#define EXPRESSION_BINARY_H
#include "Expression.h"
enum class ExpressionBinaryOperation { enum class ExpressionBinaryOperation {
EQUAL, EQUAL,
@@ -26,4 +29,6 @@ public:
ExpressionBinaryOperation getOperation(); ExpressionBinaryOperation getOperation();
shared_ptr<Expression> getLeft(); shared_ptr<Expression> getLeft();
shared_ptr<Expression> getRight(); shared_ptr<Expression> getRight();
}; };
#endif

View File

@@ -15,14 +15,14 @@ shared_ptr<ExpressionLiteral> ExpressionLiteral::expressionLiteralForToken(share
case TokenKind::INTEGER_DEC: { case TokenKind::INTEGER_DEC: {
string numString = token->getLexme(); string numString = token->getLexme();
erase(numString, '_'); erase(numString, '_');
expression->sint32Value = stoi(numString, nullptr, 10); expression->s32Value = stoi(numString, nullptr, 10);
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
break; break;
} }
case TokenKind::INTEGER_HEX: { case TokenKind::INTEGER_HEX: {
string numString = token->getLexme(); string numString = token->getLexme();
erase(numString, '_'); erase(numString, '_');
expression->sint32Value = stoi(numString, nullptr, 16); expression->u32Value = stoul(numString, nullptr, 16);
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
break; break;
} }
@@ -30,7 +30,7 @@ shared_ptr<ExpressionLiteral> ExpressionLiteral::expressionLiteralForToken(share
string numString = token->getLexme(); string numString = token->getLexme();
erase(numString, '_'); erase(numString, '_');
numString = numString.substr(2, numString.size()-1); numString = numString.substr(2, numString.size()-1);
expression->sint32Value = stoi(numString, nullptr, 2); expression->u32Value = stoul(numString, nullptr, 2);
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
break; break;
} }
@@ -41,13 +41,14 @@ shared_ptr<ExpressionLiteral> ExpressionLiteral::expressionLiteralForToken(share
return nullptr; return nullptr;
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
expression->sint32Value = *charValue; expression->u32Value = *charValue;
return expression; return expression;
} }
case TokenKind::REAL: case TokenKind::REAL: {
expression->real32Value = stof(token->getLexme()); expression->r32Value = stof(token->getLexme());
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
break; break;
}
default: default:
return nullptr; return nullptr;
} }
@@ -62,10 +63,22 @@ bool ExpressionLiteral::getBoolValue() {
return boolValue; return boolValue;
} }
int32_t ExpressionLiteral::getSint32Value() { uint8_t ExpressionLiteral::getU8Value() {
return sint32Value; return u8Value;
} }
float ExpressionLiteral::getReal32Value() { uint32_t ExpressionLiteral::getU32Value() {
return real32Value; return u32Value;
}
int8_t ExpressionLiteral::getS8Value() {
return s8Value;
}
int32_t ExpressionLiteral::getS32Value() {
return s32Value;
}
float ExpressionLiteral::getR32Value() {
return r32Value;
} }

View File

@@ -6,16 +6,22 @@
class ExpressionLiteral: public Expression { class ExpressionLiteral: public Expression {
private: private:
bool boolValue; bool boolValue;
int32_t sint32Value; uint8_t u8Value;
float real32Value; uint32_t u32Value;
int8_t s8Value;
int32_t s32Value;
float r32Value;
public: public:
static shared_ptr<ExpressionLiteral> expressionLiteralForToken(shared_ptr<Token> token); static shared_ptr<ExpressionLiteral> expressionLiteralForToken(shared_ptr<Token> token);
ExpressionLiteral(); ExpressionLiteral();
bool getBoolValue(); bool getBoolValue();
int32_t getSint32Value(); uint8_t getU8Value();
float getReal32Value(); uint32_t getU32Value();
int8_t getS8Value();
int32_t getS32Value();
float getR32Value();
}; };
#endif #endif

View File

@@ -0,0 +1,29 @@
#include "ExpressionUnary.h"
#include "Lexer/Token.h"
ExpressionUnary::ExpressionUnary(shared_ptr<Token> token, shared_ptr<Expression> expression):
Expression(ExpressionKind::UNARY, nullptr), expression(expression) {
switch (token->getKind()) {
case TokenKind::PLUS:
operation = ExpressionUnaryOperation::PLUS;
valueType = expression->getValueType();
break;
case TokenKind::MINUS:
operation = ExpressionUnaryOperation::MINUS;
valueType = expression->getValueType();
break;
default:
operation = ExpressionUnaryOperation::INVALID;
valueType = nullptr;
break;
}
}
ExpressionUnaryOperation ExpressionUnary::getOperation() {
return operation;
}
shared_ptr<Expression> ExpressionUnary::getExpression() {
return expression;
}

View File

@@ -0,0 +1,23 @@
#ifndef EXPRESSION_UNARY_H
#define EXPRESSION_UNARY_H
#include "Expression.h"
enum class ExpressionUnaryOperation {
PLUS,
MINUS,
INVALID
};
class ExpressionUnary: public Expression {
private:
ExpressionUnaryOperation operation;
shared_ptr<Expression> expression;
public:
ExpressionUnary(shared_ptr<Token> token, shared_ptr<Expression> expression);
ExpressionUnaryOperation getOperation();
shared_ptr<Expression> getExpression();
};
#endif

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();
@@ -742,8 +756,8 @@ shared_ptr<Expression> Parser::matchPrimary() {
return expression; return expression;
expression = matchExpressionArrayLiteral(); expression = matchExpressionArrayLiteral();
if (expression != nullptr || errors.size() > errorsCount) if (expression != nullptr || errors.size() > errorsCount)
return expression; return expression;
expression = matchExpressionLiteral(); expression = matchExpressionLiteral();
if (expression != nullptr || errors.size() > errorsCount) if (expression != nullptr || errors.size() > errorsCount)
@@ -1052,7 +1066,7 @@ optional<ParseeResult> Parser::valueTypeParseeResult(int index) {
int storedIndex = currentIndex; int storedIndex = currentIndex;
currentIndex = index; currentIndex = index;
shared_ptr<Expression> expressionValue = matchExpressionLiteral(); shared_ptr<Expression> expressionValue = matchExpressionLiteral();
typeArg = dynamic_pointer_cast<ExpressionLiteral>(expressionValue)->getSint32Value(); typeArg = dynamic_pointer_cast<ExpressionLiteral>(expressionValue)->getU32Value();
currentIndex = storedIndex; currentIndex = storedIndex;
index++; index++;
} }

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

View File

@@ -4,8 +4,11 @@
shared_ptr<ValueType> ValueType::NONE = make_shared<ValueType>(ValueTypeKind::NONE, nullptr, 0); shared_ptr<ValueType> ValueType::NONE = make_shared<ValueType>(ValueTypeKind::NONE, nullptr, 0);
shared_ptr<ValueType> ValueType::BOOL = make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0); shared_ptr<ValueType> ValueType::BOOL = make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0);
shared_ptr<ValueType> ValueType::SINT32 = make_shared<ValueType>(ValueTypeKind::SINT32, nullptr, 0); shared_ptr<ValueType> ValueType::U8 = make_shared<ValueType>(ValueTypeKind::U8, nullptr, 0);
shared_ptr<ValueType> ValueType::REAL32 = make_shared<ValueType>(ValueTypeKind::REAL32, nullptr, 0); shared_ptr<ValueType> ValueType::U32 = make_shared<ValueType>(ValueTypeKind::U32, nullptr, 0);
shared_ptr<ValueType> ValueType::S8 = make_shared<ValueType>(ValueTypeKind::S8, nullptr, 0);
shared_ptr<ValueType> ValueType::S32 = make_shared<ValueType>(ValueTypeKind::S32, nullptr, 0);
shared_ptr<ValueType> ValueType::R32 = make_shared<ValueType>(ValueTypeKind::R32, nullptr, 0);
ValueType::ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg): ValueType::ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg):
kind(kind), subType(subType), valueArg(valueArg) { } kind(kind), subType(subType), valueArg(valueArg) { }
@@ -16,10 +19,16 @@ shared_ptr<ValueType> ValueType::valueTypeForToken(shared_ptr<Token> token, shar
string lexme = token->getLexme(); string lexme = token->getLexme();
if (lexme.compare("bool") == 0) if (lexme.compare("bool") == 0)
return make_shared<ValueType>(ValueTypeKind::BOOL, subType, valueArg); return make_shared<ValueType>(ValueTypeKind::BOOL, subType, valueArg);
else if (lexme.compare("sint32") == 0) else if (lexme.compare("u8") == 0)
return make_shared<ValueType>(ValueTypeKind::SINT32, subType, valueArg); return make_shared<ValueType>(ValueTypeKind::U8, subType, valueArg);
else if (lexme.compare("real32") == 0) else if (lexme.compare("u32") == 0)
return make_shared<ValueType>(ValueTypeKind::REAL32, subType, valueArg); return make_shared<ValueType>(ValueTypeKind::U32, subType, valueArg);
else if (lexme.compare("s8") == 0)
return make_shared<ValueType>(ValueTypeKind::S8, subType, valueArg);
else if (lexme.compare("s32") == 0)
return make_shared<ValueType>(ValueTypeKind::S32, subType, valueArg);
else if (lexme.compare("r32") == 0)
return make_shared<ValueType>(ValueTypeKind::R32, subType, valueArg);
else if (lexme.compare("data") == 0) else if (lexme.compare("data") == 0)
return make_shared<ValueType>(ValueTypeKind::DATA, subType, valueArg); return make_shared<ValueType>(ValueTypeKind::DATA, subType, valueArg);
else else
@@ -28,12 +37,13 @@ shared_ptr<ValueType> ValueType::valueTypeForToken(shared_ptr<Token> token, shar
case TokenKind::BOOL: case TokenKind::BOOL:
return make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0); return make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0);
case TokenKind::INTEGER_DEC: case TokenKind::INTEGER_DEC:
return make_shared<ValueType>(ValueTypeKind::S32, nullptr, 0);
case TokenKind::INTEGER_HEX: case TokenKind::INTEGER_HEX:
case TokenKind::INTEGER_BIN: case TokenKind::INTEGER_BIN:
case TokenKind::INTEGER_CHAR: case TokenKind::INTEGER_CHAR:
return make_shared<ValueType>(ValueTypeKind::SINT32, nullptr, 0); return make_shared<ValueType>(ValueTypeKind::U32, nullptr, 0);
case TokenKind::REAL: case TokenKind::REAL:
return make_shared<ValueType>(ValueTypeKind::REAL32, nullptr, 0); return make_shared<ValueType>(ValueTypeKind::R32, nullptr, 0);
default: default:
return nullptr; return nullptr;
} }

View File

@@ -10,8 +10,11 @@ using namespace std;
enum class ValueTypeKind { enum class ValueTypeKind {
NONE, NONE,
BOOL, BOOL,
SINT32, U8,
REAL32, U32,
S8,
S32,
R32,
DATA DATA
}; };
@@ -24,8 +27,11 @@ private:
public: public:
static shared_ptr<ValueType> NONE; static shared_ptr<ValueType> NONE;
static shared_ptr<ValueType> BOOL; static shared_ptr<ValueType> BOOL;
static shared_ptr<ValueType> SINT32; static shared_ptr<ValueType> U8;
static shared_ptr<ValueType> REAL32; static shared_ptr<ValueType> U32;
static shared_ptr<ValueType> S8;
static shared_ptr<ValueType> S32;
static shared_ptr<ValueType> R32;
static shared_ptr<ValueType> valueTypeForToken(shared_ptr<Token> token, shared_ptr<ValueType> subType, int valueArg); static shared_ptr<ValueType> valueTypeForToken(shared_ptr<Token> token, shared_ptr<ValueType> subType, int valueArg);
ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg); ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg);