From f4f786e3a6dff43c5cca10c9f4f44cb3ce48ce50 Mon Sep 17 00:00:00 2001 From: mmatera Date: Sat, 30 Nov 2024 11:45:19 -0300 Subject: [PATCH 1/3] add a WL module with functions to test relative precedences of operators. --- test/testprecedence.m | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 test/testprecedence.m diff --git a/test/testprecedence.m b/test/testprecedence.m new file mode 100644 index 0000000..0b73e12 --- /dev/null +++ b/test/testprecedence.m @@ -0,0 +1,49 @@ + +PrecedenceOrderByParsing::usage="`PrecedenceOrderByParsing[op1, op2]` \ +Evaluates the precedence ordering of two operators, according the way they are parsed. 1 if op1 has lower precedence than op2, +0 if they are equal and -1 if op2 has lower precedence than op1. If order cannot be determined, return None. +" + +CheckPrecedenceOutput::usage="`CheckPrecedenceOutput[op]`\ checks if the Precedence value reported by `Precedence[op]` is \ +consistent with the way in which expressions involving `op` are formatted when are inside an `Infix` expression." + + +(*Check the order of the precedence for two operators +by looking how are they parsed. +*) +PrecedenceOrderByParsing[op1_String, op2_String] := + Module[{a, b, c, h1, h2, hl, hr, testexpr}, + h1 = ToExpression["a" <> op1 <> "b"][[0]]; + h2 = ToExpression["a" <> op2 <> "b"][[0]]; + hl = Head[ToExpression["a" <> op1 <> "b" <> op2 <> "c"]]; + hr = Head[ToExpression["a" <> op2 <> "b" <> op1 <> "c"]]; + If[hl === hr, Return[If[hl === h1, 1, If[hl === h2, -1, None]]], + Return[0]] + ] + + +(*Check if the OutputForm is consistent with the precedence*) +CheckPrecedenceOutput[op_String] := + Module[{a, b, c, precedence, testexpr, test, lesseq, largeeq}, + testexpr = ToExpression["b" <> op <> "c"]; + precedence = IntegerPart[Precedence[Head[testexpr]]]; + test = ToString[Infix[{a, testexpr}, "~", precedence - 1, None], + OutputForm]; + If[StringPart[test, -1] == ")", Return[False]]; + test = ToString[Infix[{a, testexpr}, "~", precedence, None], + OutputForm]; + If[StringPart[test, -1] != ")", Return[False]]; + test = ToString[Infix[{a, testexpr}, "~", precedence + 1, None], + OutputForm]; + If[StringPart[test, -1] != ")", Return[False]]; + test = ToString[Infix[{testexpr, a}, "~", precedence - 1, None], + OutputForm]; + If[StringPart[test, 1] == "(", Return[False]]; + test = ToString[Infix[{testexpr, a}, "~", precedence, None], + OutputForm]; + If[StringPart[test, 1] != "(", Return[False]]; + test = ToString[Infix[{testexpr, a}, "~", precedence + 1, None], + OutputForm]; + If[StringPart[test, 1] != "(", Return[False]]; + True + ] From 0143186ddaa0b52f68877d14626ae237d7f196e3 Mon Sep 17 00:00:00 2001 From: mmatera Date: Sat, 30 Nov 2024 11:46:35 -0300 Subject: [PATCH 2/3] begin and end package --- test/testprecedence.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/testprecedence.m b/test/testprecedence.m index 0b73e12..c05304e 100644 --- a/test/testprecedence.m +++ b/test/testprecedence.m @@ -8,6 +8,9 @@ consistent with the way in which expressions involving `op` are formatted when are inside an `Infix` expression." +BeginPackage["testprecedences`"]; + + (*Check the order of the precedence for two operators by looking how are they parsed. *) @@ -47,3 +50,5 @@ If[StringPart[test, 1] != "(", Return[False]]; True ] + +EndPackage[] \ No newline at end of file From 0feb4377fb47e530d9adbde393742d5d5f21ff21 Mon Sep 17 00:00:00 2001 From: mmatera Date: Sat, 30 Nov 2024 11:56:55 -0300 Subject: [PATCH 3/3] longer explanation --- test/testprecedence.m | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/test/testprecedence.m b/test/testprecedence.m index c05304e..dc49193 100644 --- a/test/testprecedence.m +++ b/test/testprecedence.m @@ -1,4 +1,31 @@ + +(**************************************************************) +(* + Tools for check the consistency of precedence data. + + Functions on this package takes strings representing + operators. + For example, + ``` + PrecedenceOrderByParsing["+","*"] + ``` + compares how the expressions `a+b*c` and `a*b+c` are parsed + to determine the precedence of `+` relative to `*`, without using + `Precedence` explicitly. + + On the other hand, `CheckPrecedenceOutput["+"]` checks that + the OutputForm of expressions of the form + `Infix[{s,a+b},"~", prec, None]` is formatted adding parenthesis + in the right place, for prec around the value reported + by `Precedence[Head[a+b]]`. + +*) +(**************************************************************) + +BeginPackage["testprecedences`"]; + + PrecedenceOrderByParsing::usage="`PrecedenceOrderByParsing[op1, op2]` \ Evaluates the precedence ordering of two operators, according the way they are parsed. 1 if op1 has lower precedence than op2, 0 if they are equal and -1 if op2 has lower precedence than op1. If order cannot be determined, return None. @@ -8,12 +35,13 @@ consistent with the way in which expressions involving `op` are formatted when are inside an `Infix` expression." -BeginPackage["testprecedences`"]; - - +Begin["`Private`"] (*Check the order of the precedence for two operators by looking how are they parsed. *) + + + PrecedenceOrderByParsing[op1_String, op2_String] := Module[{a, b, c, h1, h2, hl, hr, testexpr}, h1 = ToExpression["a" <> op1 <> "b"][[0]]; @@ -50,5 +78,5 @@ If[StringPart[test, 1] != "(", Return[False]]; True ] - +End[] EndPackage[] \ No newline at end of file