类型后端
计算器引擎的数值实现由 5 个 SimpleCalculatorFactory 子类提供,全部位于 openmods.calc.types。它们共享同一套构建契约(src/main/java/openmods/calc/SimpleCalculatorFactory.java:5),玩家可在运行时用 =config new <类型> 切换。
MULTI(多类型值)后端规模远超其它四个(2415 行 vs 171–403 行),单独成页:多类型值系统。
基本信息
| 后端 | 工厂类 | 数值类型 | 文件行数 |
|---|---|---|---|
DOUBLE |
openmods.calc.types.fp.DoubleCalculatorFactory |
java.lang.Double |
403 |
FRACTION |
openmods.calc.types.fraction.FractionCalculatorFactory |
org.apache.commons.lang3.math.Fraction |
252 |
BIGINT |
openmods.calc.types.bigint.BigIntCalculatorFactory |
java.math.BigInteger |
315 |
BOOL |
openmods.calc.types.bool.BoolCalculatorFactory |
java.lang.Boolean |
171 |
MULTI |
openmods.calc.types.multi.TypedValueCalculatorFactory |
openmods.calc.types.multi.TypedValue |
2415 |
枚举定义于 CalculatorType(src/main/java/openmods/calc/command/CalcState.java:120),各常量行号:DOUBLE :122、FRACTION :155、BIGINT :188、MULTI :221、BOOL :248。启动时的活动计算器为 DOUBLE(CalcState.java:265)。
功能
统一构建契约
SimpleCalculatorFactory<E, M>(SimpleCalculatorFactory.java:5)把构建过程固定为 5 步,子类只需覆写取空值、取值解析器、造打印器、配环境、配算符这几个钩子:
OperatorDictionary → configureOperators
Environment → createStackManipulationFunctions(注入 swap/pop/dup)→ configureEnvironment
Compilers → 由 ICompilerMapFactory 提供
IValuePrinter → createValuePrinter
(SimpleCalculatorFactory.java:21-30)。注意 swap/pop/dup 三个栈函数在每个后端都无条件注入(.java:25),因此下表的内建符号计数不含它们。
内建符号与算符统计
| 后端 | 全局符号 | 二元算符 | 一元算符 |
|---|---|---|---|
DOUBLE |
34 | 7 | 3 |
FRACTION |
14 | 4 | 3 |
BIGINT |
14(源码出现 15 次,见下) | 11 | 4 |
BOOL |
3 | 13 | 2 |
MULTI |
66 | 30 | 6 |
统计方式:grep -c 'setGlobalSymbol(' / grep -c 'registerBinaryOperator(' / grep -c 'registerUnaryOperator('(types 目录下逐文件)。
DOUBLE — 浮点
全局符号 34 个(DoubleCalculatorFactory.java:42-287):
- 常量:
PIEINFMAX(:42-45,其中MAX绑定的是Double.MIN_VALUE) - 一元数学:
abssgnsqrtceilfloorcoscoshsinsinhtantanhacosacoshasinasinhatanatanhlog10lnexpraddeg - 二元数学:
atan2log(log为二元,接受底数) - 聚合:
minmaxsumavg(均基于AccumulatorFunction,:224,232,240,248) - 随机:
rand(:279)gauss(:287,高斯分布)
算符:一元 neg + -(:303,311,319),二元 + - * / % ^ **(:327,335,343,351,359,367,375)。
FRACTION — 精确有理数
全局符号 14 个(FractionCalculatorFactory.java):abs sgn numerator denominator frac int sqrt log min max sum avg rand gauss。
算符:一元 neg + -(:176,184,192),二元 + - * /(:200,208,216,224)。其中 * 通过 .setDefault() 设为默认二元算符(:222)。不提供 % ^ ** —— 与 DOUBLE 的显著差异。
BIGINT — 任意精度整数
全局符号源码出现 15 次、去重后仅 13 个:abs sgn min max sum avg gcd modpow get set clear flip rand。
差异成因:gcd 在 BigIntCalculatorFactory.java:98 与 :106 被连续注册两次,两处实现完全相同(均返回 left.gcd(right)),第二次覆盖第一次。这是一处真实的冗余注册,不是统计误差。
算符:一元 ~ neg + -(:174,182,190,198),二元 ^ | & + - * / % ** << >>(:206-286)。无浮点/三角函数。
优先级常量按运算类别分为 6 档(BigIntCalculatorFactory.java:165-170):PRIORITY_EXP=6 > PRIORITY_MULTIPLY=5 > PRIORITY_ADD=4 > PRIORITY_BITSHIFT=3 > PRIORITY_BITWISE=2 > PRIORITY_ASSIGN=1。
BOOL — 布尔逻辑
全局符号仅 3 个:true false rand。
算符 13 个二元 + 2 个一元(BoolCalculatorFactory.java:129-149),全部以多个别名指向同一实现:
| 实现类 | 别名 | 行 |
|---|---|---|
OpNot(一元) |
~、not |
:130,131 |
OpXor |
^、xor、!= |
:133,134,135 |
OpIff |
=、<=>、eq、iff |
:137,138,139,140 |
OpImplies |
=>、implies |
:142,143 |
OpOr |
` | 、or` |
OpAnd |
&、and |
:148,149 |
即 6 个逻辑实现展开为 13 个二元 + 2 个一元算符名。= 在此处是等价(iff),与数学惯例不同。
数值
| 数值名 | 值 |
|---|---|
| 后端数 | 5(CalcState.java:122,155,188,221,248) |
| 默认后端 | DOUBLE(CalcState.java:265) |
| 每后端无条件注入的栈函数 | 3(swap/pop/dup) |
BIGINT 冗余注册符号 |
1(gcd,BigIntCalculatorFactory.java:98 与 :106) |
BOOL 二元算符别名展开比 |
13 个算符名 / 6 个实现类 |
交互
后端本身无玩家交互。切换路径:
| 指令 | 行为 |
|---|---|
=config new double |
新建 DOUBLE 计算器 |
=config new fraction |
新建 FRACTION 计算器 |
=config new bigint |
新建 BIGINT 计算器 |
=config new multi |
新建 MULTI 计算器 |
=config new bool |
新建 BOOL 计算器 |
=config store <名字> |
给当前计算器命名 |
=config load <名字> |
切换到已命名计算器 |
=config push / =config pop |
计算器栈压入/弹出 |
合法类型取自 CalculatorType.values(),非法值抛 openmodslib.command.calc_invalid_type(CommandCalcFactory 中 config.new 分支)。
DOUBLE / FRACTION / BIGINT 三个数值后端还额外绑定 3 个游戏内坐标符号 _x / _y / _z,取自指令发送者的方块坐标(如 CalcState.java:128,136,144);MULTI 后端则绑定 player(CalcState.java:229)。所有后端都通过 SenderHolder.addPrinter 获得 p(打印)与 print(取值)两个输出符号(CalcState.java:78,101)。