Set up rime-frost basic configuration
This commit is contained in:
251
lua/calculator.lua
Normal file
251
lua/calculator.lua
Normal file
@@ -0,0 +1,251 @@
|
||||
-- author: https://github.com/ChaosAlphard
|
||||
-- 说明 https://github.com/gaboolic/rime-shuangpin-fuzhuma/pull/41
|
||||
local M = {}
|
||||
|
||||
function M.init(env)
|
||||
local config = env.engine.schema.config
|
||||
env.name_space = env.name_space:gsub('^*', '')
|
||||
M.prefix = config:get_string(env.name_space .. '/trigger') or 'V'
|
||||
end
|
||||
|
||||
local function startsWith(str, start)
|
||||
return string.sub(str, 1, string.len(start)) == start
|
||||
end
|
||||
|
||||
local function truncateFromStart(str, truncateStr)
|
||||
return string.sub(str, string.len(truncateStr) + 1)
|
||||
end
|
||||
|
||||
-- 函数表
|
||||
local calcPlugin = {
|
||||
-- e, exp(1) = e^1 = e
|
||||
e = math.exp(1),
|
||||
-- π
|
||||
pi = math.pi
|
||||
}
|
||||
|
||||
-- random([m [,n ]]) 返回m-n之间的随机数, n为空则返回1-m之间, 都为空则返回0-1之间的小数
|
||||
local function random(...)
|
||||
return math.random(...)
|
||||
end
|
||||
-- 注册到函数表中
|
||||
calcPlugin["rdm"] = random
|
||||
|
||||
-- 正弦
|
||||
local function sin(x)
|
||||
return math.sin(x)
|
||||
end
|
||||
calcPlugin["sin"] = sin
|
||||
|
||||
-- 双曲正弦
|
||||
local function sinh(x)
|
||||
return math.sinh(x)
|
||||
end
|
||||
calcPlugin["sinh"] = sinh
|
||||
|
||||
-- 反正弦
|
||||
local function asin(x)
|
||||
return math.asin(x)
|
||||
end
|
||||
calcPlugin["asin"] = asin
|
||||
|
||||
-- 余弦
|
||||
local function cos(x)
|
||||
return math.cos(x)
|
||||
end
|
||||
calcPlugin["cos"] = cos
|
||||
|
||||
-- 双曲余弦
|
||||
local function cosh(x)
|
||||
return math.cosh(x)
|
||||
end
|
||||
calcPlugin["cosh"] = cosh
|
||||
|
||||
-- 反余弦
|
||||
local function acos(x)
|
||||
return math.acos(x)
|
||||
end
|
||||
calcPlugin["acos"] = acos
|
||||
|
||||
-- 正切
|
||||
local function tan(x)
|
||||
return math.tan(x)
|
||||
end
|
||||
calcPlugin["tan"] = tan
|
||||
|
||||
-- 双曲正切
|
||||
local function tanh(x)
|
||||
return math.tanh(x)
|
||||
end
|
||||
calcPlugin["tanh"] = tanh
|
||||
|
||||
-- 反正切
|
||||
local function atan(x)
|
||||
return math.atan(x)
|
||||
end
|
||||
calcPlugin["atan"] = atan
|
||||
|
||||
-- 返回以弧度为单位的点(x,y)相对于x轴的逆时针角度。y是点的纵坐标,x是点的横坐标
|
||||
-- 返回范围从−π到π (以弧度为单位),其中负角度表示向下旋转,正角度表示向上旋转
|
||||
-- 它与传统的 math.atan(y/x) 函数相比,具有更好的数学定义,因为它能够正确处理边界情况(例如x=0)
|
||||
local function atan2(y, x)
|
||||
return math.atan2(y, x)
|
||||
end
|
||||
calcPlugin["atan2"] = atan2
|
||||
|
||||
-- 将角度从弧度转换为度 e.g. deg(π) = 180
|
||||
local function deg(x)
|
||||
return math.deg(x)
|
||||
end
|
||||
calcPlugin["deg"] = deg
|
||||
|
||||
-- 将角度从度转换为弧度 e.g. rad(180) = π
|
||||
local function rad(x)
|
||||
return math.rad(x)
|
||||
end
|
||||
calcPlugin["rad"] = rad
|
||||
|
||||
-- 返回两个值, 无法参与运算后续
|
||||
-- 返回m,e 使得x = m*2^e
|
||||
-- local function frexp(x)
|
||||
-- return math.frexp(x)
|
||||
-- end
|
||||
-- calcPlugin["frexp"] = frexp
|
||||
|
||||
-- 返回 x*2^y
|
||||
local function ldexp(x, y)
|
||||
return math.ldexp(x, y)
|
||||
end
|
||||
calcPlugin["ldexp"] = ldexp
|
||||
|
||||
-- 返回 e^x
|
||||
local function exp(x)
|
||||
return math.exp(x)
|
||||
end
|
||||
calcPlugin["exp"] = exp
|
||||
|
||||
-- 返回x的平方根 e.g. sqrt(x) = x^0.5
|
||||
local function sqrt(x)
|
||||
return math.sqrt(x)
|
||||
end
|
||||
calcPlugin["sqrt"] = sqrt
|
||||
|
||||
-- x为底的对数, log(10, 100) = log(100) / log(10) = 2
|
||||
local function log(x, y)
|
||||
-- 不能为负数或0
|
||||
if x <= 0 or y <= 0 then return nil end
|
||||
|
||||
return math.log(y) / math.log(x)
|
||||
end
|
||||
calcPlugin["log"] = log
|
||||
|
||||
-- 自然数e为底的对数
|
||||
local function loge(x)
|
||||
-- 不能为负数或0
|
||||
if x <= 0 then return nil end
|
||||
|
||||
return math.log(x)
|
||||
end
|
||||
calcPlugin["loge"] = loge
|
||||
|
||||
-- 10为底的对数
|
||||
local function log10(x)
|
||||
-- 不能为负数或0
|
||||
if x <= 0 then return nil end
|
||||
|
||||
return math.log10(x)
|
||||
end
|
||||
calcPlugin["log10"] = log10
|
||||
|
||||
-- 平均值
|
||||
local function avg(...)
|
||||
local data = {...}
|
||||
local n = select("#", ...)
|
||||
-- 样本数量不能为0
|
||||
if n == 0 then return nil end
|
||||
|
||||
-- 计算总和
|
||||
local sum = 0
|
||||
for _, value in ipairs(data) do
|
||||
sum = sum + value
|
||||
end
|
||||
|
||||
return sum / n
|
||||
end
|
||||
calcPlugin["avg"] = avg
|
||||
|
||||
-- 方差
|
||||
local function variance(...)
|
||||
local data = {...}
|
||||
local n = select("#", ...)
|
||||
-- 样本数量不能为0
|
||||
if n == 0 then return nil end
|
||||
|
||||
-- 计算均值
|
||||
local sum = 0
|
||||
for _, value in ipairs(data) do
|
||||
sum = sum + value
|
||||
end
|
||||
local mean = sum / n
|
||||
|
||||
-- 计算方差
|
||||
local sum_squared_diff = 0
|
||||
for _, value in ipairs(data) do
|
||||
sum_squared_diff = sum_squared_diff + (value - mean)^2
|
||||
end
|
||||
|
||||
return sum_squared_diff / n
|
||||
end
|
||||
calcPlugin["var"] = variance
|
||||
|
||||
-- 阶乘
|
||||
local function factorial(x)
|
||||
-- 不能为负数
|
||||
if x < 0 then return nil end
|
||||
if x == 0 or x == 1 then return 1 end
|
||||
|
||||
local result = 1
|
||||
for i = 1, x do
|
||||
result = result * i
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
calcPlugin["fact"] = factorial
|
||||
|
||||
-- 实现阶乘计算(!)
|
||||
local function replaceToFactorial(str)
|
||||
-- 替换[0-9]!字符为fact([0-9])以实现阶乘
|
||||
return str:gsub("([0-9]+)!", "fact(%1)")
|
||||
end
|
||||
|
||||
-- 简单计算器
|
||||
function M.func(input, seg, env)
|
||||
if not startsWith(input, M.prefix) then return end
|
||||
-- 提取算式
|
||||
local express = truncateFromStart(input, M.prefix)
|
||||
-- 算式长度 < 2 直接终止(没有计算意义)
|
||||
if (string.len(express) < 2) then return end
|
||||
-- pcall()的原因需要控制一下 . 符号的位置
|
||||
-- 现在不需要了
|
||||
-- if (string.match(express, "[^0-9]%.")) then
|
||||
-- yield(Candidate(input, seg.start, seg._end, express, "小数点不能在非数字字符后面"))
|
||||
-- return
|
||||
-- end
|
||||
local code = replaceToFactorial(express)
|
||||
|
||||
local success, result = pcall(load("return " .. code, "calculate", "t", calcPlugin))
|
||||
if success then
|
||||
yield(Candidate(input, seg.start, seg._end, result, ""))
|
||||
yield(Candidate(input, seg.start, seg._end, express .. "=" .. result, ""))
|
||||
else
|
||||
yield(Candidate(input, seg.start, seg._end, express, "解析失败"))
|
||||
yield(Candidate(input, seg.start, seg._end, code, "入参"))
|
||||
-- TODO: 错误信息记录到日志中
|
||||
-- print("express: " .. express)
|
||||
-- print("code: " .. code)
|
||||
-- print("result: " .. result)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user