Experimental exact-decimal FEEL and DMN interpreter
| 面 | 对应 | 说明 |
|---|---|---|
| 当前源码 | 0.2.1,待发布 | 包含 Playground 多文件 import 与宿主函数桥;已发布 0.2.0 的源码对应 tag v0.2.0 |
| mooncakes | sundaysebasidian-byte/moondmn@0.2.0 | 包内容固定,不随 main 变化 |
| Pages | 最近一次推送到 main 的构建 | pages.yml 每次 push 到 main 都会重新构建,可能领先于 0.2.0 |
# 源码测试
git checkout v0.2.0
moon test --target all
# 安装包调用:在仓库外新建模块,把“安装与接入”中的 import 和示例原样放入 cmd/main
moon new consumer && cd consumer
moon add sundaysebasidian-byte/moondmn@0.2.0
moon run cmd/main
# 线上引擎:打开 Pages;对应的构建见 Actions 中 Pages 工作流的运行记录
gh run list --workflow pages.yml --limit 1scripts/build-web.sh
node web/smoke.mjs
python3 -m http.server -d web/dist 8000export PATH="$HOME/.moon/bin:$PATH"
moon version
moon buildmoon add sundaysebasidian-byte/moondmngit clone https://github.com/sundaysebasidian-byte/moondmn.git
cd moondmn
moon build
moon run cmd/main -- feel 'sum([1, 2, 3]) * 2'12import {
"sundaysebasidian-byte/moondmn",
"sundaysebasidian-byte/moondmn/feel/types",
}fn main {
let result = @moondmn.feel_eval("sum([1, 2, 3]) * 2") catch {
@types.Failure(_, _, _, message) => "error: " + message
}
println(result) // 12
}moon run examples/api-demomoon run cmd/main -- feel 'Applicant Age >= 18' --context examples/input.jsontruemoon run cmd/main -- feel 'list replace([1, 2, 3], 2, 4)'[1,4,3]moon run cmd/main -- eval examples/eligibility.dmn \
--decision Eligible --input examples/input.jsontruemoon run cmd/main -- lint examples/eligibility.dmn[]./scripts/fetch-tck.sh
moon run cmd/main --target native -- tck .tck/TestCases/compliance-level-2 \
--json evidence/tck-level-2.json
moon run cmd/main --target native -- tck .tck/TestCases/compliance-level-3 \
--json evidence/tck-level-3.jsonmoon run cmd/main --target native -- tck .tck/TestCases/compliance-level-3/0068-feel-equality| 能力 | 状态 | 说明 |
|---|---|---|
| FEEL 精确十进制、三值逻辑与 null 相等 | 已支持 | 34 位、半偶舍入、scale [-6111,6176];sqrt、log、exp 等超越函数经有限精度浮点桥接 |
| 日期、时间、时长、时区 | 已支持,时区数据有限 | 时区内置 IANA 2026e 的 39 个名称、1970–2100 年;范围外返回 E_ZONE_RANGE,未知名称返回 E_ZONE_UNSUPPORTED,DST gap 报错、overlap 取较早时刻 |
| 列表、上下文、区间、过滤器、路径、迭代器 | 已支持 | 多词名称按作用域内已知键识别;比较式区间保留运算符,(=3) 与 [3..3] 不相等 |
| 用户函数、BKM、决策服务、DRG、类型系统 | 已支持 | 类型化参数含单元素列表包装与 date→UTC 午夜转换 |
| 决策表 | 已支持 | U、A、P、F、R、O、C、C+、C<、C>、C# 全部命中策略 |
| 内置函数 | 已支持(约 90 个) | 覆盖 §10.3.4 的各分组,TCK 内置函数套件除下表所列外全部通过;matches/replace/split 使用自研 XPath 正则(标志 s m i x q) |
| lint | 已支持 | 未定义引用、重复规则、缺口;输入域为有限枚举(最多 4096 个组合)时可证明完整覆盖,开放域只给提示,不判错 |
| now() / today() | 已支持,需注入时钟 | API 的 clock 参数、CLI 的 --now;引擎不读系统时钟 |
| 多文件 import 与命名空间引用 | 已支持 | 别名、嵌套导入、namespace 隔离、导入类型与 invocable;Playground 支持内存多文件导入;7 个 TCK 用例全部通过。见 API 与示例 |
| 外部函数(Java) | 已支持宿主函数桥;JVM 调用不支持 | 影响:只有使用 external {java:...} 的模型;18 个 TCK 用例,均调用 JDK 类库。wasm-gc / js 没有 JVM,引擎不模拟 JDK |
| 级别 | 用例数 | 通过 | 通过率 |
|---|---|---|---|
| Level 2 | 116 | 116 | 100.0% |
| Level 3 | 3291 | 3265 | 99.21% |
| 原因 | 用例数 | 性质 |
|---|---|---|
| Java 外部函数(0076-feel-external-java) | 18 | 宿主桥已支持;不调用 JVM、不模拟 JDK,未注册时 E_EXTERNAL_UNBOUND |
| 驱动不提供时钟(1148、1149) | 4 | 库已支持注入时钟,TCK 驱动未注入 |
| 小数秒相等(0068) | 2 | 实现保留小数秒;TCK 期望忽略毫秒,与 DMN 1.5 §10.3.2.3 的文本存在差异 |
| 无日期的命名时区 time 相减(0100) | 2 | 无日期无法唯一确定 DST 偏移,显式拒绝 |
moon fmt --check
moon check --deny-warn
moon test # native
moon test --target wasm-gc
moon test --target wasm
moon test --target js
moon info # 重新生成 .mbti,提交后不应有差异fn evaluate_compiled(expression : Expr, input : String, clock? : () -> DateTime?) -> String raise EngineErrorfn evaluate_decision(model : Model, name : String, input : String, host? : Map[String, Value], clock? : () -> DateTime?) -> String raise EngineErrorfn feel_eval(source : String, context? : String, host? : Map[String, Value], clock? : () -> DateTime?) -> String raise EngineErrorfn parse_model(xml : String, resolver? : (String, String) -> String raise EngineError?) -> Model raise EngineErrorInstall
Download zipExperimental exact-decimal FEEL and DMN interpreter