rimeIce/lua/calc_translator.lua

210 lines
6.1 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 计算器插件
-- author: https://github.com/ChaosAlphard
local calc = {}
function calc.init( env )
local config = env.engine.schema.config
env.prefix = config:get_string( 'calculator/prefix' ) or 'cC'
env.show_prefix = config:get_bool( 'calculator/show_prefix' ) -- set to true to show prefix in preedit area
-- env.decimalPlaces = config:get_string('calculator/decimalPlaces') or '4'
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 function yield_calc_cand( seg, cand_text, cand_comment, cand_preedit, show_prefix )
local cand = Candidate( 'calc', seg.start, seg._end, cand_text, cand_comment )
cand.quality = 99999
if not show_prefix then cand.preedit = cand_preedit end
yield( cand )
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
calcPlugin['random'] = 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
-- 反正切
-- 返回以弧度为单位的点相对于x轴的逆时针角度。x是点的横纵坐标比值
-- 返回范围从−π到π (以弧度为单位),其中负角度表示向下旋转,正角度表示向上旋转
local function atan( x ) return math.atan( x ) end
calcPlugin['atan'] = atan
-- 反正切
-- atan( y/x ) = atan2(y, x)
-- 返回以弧度为单位的点相对于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 )
local m, e = math.frexp( x )
return m .. ' * 2^' .. e
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
-- y为底x的对数, 使用换底公式实现
local function log( y, x )
-- 不能为负数或0
if x <= 0 or y <= 0 then return nil end
return math.log( x ) / math.log( y )
end
calcPlugin['log'] = log
-- e为底x的对数
local function loge( x )
-- 不能为负数或0
if x <= 0 then return nil end
return math.log( x )
end
calcPlugin['loge'] = loge
-- 10为底x的对数
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 calc.func( input, seg, env )
if not seg:has_tag( 'calculator' ) or input == '' then return end
-- 提取算式
local express = truncateFromStart( input, env.prefix )
if express == '' then return end -- 防止用户写错了正则表达式造成错误
local code = replaceToFactorial( express )
local success, result = pcall( load( 'return ' .. code, 'calculate', 't', calcPlugin ) )
if success and result and (type( result ) == 'string' or type( result ) == 'number') and #tostring( result ) > 0 then
yield_calc_cand( seg, result, '', express, env.show_prefix )
yield_calc_cand( seg, express .. '=' .. result, '', express, env.show_prefix )
else
yield_calc_cand( seg, express, '解析失败', express, env.show_prefix )
yield_calc_cand( seg, code, '入参', express, env.show_prefix )
end
end
return calc