Merge pull request #25 from rafalgrodzinski/22-support-arrays
Support arrays
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,6 +1,9 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
*.o
|
|
||||||
brb
|
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
|
|
||||||
|
# project build artifacts
|
||||||
*.dSYM
|
*.dSYM
|
||||||
build/
|
build/
|
||||||
|
|
||||||
|
# brb build artifiacts
|
||||||
|
*.o
|
||||||
|
|||||||
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -6,7 +6,7 @@
|
|||||||
"type": "lldb-dap",
|
"type": "lldb-dap",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${command:cmake.launchTargetPath}",
|
"program": "${command:cmake.launchTargetPath}",
|
||||||
"args": ["-v", "${workspaceFolder}/test.brc"],
|
"args": ["-v", "${workspaceFolder}/samples/hello.brc"],
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"internalConsoleOptions": "openOnSessionStart",
|
"internalConsoleOptions": "openOnSessionStart",
|
||||||
}
|
}
|
||||||
|
|||||||
12
samples/hello.brc
Normal file
12
samples/hello.brc
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
@extern putchar fun: character sint32 -> sint32
|
||||||
|
|
||||||
|
main fun -> sint32
|
||||||
|
text data<sint32> <- "Hello, world!\n"
|
||||||
|
|
||||||
|
rep i sint32 <- 0, text[i] != 0:
|
||||||
|
putchar(text[i])
|
||||||
|
i <- i + 1
|
||||||
|
;
|
||||||
|
|
||||||
|
ret 0
|
||||||
|
;
|
||||||
25
samples/test.brc
Normal file
25
samples/test.brc
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
@extern putchar fun: character sint32 -> sint32
|
||||||
|
|
||||||
|
/*
|
||||||
|
User type
|
||||||
|
name data<u8, 32>
|
||||||
|
age u32
|
||||||
|
successRatio r32
|
||||||
|
isActive bool
|
||||||
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
i u32 <- 0, rep text[i] != 0:
|
||||||
|
putchar(text[i])
|
||||||
|
i++
|
||||||
|
;
|
||||||
|
*/
|
||||||
|
|
||||||
|
// text data<u8> <- "Hello world!"
|
||||||
|
|
||||||
|
main fun -> sint32
|
||||||
|
text data<sint32> <- "Hello string!\n"
|
||||||
|
|
||||||
|
ret 0
|
||||||
|
;
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "Parser/Expression/ExpressionGrouping.h"
|
#include "Parser/Expression/ExpressionGrouping.h"
|
||||||
#include "Parser/Expression/ExpressionLiteral.h"
|
#include "Parser/Expression/ExpressionLiteral.h"
|
||||||
|
#include "Parser/Expression/ExpressionArrayLiteral.h"
|
||||||
#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"
|
||||||
@@ -126,12 +127,30 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr<StatementFunction> state
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement) {
|
void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement) {
|
||||||
llvm::Value *value = valueForExpression(statement->getExpression());
|
if (statement->getValueType()->getKind() == ValueTypeKind::DATA) {
|
||||||
llvm::AllocaInst *alloca = builder->CreateAlloca(typeForValueType(statement->getValueType()), nullptr, statement->getName());
|
vector<llvm::Value *> values = valuesForExpression(statement->getExpression());
|
||||||
|
|
||||||
if (!setAlloca(statement->getName(), alloca))
|
llvm::ArrayType *type = (llvm::ArrayType *)typeForValueType(statement->getValueType(), values.size());
|
||||||
return;
|
llvm::AllocaInst *alloca = builder->CreateAlloca(type, nullptr, statement->getName());
|
||||||
builder->CreateStore(value, alloca);
|
if (!setAlloca(statement->getName(), alloca))
|
||||||
|
return;
|
||||||
|
for (int i=0; i < type->getNumElements(); i++) {
|
||||||
|
llvm::Value *index[] = {
|
||||||
|
builder->getInt32(0),
|
||||||
|
builder->getInt32(i)
|
||||||
|
};
|
||||||
|
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}_{}", statement->getName(), i));
|
||||||
|
|
||||||
|
builder->CreateStore(values[i], elementPtr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
llvm::Value *value = valueForExpression(statement->getExpression());
|
||||||
|
llvm::AllocaInst *alloca = builder->CreateAlloca(typeForValueType(statement->getValueType(), 0), nullptr, statement->getName());
|
||||||
|
|
||||||
|
if (!setAlloca(statement->getName(), alloca))
|
||||||
|
return;
|
||||||
|
builder->CreateStore(value, alloca);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleBuilder::buildAssignment(shared_ptr<StatementAssignment> statement) {
|
void ModuleBuilder::buildAssignment(shared_ptr<StatementAssignment> statement) {
|
||||||
@@ -140,7 +159,20 @@ void ModuleBuilder::buildAssignment(shared_ptr<StatementAssignment> statement) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
llvm::Value *value = valueForExpression(statement->getExpression());
|
llvm::Value *value = valueForExpression(statement->getExpression());
|
||||||
builder->CreateStore(value, alloca);
|
|
||||||
|
if (statement->getIndexExpression()) {
|
||||||
|
llvm::Value *indexValue = valueForExpression(statement->getIndexExpression());
|
||||||
|
llvm::Value *index[] = {
|
||||||
|
builder->getInt32(0),
|
||||||
|
indexValue
|
||||||
|
};
|
||||||
|
llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType();
|
||||||
|
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", statement->getName()));
|
||||||
|
|
||||||
|
builder->CreateStore(value, elementPtr);
|
||||||
|
} else {
|
||||||
|
builder->CreateStore(value, alloca);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleBuilder::buildBlock(shared_ptr<StatementBlock> statement) {
|
void ModuleBuilder::buildBlock(shared_ptr<StatementBlock> statement) {
|
||||||
@@ -250,6 +282,16 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<llvm::Value*> ModuleBuilder::valuesForExpression(shared_ptr<Expression> expression) {
|
||||||
|
switch (expression->getKind()) {
|
||||||
|
case ExpressionKind::ARRAY_LITERAL:
|
||||||
|
return valuesForArrayLiteral(dynamic_pointer_cast<ExpressionArrayLiteral>(expression));
|
||||||
|
default:
|
||||||
|
markError(0, 0, "Unexpected expression");
|
||||||
|
return vector<llvm::Value*>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr<ExpressionLiteral> expression) {
|
llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr<ExpressionLiteral> expression) {
|
||||||
if (expression->getValueType() == nullptr)
|
if (expression->getValueType() == nullptr)
|
||||||
return llvm::UndefValue::get(typeVoid);
|
return llvm::UndefValue::get(typeVoid);
|
||||||
@@ -266,6 +308,14 @@ llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr<ExpressionLiteral> expres
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<llvm::Value*> ModuleBuilder::valuesForArrayLiteral(shared_ptr<ExpressionArrayLiteral> expression) {
|
||||||
|
vector<llvm::Value*> values;
|
||||||
|
for (shared_ptr<Expression> &expression : expression->getExpressions()) {
|
||||||
|
values.push_back(valueForExpression(expression));
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
llvm::Value *ModuleBuilder::valueForGrouping(shared_ptr<ExpressionGrouping> expression) {
|
llvm::Value *ModuleBuilder::valueForGrouping(shared_ptr<ExpressionGrouping> expression) {
|
||||||
return valueForExpression(expression->getExpression());
|
return valueForExpression(expression->getExpression());
|
||||||
}
|
}
|
||||||
@@ -274,6 +324,9 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> expressi
|
|||||||
llvm::Value *leftValue = valueForExpression(expression->getLeft());
|
llvm::Value *leftValue = valueForExpression(expression->getLeft());
|
||||||
llvm::Value *rightValue = valueForExpression(expression->getRight());
|
llvm::Value *rightValue = valueForExpression(expression->getRight());
|
||||||
|
|
||||||
|
if (leftValue == nullptr || rightValue == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
llvm::Type *type = leftValue->getType();
|
llvm::Type *type = leftValue->getType();
|
||||||
|
|
||||||
if (type == typeBool) {
|
if (type == typeBool) {
|
||||||
@@ -411,7 +464,19 @@ llvm::Value *ModuleBuilder::valueForVar(shared_ptr<ExpressionVariable> expressio
|
|||||||
if (alloca == nullptr)
|
if (alloca == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName());
|
if (expression->getIndexExpression()) {
|
||||||
|
llvm::Value *indexValue = valueForExpression(expression->getIndexExpression());
|
||||||
|
llvm::Value *index[] = {
|
||||||
|
builder->getInt32(0),
|
||||||
|
indexValue
|
||||||
|
};
|
||||||
|
llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType();
|
||||||
|
llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", expression->getName()));
|
||||||
|
|
||||||
|
return builder->CreateLoad(type->getArrayElementType(), elementPtr);
|
||||||
|
} else {
|
||||||
|
return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression) {
|
llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression) {
|
||||||
@@ -475,7 +540,7 @@ llvm::Function* ModuleBuilder::getFun(string name) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType) {
|
llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType, int count) {
|
||||||
switch (valueType->getKind()) {
|
switch (valueType->getKind()) {
|
||||||
case ValueTypeKind::NONE:
|
case ValueTypeKind::NONE:
|
||||||
return typeVoid;
|
return typeVoid;
|
||||||
@@ -485,6 +550,14 @@ llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType) {
|
|||||||
return typeSint32;
|
return typeSint32;
|
||||||
case ValueTypeKind::REAL32:
|
case ValueTypeKind::REAL32:
|
||||||
return typeReal32;
|
return typeReal32;
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class ValueType;
|
|||||||
class Expression;
|
class Expression;
|
||||||
class ExpressionGrouping;
|
class ExpressionGrouping;
|
||||||
class ExpressionLiteral;
|
class ExpressionLiteral;
|
||||||
|
class ExpressionArrayLiteral;
|
||||||
class ExpressionVariable;
|
class ExpressionVariable;
|
||||||
class ExpressionCall;
|
class ExpressionCall;
|
||||||
class ExpressionIfElse;
|
class ExpressionIfElse;
|
||||||
@@ -69,7 +70,9 @@ private:
|
|||||||
void buildExpression(shared_ptr<StatementExpression> statement);
|
void buildExpression(shared_ptr<StatementExpression> statement);
|
||||||
|
|
||||||
llvm::Value *valueForExpression(shared_ptr<Expression> expression);
|
llvm::Value *valueForExpression(shared_ptr<Expression> expression);
|
||||||
|
vector<llvm::Value*> valuesForExpression(shared_ptr<Expression> expression);
|
||||||
llvm::Value *valueForLiteral(shared_ptr<ExpressionLiteral> expression);
|
llvm::Value *valueForLiteral(shared_ptr<ExpressionLiteral> expression);
|
||||||
|
vector<llvm::Value*> valuesForArrayLiteral(shared_ptr<ExpressionArrayLiteral> expression);
|
||||||
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);
|
||||||
@@ -85,7 +88,7 @@ private:
|
|||||||
bool setFun(string name, llvm::Function *fun);
|
bool setFun(string name, llvm::Function *fun);
|
||||||
llvm::Function *getFun(string name);
|
llvm::Function *getFun(string name);
|
||||||
|
|
||||||
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType);
|
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType, int count = 0);
|
||||||
|
|
||||||
void markError(int line, int column, string message);
|
void markError(int line, int column, string message);
|
||||||
|
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ vector<shared_ptr<Token>> Lexer::getTokens() {
|
|||||||
currentLine = 0;
|
currentLine = 0;
|
||||||
currentColumn = 0;
|
currentColumn = 0;
|
||||||
|
|
||||||
|
tokens.clear();
|
||||||
errors.clear();
|
errors.clear();
|
||||||
|
|
||||||
vector<shared_ptr<Token>> tokens;
|
|
||||||
shared_ptr<Token> token;
|
shared_ptr<Token> token;
|
||||||
do {
|
do {
|
||||||
token = nextToken();
|
token = nextToken();
|
||||||
@@ -126,6 +126,14 @@ shared_ptr<Token> Lexer::nextToken() {
|
|||||||
if (token != nullptr)
|
if (token != nullptr)
|
||||||
return token;
|
return token;
|
||||||
|
|
||||||
|
token = match(TokenKind::LEFT_SQUARE_BRACKET, "[", false);
|
||||||
|
if (token != nullptr)
|
||||||
|
return token;
|
||||||
|
|
||||||
|
token = match(TokenKind::RIGHT_SQUARE_BRACKET, "]", false);
|
||||||
|
if (token != nullptr)
|
||||||
|
return token;
|
||||||
|
|
||||||
token = match(TokenKind::COMMA, ",", false);
|
token = match(TokenKind::COMMA, ",", false);
|
||||||
if (token != nullptr)
|
if (token != nullptr)
|
||||||
return token;
|
return token;
|
||||||
@@ -242,16 +250,12 @@ shared_ptr<Token> Lexer::nextToken() {
|
|||||||
if (token != nullptr)
|
if (token != nullptr)
|
||||||
return token;
|
return token;
|
||||||
|
|
||||||
|
token = matchString();
|
||||||
|
if (token != nullptr)
|
||||||
|
return token;
|
||||||
|
|
||||||
// type
|
// type
|
||||||
token = match(TokenKind::TYPE, "bool", true);
|
token = matchType();
|
||||||
if (token != nullptr)
|
|
||||||
return token;
|
|
||||||
|
|
||||||
token = match(TokenKind::TYPE, "sint32", true);
|
|
||||||
if (token != nullptr)
|
|
||||||
return token;
|
|
||||||
|
|
||||||
token = match(TokenKind::TYPE, "real32", true);
|
|
||||||
if (token != nullptr)
|
if (token != nullptr)
|
||||||
return token;
|
return token;
|
||||||
|
|
||||||
@@ -405,6 +409,27 @@ shared_ptr<Token> Lexer::matchReal() {
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_ptr<Token> Lexer::matchString() {
|
||||||
|
int nextIndex = currentIndex;
|
||||||
|
|
||||||
|
if (currentIndex >= source.size() || source.at(nextIndex) != '\"')
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
bool isClosing = false;
|
||||||
|
do {
|
||||||
|
nextIndex++;
|
||||||
|
isClosing = source.at(nextIndex) == '\"' && source.at(nextIndex - 1) != '\\';
|
||||||
|
} while (nextIndex < source.length() && !isClosing);
|
||||||
|
|
||||||
|
if (!isClosing)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
string lexme = source.substr(currentIndex, nextIndex - currentIndex + 1);
|
||||||
|
shared_ptr<Token> token = make_shared<Token>(TokenKind::STRING, lexme, currentLine, currentColumn);
|
||||||
|
advanceWithToken(token);
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<Token> Lexer::matchIdentifier() {
|
shared_ptr<Token> Lexer::matchIdentifier() {
|
||||||
int nextIndex = currentIndex;
|
int nextIndex = currentIndex;
|
||||||
|
|
||||||
@@ -420,6 +445,24 @@ shared_ptr<Token> Lexer::matchIdentifier() {
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_ptr<Token> Lexer::matchType() {
|
||||||
|
int nextIndex = currentIndex;
|
||||||
|
|
||||||
|
if (tokens.empty() || !tokens.back()->isOfKind({TokenKind::IDENTIFIER, TokenKind::LESS, TokenKind::RIGHT_ARROW}))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
while (nextIndex < source.length() && isIdentifier(nextIndex))
|
||||||
|
nextIndex++;
|
||||||
|
|
||||||
|
if (nextIndex == currentIndex || !isSeparator(nextIndex))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
string lexme = source.substr(currentIndex, nextIndex - currentIndex);
|
||||||
|
shared_ptr<Token> token = make_shared<Token>(TokenKind::TYPE, lexme, currentLine, currentColumn);
|
||||||
|
advanceWithToken(token);
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<Token> Lexer::matchEnd() {
|
shared_ptr<Token> Lexer::matchEnd() {
|
||||||
if (currentIndex >= source.length())
|
if (currentIndex >= source.length())
|
||||||
return make_shared<Token>(TokenKind::END, "", currentLine, currentColumn);
|
return make_shared<Token>(TokenKind::END, "", currentLine, currentColumn);
|
||||||
@@ -472,6 +515,8 @@ bool Lexer::isSeparator(int index) {
|
|||||||
case '>':
|
case '>':
|
||||||
case '(':
|
case '(':
|
||||||
case ')':
|
case ')':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
case ',':
|
case ',':
|
||||||
case ':':
|
case ':':
|
||||||
case ';':
|
case ';':
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ private:
|
|||||||
int currentIndex;
|
int currentIndex;
|
||||||
int currentLine;
|
int currentLine;
|
||||||
int currentColumn;
|
int currentColumn;
|
||||||
|
vector<shared_ptr<Token>> tokens;
|
||||||
vector<shared_ptr<Error>> errors;
|
vector<shared_ptr<Error>> errors;
|
||||||
|
|
||||||
shared_ptr<Token> nextToken();
|
shared_ptr<Token> nextToken();
|
||||||
@@ -24,6 +25,8 @@ private:
|
|||||||
shared_ptr<Token> matchIntegerBin();
|
shared_ptr<Token> matchIntegerBin();
|
||||||
shared_ptr<Token> matchIntegerChar();
|
shared_ptr<Token> matchIntegerChar();
|
||||||
shared_ptr<Token> matchReal();
|
shared_ptr<Token> matchReal();
|
||||||
|
shared_ptr<Token> matchString();
|
||||||
|
shared_ptr<Token> matchType();
|
||||||
shared_ptr<Token> matchIdentifier();
|
shared_ptr<Token> matchIdentifier();
|
||||||
shared_ptr<Token> matchEnd();
|
shared_ptr<Token> matchEnd();
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ vector<TokenKind> Token::tokensLiteral = {
|
|||||||
TokenKind::INTEGER_HEX,
|
TokenKind::INTEGER_HEX,
|
||||||
TokenKind::INTEGER_BIN,
|
TokenKind::INTEGER_BIN,
|
||||||
TokenKind::INTEGER_CHAR,
|
TokenKind::INTEGER_CHAR,
|
||||||
TokenKind::REAL
|
TokenKind::REAL,
|
||||||
|
TokenKind::STRING
|
||||||
};
|
};
|
||||||
|
|
||||||
Token::Token(TokenKind kind, string lexme, int line, int column):
|
Token::Token(TokenKind kind, string lexme, int line, int column):
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ enum class TokenKind {
|
|||||||
|
|
||||||
LEFT_PAREN,
|
LEFT_PAREN,
|
||||||
RIGHT_PAREN,
|
RIGHT_PAREN,
|
||||||
|
LEFT_SQUARE_BRACKET,
|
||||||
|
RIGHT_SQUARE_BRACKET,
|
||||||
COMMA,
|
COMMA,
|
||||||
COLON,
|
COLON,
|
||||||
SEMICOLON,
|
SEMICOLON,
|
||||||
@@ -39,6 +41,7 @@ enum class TokenKind {
|
|||||||
INTEGER_BIN,
|
INTEGER_BIN,
|
||||||
INTEGER_CHAR,
|
INTEGER_CHAR,
|
||||||
REAL,
|
REAL,
|
||||||
|
STRING,
|
||||||
IDENTIFIER,
|
IDENTIFIER,
|
||||||
TYPE,
|
TYPE,
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "Parser/Expression/ExpressionVariable.h"
|
#include "Parser/Expression/ExpressionVariable.h"
|
||||||
#include "Parser/Expression/ExpressionGrouping.h"
|
#include "Parser/Expression/ExpressionGrouping.h"
|
||||||
#include "Parser/Expression/ExpressionLiteral.h"
|
#include "Parser/Expression/ExpressionLiteral.h"
|
||||||
|
#include "Parser/Expression/ExpressionArrayLiteral.h"
|
||||||
#include "Parser/Expression/ExpressionCall.h"
|
#include "Parser/Expression/ExpressionCall.h"
|
||||||
#include "Parser/Expression/ExpressionBlock.h"
|
#include "Parser/Expression/ExpressionBlock.h"
|
||||||
|
|
||||||
@@ -56,6 +57,10 @@ string Logger::toString(shared_ptr<Token> token) {
|
|||||||
return "(";
|
return "(";
|
||||||
case TokenKind::RIGHT_PAREN:
|
case TokenKind::RIGHT_PAREN:
|
||||||
return ")";
|
return ")";
|
||||||
|
case TokenKind::LEFT_SQUARE_BRACKET:
|
||||||
|
return "[";
|
||||||
|
case TokenKind::RIGHT_SQUARE_BRACKET:
|
||||||
|
return "]";
|
||||||
case TokenKind::COMMA:
|
case TokenKind::COMMA:
|
||||||
return ",";
|
return ",";
|
||||||
case TokenKind::COLON:
|
case TokenKind::COLON:
|
||||||
@@ -79,6 +84,8 @@ string Logger::toString(shared_ptr<Token> token) {
|
|||||||
return "INT_CHAR(" + token->getLexme() + ")";
|
return "INT_CHAR(" + token->getLexme() + ")";
|
||||||
case TokenKind::REAL:
|
case TokenKind::REAL:
|
||||||
return "REAL(" + token->getLexme() + ")";
|
return "REAL(" + token->getLexme() + ")";
|
||||||
|
case TokenKind::STRING:
|
||||||
|
return "STRING(" + token->getLexme() + ")";
|
||||||
case TokenKind::IDENTIFIER:
|
case TokenKind::IDENTIFIER:
|
||||||
return "ID(" + token->getLexme() + ")";
|
return "ID(" + token->getLexme() + ")";
|
||||||
case TokenKind::TYPE:
|
case TokenKind::TYPE:
|
||||||
@@ -135,6 +142,10 @@ string Logger::toString(TokenKind tokenKind) {
|
|||||||
return "(";
|
return "(";
|
||||||
case TokenKind::RIGHT_PAREN:
|
case TokenKind::RIGHT_PAREN:
|
||||||
return ")";
|
return ")";
|
||||||
|
case TokenKind::LEFT_SQUARE_BRACKET:
|
||||||
|
return "[";
|
||||||
|
case TokenKind::RIGHT_SQUARE_BRACKET:
|
||||||
|
return "]";
|
||||||
case TokenKind::COMMA:
|
case TokenKind::COMMA:
|
||||||
return ",";
|
return ",";
|
||||||
case TokenKind::COLON:
|
case TokenKind::COLON:
|
||||||
@@ -155,6 +166,8 @@ string Logger::toString(TokenKind tokenKind) {
|
|||||||
return "LITERAL(INTEGER)";
|
return "LITERAL(INTEGER)";
|
||||||
case TokenKind::REAL:
|
case TokenKind::REAL:
|
||||||
return "LITERAL(REAL)";
|
return "LITERAL(REAL)";
|
||||||
|
case TokenKind::STRING:
|
||||||
|
return "LITERAL(STRING)";
|
||||||
case TokenKind::IDENTIFIER:
|
case TokenKind::IDENTIFIER:
|
||||||
return "LITERAL(ID)";
|
return "LITERAL(ID)";
|
||||||
case TokenKind::TYPE:
|
case TokenKind::TYPE:
|
||||||
@@ -191,6 +204,8 @@ string Logger::toString(shared_ptr<ValueType> valueType) {
|
|||||||
return "SINT32";
|
return "SINT32";
|
||||||
case ValueTypeKind::REAL32:
|
case ValueTypeKind::REAL32:
|
||||||
return "REAL32";
|
return "REAL32";
|
||||||
|
case ValueTypeKind::DATA:
|
||||||
|
return "[]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,6 +323,8 @@ string Logger::toString(shared_ptr<Expression> expression) {
|
|||||||
return toString(dynamic_pointer_cast<ExpressionGrouping>(expression));
|
return toString(dynamic_pointer_cast<ExpressionGrouping>(expression));
|
||||||
case ExpressionKind::LITERAL:
|
case ExpressionKind::LITERAL:
|
||||||
return toString(dynamic_pointer_cast<ExpressionLiteral>(expression));
|
return toString(dynamic_pointer_cast<ExpressionLiteral>(expression));
|
||||||
|
case ExpressionKind::ARRAY_LITERAL:
|
||||||
|
return toString(dynamic_pointer_cast<ExpressionArrayLiteral>(expression));
|
||||||
case ExpressionKind::CALL:
|
case ExpressionKind::CALL:
|
||||||
return toString(dynamic_pointer_cast<ExpressionCall>(expression));
|
return toString(dynamic_pointer_cast<ExpressionCall>(expression));
|
||||||
case ExpressionKind::BLOCK:
|
case ExpressionKind::BLOCK:
|
||||||
@@ -359,7 +376,11 @@ string Logger::toString(shared_ptr<ExpressionIfElse> expression) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string Logger::toString(shared_ptr<ExpressionVariable> expression) {
|
string Logger::toString(shared_ptr<ExpressionVariable> expression) {
|
||||||
return format("VAR({})", expression->getName());
|
string text = format("VAR({}", expression->getName());
|
||||||
|
if (expression->getIndexExpression() != nullptr)
|
||||||
|
text += format("|{}", toString(expression->getIndexExpression()));
|
||||||
|
text += ")";
|
||||||
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Logger::toString(shared_ptr<ExpressionGrouping> expression) {
|
string Logger::toString(shared_ptr<ExpressionGrouping> expression) {
|
||||||
@@ -379,9 +400,23 @@ string Logger::toString(shared_ptr<ExpressionLiteral> expression) {
|
|||||||
return to_string(expression->getSint32Value());
|
return to_string(expression->getSint32Value());
|
||||||
case ValueTypeKind::REAL32:
|
case ValueTypeKind::REAL32:
|
||||||
return to_string(expression->getReal32Value());
|
return to_string(expression->getReal32Value());
|
||||||
|
default:
|
||||||
|
return "?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string Logger::toString(shared_ptr<ExpressionArrayLiteral> expression) {
|
||||||
|
string text;
|
||||||
|
text += "[";
|
||||||
|
for (int i=0; i<expression->getExpressions().size(); i++) {
|
||||||
|
text += toString(expression->getExpressions().at(i));
|
||||||
|
if (i < expression->getExpressions().size() - 1)
|
||||||
|
text += ", ";
|
||||||
|
}
|
||||||
|
text += "]";
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
string Logger::toString(shared_ptr<ExpressionCall> expression) {
|
string Logger::toString(shared_ptr<ExpressionCall> expression) {
|
||||||
string argsString;
|
string argsString;
|
||||||
for (int i = 0; i < expression->getArgumentExpressions().size(); i++) {
|
for (int i = 0; i < expression->getArgumentExpressions().size(); i++) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class ExpressionIfElse;
|
|||||||
class ExpressionVariable;
|
class ExpressionVariable;
|
||||||
class ExpressionGrouping;
|
class ExpressionGrouping;
|
||||||
class ExpressionLiteral;
|
class ExpressionLiteral;
|
||||||
|
class ExpressionArrayLiteral;
|
||||||
class ExpressionCall;
|
class ExpressionCall;
|
||||||
class ExpressionBlock;
|
class ExpressionBlock;
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ private:
|
|||||||
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);
|
||||||
static string toString(shared_ptr<ExpressionLiteral> expression);
|
static string toString(shared_ptr<ExpressionLiteral> expression);
|
||||||
|
static string toString(shared_ptr<ExpressionArrayLiteral> expression);
|
||||||
static string toString(shared_ptr<ExpressionCall> expression);
|
static string toString(shared_ptr<ExpressionCall> expression);
|
||||||
static string toString(shared_ptr<ExpressionBlock> expression);
|
static string toString(shared_ptr<ExpressionBlock> expression);
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using namespace std;
|
|||||||
|
|
||||||
enum class ExpressionKind {
|
enum class ExpressionKind {
|
||||||
LITERAL,
|
LITERAL,
|
||||||
|
ARRAY_LITERAL,
|
||||||
GROUPING,
|
GROUPING,
|
||||||
BINARY,
|
BINARY,
|
||||||
IF_ELSE,
|
IF_ELSE,
|
||||||
|
|||||||
47
src/Parser/Expression/ExpressionArrayLiteral.cpp
Normal file
47
src/Parser/Expression/ExpressionArrayLiteral.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "ExpressionArrayLiteral.h"
|
||||||
|
|
||||||
|
#include "Lexer/Token.h"
|
||||||
|
#include "Parser/Expression/ExpressionLiteral.h"
|
||||||
|
|
||||||
|
shared_ptr<ExpressionArrayLiteral> ExpressionArrayLiteral::expressionArrayLiteralForExpressions(vector<shared_ptr<Expression>> expressions) {
|
||||||
|
shared_ptr<ExpressionArrayLiteral> expression = make_shared<ExpressionArrayLiteral>();
|
||||||
|
expression->expressions = expressions;
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ExpressionArrayLiteral> ExpressionArrayLiteral::expressionArrayLiteralForTokenString(shared_ptr<Token> tokenString) {
|
||||||
|
if (tokenString->getKind() != TokenKind::STRING)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
shared_ptr<ExpressionArrayLiteral> expression = make_shared<ExpressionArrayLiteral>();
|
||||||
|
|
||||||
|
vector<shared_ptr<Expression>> expressions;
|
||||||
|
string stringValue = tokenString->getLexme();
|
||||||
|
for (int i=1; i<stringValue.length()-1; i++) {
|
||||||
|
string lexme = stringValue.substr(i, 1);
|
||||||
|
if (stringValue[i] == '\\') {
|
||||||
|
lexme = stringValue.substr(i, 2);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
shared_ptr<Token> token = make_shared<Token>(TokenKind::INTEGER_CHAR, lexme, tokenString->getLine(), tokenString->getColumn() + i);
|
||||||
|
shared_ptr<ExpressionLiteral> expression = ExpressionLiteral::expressionLiteralForToken(token);
|
||||||
|
expressions.push_back(expression);
|
||||||
|
|
||||||
|
// add terminal 0 if missing
|
||||||
|
if (i == stringValue.length() - 2 && lexme.compare("\\0") != 0) {
|
||||||
|
shared_ptr<Token> token = make_shared<Token>(TokenKind::INTEGER_CHAR, "\\0", tokenString->getLine(), tokenString->getColumn() + i + lexme.length());
|
||||||
|
shared_ptr<ExpressionLiteral> expression = ExpressionLiteral::expressionLiteralForToken(token);
|
||||||
|
expressions.push_back(expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expression->expressions = expressions;
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpressionArrayLiteral::ExpressionArrayLiteral():
|
||||||
|
Expression(ExpressionKind::ARRAY_LITERAL, nullptr) { }
|
||||||
|
|
||||||
|
vector<shared_ptr<Expression>> ExpressionArrayLiteral::getExpressions() {
|
||||||
|
return expressions;
|
||||||
|
}
|
||||||
18
src/Parser/Expression/ExpressionArrayLiteral.h
Normal file
18
src/Parser/Expression/ExpressionArrayLiteral.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef EXPRESSION_ARRAY_LITERAL_H
|
||||||
|
#define EXPRESSION_ARRAY_LITERAL_H
|
||||||
|
|
||||||
|
#include "Expression.h"
|
||||||
|
|
||||||
|
class ExpressionArrayLiteral: public Expression {
|
||||||
|
private:
|
||||||
|
vector<shared_ptr<Expression>> expressions;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static shared_ptr<ExpressionArrayLiteral> expressionArrayLiteralForExpressions(vector<shared_ptr<Expression>> expressions);
|
||||||
|
static shared_ptr<ExpressionArrayLiteral> expressionArrayLiteralForTokenString(shared_ptr<Token> tokenString);
|
||||||
|
|
||||||
|
ExpressionArrayLiteral();
|
||||||
|
vector<shared_ptr<Expression>> getExpressions();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,79 +1,63 @@
|
|||||||
#include "ExpressionLiteral.h"
|
#include "ExpressionLiteral.h"
|
||||||
|
|
||||||
|
#include "Utils.h"
|
||||||
#include "Lexer/Token.h"
|
#include "Lexer/Token.h"
|
||||||
#include "Parser/ValueType.h"
|
#include "Parser/ValueType.h"
|
||||||
|
|
||||||
ExpressionLiteral::ExpressionLiteral():
|
shared_ptr<ExpressionLiteral> ExpressionLiteral::expressionLiteralForToken(shared_ptr<Token> token) {
|
||||||
Expression(ExpressionKind::LITERAL, nullptr) { }
|
shared_ptr<ExpressionLiteral> expression = make_shared<ExpressionLiteral>();
|
||||||
|
|
||||||
ExpressionLiteral::ExpressionLiteral(shared_ptr<Token> token):
|
|
||||||
Expression(ExpressionKind::LITERAL, nullptr) {
|
|
||||||
switch (token->getKind()) {
|
switch (token->getKind()) {
|
||||||
case TokenKind::BOOL:
|
case TokenKind::BOOL:
|
||||||
boolValue = token->getLexme().compare("true") == 0;
|
expression->boolValue = token->getLexme().compare("true") == 0;
|
||||||
valueType = ValueType::valueTypeForToken(token);
|
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
|
||||||
break;
|
break;
|
||||||
case TokenKind::INTEGER_DEC: {
|
case TokenKind::INTEGER_DEC: {
|
||||||
string numString = token->getLexme();
|
string numString = token->getLexme();
|
||||||
erase(numString, '_');
|
erase(numString, '_');
|
||||||
sint32Value = stoi(numString, nullptr, 10);
|
expression->sint32Value = stoi(numString, nullptr, 10);
|
||||||
valueType = ValueType::valueTypeForToken(token);
|
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, '_');
|
||||||
sint32Value = stoi(numString, nullptr, 16);
|
expression->sint32Value = stoi(numString, nullptr, 16);
|
||||||
valueType = ValueType::valueTypeForToken(token);
|
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TokenKind::INTEGER_BIN: {
|
case TokenKind::INTEGER_BIN: {
|
||||||
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);
|
||||||
sint32Value = stoi(numString, nullptr, 2);
|
expression->sint32Value = stoi(numString, nullptr, 2);
|
||||||
valueType = ValueType::valueTypeForToken(token);
|
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TokenKind::INTEGER_CHAR: {
|
case TokenKind::INTEGER_CHAR: {
|
||||||
string charString = token->getLexme();
|
string charString = token->getLexme();
|
||||||
|
optional<int> charValue = Utils::charStringToInt(charString);
|
||||||
|
if (!charValue)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
valueType = ValueType::valueTypeForToken(token);
|
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
|
||||||
if (charString.length() == 3) {
|
expression->sint32Value = *charValue;
|
||||||
sint32Value = charString[1];
|
return expression;
|
||||||
} else if (charString.length() == 4 && charString[1] == '\\') {
|
|
||||||
switch (charString[2]) {
|
|
||||||
case 'b':
|
|
||||||
sint32Value = '\b';
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
sint32Value = '\n';
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
sint32Value = '\t';
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
sint32Value = '\\';
|
|
||||||
break;
|
|
||||||
case '\'':
|
|
||||||
sint32Value = '\'';
|
|
||||||
break;
|
|
||||||
case '\"':
|
|
||||||
sint32Value = '\"';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case TokenKind::REAL:
|
case TokenKind::REAL:
|
||||||
real32Value = stof(token->getLexme());
|
expression->real32Value = stof(token->getLexme());
|
||||||
valueType = ValueType::valueTypeForToken(token);
|
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
exit(1);
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExpressionLiteral::ExpressionLiteral():
|
||||||
|
Expression(ExpressionKind::LITERAL, nullptr) { }
|
||||||
|
|
||||||
bool ExpressionLiteral::getBoolValue() {
|
bool ExpressionLiteral::getBoolValue() {
|
||||||
return boolValue;
|
return boolValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
#include "Parser/Expression/Expression.h"
|
#ifndef EXPRESSION_LITERAL_H
|
||||||
|
#define EXPRESSION_LITERAL_H
|
||||||
|
|
||||||
|
#include "Expression.h"
|
||||||
|
|
||||||
class ExpressionLiteral: public Expression {
|
class ExpressionLiteral: public Expression {
|
||||||
private:
|
private:
|
||||||
@@ -7,9 +10,12 @@ private:
|
|||||||
float real32Value;
|
float real32Value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExpressionLiteral(shared_ptr<Token> token);
|
static shared_ptr<ExpressionLiteral> expressionLiteralForToken(shared_ptr<Token> token);
|
||||||
|
|
||||||
ExpressionLiteral();
|
ExpressionLiteral();
|
||||||
bool getBoolValue();
|
bool getBoolValue();
|
||||||
int32_t getSint32Value();
|
int32_t getSint32Value();
|
||||||
float getReal32Value();
|
float getReal32Value();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
#include "ExpressionVariable.h"
|
#include "ExpressionVariable.h"
|
||||||
|
|
||||||
ExpressionVariable::ExpressionVariable(string name):
|
ExpressionVariable::ExpressionVariable(string name, shared_ptr<Expression> indexExpression):
|
||||||
Expression(ExpressionKind::VAR, nullptr), name(name) { }
|
Expression(ExpressionKind::VAR, nullptr), name(name), indexExpression(indexExpression) { }
|
||||||
|
|
||||||
string ExpressionVariable::getName() {
|
string ExpressionVariable::getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_ptr<Expression> ExpressionVariable::getIndexExpression() {
|
||||||
|
return indexExpression;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
class ExpressionVariable: public Expression {
|
class ExpressionVariable: public Expression {
|
||||||
private:
|
private:
|
||||||
string name;
|
string name;
|
||||||
|
shared_ptr<Expression> indexExpression;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExpressionVariable(string name);
|
ExpressionVariable(string name, shared_ptr<Expression> indexExpression);
|
||||||
string getName();
|
string getName();
|
||||||
|
shared_ptr<Expression> getIndexExpression();
|
||||||
};
|
};
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "Parser/Expression/ExpressionGrouping.h"
|
#include "Parser/Expression/ExpressionGrouping.h"
|
||||||
#include "Parser/Expression/ExpressionLiteral.h"
|
#include "Parser/Expression/ExpressionLiteral.h"
|
||||||
|
#include "Parser/Expression/ExpressionArrayLiteral.h"
|
||||||
#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"
|
||||||
@@ -121,8 +122,8 @@ shared_ptr<Statement> Parser::matchStatementMetaExternFunction() {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex++);
|
shared_ptr<Token> identifierToken = tokens.at(currentIndex++);
|
||||||
shared_ptr<Token> argumentTypeToken = tokens.at(currentIndex++);
|
//shared_ptr<Token> argumentTypeToken = tokens.at(currentIndex++);
|
||||||
shared_ptr<ValueType> argumentType = ValueType::valueTypeForToken(argumentTypeToken);
|
shared_ptr<ValueType> argumentType = matchValueType();
|
||||||
if (argumentType == nullptr) {
|
if (argumentType == nullptr) {
|
||||||
markError(TokenKind::TYPE, {});
|
markError(TokenKind::TYPE, {});
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -136,14 +137,12 @@ shared_ptr<Statement> Parser::matchStatementMetaExternFunction() {
|
|||||||
if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) {
|
if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) {
|
||||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line
|
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line
|
||||||
|
|
||||||
shared_ptr<Token> returnTypeToken = tokens.at(currentIndex);
|
//shared_ptr<Token> returnTypeToken = tokens.at(currentIndex);
|
||||||
returnType = ValueType::valueTypeForToken(returnTypeToken);
|
returnType = matchValueType();
|
||||||
if (returnType == nullptr) {
|
if (returnType == nullptr) {
|
||||||
markError(TokenKind::TYPE, {});
|
markError(TokenKind::TYPE, {});
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentIndex++; // type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return make_shared<StatementMetaExternFunction>(identifierToken->getLexme(), arguments, returnType);
|
return make_shared<StatementMetaExternFunction>(identifierToken->getLexme(), arguments, returnType);
|
||||||
@@ -154,21 +153,7 @@ shared_ptr<Statement> Parser::matchStatementVariable() {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex++);
|
shared_ptr<Token> identifierToken = tokens.at(currentIndex++);
|
||||||
shared_ptr<Token> valueTypeToken = tokens.at(currentIndex);
|
shared_ptr<ValueType> valueType = matchValueType();
|
||||||
|
|
||||||
shared_ptr<ValueType> valueType;
|
|
||||||
if (valueTypeToken->getLexme().compare("bool") == 0)
|
|
||||||
valueType = ValueType::BOOL;
|
|
||||||
else if (valueTypeToken->getLexme().compare("sint32") == 0)
|
|
||||||
valueType = ValueType::SINT32;
|
|
||||||
else if (valueTypeToken->getLexme().compare("real32") == 0)
|
|
||||||
valueType = ValueType::REAL32;
|
|
||||||
else {
|
|
||||||
markError(TokenKind::TYPE, {});
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentIndex++; // type
|
|
||||||
|
|
||||||
// Expect left arrow
|
// Expect left arrow
|
||||||
if (!tryMatchingTokenKinds({TokenKind::LEFT_ARROW}, true, true)) {
|
if (!tryMatchingTokenKinds({TokenKind::LEFT_ARROW}, true, true)) {
|
||||||
@@ -205,8 +190,7 @@ shared_ptr<Statement> Parser::matchStatementFunction() {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex++);
|
shared_ptr<Token> identifierToken = tokens.at(currentIndex++);
|
||||||
shared_ptr<Token> argumentTypeToken = tokens.at(currentIndex++);
|
shared_ptr<ValueType> argumentType = matchValueType();
|
||||||
shared_ptr<ValueType> argumentType = ValueType::valueTypeForToken(argumentTypeToken);
|
|
||||||
if (argumentType == nullptr) {
|
if (argumentType == nullptr) {
|
||||||
markError(TokenKind::TYPE, {});
|
markError(TokenKind::TYPE, {});
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -220,14 +204,11 @@ shared_ptr<Statement> Parser::matchStatementFunction() {
|
|||||||
if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) {
|
if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) {
|
||||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line
|
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line
|
||||||
|
|
||||||
shared_ptr<Token> returnTypeToken = tokens.at(currentIndex);
|
returnType = matchValueType();
|
||||||
returnType = ValueType::valueTypeForToken(returnTypeToken);
|
|
||||||
if (returnType == nullptr) {
|
if (returnType == nullptr) {
|
||||||
markError(TokenKind::TYPE, {});
|
markError(TokenKind::TYPE, {});
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentIndex++; // type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// consume new line
|
// consume new line
|
||||||
@@ -261,27 +242,43 @@ shared_ptr<Statement> Parser::matchStatementBlock(vector<TokenKind> terminalToke
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// except new line
|
// except new line
|
||||||
if (statement != nullptr && !tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) {
|
if (statement != nullptr && !tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true))
|
||||||
markError(TokenKind::NEW_LINE, {});
|
markError(TokenKind::NEW_LINE, {});
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return make_shared<StatementBlock>(statements);
|
return make_shared<StatementBlock>(statements);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Statement> Parser::matchStatementAssignment() {
|
shared_ptr<Statement> Parser::matchStatementAssignment() {
|
||||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::LEFT_ARROW}, true, false))
|
int startIndex = currentIndex;
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
|
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, false))
|
||||||
|
return nullptr;
|
||||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex++);
|
shared_ptr<Token> identifierToken = tokens.at(currentIndex++);
|
||||||
currentIndex++; // arrow
|
shared_ptr<Expression> indexExpression;
|
||||||
|
|
||||||
|
if (tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) {
|
||||||
|
indexExpression = nextExpression();
|
||||||
|
if (indexExpression == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) {
|
||||||
|
markError(TokenKind::RIGHT_SQUARE_BRACKET, {});
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assignment requires left arrow, otherwise abort
|
||||||
|
if (!tryMatchingTokenKinds({TokenKind::LEFT_ARROW}, true, true)) {
|
||||||
|
currentIndex = startIndex;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<Expression> expression = nextExpression();
|
shared_ptr<Expression> expression = nextExpression();
|
||||||
if (expression == nullptr)
|
if (expression == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return make_shared<StatementAssignment>(identifierToken->getLexme(), expression);
|
return make_shared<StatementAssignment>(identifierToken->getLexme(), indexExpression, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Statement> Parser::matchStatementReturn() {
|
shared_ptr<Statement> Parser::matchStatementReturn() {
|
||||||
@@ -313,7 +310,7 @@ shared_ptr<Statement> Parser::matchStatementRepeat() {
|
|||||||
// got initial, expect comma
|
// got initial, expect comma
|
||||||
if (initStatement != nullptr && !tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) {
|
if (initStatement != nullptr && !tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) {
|
||||||
markError(TokenKind::COMMA, {});
|
markError(TokenKind::COMMA, {});
|
||||||
return nullptr;
|
goto afterIf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional new line
|
// optional new line
|
||||||
@@ -326,7 +323,7 @@ shared_ptr<Statement> Parser::matchStatementRepeat() {
|
|||||||
// got pre-condition, expect comma
|
// got pre-condition, expect comma
|
||||||
if (!tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) {
|
if (!tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) {
|
||||||
markError(TokenKind::COMMA, {});
|
markError(TokenKind::COMMA, {});
|
||||||
return nullptr;
|
goto afterIf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional new line
|
// optional new line
|
||||||
@@ -338,10 +335,11 @@ shared_ptr<Statement> Parser::matchStatementRepeat() {
|
|||||||
// expect colon
|
// expect colon
|
||||||
if (!tryMatchingTokenKinds({TokenKind::COLON}, true, true)) {
|
if (!tryMatchingTokenKinds({TokenKind::COLON}, true, true)) {
|
||||||
markError(TokenKind::COLON, {});
|
markError(TokenKind::COLON, {});
|
||||||
return nullptr;
|
goto afterIf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
afterIf:
|
||||||
|
|
||||||
isMultiLine = tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
|
isMultiLine = tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
|
||||||
|
|
||||||
@@ -437,28 +435,32 @@ shared_ptr<Expression> Parser::matchFactor() {
|
|||||||
|
|
||||||
shared_ptr<Expression> Parser::matchPrimary() {
|
shared_ptr<Expression> Parser::matchPrimary() {
|
||||||
shared_ptr<Expression> expression;
|
shared_ptr<Expression> expression;
|
||||||
|
int errorsCount = errors.size();
|
||||||
|
|
||||||
expression = matchExpressionGrouping();
|
expression = matchExpressionGrouping();
|
||||||
if (expression != nullptr)
|
if (expression != nullptr || errors.size() > errorsCount)
|
||||||
return expression;
|
return expression;
|
||||||
|
|
||||||
|
expression = matchExpressionArrayLiteral();
|
||||||
|
if (expression != nullptr || errors.size() > errorsCount)
|
||||||
|
return expression;
|
||||||
|
|
||||||
expression = matchExpressionLiteral();
|
expression = matchExpressionLiteral();
|
||||||
if (expression != nullptr)
|
if (expression != nullptr || errors.size() > errorsCount)
|
||||||
return expression;
|
return expression;
|
||||||
|
|
||||||
expression = matchExpressionCall();
|
expression = matchExpressionCall();
|
||||||
if (expression != nullptr)
|
if (expression != nullptr || errors.size() > errorsCount)
|
||||||
return expression;
|
return expression;
|
||||||
|
|
||||||
expression = matchExpressionVariable();
|
expression = matchExpressionVariable();
|
||||||
if (expression != nullptr)
|
if (expression != nullptr || errors.size() > errorsCount)
|
||||||
return expression;
|
return expression;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Expression> Parser::matchExpressionGrouping() {
|
shared_ptr<Expression> Parser::matchExpressionGrouping() {
|
||||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
|
||||||
if (tryMatchingTokenKinds({TokenKind::LEFT_PAREN}, true, true)) {
|
if (tryMatchingTokenKinds({TokenKind::LEFT_PAREN}, true, true)) {
|
||||||
shared_ptr<Expression> expression = matchTerm();
|
shared_ptr<Expression> expression = matchTerm();
|
||||||
// has grouped expression failed?
|
// has grouped expression failed?
|
||||||
@@ -478,18 +480,53 @@ shared_ptr<Expression> Parser::matchExpressionLiteral() {
|
|||||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
shared_ptr<Token> token = tokens.at(currentIndex);
|
||||||
|
|
||||||
if (tryMatchingTokenKinds(Token::tokensLiteral, false, true))
|
if (tryMatchingTokenKinds(Token::tokensLiteral, false, true))
|
||||||
return make_shared<ExpressionLiteral>(token);
|
return ExpressionLiteral::expressionLiteralForToken(token);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<Expression> Parser::matchExpressionArrayLiteral() {
|
||||||
|
if (tryMatchingTokenKinds({TokenKind::STRING}, true, false)) {
|
||||||
|
return ExpressionArrayLiteral::expressionArrayLiteralForTokenString(tokens.at(currentIndex++));
|
||||||
|
} else if (tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) {
|
||||||
|
vector<shared_ptr<Expression>> expressions;
|
||||||
|
if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) {
|
||||||
|
do {
|
||||||
|
shared_ptr<Expression> expression = nextExpression();
|
||||||
|
if (expression != nullptr)
|
||||||
|
expressions.push_back(expression);
|
||||||
|
} while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true));
|
||||||
|
|
||||||
|
if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) {
|
||||||
|
markError(TokenKind::RIGHT_SQUARE_BRACKET, {});
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExpressionArrayLiteral::expressionArrayLiteralForExpressions(expressions);
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Expression> Parser::matchExpressionVariable() {
|
shared_ptr<Expression> Parser::matchExpressionVariable() {
|
||||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, false))
|
||||||
|
return nullptr;
|
||||||
|
shared_ptr<Token> idToken = tokens.at(currentIndex++);
|
||||||
|
shared_ptr<Expression> indexExpression;
|
||||||
|
|
||||||
if (tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, true))
|
if (tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) {
|
||||||
return make_shared<ExpressionVariable>(token->getLexme());
|
indexExpression = nextExpression();
|
||||||
|
if (indexExpression == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
return nullptr;
|
if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) {
|
||||||
|
markError(TokenKind::RIGHT_SQUARE_BRACKET, {});
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_shared<ExpressionVariable>(idToken->getLexme(), indexExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Expression> Parser::matchExpressionCall() {
|
shared_ptr<Expression> Parser::matchExpressionCall() {
|
||||||
@@ -614,6 +651,46 @@ shared_ptr<Expression> Parser::matchExpressionBlock(vector<TokenKind> terminalTo
|
|||||||
return make_shared<ExpressionBlock>(statements);
|
return make_shared<ExpressionBlock>(statements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_ptr<ValueType> Parser::matchValueType() {
|
||||||
|
if (!tryMatchingTokenKinds({TokenKind::TYPE}, true, false))
|
||||||
|
return nullptr;
|
||||||
|
shared_ptr<Token> typeToken = tokens.at(currentIndex++);
|
||||||
|
shared_ptr<ValueType> subType;
|
||||||
|
int valueArg = 0;
|
||||||
|
|
||||||
|
if (tryMatchingTokenKinds({TokenKind::LESS}, true, true)) {
|
||||||
|
if (!tryMatchingTokenKinds({TokenKind::TYPE}, true, false)) {
|
||||||
|
markError(TokenKind::TYPE, {});
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
subType = matchValueType();
|
||||||
|
if (subType == nullptr)
|
||||||
|
return subType;
|
||||||
|
|
||||||
|
if (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) {
|
||||||
|
if (!tryMatchingTokenKinds({TokenKind::INTEGER_DEC, TokenKind::INTEGER_HEX, TokenKind::INTEGER_BIN, TokenKind::INTEGER_CHAR}, false, false)) {
|
||||||
|
markError({}, "Expected integer literal");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
shared_ptr<Expression> expressionValue = matchExpressionLiteral();
|
||||||
|
if (expressionValue == nullptr) {
|
||||||
|
markError({}, "Expected integer literal");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
valueArg = dynamic_pointer_cast<ExpressionLiteral>(expressionValue)->getSint32Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!tryMatchingTokenKinds({TokenKind::GREATER}, true, true)) {
|
||||||
|
markError(TokenKind::GREATER, {});
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValueType::valueTypeForToken(typeToken, subType, valueArg);
|
||||||
|
}
|
||||||
|
|
||||||
bool Parser::tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance) {
|
bool Parser::tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance) {
|
||||||
int requiredCount = shouldMatchAll ? kinds.size() : 1;
|
int requiredCount = shouldMatchAll ? kinds.size() : 1;
|
||||||
if (currentIndex + requiredCount > tokens.size())
|
if (currentIndex + requiredCount > tokens.size())
|
||||||
@@ -655,5 +732,9 @@ void Parser::markError(optional<TokenKind> expectedTokenKind, optional<string> m
|
|||||||
while (!tryMatchingTokenKinds(safeKinds, false, true))
|
while (!tryMatchingTokenKinds(safeKinds, false, true))
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
|
|
||||||
|
// Last END should not be consumed
|
||||||
|
if (currentIndex > tokens.size() - 1)
|
||||||
|
currentIndex = tokens.size() - 1;
|
||||||
|
|
||||||
errors.push_back(Error::parserError(actualToken, expectedTokenKind, message));
|
errors.push_back(Error::parserError(actualToken, expectedTokenKind, message));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,11 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class Error;
|
||||||
|
|
||||||
class Token;
|
class Token;
|
||||||
enum class TokenKind;
|
enum class TokenKind;
|
||||||
class Error;
|
class ValueType;
|
||||||
|
|
||||||
class Expression;
|
class Expression;
|
||||||
class Statement;
|
class Statement;
|
||||||
@@ -40,12 +42,15 @@ private:
|
|||||||
|
|
||||||
shared_ptr<Expression> matchExpressionGrouping();
|
shared_ptr<Expression> matchExpressionGrouping();
|
||||||
shared_ptr<Expression> matchExpressionLiteral();
|
shared_ptr<Expression> matchExpressionLiteral();
|
||||||
|
shared_ptr<Expression> matchExpressionArrayLiteral();
|
||||||
shared_ptr<Expression> matchExpressionVariable();
|
shared_ptr<Expression> matchExpressionVariable();
|
||||||
shared_ptr<Expression> matchExpressionCall();
|
shared_ptr<Expression> matchExpressionCall();
|
||||||
shared_ptr<Expression> matchExpressionIfElse();
|
shared_ptr<Expression> matchExpressionIfElse();
|
||||||
shared_ptr<Expression> matchExpressionBinary(shared_ptr<Expression> left);
|
shared_ptr<Expression> matchExpressionBinary(shared_ptr<Expression> left);
|
||||||
shared_ptr<Expression> matchExpressionBlock(vector<TokenKind> terminalTokenKinds);
|
shared_ptr<Expression> matchExpressionBlock(vector<TokenKind> terminalTokenKinds);
|
||||||
|
|
||||||
|
shared_ptr<ValueType> matchValueType();
|
||||||
|
|
||||||
bool tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance);
|
bool tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance);
|
||||||
|
|
||||||
void markError(optional<TokenKind> expectedTokenKind, optional<string> message);
|
void markError(optional<TokenKind> expectedTokenKind, optional<string> message);
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
#include "StatementAssignment.h"
|
#include "StatementAssignment.h"
|
||||||
|
|
||||||
StatementAssignment::StatementAssignment(string name, shared_ptr<Expression> expression):
|
StatementAssignment::StatementAssignment(string name, shared_ptr<Expression> indexExpression, shared_ptr<Expression> expression):
|
||||||
Statement(StatementKind::ASSIGNMENT), name(name), expression(expression) { }
|
Statement(StatementKind::ASSIGNMENT), name(name), indexExpression(indexExpression), expression(expression) { }
|
||||||
|
|
||||||
string StatementAssignment::getName() {
|
string StatementAssignment::getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_ptr<Expression> StatementAssignment::getIndexExpression() {
|
||||||
|
return indexExpression;
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<Expression> StatementAssignment::getExpression() {
|
shared_ptr<Expression> StatementAssignment::getExpression() {
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
@@ -5,10 +5,12 @@ class Expression;
|
|||||||
class StatementAssignment: public Statement {
|
class StatementAssignment: public Statement {
|
||||||
private:
|
private:
|
||||||
string name;
|
string name;
|
||||||
|
shared_ptr<Expression> indexExpression;
|
||||||
shared_ptr<Expression> expression;
|
shared_ptr<Expression> expression;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StatementAssignment(string name, shared_ptr<Expression> expression);
|
StatementAssignment(string name, shared_ptr<Expression> indexExpressio, shared_ptr<Expression> expression);
|
||||||
string getName();
|
string getName();
|
||||||
|
shared_ptr<Expression> getIndexExpression();
|
||||||
shared_ptr<Expression> getExpression();
|
shared_ptr<Expression> getExpression();
|
||||||
};
|
};
|
||||||
@@ -2,36 +2,38 @@
|
|||||||
|
|
||||||
#include "Lexer/Token.h"
|
#include "Lexer/Token.h"
|
||||||
|
|
||||||
shared_ptr<ValueType> ValueType::NONE = make_shared<ValueType>(ValueTypeKind::NONE);
|
shared_ptr<ValueType> ValueType::NONE = make_shared<ValueType>(ValueTypeKind::NONE, nullptr, 0);
|
||||||
shared_ptr<ValueType> ValueType::BOOL = make_shared<ValueType>(ValueTypeKind::BOOL);
|
shared_ptr<ValueType> ValueType::BOOL = make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0);
|
||||||
shared_ptr<ValueType> ValueType::SINT32 = make_shared<ValueType>(ValueTypeKind::SINT32);
|
shared_ptr<ValueType> ValueType::SINT32 = make_shared<ValueType>(ValueTypeKind::SINT32, nullptr, 0);
|
||||||
shared_ptr<ValueType> ValueType::REAL32 = make_shared<ValueType>(ValueTypeKind::REAL32);
|
shared_ptr<ValueType> ValueType::REAL32 = make_shared<ValueType>(ValueTypeKind::REAL32, nullptr, 0);
|
||||||
|
|
||||||
ValueType::ValueType(ValueTypeKind kind):
|
ValueType::ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg):
|
||||||
kind(kind) { }
|
kind(kind), subType(subType), valueArg(valueArg) { }
|
||||||
|
|
||||||
shared_ptr<ValueType> ValueType::valueTypeForToken(shared_ptr<Token> token) {
|
shared_ptr<ValueType> ValueType::valueTypeForToken(shared_ptr<Token> token, shared_ptr<ValueType> subType, int valueArg) {
|
||||||
switch (token->getKind()) {
|
switch (token->getKind()) {
|
||||||
case TokenKind::TYPE: {
|
case TokenKind::TYPE: {
|
||||||
string lexme = token->getLexme();
|
string lexme = token->getLexme();
|
||||||
if (lexme.compare("bool") == 0)
|
if (lexme.compare("bool") == 0)
|
||||||
return make_shared<ValueType>(ValueTypeKind::BOOL);
|
return make_shared<ValueType>(ValueTypeKind::BOOL, subType, valueArg);
|
||||||
else if (lexme.compare("sint32") == 0)
|
else if (lexme.compare("sint32") == 0)
|
||||||
return make_shared<ValueType>(ValueTypeKind::SINT32);
|
return make_shared<ValueType>(ValueTypeKind::SINT32, subType, valueArg);
|
||||||
else if (lexme.compare("real32") == 0)
|
else if (lexme.compare("real32") == 0)
|
||||||
return make_shared<ValueType>(ValueTypeKind::REAL32);
|
return make_shared<ValueType>(ValueTypeKind::REAL32, subType, valueArg);
|
||||||
|
else if (lexme.compare("data") == 0)
|
||||||
|
return make_shared<ValueType>(ValueTypeKind::DATA, subType, valueArg);
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
case TokenKind::BOOL:
|
case TokenKind::BOOL:
|
||||||
return make_shared<ValueType>(ValueTypeKind::BOOL);
|
return make_shared<ValueType>(ValueTypeKind::BOOL, nullptr, 0);
|
||||||
case TokenKind::INTEGER_DEC:
|
case TokenKind::INTEGER_DEC:
|
||||||
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);
|
return make_shared<ValueType>(ValueTypeKind::SINT32, nullptr, 0);
|
||||||
case TokenKind::REAL:
|
case TokenKind::REAL:
|
||||||
return make_shared<ValueType>(ValueTypeKind::REAL32);
|
return make_shared<ValueType>(ValueTypeKind::REAL32, nullptr, 0);
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -40,3 +42,11 @@ shared_ptr<ValueType> ValueType::valueTypeForToken(shared_ptr<Token> token) {
|
|||||||
ValueTypeKind ValueType::getKind() {
|
ValueTypeKind ValueType::getKind() {
|
||||||
return kind;
|
return kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_ptr<ValueType> ValueType::getSubType() {
|
||||||
|
return subType;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ValueType::getValueArg() {
|
||||||
|
return valueArg;
|
||||||
|
}
|
||||||
@@ -11,22 +11,27 @@ enum class ValueTypeKind {
|
|||||||
NONE,
|
NONE,
|
||||||
BOOL,
|
BOOL,
|
||||||
SINT32,
|
SINT32,
|
||||||
REAL32
|
REAL32,
|
||||||
|
DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
class ValueType {
|
class ValueType {
|
||||||
private:
|
private:
|
||||||
ValueTypeKind kind;
|
ValueTypeKind kind;
|
||||||
|
shared_ptr<ValueType> subType;
|
||||||
|
int valueArg;
|
||||||
|
|
||||||
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> SINT32;
|
||||||
static shared_ptr<ValueType> REAL32;
|
static shared_ptr<ValueType> REAL32;
|
||||||
static shared_ptr<ValueType> valueTypeForToken(shared_ptr<Token> token);
|
static shared_ptr<ValueType> valueTypeForToken(shared_ptr<Token> token, shared_ptr<ValueType> subType, int valueArg);
|
||||||
|
|
||||||
ValueType(ValueTypeKind kind);
|
ValueType(ValueTypeKind kind, shared_ptr<ValueType> subType, int valueArg);
|
||||||
ValueTypeKind getKind();
|
ValueTypeKind getKind();
|
||||||
|
shared_ptr<ValueType> getSubType();
|
||||||
|
int getValueArg();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
36
src/Utils.cpp
Normal file
36
src/Utils.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
optional<int> Utils::charStringToInt(string charString) {
|
||||||
|
switch (charString.length()) {
|
||||||
|
case 1:
|
||||||
|
return charString[0];
|
||||||
|
case 3:
|
||||||
|
return charString[1];
|
||||||
|
case 4:
|
||||||
|
charString[0] = charString[1];
|
||||||
|
charString[1] = charString[2];
|
||||||
|
case 2:
|
||||||
|
if (charString[0] != '\\')
|
||||||
|
return {};
|
||||||
|
switch (charString[1]) {
|
||||||
|
case 'b':
|
||||||
|
return '\b';
|
||||||
|
case 'n':
|
||||||
|
return '\n';
|
||||||
|
case 't':
|
||||||
|
return '\t';
|
||||||
|
case '\\':
|
||||||
|
return '\\';
|
||||||
|
case '\'':
|
||||||
|
return '\'';
|
||||||
|
case '\"':
|
||||||
|
return '\"';
|
||||||
|
case '0':
|
||||||
|
return '\0';
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/Utils.h
Normal file
13
src/Utils.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef UTILS_H
|
||||||
|
#define UTILS_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class Utils {
|
||||||
|
public:
|
||||||
|
static optional<int> charStringToInt(string charString);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user