String literals
This commit is contained in:
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,12 +1,9 @@
|
|||||||
# ignore files without extensions
|
|
||||||
*
|
|
||||||
!*.*
|
|
||||||
# brb build artifiacts
|
|
||||||
*.o
|
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
|
|
||||||
# project build artifacts
|
# project build artifacts
|
||||||
*.dSYM
|
*.dSYM
|
||||||
build/
|
build/
|
||||||
|
|
||||||
|
# brb build artifiacts
|
||||||
|
*.o
|
||||||
|
|||||||
7
samples/test.brc
Normal file
7
samples/test.brc
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@extern putchar fun: character sint32 -> sint32
|
||||||
|
|
||||||
|
main fun -> sint32
|
||||||
|
text data<sint32> <- "Hello string!\n"
|
||||||
|
|
||||||
|
ret 0
|
||||||
|
;
|
||||||
@@ -250,6 +250,10 @@ 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 = matchType();
|
token = matchType();
|
||||||
if (token != nullptr)
|
if (token != nullptr)
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ 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> 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):
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ enum class TokenKind {
|
|||||||
INTEGER_BIN,
|
INTEGER_BIN,
|
||||||
INTEGER_CHAR,
|
INTEGER_CHAR,
|
||||||
REAL,
|
REAL,
|
||||||
|
STRING,
|
||||||
IDENTIFIER,
|
IDENTIFIER,
|
||||||
TYPE,
|
TYPE,
|
||||||
|
|
||||||
|
|||||||
@@ -84,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:
|
||||||
@@ -164,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:
|
||||||
|
|||||||
@@ -1,8 +1,34 @@
|
|||||||
#include "ExpressionArrayLiteral.h"
|
#include "ExpressionArrayLiteral.h"
|
||||||
|
|
||||||
|
#include "Lexer/Token.h"
|
||||||
|
#include "Parser/Expression/ExpressionLiteral.h"
|
||||||
|
|
||||||
ExpressionArrayLiteral::ExpressionArrayLiteral(vector<shared_ptr<Expression>> expressions):
|
ExpressionArrayLiteral::ExpressionArrayLiteral(vector<shared_ptr<Expression>> expressions):
|
||||||
Expression(ExpressionKind::ARRAY_LITERAL, nullptr), expressions(expressions) { }
|
Expression(ExpressionKind::ARRAY_LITERAL, nullptr), expressions(expressions) { }
|
||||||
|
|
||||||
|
shared_ptr<ExpressionArrayLiteral> ExpressionArrayLiteral::expressionArrayLiteralForExpressions(vector<shared_ptr<Expression>> expressions) {
|
||||||
|
return make_shared<ExpressionArrayLiteral>(expressions);
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<ExpressionArrayLiteral> ExpressionArrayLiteral::expressionArrayLiteralForTokenString(shared_ptr<Token> tokenString) {
|
||||||
|
if (tokenString->getKind() != TokenKind::STRING)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
return make_shared<ExpressionArrayLiteral>(expressions);
|
||||||
|
}
|
||||||
|
|
||||||
vector<shared_ptr<Expression>> ExpressionArrayLiteral::getExpressions() {
|
vector<shared_ptr<Expression>> ExpressionArrayLiteral::getExpressions() {
|
||||||
return expressions;
|
return expressions;
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,9 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ExpressionArrayLiteral(vector<shared_ptr<Expression>> expressions);
|
ExpressionArrayLiteral(vector<shared_ptr<Expression>> expressions);
|
||||||
|
//ExpressionArrayLiteral(shared_ptr<Token> tokenString);
|
||||||
|
static shared_ptr<ExpressionArrayLiteral> expressionArrayLiteralForExpressions(vector<shared_ptr<Expression>> expressions);
|
||||||
|
static shared_ptr<ExpressionArrayLiteral> expressionArrayLiteralForTokenString(shared_ptr<Token> tokenString);
|
||||||
vector<shared_ptr<Expression>> getExpressions();
|
vector<shared_ptr<Expression>> getExpressions();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,26 @@
|
|||||||
#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"
|
||||||
|
|
||||||
|
shared_ptr<ExpressionLiteral> ExpressionLiteral::expressionLiteralForToken(shared_ptr<Token> token) {
|
||||||
|
switch (token->getKind()) {
|
||||||
|
case TokenKind::INTEGER_CHAR: {
|
||||||
|
string charString = token->getLexme();
|
||||||
|
optional<int> charValue = Utils::charStringToInt(charString);
|
||||||
|
if (!charValue)
|
||||||
|
return nullptr;
|
||||||
|
shared_ptr<ExpressionLiteral> expression = make_shared<ExpressionLiteral>();
|
||||||
|
expression->valueType = ValueType::valueTypeForToken(token, nullptr, 0);
|
||||||
|
expression->sint32Value = *charValue;
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ExpressionLiteral::ExpressionLiteral():
|
ExpressionLiteral::ExpressionLiteral():
|
||||||
Expression(ExpressionKind::LITERAL, nullptr) { }
|
Expression(ExpressionKind::LITERAL, nullptr) { }
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ private:
|
|||||||
float real32Value;
|
float real32Value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static shared_ptr<ExpressionLiteral> expressionLiteralForToken(shared_ptr<Token> token);
|
||||||
|
|
||||||
ExpressionLiteral(shared_ptr<Token> token);
|
ExpressionLiteral(shared_ptr<Token> token);
|
||||||
ExpressionLiteral();
|
ExpressionLiteral();
|
||||||
bool getBoolValue();
|
bool getBoolValue();
|
||||||
|
|||||||
@@ -421,11 +421,11 @@ shared_ptr<Expression> Parser::matchPrimary() {
|
|||||||
if (expression != nullptr)
|
if (expression != nullptr)
|
||||||
return expression;
|
return expression;
|
||||||
|
|
||||||
expression = matchExpressionLiteral();
|
expression = matchExpressionArrayLiteral();
|
||||||
if (expression != nullptr)
|
if (expression != nullptr)
|
||||||
return expression;
|
return expression;
|
||||||
|
|
||||||
expression = matchExpressionArrayLiteral();
|
expression = matchExpressionLiteral();
|
||||||
if (expression != nullptr)
|
if (expression != nullptr)
|
||||||
return expression;
|
return expression;
|
||||||
|
|
||||||
@@ -466,9 +466,9 @@ shared_ptr<Expression> Parser::matchExpressionLiteral() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Expression> Parser::matchExpressionArrayLiteral() {
|
shared_ptr<Expression> Parser::matchExpressionArrayLiteral() {
|
||||||
if (!tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true))
|
if (tryMatchingTokenKinds({TokenKind::STRING}, true, false)) {
|
||||||
return nullptr;
|
return ExpressionArrayLiteral::expressionArrayLiteralForTokenString(tokens.at(currentIndex++));
|
||||||
|
} else if (tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) {
|
||||||
vector<shared_ptr<Expression>> expressions;
|
vector<shared_ptr<Expression>> expressions;
|
||||||
if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) {
|
if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) {
|
||||||
do {
|
do {
|
||||||
@@ -485,6 +485,9 @@ shared_ptr<Expression> Parser::matchExpressionArrayLiteral() {
|
|||||||
|
|
||||||
|
|
||||||
return make_shared<ExpressionArrayLiteral>(expressions);
|
return make_shared<ExpressionArrayLiteral>(expressions);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Expression> Parser::matchExpressionVariable() {
|
shared_ptr<Expression> Parser::matchExpressionVariable() {
|
||||||
|
|||||||
34
src/Utils.cpp
Normal file
34
src/Utils.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#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 '\"';
|
||||||
|
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