diff --git a/.gitignore b/.gitignore index 94ff068..b46f74d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +# ingnore files without extension +* +!*.* +!*/ + .DS_Store .vscode/settings.json @@ -7,3 +12,4 @@ build/ # brb build artifiacts *.o +*.asm \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 0fc81a3..99f9dd4 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -3,12 +3,17 @@ "tasks": [ { "label": "Build Bits Runner Builder (Debug)", - "type": "cmake", - "command": "build", + "type": "shell", + "command": "cmake -B build && cmake --build build --config Debug", "group": { "kind": "build", "isDefault": true } + }, + { + "label": "Clean", + "type": "shell", + "command": "rm -rf build *.o *.asm; find ./ -perm +100 -type f -maxdepth 1 -delete" } ] } \ No newline at end of file diff --git a/samples/fib.brc b/samples/fib.brc index 11fd516..9835c85 100644 --- a/samples/fib.brc +++ b/samples/fib.brc @@ -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: number else @@ -8,13 +8,13 @@ fib fun: number sint32 -> sint32 ; ; -printNum fun: number sint32 - biggest sint32 <- 10 +printNum fun: number u32 + biggest u32 <- 10 rep biggest <= number: biggest <- biggest * 10 biggest <- biggest / 10 rep biggest > 0: - digit sint32 <- number / biggest + digit u32 <- number / biggest putchar(digit + '0') number <- number % biggest biggest <- biggest / 10 @@ -22,9 +22,9 @@ printNum fun: number sint32 ; // Print first 20 fibonaci numbers -main fun -> sint32 - rep i sint32 <- 0, i < 20: - res sint32 <- fib(i) +main fun -> u32 + rep i u32 <- 0, i < 20: + res u32 <- fib(i) printNum(res) putchar('\n') i <- i + 1 diff --git a/samples/hello.brc b/samples/hello.brc index b8fa9d7..e93c560 100644 --- a/samples/hello.brc +++ b/samples/hello.brc @@ -1,9 +1,9 @@ -@extern putchar fun: character sint32 -> sint32 +@extern putchar fun: character u32 -> u32 -main fun -> sint32 - text data <- "Hello, world!\n" +main fun -> u32 + text data <- "Hello, world!\n" - rep i sint32 <- 0, text[i] != 0: + rep i u32 <- 0, text[i] != 0: putchar(text[i]) i <- i + 1 ; diff --git a/samples/test.brc b/samples/test.brc index 21321d7..baa3e8f 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -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 @@ -28,10 +28,10 @@ i u32 <- 0, rep text[i] != 0: 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 mov $0, $1 -; +;*/ /*rawAdd raw: num1 sint32, num2 sint32 -> sint32 add $1, $2 @@ -48,13 +48,14 @@ rawAdd raw<"=r,r,r">: num1 sint32, num2 sint32 -> sint32 ;*/ -main fun -> sint32 - /*a sint32 <- 4 - b sint32 <- 5 +main fun -> u32 + num1 u8 <- 42 + num2 s8 <- 3 - +15 + num3 u32 <- 1234123 + num4 s32 <- -345345 + num5 r32 <- -42.58 - res sint32 <- rawAdd(4, 5)*/ - putchar('@') - putchar('\n') + num5 + num3 ret 0 ; \ No newline at end of file diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 525652c..4fdd0d8 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -11,6 +11,7 @@ #include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionIfElse.h" #include "Parser/Expression/ExpressionBinary.h" +#include "Parser/Expression/ExpressionUnary.h" #include "Parser/Expression/ExpressionBlock.h" #include "Parser/Statement/StatementFunction.h" @@ -32,8 +33,11 @@ moduleName(moduleName), sourceFileName(sourceFileName), statements(statements) { typeVoid = llvm::Type::getVoidTy(*context); typeBool = llvm::Type::getInt1Ty(*context); - typeSint32 = llvm::Type::getInt32Ty(*context); - typeReal32 = llvm::Type::getFloatTy(*context); + typeU8 = llvm::Type::getInt8Ty(*context); + typeU32 = llvm::Type::getInt32Ty(*context); + typeS8 = llvm::Type::getInt8Ty(*context); + typeS32 = llvm::Type::getInt32Ty(*context); + typeR32 = llvm::Type::getFloatTy(*context); } shared_ptr ModuleBuilder::getModule() { @@ -93,9 +97,15 @@ void ModuleBuilder::buildStatement(shared_ptr statement) { void ModuleBuilder::buildFunction(shared_ptr statement) { // function types llvm::Type *returnType = typeForValueType(statement->getReturnValueType()); + if (returnType == nullptr) + return; vector argTypes; - for (pair> &arg : statement->getArguments()) - argTypes.push_back(typeForValueType(arg.second)); + for (pair> &arg : statement->getArguments()) { + llvm::Type *argType = typeForValueType(arg.second); + if (argType == nullptr) + return; + argTypes.push_back(argType); + } // build function declaration llvm::FunctionType *funType = llvm::FunctionType::get(returnType, argTypes, false); @@ -169,6 +179,8 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr statement) } } else { llvm::Value *value = valueForExpression(statement->getExpression()); + if (value == nullptr) + return; llvm::AllocaInst *alloca = builder->CreateAlloca(typeForValueType(statement->getValueType(), 0), nullptr, statement->getName()); if (!setAlloca(statement->getName(), alloca)) @@ -268,7 +280,10 @@ void ModuleBuilder::buildMetaExternFunction(shared_ptrgetReturnValueType()), 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()); if (!setFun(statement->getName(), fun)) return; @@ -294,6 +309,8 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr expression return valueForExpression(dynamic_pointer_cast(expression)->getExpression()); case ExpressionKind::BINARY: return valueForBinary(dynamic_pointer_cast(expression)); + case ExpressionKind::UNARY: + return valueForUnary(dynamic_pointer_cast(expression)); case ExpressionKind::IF_ELSE: return valueForIfElse(dynamic_pointer_cast(expression)); case ExpressionKind::VAR: @@ -325,10 +342,16 @@ llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr expres return llvm::UndefValue::get(typeVoid); case ValueTypeKind::BOOL: return llvm::ConstantInt::get(typeBool, expression->getBoolValue(), true); - case ValueTypeKind::SINT32: - return llvm::ConstantInt::get(typeSint32, expression->getSint32Value(), true); - case ValueTypeKind::REAL32: - return llvm::ConstantInt::get(typeReal32, expression->getReal32Value(), true); + case ValueTypeKind::U8: + return llvm::ConstantInt::get(typeU8, expression->getU8Value(), true); + case ValueTypeKind::U32: + 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 expressi if (type == typeBool) { return valueForBinaryBool(expression->getOperation(), leftValue, rightValue); - } else if (type == typeSint32 || type == typeVoid) { - return valueForBinaryInteger(expression->getOperation(), leftValue, rightValue); - } else if (type == typeReal32) { + } else if (type == typeU8 || type == typeU32) { + return valueForBinaryUnsignedInteger(expression->getOperation(), leftValue, rightValue); + } else if (type == typeS8 || type == typeS32) { + return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue); + } else if (type == typeR32) { return valueForBinaryReal(expression->getOperation(), leftValue, rightValue); } @@ -372,35 +397,62 @@ llvm::Value *ModuleBuilder::valueForBinaryBool(ExpressionBinaryOperation operati case ExpressionBinaryOperation::NOT_EQUAL: return builder->CreateICmpNE(leftValue, rightValue); default: - markError(0, 0, "Unexpecgted operation for boolean operands"); + markError(0, 0, "Unexpected operation for boolean operands"); 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) { - 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); + 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->CreateNUWAdd(leftValue, rightValue); + case ExpressionBinaryOperation::SUB: + return builder->CreateNUWSub(leftValue, rightValue); + case ExpressionBinaryOperation::MUL: + return builder->CreateNUWMul(leftValue, rightValue); + case ExpressionBinaryOperation::DIV: + return builder->CreateUDiv(leftValue, rightValue); + case ExpressionBinaryOperation::MOD: + 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 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 expression) { shared_ptr conditionExpression = expression->getCondition(); @@ -600,22 +672,32 @@ llvm::InlineAsm *ModuleBuilder::getRawFun(string name) { } llvm::Type *ModuleBuilder::typeForValueType(shared_ptr valueType, int count) { + if (valueType == nullptr) { + markError(0, 0, "Missing type"); + return nullptr; + } + switch (valueType->getKind()) { case ValueTypeKind::NONE: return typeVoid; case ValueTypeKind::BOOL: return typeBool; - case ValueTypeKind::SINT32: - return typeSint32; - case ValueTypeKind::REAL32: - return typeReal32; + case ValueTypeKind::U8: + return typeU8; + case ValueTypeKind::U32: + return typeU32; + case ValueTypeKind::S8: + return typeS8; + case ValueTypeKind::S32: + return typeS32; + case ValueTypeKind::R32: + return typeR32; case ValueTypeKind::DATA: { if (valueType->getSubType() == nullptr) return nullptr; if (valueType->getValueArg() > 0) count = valueType->getValueArg(); return llvm::ArrayType::get(typeForValueType(valueType->getSubType(), count), count); - return nullptr; } } } diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index 3378856..872b4ad 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -23,6 +23,7 @@ class ExpressionVariable; class ExpressionCall; class ExpressionIfElse; class ExpressionBinary; +class ExpressionUnary; enum class ExpressionBinaryOperation; class Statement; @@ -56,8 +57,11 @@ private: llvm::Type *typeVoid; llvm::Type *typeBool; - llvm::IntegerType *typeSint32; - llvm::Type *typeReal32; + llvm::IntegerType *typeU8; + llvm::IntegerType *typeU32; + llvm::IntegerType *typeS8; + llvm::IntegerType *typeS32; + llvm::Type *typeR32; vector> statements; stack scopes; @@ -80,8 +84,10 @@ private: llvm::Value *valueForGrouping(shared_ptr expression); llvm::Value *valueForBinary(shared_ptr expression); 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 *valueForUnary(shared_ptr expression); llvm::Value *valueForIfElse(shared_ptr expression); llvm::Value *valueForVar(shared_ptr expression); llvm::Value *valueForCall(shared_ptr expression); diff --git a/src/Lexer/Token.cpp b/src/Lexer/Token.cpp index 5fcc1df..2adddfe 100644 --- a/src/Lexer/Token.cpp +++ b/src/Lexer/Token.cpp @@ -4,21 +4,30 @@ vector Token::tokensEquality = { TokenKind::EQUAL, TokenKind::NOT_EQUAL }; + vector Token::tokensComparison = { TokenKind::LESS, TokenKind::LESS_EQUAL, TokenKind::GREATER, TokenKind::GREATER_EQUAL }; + vector Token::tokensTerm = { TokenKind::PLUS, TokenKind::MINUS }; + vector Token::tokensFactor = { TokenKind::STAR, TokenKind::SLASH, TokenKind::PERCENT }; + +vector Token::tokensUnary = { + TokenKind::PLUS, + TokenKind::MINUS +}; + vector Token::tokensBinary = { TokenKind::EQUAL, TokenKind::NOT_EQUAL, @@ -35,6 +44,7 @@ vector Token::tokensBinary = { TokenKind::SLASH, TokenKind::PERCENT }; + vector Token::tokensLiteral = { TokenKind::BOOL, TokenKind::INTEGER_DEC, diff --git a/src/Lexer/Token.h b/src/Lexer/Token.h index c6ee86a..4b1ab57 100644 --- a/src/Lexer/Token.h +++ b/src/Lexer/Token.h @@ -65,6 +65,7 @@ public: static vector tokensComparison; static vector tokensTerm; static vector tokensFactor; + static vector tokensUnary; static vector tokensBinary; static vector tokensLiteral; diff --git a/src/Logger.cpp b/src/Logger.cpp index 98dd04e..d5ca83d 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -20,6 +20,7 @@ #include "Parser/Expression/Expression.h" #include "Parser/Expression/ExpressionBinary.h" +#include "Parser/Expression/ExpressionUnary.h" #include "Parser/Expression/ExpressionIfElse.h" #include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionGrouping.h" @@ -202,15 +203,24 @@ string Logger::toString(TokenKind tokenKind) { } string Logger::toString(shared_ptr valueType) { + if (valueType == nullptr) + return "{INVALID}"; + switch (valueType->getKind()) { case ValueTypeKind::NONE: return "NONE"; case ValueTypeKind::BOOL: return "BOOL"; - case ValueTypeKind::SINT32: - return "SINT32"; - case ValueTypeKind::REAL32: - return "REAL32"; + case ValueTypeKind::U8: + return "U8"; + case ValueTypeKind::U32: + return "U32"; + case ValueTypeKind::S8: + return "S8"; + case ValueTypeKind::S32: + return "S32"; + case ValueTypeKind::R32: + return "R32"; case ValueTypeKind::DATA: return "[]"; } @@ -338,7 +348,9 @@ string Logger::toString(shared_ptr statement) { string Logger::toString(shared_ptr expression) { switch (expression->getKind()) { case ExpressionKind::BINARY: - return toString(dynamic_pointer_cast(expression)); + return toString(dynamic_pointer_cast(expression)); + case ExpressionKind::UNARY: + return toString(dynamic_pointer_cast(expression)); case ExpressionKind::IF_ELSE: return toString(dynamic_pointer_cast(expression)); case ExpressionKind::VAR: @@ -385,6 +397,17 @@ string Logger::toString(shared_ptr expression) { } } +string Logger::toString(shared_ptr 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 expression) { string text; @@ -420,10 +443,16 @@ string Logger::toString(shared_ptr expression) { return "NONE"; case ValueTypeKind::BOOL: return expression->getBoolValue() ? "true" : "false"; - case ValueTypeKind::SINT32: - return to_string(expression->getSint32Value()); - case ValueTypeKind::REAL32: - return to_string(expression->getReal32Value()); + case ValueTypeKind::U8: + return to_string(expression->getU8Value()); + case ValueTypeKind::U32: + 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: return "?"; } diff --git a/src/Logger.h b/src/Logger.h index 3101911..72e6746 100644 --- a/src/Logger.h +++ b/src/Logger.h @@ -20,6 +20,7 @@ class StatementExpression; class Expression; class ExpressionBinary; +class ExpressionUnary; class ExpressionIfElse; class ExpressionVariable; class ExpressionGrouping; @@ -51,6 +52,7 @@ private: static string toString(shared_ptr expression); static string toString(shared_ptr expression); + static string toString(shared_ptr expression); static string toString(shared_ptr expression); static string toString(shared_ptr expression); static string toString(shared_ptr expression); diff --git a/src/Parser/Expression/Expression.h b/src/Parser/Expression/Expression.h index 66bd170..a335052 100644 --- a/src/Parser/Expression/Expression.h +++ b/src/Parser/Expression/Expression.h @@ -12,6 +12,7 @@ enum class ExpressionKind { LITERAL, ARRAY_LITERAL, GROUPING, + UNARY, BINARY, IF_ELSE, VAR, diff --git a/src/Parser/Expression/ExpressionBinary.h b/src/Parser/Expression/ExpressionBinary.h index 0c5bb4c..56b31fa 100644 --- a/src/Parser/Expression/ExpressionBinary.h +++ b/src/Parser/Expression/ExpressionBinary.h @@ -1,4 +1,7 @@ -#include "Parser/Expression/Expression.h" +#ifndef EXPRESSION_BINARY_H +#define EXPRESSION_BINARY_H + +#include "Expression.h" enum class ExpressionBinaryOperation { EQUAL, @@ -26,4 +29,6 @@ public: ExpressionBinaryOperation getOperation(); shared_ptr getLeft(); shared_ptr getRight(); -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionLiteral.cpp b/src/Parser/Expression/ExpressionLiteral.cpp index 648046e..4675d40 100644 --- a/src/Parser/Expression/ExpressionLiteral.cpp +++ b/src/Parser/Expression/ExpressionLiteral.cpp @@ -15,14 +15,14 @@ shared_ptr ExpressionLiteral::expressionLiteralForToken(share case TokenKind::INTEGER_DEC: { string numString = token->getLexme(); erase(numString, '_'); - expression->sint32Value = stoi(numString, nullptr, 10); + expression->s32Value = stoi(numString, nullptr, 10); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); break; } case TokenKind::INTEGER_HEX: { string numString = token->getLexme(); erase(numString, '_'); - expression->sint32Value = stoi(numString, nullptr, 16); + expression->u32Value = stoul(numString, nullptr, 16); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); break; } @@ -30,7 +30,7 @@ shared_ptr ExpressionLiteral::expressionLiteralForToken(share string numString = token->getLexme(); erase(numString, '_'); 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); break; } @@ -41,13 +41,14 @@ shared_ptr ExpressionLiteral::expressionLiteralForToken(share return nullptr; expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); - expression->sint32Value = *charValue; + expression->u32Value = *charValue; return expression; } - case TokenKind::REAL: - expression->real32Value = stof(token->getLexme()); + case TokenKind::REAL: { + expression->r32Value = stof(token->getLexme()); expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0); break; + } default: return nullptr; } @@ -62,10 +63,22 @@ bool ExpressionLiteral::getBoolValue() { return boolValue; } -int32_t ExpressionLiteral::getSint32Value() { - return sint32Value; +uint8_t ExpressionLiteral::getU8Value() { + return u8Value; } -float ExpressionLiteral::getReal32Value() { - return real32Value; +uint32_t ExpressionLiteral::getU32Value() { + return u32Value; +} + +int8_t ExpressionLiteral::getS8Value() { + return s8Value; +} + +int32_t ExpressionLiteral::getS32Value() { + return s32Value; +} + +float ExpressionLiteral::getR32Value() { + return r32Value; } diff --git a/src/Parser/Expression/ExpressionLiteral.h b/src/Parser/Expression/ExpressionLiteral.h index 89b545e..89b8bf4 100644 --- a/src/Parser/Expression/ExpressionLiteral.h +++ b/src/Parser/Expression/ExpressionLiteral.h @@ -6,16 +6,22 @@ class ExpressionLiteral: public Expression { private: bool boolValue; - int32_t sint32Value; - float real32Value; + uint8_t u8Value; + uint32_t u32Value; + int8_t s8Value; + int32_t s32Value; + float r32Value; public: static shared_ptr expressionLiteralForToken(shared_ptr token); ExpressionLiteral(); bool getBoolValue(); - int32_t getSint32Value(); - float getReal32Value(); + uint8_t getU8Value(); + uint32_t getU32Value(); + int8_t getS8Value(); + int32_t getS32Value(); + float getR32Value(); }; #endif \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionUnary.cpp b/src/Parser/Expression/ExpressionUnary.cpp new file mode 100644 index 0000000..ddc570d --- /dev/null +++ b/src/Parser/Expression/ExpressionUnary.cpp @@ -0,0 +1,29 @@ +#include "ExpressionUnary.h" + +#include "Lexer/Token.h" + +ExpressionUnary::ExpressionUnary(shared_ptr token, shared_ptr 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 ExpressionUnary::getExpression() { + return expression; +} \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionUnary.h b/src/Parser/Expression/ExpressionUnary.h new file mode 100644 index 0000000..2ba56fd --- /dev/null +++ b/src/Parser/Expression/ExpressionUnary.h @@ -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; + +public: + ExpressionUnary(shared_ptr token, shared_ptr expression); + ExpressionUnaryOperation getOperation(); + shared_ptr getExpression(); +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 0db1a3d..bdf291f 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -12,6 +12,7 @@ #include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionIfElse.h" +#include "Parser/Expression/ExpressionUnary.h" #include "Parser/Expression/ExpressionBinary.h" #include "Parser/Expression/ExpressionBlock.h" @@ -723,7 +724,7 @@ shared_ptr Parser::matchTerm() { } shared_ptr Parser::matchFactor() { - shared_ptr expression = matchPrimary(); + shared_ptr expression = matchUnary(); if (expression == nullptr) return nullptr; @@ -733,6 +734,19 @@ shared_ptr Parser::matchFactor() { return expression; } +shared_ptr Parser::matchUnary() { + shared_ptr token = tokens.at(currentIndex); + + if (tryMatchingTokenKinds(Token::tokensUnary, false, true)) { + shared_ptr expression = matchPrimary(); + if (expression == nullptr) + return nullptr; + return make_shared(token, expression); + } + + return matchPrimary(); +} + shared_ptr Parser::matchPrimary() { shared_ptr expression; int errorsCount = errors.size(); @@ -742,8 +756,8 @@ shared_ptr Parser::matchPrimary() { return expression; expression = matchExpressionArrayLiteral(); - if (expression != nullptr || errors.size() > errorsCount) - return expression; + if (expression != nullptr || errors.size() > errorsCount) + return expression; expression = matchExpressionLiteral(); if (expression != nullptr || errors.size() > errorsCount) @@ -1052,7 +1066,7 @@ optional Parser::valueTypeParseeResult(int index) { int storedIndex = currentIndex; currentIndex = index; shared_ptr expressionValue = matchExpressionLiteral(); - typeArg = dynamic_pointer_cast(expressionValue)->getSint32Value(); + typeArg = dynamic_pointer_cast(expressionValue)->getU32Value(); currentIndex = storedIndex; index++; } diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 8e5a8d5..0e27960 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -43,7 +43,8 @@ private: shared_ptr matchComparison(); // <, <=, >, >= shared_ptr matchTerm(); // +, - shared_ptr matchFactor(); // *, /, % - shared_ptr matchPrimary(); // integer, () + shared_ptr matchUnary(); // +, - + shared_ptr matchPrimary(); // literal, () shared_ptr matchExpressionGrouping(); shared_ptr matchExpressionLiteral(); diff --git a/src/Parser/ValueType.cpp b/src/Parser/ValueType.cpp index 6f5945d..566342b 100644 --- a/src/Parser/ValueType.cpp +++ b/src/Parser/ValueType.cpp @@ -4,8 +4,11 @@ shared_ptr ValueType::NONE = make_shared(ValueTypeKind::NONE, nullptr, 0); shared_ptr ValueType::BOOL = make_shared(ValueTypeKind::BOOL, nullptr, 0); -shared_ptr ValueType::SINT32 = make_shared(ValueTypeKind::SINT32, nullptr, 0); -shared_ptr ValueType::REAL32 = make_shared(ValueTypeKind::REAL32, nullptr, 0); +shared_ptr ValueType::U8 = make_shared(ValueTypeKind::U8, nullptr, 0); +shared_ptr ValueType::U32 = make_shared(ValueTypeKind::U32, nullptr, 0); +shared_ptr ValueType::S8 = make_shared(ValueTypeKind::S8, nullptr, 0); +shared_ptr ValueType::S32 = make_shared(ValueTypeKind::S32, nullptr, 0); +shared_ptr ValueType::R32 = make_shared(ValueTypeKind::R32, nullptr, 0); ValueType::ValueType(ValueTypeKind kind, shared_ptr subType, int valueArg): kind(kind), subType(subType), valueArg(valueArg) { } @@ -16,10 +19,16 @@ shared_ptr ValueType::valueTypeForToken(shared_ptr token, shar string lexme = token->getLexme(); if (lexme.compare("bool") == 0) return make_shared(ValueTypeKind::BOOL, subType, valueArg); - else if (lexme.compare("sint32") == 0) - return make_shared(ValueTypeKind::SINT32, subType, valueArg); - else if (lexme.compare("real32") == 0) - return make_shared(ValueTypeKind::REAL32, subType, valueArg); + else if (lexme.compare("u8") == 0) + return make_shared(ValueTypeKind::U8, subType, valueArg); + else if (lexme.compare("u32") == 0) + return make_shared(ValueTypeKind::U32, subType, valueArg); + else if (lexme.compare("s8") == 0) + return make_shared(ValueTypeKind::S8, subType, valueArg); + else if (lexme.compare("s32") == 0) + return make_shared(ValueTypeKind::S32, subType, valueArg); + else if (lexme.compare("r32") == 0) + return make_shared(ValueTypeKind::R32, subType, valueArg); else if (lexme.compare("data") == 0) return make_shared(ValueTypeKind::DATA, subType, valueArg); else @@ -28,12 +37,13 @@ shared_ptr ValueType::valueTypeForToken(shared_ptr token, shar case TokenKind::BOOL: return make_shared(ValueTypeKind::BOOL, nullptr, 0); case TokenKind::INTEGER_DEC: + return make_shared(ValueTypeKind::S32, nullptr, 0); case TokenKind::INTEGER_HEX: case TokenKind::INTEGER_BIN: case TokenKind::INTEGER_CHAR: - return make_shared(ValueTypeKind::SINT32, nullptr, 0); + return make_shared(ValueTypeKind::U32, nullptr, 0); case TokenKind::REAL: - return make_shared(ValueTypeKind::REAL32, nullptr, 0); + return make_shared(ValueTypeKind::R32, nullptr, 0); default: return nullptr; } diff --git a/src/Parser/ValueType.h b/src/Parser/ValueType.h index ce118eb..2b77f2f 100644 --- a/src/Parser/ValueType.h +++ b/src/Parser/ValueType.h @@ -10,8 +10,11 @@ using namespace std; enum class ValueTypeKind { NONE, BOOL, - SINT32, - REAL32, + U8, + U32, + S8, + S32, + R32, DATA }; @@ -24,8 +27,11 @@ private: public: static shared_ptr NONE; static shared_ptr BOOL; - static shared_ptr SINT32; - static shared_ptr REAL32; + static shared_ptr U8; + static shared_ptr U32; + static shared_ptr S8; + static shared_ptr S32; + static shared_ptr R32; static shared_ptr valueTypeForToken(shared_ptr token, shared_ptr subType, int valueArg); ValueType(ValueTypeKind kind, shared_ptr subType, int valueArg);