From 372064af20a456989c2a9ea2fda6e535d74dbafd Mon Sep 17 00:00:00 2001
From: Egor Tensin <Egor.Tensin@gmail.com>
Date: Mon, 30 Dec 2019 13:06:13 +0300
Subject: support the power (^) operator

It doesn't work with the unary minus currently (as is reflected in the
tests), it should have a higher precedence.
---
 test/unit_tests/lexer.cpp  | 10 ++++++++++
 test/unit_tests/parser.cpp |  8 ++++++++
 2 files changed, 18 insertions(+)

(limited to 'test')

diff --git a/test/unit_tests/lexer.cpp b/test/unit_tests/lexer.cpp
index aa4011c..0f65979 100644
--- a/test/unit_tests/lexer.cpp
+++ b/test/unit_tests/lexer.cpp
@@ -53,6 +53,7 @@ BOOST_AUTO_TEST_CASE(test_parse_const_token) {
     // parse_* functions only consume a single token:
     BOOST_TEST(details::parse_const_token("+/*").value() == Type::PLUS);
     BOOST_TEST(details::parse_const_token("-").value() == Type::MINUS);
+    BOOST_TEST(details::parse_const_token("^^").value() == Type::CARET);
     BOOST_TEST(!details::parse_const_token("&+").has_value());
 }
 
@@ -63,6 +64,7 @@ const std::vector<std::string_view> input{
     "",
     " + - ",
     "1+2",
+    ".5^-1 ^ 4",
     "1+2 *  (3- 4e-2)",
     " 2 * (1 + 3 * (1 - -3)) ",
 };
@@ -92,6 +94,14 @@ const std::vector<Expected> expected{
         Token{Type::PLUS},
         Token{2},
     }},
+    {{
+        Token{.5},
+        Token{Type::CARET},
+        Token{Type::MINUS},
+        Token{1},
+        Token{Type::CARET},
+        Token{4},
+    }},
     {{
         Token{1},
         Token{Type::PLUS},
diff --git a/test/unit_tests/parser.cpp b/test/unit_tests/parser.cpp
index 562c6b7..37d9e0a 100644
--- a/test/unit_tests/parser.cpp
+++ b/test/unit_tests/parser.cpp
@@ -30,6 +30,10 @@ const std::vector<std::string_view> input{
     " 2 * (1 + 3) ",
     " 2 * (1 + 3 * (1 - -3)) ",
     " -2 * ---- (3 + -100e-1)  ", // Looks weird, but also works in e.g. Python
+    "2 ^ 3 ^ 3",
+    "(2 ^ 3) ^ 3", // Power operator is right-associative
+    "(.5 ^ -1) ^ 4",
+    ".5 ^ -1 ^ 4", // Power operator has higher precedence than the unary minus
 };
 
 const std::vector<double> expected{
@@ -39,6 +43,10 @@ const std::vector<double> expected{
     8,
     26,
     14,
+    134217728,
+    512,
+    16,
+    2,
 };
 
 }
-- 
cgit v1.2.3