Skip to content

Commit e10b925

Browse files
committed
Add workaround for log & ln function
1 parent 6841ad5 commit e10b925

File tree

3 files changed

+67
-6
lines changed

3 files changed

+67
-6
lines changed

Flow.Launcher.Test/Plugins/CalculatorTest.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@ public CalculatorPluginTest()
5353
[TestCase(@"min(1,-1,-2)", "-2")]
5454
[TestCase(@"max(1,-1,-2)", "1")]
5555
[TestCase(@"sqrt(16)", "4")]
56-
[TestCase(@"sin(pi)", "0")]
56+
[TestCase(@"sin(pi)", "0.0000000000")]
5757
[TestCase(@"cos(0)", "1")]
5858
[TestCase(@"tan(0)", "0")]
59+
[TestCase(@"log10(100)", "2")]
5960
[TestCase(@"log(100)", "2")]
61+
[TestCase(@"log2(8)", "3")]
6062
[TestCase(@"ln(e)", "1")]
6163
[TestCase(@"abs(-5)", "5")]
6264
// Constants

Plugins/Flow.Launcher.Plugin.Calculator/Main.cs

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public class Main : IPlugin, IPluginI18n, ISettingProvider
1616
private static readonly Regex ThousandGroupRegex = MainRegexHelper.GetThousandGroupRegex();
1717
private static readonly Regex NumberRegex = MainRegexHelper.GetNumberRegex();
1818
private static readonly Regex PowRegex = MainRegexHelper.GetPowRegex();
19+
private static readonly Regex LogRegex = MainRegexHelper.GetLogRegex();
20+
private static readonly Regex LnRegex = MainRegexHelper.GetLnRegex();
1921
private static readonly Regex FunctionRegex = MainRegexHelper.GetFunctionRegex();
2022

2123
private static Engine MagesEngine;
@@ -67,12 +69,36 @@ public List<Result> Query(Query query)
6769
// https://github.com/FlorianRappl/Mages/issues/132
6870
// We bypass it by rewriting any pow(x,y) expression to the equivalent (x^y) expression
6971
// before the engine sees it. This loop handles nested calls.
70-
string previous;
71-
do
7272
{
73-
previous = expression;
74-
expression = PowRegex.Replace(previous, PowMatchEvaluator);
75-
} while (previous != expression);
73+
string previous;
74+
do
75+
{
76+
previous = expression;
77+
expression = PowRegex.Replace(previous, PowMatchEvaluator);
78+
} while (previous != expression);
79+
}
80+
// WORKAROUND END
81+
82+
// WORKAROUND START: The 'log' & 'ln' function in Mages v3.0.0 are broken.
83+
// https://github.com/FlorianRappl/Mages/issues/137
84+
// We bypass it by rewriting any log & ln expression to the equivalent (log10 & log) expression
85+
// before the engine sees it. This loop handles nested calls.
86+
{
87+
string previous;
88+
do
89+
{
90+
previous = expression;
91+
expression = LogRegex.Replace(previous, LogMatchEvaluator);
92+
} while (previous != expression);
93+
}
94+
{
95+
string previous;
96+
do
97+
{
98+
previous = expression;
99+
expression = LnRegex.Replace(previous, LnMatchEvaluator);
100+
} while (previous != expression);
101+
}
76102
// WORKAROUND END
77103

78104
var result = MagesEngine.Interpret(expression);
@@ -200,6 +226,33 @@ private static string PowMatchEvaluator(Match m)
200226
return $"({arg1}^{arg2})";
201227
}
202228

229+
private static string LogMatchEvaluator(Match m)
230+
{
231+
// m.Groups[1].Value will be `(...)` with parens
232+
var contentWithParen = m.Groups[1].Value;
233+
var argsContent = contentWithParen[1..^1];
234+
235+
// log is unary — if malformed, return original to let Mages handle it
236+
var arg = argsContent.Trim();
237+
if (string.IsNullOrEmpty(arg)) return m.Value;
238+
239+
// log(x) -> log10(x) (natural log)
240+
return $"(log10({arg}))";
241+
}
242+
243+
private static string LnMatchEvaluator(Match m)
244+
{
245+
// m.Groups[1].Value will be `(...)` with parens
246+
var contentWithParen = m.Groups[1].Value;
247+
var argsContent = contentWithParen[1..^1];
248+
249+
// ln is unary — if malformed, return original to let Mages handle it
250+
var arg = argsContent.Trim();
251+
if (string.IsNullOrEmpty(arg)) return m.Value;
252+
253+
// ln(x) -> log(x) (natural log)
254+
return $"(log({arg}))";
255+
}
203256
private static string NormalizeNumber(string numberStr, bool isFunctionPresent, string decimalSep, string groupSep)
204257
{
205258
if (isFunctionPresent)

Plugins/Flow.Launcher.Plugin.Calculator/MainRegexHelper.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ internal static partial class MainRegexHelper
1313
[GeneratedRegex(@"\bpow(\((?:[^()\[\]]|\((?<Depth>)|\)(?<-Depth>)|\[(?<Depth>)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
1414
public static partial Regex GetPowRegex();
1515

16+
[GeneratedRegex(@"\blog(\((?:[^()\[\]]|\((?<Depth>)|\)(?<-Depth>)|\[(?<Depth>)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
17+
public static partial Regex GetLogRegex();
18+
19+
[GeneratedRegex(@"\bln(\((?:[^()\[\]]|\((?<Depth>)|\)(?<-Depth>)|\[(?<Depth>)|\](?<-Depth>))*(?(Depth)(?!))\))", RegexOptions.Compiled | RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
20+
public static partial Regex GetLnRegex();
21+
1622
[GeneratedRegex(@"\b(sqrt|pow|factorial|abs|sign|ceil|floor|round|exp|log|log2|log10|min|max|lt|eq|gt|sin|cos|tan|arcsin|arccos|arctan|isnan|isint|isprime|isinfty|rand|randi|type|is|as|length|throw|catch|eval|map|clamp|lerp|regex|shuffle)\s*\(", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
1723
public static partial Regex GetFunctionRegex();
1824
}

0 commit comments

Comments
 (0)