Add semantic of bool logic and comparisons + tests

This commit is contained in:
ala89 2023-11-27 21:16:39 +01:00
parent 285c054d37
commit 1dec4b3c4f
4 changed files with 156 additions and 4 deletions

View File

@ -6,6 +6,18 @@
#include "include/memory.h" #include "include/memory.h"
using namespace std; using namespace std;
bool bool_cast(EvalResult value) {
if (holds_alternative<int>(value)) {
return get<int>(value) != 0;
}
else if (holds_alternative<double>(value)) {
return get<double>(value) != 0;
}
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);
@ -44,6 +56,59 @@ EvalResult eval(Node &ast, Memory &memory) {
memory.remove_scope(); memory.remove_scope();
return {}; return {};
} break; } break;
case NodeType::Eq: {
EvalResult e1 = eval(node.children[0], memory);
EvalResult e2 = eval(node.children[1], memory);
return e1 == e2;
} break;
case NodeType::Neq: {
EvalResult e1 = eval(node.children[0], memory);
EvalResult e2 = eval(node.children[1], memory);
return e1 != e2;
} break;
case NodeType::Lor: {
EvalResult e1 = eval(node.children[0], memory);
EvalResult e2 = eval(node.children[1], memory);
return bool_cast(e1) || bool_cast(e2);
} break;
case NodeType::Land: {
EvalResult e1 = eval(node.children[0], memory);
EvalResult e2 = eval(node.children[1], memory);
return bool_cast(e1) && bool_cast(e2);
} break;
case NodeType::Neg: {
EvalResult e1 = eval(node.children[0], memory);
return !bool_cast(e1);
} break;
case NodeType::Lt: {
EvalResult e1 = eval(node.children[0], memory);
EvalResult e2 = eval(node.children[1], memory);
return e1 < e2;
} break;
case NodeType::Gt: {
EvalResult e1 = eval(node.children[0], memory);
EvalResult e2 = eval(node.children[1], memory);
return e1 > e2;
} break;
case NodeType::Leq: {
EvalResult e1 = eval(node.children[0], memory);
EvalResult e2 = eval(node.children[1], memory);
return e1 <= e2;
} break;
case NodeType::Geq: {
EvalResult e1 = eval(node.children[0], memory);
EvalResult e2 = eval(node.children[1], memory);
return e1 >= e2;
} break;
case NodeType::Plus: { case NodeType::Plus: {
int e1 = get<int>(eval(node.children[0], memory)); int e1 = get<int>(eval(node.children[0], memory));
int e2 = get<int>(eval(node.children[1], memory)); int e2 = get<int>(eval(node.children[1], memory));

63
test/bool_logic.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "include/test.h"
#include "../src/include/memory.h"
#include "../src/include/tokenize.h"
#include "../src/include/parser.h"
#include "../src/include/interpreter.h"
int execute(string s) {
Memory memory = Memory();
vector<Token> tokens = tokenize({ s });
Node ast = parse(tokens);
EvalResult res = eval(ast, memory);
return get<int>(res);
}
int main() {
_TEST_PRESENTATION("Logique Booléenne");
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("1 && 0;") == 0),
"Et",
true
);
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("1 || 0;") == 1),
"Ou",
true
);
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("!1;") == 0),
"Négation",
true
);
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("2 == 2;") == 1),
"Égalité",
true
);
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("2 != 2;") == 0),
"Différence",
true
);
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("0 == 0 || 1;") == 1),
"Parenthésage",
true
);
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("2 == 1 + 1;") == 1),
"Priorités",
true
);
return 0;
}

View File

@ -25,7 +25,7 @@ int main() {
_TEST_ASSERT( _TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("12 - 4 - 20;") == -12), _TEST_NO_EXCEPTION(execute("12 - 4 - 20;") == -12),
"Ordre de soustraction", "Parenthésage",
true true
); );
@ -36,13 +36,13 @@ int main() {
); );
_TEST_ASSERT( _TEST_ASSERT(
_TEST_IS_EXCEPTION(execute("1 / (5 - 5);"), RuntimeError), _TEST_IS_EXCEPTION(execute("1 / 0;"), RuntimeError),
"Division par 0", "Division par 0",
true true
); );
_TEST_ASSERT( _TEST_ASSERT(
_TEST_IS_EXCEPTION(execute("1 % (5 - 5);"), RuntimeError), _TEST_IS_EXCEPTION(execute("1 % 0;"), RuntimeError),
"Modulo par 0", "Modulo par 0",
true true
); );
@ -65,5 +65,29 @@ int main() {
true true
); );
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("1 < 2;") == 1),
"Inférieur strict",
true
);
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("2 > 3;") == 0),
"Supérieur strict",
true
);
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("2 <= 1;") == 0),
"Inférieur ou égal",
true
);
_TEST_ASSERT(
_TEST_NO_EXCEPTION(execute("2 >= 1;") == 1),
"Supérieur ou égal",
true
);
return 0; return 0;
} }

View File

@ -109,7 +109,7 @@ int main() {
false false
) )
_TEST_ASSERT(true, "+++", true) _TEST_ASSERT(true, "Triple plus", true)
} }
/* Incorrect input */ /* Incorrect input */