kharp – K version 3 语言解释器(C# 实现)

Hacker News Top 工具

摘要

一个用 C# 实现的开源 K 版本 3 编程语言解释器,采用带有 Commons Clause 的 MIT 许可证。它完全实现了 K 参考手册,并包含增强功能,例如用于 .NET 对象的外部函数接口(FFI)。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/05/18 09:54

ERufian/ksharp 源代码:https://github.com/ERufian/ksharp

kharp - C# 实现的 K 语言版本 3 解释器

完整实现 K 编程语言(版本 3),属于 APL 家族的向量编程语言。


法律条款

ksharp 版权 © 2026 Eusebio Rufian-Zilbermann 等人。
本软件采用 MIT 许可证 + Commons Clause 进行授权。
您可以自由使用、修改和分发本软件(包括用于商业产品),但需包含署名,且不得直接出售本软件(或主要价值来源于本软件的产品)。
完整许可证文本:LICENSE

重要提示:
本软件按“现状”提供。您有责任:(a) 为本软件预期修改的任何数据文件保留适当的备份副本;(b) 确保使用本软件写入存储系统的数据能够完整且完整地读取。
本产品的作者不对因使用本产品直接或间接导致的任何数据丢失承担责任。


📚 目录

🎯 当前状态

🆎 Beta 状态

K 参考手册中的核心语言已完整实现:原生动词、副词、修改、索引、应用与赋值、函数、条件结构、I/O 与通信、系统变量与系统函数。
外部函数接口允许使用 Microsoft .NET 对象。
当我开始这个项目时,能够运行我书中的所有惯用法(https://www.nsl.com/papers/idioms_K3.pdf)只是一个梦想,而实际在不到 6 个月内实现它,真是一次令人振奋的经历。
这是一个值得作为项目 Beta 版本发布的里程碑。

📉 剩余目标

  • 调试:我的开发主要围绕单元测试框架,我不需要调试,因此降低了优先级,但它仍是 1.0 目标的一部分。
  • 解析:架构是简单的“分词 -> 解析为 AST 节点 -> 求值”。它不像其他 k 和 APL 家族语言的解释器那样使用栈或有限状态机。结果不如我所期望的健壮。注意:如果你遇到解析问题,请报告问题并尝试简化表达式;长而巧妙的一行代码,甚至一些不那么“长而巧妙”的表达式,都有中等概率混淆解析器。
  • 简化:AI 辅助开发速度很快,但也快速积累了技术债务。尤其是“旧解析器”的移除从未完全完成(最初的“旧”解析器尝试从左到右带回溯的求值,直到最终变得不可持续,被当前的 Long-Right-Scope 解析器取代)。最终结果代码比必要的更复杂,简化将有益。
  • 优化:我不期望 ksharp 在性能上能与 k 的原生实现竞争。基于 .NET 虚拟机并使用托管内存带来了一些好处(垃圾回收的内存使用、不会因畸形数据的内存访问问题而崩溃、丰富的生态系统等),但这些是以性能为代价的。尽管如此,仍有一些性能改进可以实现:利用全局符号表哈希集,或在求值结果之前利用 Linq-to-objects 状态机优化。

✂️ 已放弃的功能

  • 我从项目目标中移除了 K 的 UI。我认为将精力花在与 .NET 的兼容上更好(这打开了多种 UI 选择,如 WinForms 和 Unity)。

📈 最新测试结果

  • 测试套件:1549/1549 测试通过(100% 成功率)

🎯 近期改进

  • 🏃 发布配置文件 - 为 Windows、Mac 和 Linux 生成可执行文件
  • 🍏 改进了命令行编辑支持 - 现在支持 Mac 和 Linux
  • 🔃 改进了递归支持 - 添加了递归深度限制(40),超限时报信号而非崩溃
  • 📂 支持分隔文件 I/O(2026 年 5 月) - 增强了 0:1: 功能,修复了 5: 功能
  • 🚀 改进了比较容差(2026 年 5 月) - 更新比较容差以更好地匹配 K 兼容性
  • 🎯 测试套件完全通过 100%(2026 年 5 月) - 成功解决了阻止某些 K 惯用法产生正确结果的解析问题
  • 🔥 支持 adnoun(2026 年 5 月) - 现在可以将 over、scan、each 和 each-prior 副词用于名词(向量、矩阵和张量),以实现散点索引、传递闭包和状态转换。

🚀 快速开始

运行 K3Sharp 解释器

cd K3CSharp  
dotnet run  

K 用户手册 (https://nsl.com/k/training/kusrlite.pdf) - 完整的 K 语言指南,包含教程和示例

已实现特性

K 参考手册 (https://nsl.com/k/training/kreflite.pdf) - 所有 K 函数、运算符和概念的详细参考

核心数据类型

  • 原子类型:整数、浮点数、字符、符号、字典、空/自类型 null、函数、64 位整数
  • 集合:列表(复杂或混合类型,包括嵌套)、整数向量、浮点数向量、字符向量、符号向量、64 位整数向量
  • 特殊值:自类型 null(0n)、无穷大(0I0i0Ij)、负无穷大(-0I-0i-0Ij)、负零(-0.0)、整数空/NaN(0N0n0Nj
  • 类型系统:动态类型,自动提升
  • 空值处理:符合 IEEE 754 的空值传播

原生运算符与有意义的字形

  • ! 一元 - 枚举
  • ! 二元,右参数为原子 - 取模
  • ! 二元,右参数为向量 - 旋转
  • # 一元 - 计数
  • # 二元 - 取
  • $ 一元 - 格式化(简单格式化)
  • $ 二元,右参数为字符向量 - 形式化
  • $ 二元,右参数非字符向量 - 格式化(带说明符的格式化)
  • % 一元 - 求逆
  • % 二元 - 除法
  • & 二元 - 最小值
  • ( ) - 分组分隔符
  • , 一元 - 列表化
  • , 二元 - 连接
  • - 一元(后跟空格) - 改变符号
  • - 二元 - 减法
  • . 作为变量路径的最后一个字符 - 属性路径
  • . 在变量路径内部 - 深入值
  • .. 在变量路径中 - 深入属性
  • . 作为字典的索引 - 属性字典
  • . 一元,列表(类型 0)参数 - 创建字典
  • . 一元,字符向量参数 - 执行
  • . 一元,字典参数 - 解构字典
  • . 二元,第一个参数是函数 - 点应用
  • . 二元,第一个参数是变量 - 深度索引
  • . 三元,第三个参数是动词 - 深度应用
  • . 三元,第三个参数是 : - 深度错误捕获
  • . 四元 - 带参数的深度应用
  • / 左边有空格 - 注释标记
  • ' 作为表达式中的单个项 - 报错
  • ' 一元 - 报错
  • : REPL 命令 - 恢复
  • : 一元 - 返回
  • :: 左边为变量名 - 全局赋值(语句)
  • : 左边为变量名 - 赋值(语句)
  • : 左边为一元动词且无参数 - 一元应用并赋值
  • : 左边为二元动词且有参数 - 二元应用并赋值
  • :[ ] 可变参数 - 条件执行并赋值(语句)
  • < 一元 - 升序排序
  • < 二元 - 小于
  • = 一元 - 分组
  • = 二元 - 等于
  • > 一元 - 降序排序
  • > 二元 - 大于
  • ? 一元 - 去重
  • ? 二元,左边为列表或空(类型 6) - 查找
  • ? 二元,左边为函数 - 反函数
  • ? 三元 - 应用反函数
  • @ 一元 - 是否为原子
  • @ 二元,左边为路径,右边为字符向量 - 在路径上执行
  • @ 二元,左边为函数 - 浅层应用
  • @ 二元,左边为变量 - 浅层索引
  • @ 三元,第三个参数是动词 - 浅层应用
  • @ 三元,第三个参数是 : - 浅层错误捕获
  • @ 四元 - 带参数的浅层应用
  • [ ] 左边有函数 - 分组和点应用
  • [ ] 左边有变量且右边为赋值或应用并赋值 - 修改
  • [ ] 左边有变量且右边无赋值 - 分组和深度索引
  • \ 在行首(允许空格,^\s*\\) - REPL 命令标记
  • ^ 一元 - 形状
  • ^ 二元 - 乘幂
  • _ 一元 - 取整
  • _ 作为前缀 - 系统保留动词或变量
  • _ 二元,左边为整数 - 丢弃
  • _ 二元,左边为整数向量 - 切割
  • { } - 分组并创建函数
  • | 一元 - 反转顺序
  • | 二元 - 最大值
  • ~ 一元,数字参数 - 非(是否为零,逻辑非)
  • ~ 一元,符号(变量路径)参数 - 属性句柄
  • ~ 二元 - 匹配
  • + 一元 - 翻转(转置)
  • + 二元 - 加法
  • * 一元 - 第一个或默认值
  • * 二元 - 乘法
  • ` 在名称或字符串字面量之前 - 符号标记
  • " "(字符串字面量)包含单个项 - 字符
  • " "(字符串字面量)包含多个项 - 字符向量
  • ; 在分组内(不包括引号内) - 列表分隔符
  • \n 在分组内(不包括引号内) - 列表分隔符
  • \n 在 REPL 中,不在分组/引号内 - 求值

核心副词系统(迭代)

  • Over (/): +/ 1 2 3 4 515(折叠/归约)
  • Scan (\): +\ 1 2 3 4 5(1;3;6;10;15)(累积)
  • Each ('): -:' 1 2 3 4(-1;-2;-3;-4)(逐元素)
  • Each-Left (\:): 1 2,\: 3 4 5(1 3 4 5;2 3 4 5)(对左参数的每个项应用操作,右参数整体)
  • Each-Right (/:): 1 2 3 +/: 4 5(5 6 7;6 7 8)(对右参数的每个项应用操作,左参数整体)
  • Each-Pair (':): ,': 1 2 3 4(2 1;3 2;4 3)(对连续对应用操作,交换左右)
  • 初始化: 1 +/ 2 3 4 515(带初始值)
  • 已修改动词的副词 🆕: ((1 2);(3 4)),/:\:((9 8);(7 6))((1 2 9 8;1 2 7 6);(3 4 9 8;3 4 7 6))(相邻副词是嵌套迭代)

名词化动词的副词(迭代索引)

  • ' 左边紧跟矩阵/张量 - 散点选择
  • / 左边紧跟索引向量 - 传递闭包(索引遍历迭代,收敛)
  • / 左边紧跟转移矩阵 - 状态转移(二维迭代索引)
  • \ 左边紧跟索引向量 - 带轨迹的传递闭包
  • \ 左边紧跟转移矩阵 - 带轨迹的状态转移
  • ': 左边紧跟转移矩阵 - 二维索引 each prior

修改、索引、应用、赋值

  • 简单赋值: a:1 2 3 4
  • 切片提取: m[3 4;1 2]
  • 切片赋值: m[3 4;1 2]:((8 9);(7 3))
  • 修改并赋值: i+:1(递增)、x-:2(递减)、n*:3(乘赋值)等

核心函数系统

  • 匿名函数: {[x;y] x + y}
  • 函数赋值: func: {[x] x * 2}
  • 函数应用: func2 . (4;5)func1 @ 5func2[3;5]
  • 投影: add . 5 创建 {[x] 5 + x}
  • 多语句: 函数可以包含分号分隔或换行分隔的语句

属性

  • 依赖 - 自动重新计算的事件系统
  • 触发器 - 变化时执行的事件系统
  • UI 属性未实现 ❌ - 可使用 .NET FFI 进行 UI 开发,预计不实现 K 的 UI。

条件结构

  • :[] - 条件值
  • do[] - 固定迭代
  • if[] - 条件执行
  • while[] - 条件循环

输入/输出与通信

K 序列化系统

  • 二进制序列化(_db:将 K 数据结构转换为二进制格式
  • 二进制反序列化(_bd:将二进制数据转换回 K 数据结构

编号的 I/O 动词

  • 0: 一元 - 从文件读取文本
  • 0: 二元 - 将文本写入文件
  • 1: 一元 - 使用内存映射访问从 K 数据文件读取
  • 1: 二元 - 将 K 数据写入文件
  • 2: 一元 - 读取整个 K 数据文件
  • 2: 二元 - FFI 加载程序集。请参阅 外部函数接口 (FFI)
  • 3: 一元,列表参数 - 打开 IPC 端口
  • 3: 一元,整数参数 - 关闭 IPC 端口
  • 3: 二元 - IPC 设置(异步 IPC)
  • 4: 一元 - 类型(获取变量类型)
  • 4: 二元 - IPC 获取(同步 IPC)
  • 5: 一元 - 字符串表示
  • 5: 二元 - 以文本追加到文件
  • 6: 一元 - 以原始字节从文件读取
  • 6: 二元 - 以原始字节写入文件

系统变量与系统函数

  • 内部信息 _d(K 目录)、_v(K 变量)、_i(索引)、_f(自引用函数)、_n(空单例)
  • 进程信息 _k(版本)、_p(端口)、_P(PID)、_w(谁)、_u(用户)
  • 系统信息 _s(空间)、_h(主机)、_a(地址)、_o(操作系统)、_c(核心数)、_r(RAM)、_m(机器 ID)
  • 三角函数_sin_cos_tan_asin_acos_atan
  • 双曲函数_sinh_cosh_tanh
  • 指数函数_exp_log_sqrt_sqr
  • 算术函数_abs_floor_ceil_div(整数除法)
  • 位运算_and_or_xor_rot_shift
  • 矩阵_dot_mul_inv_lsq(最小二乘回归)
  • 时间函数:完整的时间和日期操作函数
  • _t:当前 K 时间(自 2035 年 1 月 1 日 UTC 午夜以来的秒数)
  • _T:当前时间(自 2035 年 1 月 1 日 UTC 午夜以来的天数)
  • _gtime:将 K 时间转换为日期/时间向量(“yyyyMMdd”;“hhmmss”)
  • _ltime:将 K 时间转换为带时区偏移的本地时间向量
  • _jd:将日期转换为儒略日(K 儒略日是从 2035 年 1 月 1 日以来的天数)
  • _dj

相似文章

我以前不知道的关于 K&R C 的一堆东西

Lobsters Hottest

这篇文章探讨了关于前 ANSI C(K&R C)的一些晦涩细节,包括 void 的缺失、不同的浮点类型以及简化的类型说明符规则。文章解释了该语言上下文相关语法是如何通过单遍编译器的限制来证明其合理性的。

openinterpreter/openinterpreter

GitHub Trending (daily)

Open Interpreter 是一个针对低成本模型优化的编码代理,支持多种测试框架和在 macOS、Linux 及 Windows 上的原生沙箱功能。

K2 参考手册 (1998)

Lobsters Hottest

K2 参考手册 (1998) 提供了 Kx Systems 的 K2 数组编程语言的文档,包括语法、操作符和系统函数。