Add double type
This commit is contained in:
parent
cfe02062a6
commit
a1fa96a626
@ -11,10 +11,10 @@ using namespace std;
|
|||||||
/**
|
/**
|
||||||
* Tokens definition
|
* Tokens definition
|
||||||
*/
|
*/
|
||||||
enum class TokenType { Type, Identifier, Int, Plus, Minus, DoublePlus, DoubleMinus, DoubleEqual, Land, Lor, Lt, Gt, Leq, Geq, NotEqual, Not, Star, Slash, Percent, Equal, Semicolon, LParenthese, RParenthese, LCurlyBracket, RCurlyBracket, If, Else, While, For };
|
enum class TokenType { Identifier, Litteral, Plus, Minus, DoublePlus, DoubleMinus, DoubleEqual, Land, Lor, Lt, Gt, Leq, Geq, NotEqual, Not, Star, Slash, Percent, Equal, Semicolon, LParenthese, RParenthese, LCurlyBracket, RCurlyBracket, If, Else, While, For };
|
||||||
enum class Type { Int };
|
enum class Type { Int };
|
||||||
|
|
||||||
using TokenData = variant<int, string, Type>;
|
using TokenData = variant<int, double, string, Type>;
|
||||||
|
|
||||||
struct CodePosition {
|
struct CodePosition {
|
||||||
int line;
|
int line;
|
||||||
@ -75,7 +75,7 @@ Unary ->
|
|||||||
| ! Unary
|
| ! Unary
|
||||||
|
|
||||||
Val ->
|
Val ->
|
||||||
| Number
|
| Litteral
|
||||||
|
|
||||||
| ++ParIdentifier
|
| ++ParIdentifier
|
||||||
| --ParIdentifier
|
| --ParIdentifier
|
||||||
|
@ -18,6 +18,29 @@ bool bool_cast(EvalResult value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int int_cast(EvalResult value) {
|
||||||
|
if (holds_alternative<int>(value)) {
|
||||||
|
return get<int>(value);
|
||||||
|
} else if (holds_alternative<double>(value)) {
|
||||||
|
return int(get<double>(value));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double double_cast(EvalResult value) {
|
||||||
|
if (holds_alternative<int>(value)) {
|
||||||
|
return double(get<int>(value));
|
||||||
|
}
|
||||||
|
else if (holds_alternative<double>(value)) {
|
||||||
|
return get<double>(value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EvalResult eval(Node &ast, Memory &memory) {
|
EvalResult eval(Node &ast, Memory &memory) {
|
||||||
if (holds_alternative<InnerNode>(ast)) {
|
if (holds_alternative<InnerNode>(ast)) {
|
||||||
InnerNode node = get<InnerNode>(ast);
|
InnerNode node = get<InnerNode>(ast);
|
||||||
@ -30,7 +53,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
return {};
|
return {};
|
||||||
break;
|
break;
|
||||||
case NodeType::If: {
|
case NodeType::If: {
|
||||||
int cond = get<int>(eval(node.children[0], memory));
|
int cond = bool_cast(eval(node.children[0], memory));
|
||||||
|
|
||||||
if (cond) {
|
if (cond) {
|
||||||
eval(node.children[1], memory);
|
eval(node.children[1], memory);
|
||||||
@ -39,7 +62,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
return {};
|
return {};
|
||||||
} break;
|
} break;
|
||||||
case NodeType::IfElse: {
|
case NodeType::IfElse: {
|
||||||
int cond = get<int>(eval(node.children[0], memory));
|
int cond = bool_cast(eval(node.children[0], memory));
|
||||||
|
|
||||||
if (cond) {
|
if (cond) {
|
||||||
eval(node.children[1], memory);
|
eval(node.children[1], memory);
|
||||||
@ -52,7 +75,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
} break;
|
} break;
|
||||||
case NodeType::While: {
|
case NodeType::While: {
|
||||||
while (true) {
|
while (true) {
|
||||||
int cond = get<int>(eval(node.children[0], memory));
|
int cond = bool_cast(eval(node.children[0], memory));
|
||||||
if (!cond) break;
|
if (!cond) break;
|
||||||
|
|
||||||
eval(node.children[1], memory);
|
eval(node.children[1], memory);
|
||||||
@ -66,7 +89,7 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
eval(node.children[0], memory);
|
eval(node.children[0], memory);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int cond = get<int>(eval(node.children[1], memory));
|
int cond = bool_cast(eval(node.children[1], memory));
|
||||||
if (!cond) break;
|
if (!cond) break;
|
||||||
|
|
||||||
eval(node.children[3], memory);
|
eval(node.children[3], memory);
|
||||||
@ -137,39 +160,95 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
return e1 >= e2;
|
return e1 >= e2;
|
||||||
} break;
|
} break;
|
||||||
case NodeType::Plus: {
|
case NodeType::Plus: {
|
||||||
int e1 = get<int>(eval(node.children[0], memory));
|
EvalResult e1 = eval(node.children[0], memory);
|
||||||
int e2 = get<int>(eval(node.children[1], memory));
|
EvalResult e2 = eval(node.children[1], memory);
|
||||||
return e1 + e2;
|
|
||||||
|
if (holds_alternative<double>(e1) || holds_alternative<double>(e2)) {
|
||||||
|
double d1 = double_cast(e1);
|
||||||
|
double d2 = double_cast(e2);
|
||||||
|
return d1 + d2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i1 = get<int>(e1);
|
||||||
|
int i2 = get<int>(e2);
|
||||||
|
return i1 + i2;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case NodeType::Minus: {
|
case NodeType::Minus: {
|
||||||
int e1 = get<int>(eval(node.children[0], memory));
|
EvalResult e1 = eval(node.children[0], memory);
|
||||||
int e2 = get<int>(eval(node.children[1], memory));
|
EvalResult e2 = eval(node.children[1], memory);
|
||||||
return e1 - e2;
|
|
||||||
|
if (holds_alternative<double>(e1) || holds_alternative<double>(e2)) {
|
||||||
|
double d1 = double_cast(e1);
|
||||||
|
double d2 = double_cast(e2);
|
||||||
|
return d1 - d2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i1 = get<int>(e1);
|
||||||
|
int i2 = get<int>(e2);
|
||||||
|
return i1 - i2;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case NodeType::Mult: {
|
case NodeType::Mult: {
|
||||||
int e1 = get<int>(eval(node.children[0], memory));
|
EvalResult e1 = eval(node.children[0], memory);
|
||||||
int e2 = get<int>(eval(node.children[1], memory));
|
EvalResult e2 = eval(node.children[1], memory);
|
||||||
return e1 * e2;
|
|
||||||
|
if (holds_alternative<double>(e1) || holds_alternative<double>(e2)) {
|
||||||
|
double d1 = double_cast(e1);
|
||||||
|
double d2 = double_cast(e2);
|
||||||
|
return d1 * d2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i1 = get<int>(e1);
|
||||||
|
int i2 = get<int>(e2);
|
||||||
|
return i1 * i2;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case NodeType::Div: {
|
case NodeType::Div: {
|
||||||
int e1 = get<int>(eval(node.children[0], memory));
|
EvalResult e1 = eval(node.children[0], memory);
|
||||||
int e2 = get<int>(eval(node.children[1], memory));
|
EvalResult e2 = eval(node.children[1], memory);
|
||||||
if (e2 == 0) throw RuntimeError("Division by 0", node.pos);
|
|
||||||
return e1 / e2;
|
if (holds_alternative<double>(e1) || holds_alternative<double>(e2)) {
|
||||||
|
double d1 = double_cast(e1);
|
||||||
|
double d2 = double_cast(e2);
|
||||||
|
if (d2 == 0) throw RuntimeError("Division by 0", node.pos);
|
||||||
|
return d1 / d2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i1 = get<int>(e1);
|
||||||
|
int i2 = get<int>(e2);
|
||||||
|
if (i2 == 0) throw RuntimeError("Division by 0", node.pos);
|
||||||
|
return i1 / i2;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case NodeType::Mod: {
|
case NodeType::Mod: {
|
||||||
int e1 = get<int>(eval(node.children[0], memory));
|
EvalResult e1 = eval(node.children[0], memory);
|
||||||
int e2 = get<int>(eval(node.children[1], memory));
|
EvalResult e2 = eval(node.children[1], memory);
|
||||||
if (e2 == 0) throw RuntimeError("Modulo by 0", node.pos);
|
|
||||||
return e1 % e2;
|
int i1 = get<int>(e1);
|
||||||
|
int i2 = get<int>(e2);
|
||||||
|
if (i2 == 0) throw RuntimeError("Modulo by 0", node.pos);
|
||||||
|
return i1 % i2;
|
||||||
} break;
|
} break;
|
||||||
case NodeType::UnaryPlus: {
|
case NodeType::UnaryPlus: {
|
||||||
int e1 = get<int>(eval(node.children[0], memory));
|
EvalResult e1 = eval(node.children[0], memory);
|
||||||
return +e1;
|
|
||||||
|
if (holds_alternative<int>(e1)) {
|
||||||
|
return +get<int>(e1);
|
||||||
|
}
|
||||||
|
else if (holds_alternative<double>(e1)) {
|
||||||
|
return +get<double>(e1);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case NodeType::UnaryMinus: {
|
case NodeType::UnaryMinus: {
|
||||||
int e1 = get<int>(eval(node.children[0], memory));
|
EvalResult e1 = eval(node.children[0], memory);
|
||||||
return -e1;
|
|
||||||
|
if (holds_alternative<int>(e1)) {
|
||||||
|
return -get<int>(e1);
|
||||||
|
}
|
||||||
|
else if (holds_alternative<double>(e1)) {
|
||||||
|
return -get<double>(e1);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case NodeType::Declaration: {
|
case NodeType::Declaration: {
|
||||||
Token typeTok = get<Token>(node.children[0]);
|
Token typeTok = get<Token>(node.children[0]);
|
||||||
@ -284,8 +363,15 @@ EvalResult eval(Node &ast, Memory &memory) {
|
|||||||
else {
|
else {
|
||||||
Token token = get<Token>(ast);
|
Token token = get<Token>(ast);
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
case TokenType::Int: {
|
case TokenType::Litteral: {
|
||||||
|
if (holds_alternative<int>(token.data)) {
|
||||||
return get<int>(token.data);
|
return get<int>(token.data);
|
||||||
|
} else if (holds_alternative<double>(token.data)) {
|
||||||
|
return get<double>(token.data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case TokenType::Identifier: {
|
case TokenType::Identifier: {
|
||||||
string identifier = get<string>(token.data);
|
string identifier = get<string>(token.data);
|
||||||
|
@ -354,7 +354,7 @@ ParseReturn parse_statement(vector<Token> tokens) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ParseReturn parse_expr_statement(vector<Token> tokens) {
|
ParseReturn parse_expr_statement(vector<Token> tokens) {
|
||||||
if (tokens.size() < 1 || tokens.back().type != TokenType::Type)
|
if (tokens.size() < 1 || tokens.back().type != TokenType::Identifier)
|
||||||
throw ParseException();
|
throw ParseException();
|
||||||
|
|
||||||
Token type = tokens.back();
|
Token type = tokens.back();
|
||||||
@ -638,7 +638,7 @@ ParseReturn parse_val(vector<Token> tokens) {
|
|||||||
throw ParseException();
|
throw ParseException();
|
||||||
|
|
||||||
switch (tokens.back().type) {
|
switch (tokens.back().type) {
|
||||||
case TokenType::Int: { //* Val -> Number
|
case TokenType::Litteral: { //* Val -> Number
|
||||||
Token number = tokens.back();
|
Token number = tokens.back();
|
||||||
tokens.pop_back();
|
tokens.pop_back();
|
||||||
return {
|
return {
|
||||||
|
215
src/tokenize.cpp
215
src/tokenize.cpp
@ -5,17 +5,43 @@
|
|||||||
#include "include/tokenize.h"
|
#include "include/tokenize.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
regex NUMBER_REGEX ("\\d+(\\.\\d+)?");
|
regex INT_REGEX ("\\d+");
|
||||||
regex TYPE_INT_REGEX ("int(\\s|$)");
|
regex DOUBLE_REGEX ("\\d+\\.\\d*|\\d*\\.\\d+");
|
||||||
regex IDENTIFIER_REGEX ("[A-Za-z_]\\w*");
|
regex IDENTIFIER_REGEX ("[A-Za-z_]\\w*");
|
||||||
|
|
||||||
|
vector<tuple<string, TokenType>> simpleTokens = {
|
||||||
|
{ "if", TokenType::If },
|
||||||
|
{ "else", TokenType::Else },
|
||||||
|
{ "while", TokenType::While },
|
||||||
|
{ "for", TokenType::For },
|
||||||
|
{ "++", TokenType::DoublePlus },
|
||||||
|
{ "--", TokenType::DoubleMinus },
|
||||||
|
{ "==", TokenType::DoubleEqual },
|
||||||
|
{ "&&", TokenType::Land },
|
||||||
|
{ "||", TokenType::Lor },
|
||||||
|
{ "<=", TokenType::Leq },
|
||||||
|
{ ">=", TokenType::Geq },
|
||||||
|
{ "!=", TokenType::NotEqual },
|
||||||
|
{ "<", TokenType::Lt },
|
||||||
|
{ ">", TokenType::Gt },
|
||||||
|
{ "!", TokenType::Not },
|
||||||
|
{ "+", TokenType::Plus },
|
||||||
|
{ "-", TokenType::Minus },
|
||||||
|
{ "*", TokenType::Star },
|
||||||
|
{ "/", TokenType::Slash },
|
||||||
|
{ "%", TokenType::Percent },
|
||||||
|
{ "=", TokenType::Equal },
|
||||||
|
{ ";", TokenType::Semicolon },
|
||||||
|
{ "(", TokenType::LParenthese },
|
||||||
|
{ ")", TokenType::RParenthese },
|
||||||
|
{ "{", TokenType::LCurlyBracket },
|
||||||
|
{ "}", TokenType::RCurlyBracket }
|
||||||
|
};
|
||||||
|
|
||||||
void _debug_print_token(Token token) {
|
void _debug_print_token(Token token) {
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
case TokenType::Type:
|
case TokenType::Litteral:
|
||||||
cout << "Type(INT)";
|
cout << "Litteral(" << "tmp" << ")";
|
||||||
break;
|
|
||||||
case TokenType::Int:
|
|
||||||
cout << "Number(" << get<int>(token.data) << ")";
|
|
||||||
break;
|
break;
|
||||||
case TokenType::Identifier:
|
case TokenType::Identifier:
|
||||||
cout << "Identifier(" << get<string>(token.data) << ")";
|
cout << "Identifier(" << get<string>(token.data) << ")";
|
||||||
@ -103,9 +129,8 @@ void _debug_print_token(Token token) {
|
|||||||
|
|
||||||
string _debug_print_token_type(TokenType type) {
|
string _debug_print_token_type(TokenType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TokenType::Type: return "Type";
|
|
||||||
case TokenType::Identifier: return "Identifier";
|
case TokenType::Identifier: return "Identifier";
|
||||||
case TokenType::Int: return "Int";
|
case TokenType::Litteral: return "Litteral";
|
||||||
case TokenType::Plus: return "Plus";
|
case TokenType::Plus: return "Plus";
|
||||||
case TokenType::Minus: return "Minus";
|
case TokenType::Minus: return "Minus";
|
||||||
case TokenType::DoublePlus: return "DoublePlus";
|
case TokenType::DoublePlus: return "DoublePlus";
|
||||||
@ -156,155 +181,41 @@ vector<Token> tokenize(vector<string> input, int initial_line) {
|
|||||||
string str = line.substr(j, string::npos);
|
string str = line.substr(j, string::npos);
|
||||||
smatch m;
|
smatch m;
|
||||||
|
|
||||||
if (regex_search(str, m, NUMBER_REGEX, regex_constants::match_continuous)) {
|
if (regex_search(str, m, DOUBLE_REGEX, regex_constants::match_continuous)) {
|
||||||
Token token = {
|
Token token = {
|
||||||
.type = TokenType::Int,
|
.type = TokenType::Litteral,
|
||||||
|
.data = stod(m.str()),
|
||||||
|
.pos = pos
|
||||||
|
};
|
||||||
|
tokens.emplace_back(token);
|
||||||
|
j += m.str().length();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regex_search(str, m, INT_REGEX, regex_constants::match_continuous)) {
|
||||||
|
Token token = {
|
||||||
|
.type = TokenType::Litteral,
|
||||||
.data = stoi(m.str()),
|
.data = stoi(m.str()),
|
||||||
.pos = pos
|
.pos = pos
|
||||||
};
|
};
|
||||||
tokens.emplace_back(token);
|
tokens.emplace_back(token);
|
||||||
j += m.str().length();
|
j += m.str().length();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (regex_search(str, m, TYPE_INT_REGEX, regex_constants::match_continuous)) {
|
|
||||||
Token token = {
|
bool matched = false;
|
||||||
.type = TokenType::Type,
|
for (auto simpleToken: simpleTokens) {
|
||||||
.data = Type::Int,
|
if (str.starts_with(get<0>(simpleToken))) {
|
||||||
.pos = pos
|
Token token = { .type = get<1>(simpleToken), .pos = pos };
|
||||||
};
|
|
||||||
tokens.emplace_back(token);
|
tokens.emplace_back(token);
|
||||||
j += m.str().length();
|
j += get<0>(simpleToken).length();
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (str.starts_with("if")) {
|
|
||||||
Token token = { .type = TokenType::If, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 2;
|
|
||||||
}
|
}
|
||||||
else if (str.starts_with("else")) {
|
if (matched) continue;
|
||||||
Token token = { .type = TokenType::Else, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
if (regex_search(str, m, IDENTIFIER_REGEX, regex_constants::match_continuous)) {
|
||||||
j += 4;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("while")) {
|
|
||||||
Token token = { .type = TokenType::While, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 5;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("for")) {
|
|
||||||
Token token = { .type = TokenType::For, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 3;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("++")) {
|
|
||||||
Token token = { .type = TokenType::DoublePlus, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 2;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("--")) {
|
|
||||||
Token token = { .type = TokenType::DoubleMinus, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 2;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("==")) {
|
|
||||||
Token token = { .type = TokenType::DoubleEqual, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 2;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("&&")) {
|
|
||||||
Token token = { .type = TokenType::Land, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 2;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("||")) {
|
|
||||||
Token token = { .type = TokenType::Lor, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 2;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("<=")) {
|
|
||||||
Token token = { .type = TokenType::Leq, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 2;
|
|
||||||
}
|
|
||||||
else if (str.starts_with(">=")) {
|
|
||||||
Token token = { .type = TokenType::Geq, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 2;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("!=")) {
|
|
||||||
Token token = { .type = TokenType::NotEqual, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 2;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("<")) {
|
|
||||||
Token token = { .type = TokenType::Lt, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with(">")) {
|
|
||||||
Token token = { .type = TokenType::Gt, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("!")) {
|
|
||||||
Token token = { .type = TokenType::Not, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("+")) {
|
|
||||||
Token token = { .type = TokenType::Plus, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("-")) {
|
|
||||||
Token token = { .type = TokenType::Minus, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("*")) {
|
|
||||||
Token token = { .type = TokenType::Star, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("/")) {
|
|
||||||
Token token = { .type = TokenType::Slash, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("%")) {
|
|
||||||
Token token = { .type = TokenType::Percent, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("=")) {
|
|
||||||
Token token = { .type = TokenType::Equal, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with(";")) {
|
|
||||||
Token token = { .type = TokenType::Semicolon, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("(")) {
|
|
||||||
Token token = { .type = TokenType::LParenthese, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with(")")) {
|
|
||||||
Token token = { .type = TokenType::RParenthese, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("{")) {
|
|
||||||
Token token = { .type = TokenType::LCurlyBracket, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (str.starts_with("}")) {
|
|
||||||
Token token = { .type = TokenType::RCurlyBracket, .pos = pos };
|
|
||||||
tokens.emplace_back(token);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
else if (regex_search(str, m, IDENTIFIER_REGEX, regex_constants::match_continuous)) {
|
|
||||||
Token token = {
|
Token token = {
|
||||||
.type = TokenType::Identifier,
|
.type = TokenType::Identifier,
|
||||||
.data = m.str(),
|
.data = m.str(),
|
||||||
@ -312,15 +223,17 @@ vector<Token> tokenize(vector<string> input, int initial_line) {
|
|||||||
};
|
};
|
||||||
tokens.emplace_back(token);
|
tokens.emplace_back(token);
|
||||||
j += m.str().length();
|
j += m.str().length();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (isspace(str[0])) {
|
|
||||||
|
if (isspace(str[0])) {
|
||||||
j += 1;
|
j += 1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
throw TokenError("Unknown token", pos);
|
throw TokenError("Unknown token", pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
@ -15,7 +15,7 @@ int main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
vector<TokenType> expectedTypes = {
|
vector<TokenType> expectedTypes = {
|
||||||
TokenType::Type, TokenType::Identifier, TokenType::Equal, TokenType::Identifier,
|
TokenType::Identifier, TokenType::Identifier, TokenType::Equal, TokenType::Identifier,
|
||||||
TokenType::DoublePlus, TokenType::DoubleMinus, TokenType::DoubleEqual, TokenType::Land,
|
TokenType::DoublePlus, TokenType::DoubleMinus, TokenType::DoubleEqual, TokenType::Land,
|
||||||
TokenType::Lor, TokenType::Lt, TokenType::Gt, TokenType::Leq, TokenType::Geq, TokenType::NotEqual,
|
TokenType::Lor, TokenType::Lt, TokenType::Gt, TokenType::Leq, TokenType::Geq, TokenType::NotEqual,
|
||||||
TokenType::Not, TokenType::Star, TokenType::Slash, TokenType::Percent, TokenType::Equal,
|
TokenType::Not, TokenType::Star, TokenType::Slash, TokenType::Percent, TokenType::Equal,
|
||||||
@ -42,12 +42,12 @@ int main() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(tokens[0].type == TokenType::Type),
|
_TEST_NO_EXCEPTION(tokens[0].type == TokenType::Identifier),
|
||||||
"Le premier token devrait être de type 'Type'",
|
"Le premier token devrait être de type 'Identifier'",
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(get<Type>(tokens[0].data) == Type::Int),
|
_TEST_NO_EXCEPTION(get<string>(tokens[0].data) == "int"),
|
||||||
"Les données du premier token devraient être 'Int'",
|
"Les données du premier token devraient être 'Int'",
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
@ -93,8 +93,8 @@ int main() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
_TEST_NO_EXCEPTION(tokens[6].type == TokenType::Int),
|
_TEST_NO_EXCEPTION(tokens[6].type == TokenType::Litteral),
|
||||||
"Le premier token devrait être de type 'Int'",
|
"Le premier token devrait être de type 'Litteral'",
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
_TEST_ASSERT(
|
_TEST_ASSERT(
|
||||||
|
Loading…
Reference in New Issue
Block a user