返回

文章详情

邮政SQL的Commodore 64 BASIC

Hacker News2026年7月3日 09:08

如果你在某个年龄阶段,词组 "38911 BASIC BYTES FREE" 会给你带来某种感觉,这种感觉是任何治疗手段都无法改变的。你还记得那蓝色的屏幕。你记得从杂志上输入三页代码,却得到 "?SYNTAX ERROR IN 2340" 的错误,不知道哪一页出了问题。你记得磁盘驱动器是设备8,并且它的速度比大陆漂移还要慢。我有一些消息:所有这些现在都在PostgreSQL内部运行。PL/CBMBASIC是一种过程语言扩展,在Commodore 64 BASIC V2上执行函数体。它不是一个仿制品,也不是一个致敬演出:它是真正的1982年的微软/Commodore解释器,通过Michael Steil的cbmbasic项目的方式,该项目将6502 ROM静态重新编译为C语言。这段C代码直接编译到扩展的共享库中,因此解释器运行在你的后端进程内。每一次函数调用都是一次内存中的电源循环:将64KB的RAM数组清零,重置CPU寄存器,并重新进入$E394的ROM。整个过程大约耗时15到20微秒,这大约比硬件曾经做到的快千倍,足够在大型表中逐行调用,而不必觉得内疚。 CREATE EXTENSION plcbmbasic; CREATE FUNCTION hello(who text) RETURNS text AS $$ 10 PRINT "HELLO, ";WHO$;"!" $$ LANGUAGE plcbmbasic; SELECT hello('WORLD'); -- HELLO, WORLD! 是的,那些是行号。是的,它们是强制性的。用户代码从第10行开始,就像自然所期望的那样,因为第0到9行是保留的:扩展会将你的函数参数作为普通的BASIC赋值注入到那里,才会运行你的代码。名为who的文本参数以WHO$的形式到达,名为lives的小整数变成真实的16位LIVES%,而其余的数字则存入40位的CBM浮点数,包含九位辉煌的有效数字。验证器有其看法,因为BASIC V2有其看法。任何编写C64程序超过一个小时的人都会发现你不能有一个名为TOTAL的变量。标记器在标识符内部的任何地方都压缩关键字,因此TOTAL包含TO并变成垃圾。SCORE包含OR。BUDGET包含GET。只有名字的前两个字符是重要的,因此USERNAME和USERID... 实际上是好的,US$和US是不同的变量,但ALPHA和ALPS静默地变成了同一个字符串。TI和ST被系统占用。该扩展提供了一个验证器,因此PostgreSQL现在在CREATE FUNCTION时提供这些意见,而不是让你在运行时重新发现它们:错误:参数名 "total" 包含BASIC关键字TO 提示:这就是为什么在Commodore 64上没有人能有一个名为TOTAL的变量。一些创伤应该得到比我们第一次得到的更好的错误信息。OUT参数通过遍历变量表。当一个BASIC程序结束时,其变量仍然保留在模拟的64KB RAM中。因此,对于OUT和INOUT参数,处理程序所做的合理事情是:它遍历BASIC自己的简单变量表,从VARTAB的$2D/$2E到ARYTAB的$2F/$30,解码类型编码的名称字节,并将5字节浮点数、16位整数和字符串描述符转换回SQL值。 CREATE FUNCTION divmod(num int, den int, OUT quot int, OUT rmd int) AS $$ 10 QUOT=INT(NUM/DEN) 20 RMD=NUM-QUOT*DEN $$ LANGUAGE plcbmbasic; SELECT * FROM divmod(47, 5); -- quot | rmd -- ------+----- -- 9 | 2 像PEEK另一个进程的内存以获取其结果并不是我期待在PostgreSQL文档中看到的模式,但在这里它感觉非常正确。数据库是设备8。 这是我最满意的部分。在Commodore 64上,你的数据存储在磁盘驱动器上,设备8,你用OPEN、INPUT#、GET#、PRINT#、CLOSE和ST状态变量与你的驱动器对话。因此在PL/CBM-BASIC中,设备8就是数据库。你OPEN的“文件名”是一个SQL语句,通过SPI在你的事务中执行: CREATE FUNCTION top_scores() RETURNS text AS $$ 10 OPEN 1,8,0,"SELECT NAME, SCORE FROM HISCORES ORDER BY SCORE DESC" 20 INPUT#1,N$,S 30 IF ST<>0 AND N$="" THEN 60 40 PRINT N$;" ";S 50 IF ST=0 THEN 20 60 CLOSE 1 $$ LANGUAGE plcbmbasic; 列值逐条以一个CR结束记录的形式返回,ST在最后一个字节位置获取EOF位(64),方式与它从1541中获取的相同。你在1985年写的读到完成的循环保持不变,包括你在空文件时需要小心的部分,这就是第30行所做的。更好的是。辅助地址15是驱动器的命令通道,你可以将DOS命令通过PRINT#发送到那里,并从中读取00, OK,00,00。这也能工作: 10 OPEN 15,8,15 20 PRINT#15,"DELETE FROM HISCORES WHERE SCORE < 1000" 30 INPUT#15,EN,EM$,RC,ES 状态记录为0,OK,<行数>,0,以纪念原版。每次PRINT#追加,终止的CR执行,因此你可以通过将它们分段发送来构建比BASIC的255字符字符串限制更长的语句。INSERT,UPDATE,DDL,随便你想。

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡