From 1dec4b3c4f2d4f52497fe4786c75aa909aebf524 Mon Sep 17 00:00:00 2001 From: ala89 Date: Mon, 27 Nov 2023 21:16:39 +0100 Subject: [PATCH] Add semantic of bool logic and comparisons + tests --- src/interpreter.cpp | 65 +++++++++++++++++++++++++++++++++++++ test/bool_logic.cpp | 63 +++++++++++++++++++++++++++++++++++ test/expr_arithmetiques.cpp | 30 +++++++++++++++-- test/tokenize.cpp | 2 +- 4 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 test/bool_logic.cpp diff --git a/src/interpreter.cpp b/src/interpreter.cpp index f7e1fe6..eba9b84 100644 --- a/src/interpreter.cpp +++ b/src/interpreter.cpp @@ -6,6 +6,18 @@ #include "include/memory.h" using namespace std; +bool bool_cast(EvalResult value) { + if (holds_alternative(value)) { + return get(value) != 0; + } + else if (holds_alternative(value)) { + return get(value) != 0; + } + else { + throw; + } +} + EvalResult eval(Node &ast, Memory &memory) { if (holds_alternative(ast)) { InnerNode node = get(ast); @@ -44,6 +56,59 @@ EvalResult eval(Node &ast, Memory &memory) { memory.remove_scope(); return {}; } 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: { int e1 = get(eval(node.children[0], memory)); int e2 = get(eval(node.children[1], memory)); diff --git a/test/bool_logic.cpp b/test/bool_logic.cpp new file mode 100644 index 0000000..9dc4b4b --- /dev/null +++ b/test/bool_logic.cpp @@ -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 tokens = tokenize({ s }); + Node ast = parse(tokens); + EvalResult res = eval(ast, memory); + + return get(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; +} \ No newline at end of file diff --git a/test/expr_arithmetiques.cpp b/test/expr_arithmetiques.cpp index 09b833e..ddc1f5c 100644 --- a/test/expr_arithmetiques.cpp +++ b/test/expr_arithmetiques.cpp @@ -25,7 +25,7 @@ int main() { _TEST_ASSERT( _TEST_NO_EXCEPTION(execute("12 - 4 - 20;") == -12), - "Ordre de soustraction", + "Parenthésage", true ); @@ -36,13 +36,13 @@ int main() { ); _TEST_ASSERT( - _TEST_IS_EXCEPTION(execute("1 / (5 - 5);"), RuntimeError), + _TEST_IS_EXCEPTION(execute("1 / 0;"), RuntimeError), "Division par 0", true ); _TEST_ASSERT( - _TEST_IS_EXCEPTION(execute("1 % (5 - 5);"), RuntimeError), + _TEST_IS_EXCEPTION(execute("1 % 0;"), RuntimeError), "Modulo par 0", true ); @@ -65,5 +65,29 @@ int main() { 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; } \ No newline at end of file diff --git a/test/tokenize.cpp b/test/tokenize.cpp index 4c19967..c97b5a3 100644 --- a/test/tokenize.cpp +++ b/test/tokenize.cpp @@ -109,7 +109,7 @@ int main() { false ) - _TEST_ASSERT(true, "+++", true) + _TEST_ASSERT(true, "Triple plus", true) } /* Incorrect input */