Node 中的复古计算语言:REXX





0/5 (0投票)
我们如何在 Node 中处理 REXX 脚本?
引言
在上一篇文章[1]中,我描述了如何在 NodeJS Web 服务器中使用 PHP 脚本。在这篇文章中,我将介绍 REXX 脚本的使用,但我只展示管理它们所需的少量 JavaScript 说明,而主要目的是分析 REXX 及其使用过程中可能出现的问题。
REXX(及 ooREXX)简要概述
REXX(Restructured Extended Executor)是由 Mike Cowlishaw 于 1979 年在 IBM 开发的一种解释型编程语言。它是一种结构化、高级的编程语言,旨在易于学习和阅读。REXX 解释器和编译器存在于各种专有和开源计算平台之上;REXX 被用作脚本和宏语言,主要用于处理数据和文本以及生成报告;它已在多年中不断发展,并在 1996 年发布了支持对象的版本 ooREXX。
REXX 可以用于通用网关接口 (CGI) 编程,也可以嵌入到 HTML 页面中(例如 PHP)。
关于 REXX 的几点
所有未被识别为语句的内容都会被发送到操作系统;这是因为 REXX 的创建目的是管理大型机上执行的各种作业;这也解释了为什么字符串的连接是通过插入空格的并置发生的(操作符 ||
避免了这种情况)。
尽管在 REXX 的面向对象版本中,存在数组、列表、队列等复杂数据结构,但在原始 REXX 中,它们可以使用一种特殊的变量类型 stem
来构建,即一个变量名后面跟一个句点。在句点之后,可以添加一个或多个变量(用句点分隔),从而获得数组或复杂结构。如果变量是数字,stem 就是一个数组,否则它就是一个哈希表[2]。
下面是一个示例,用于验证 RANDOM
函数是否通过了卡方检验。
dice. = 0 -- set the defaults value of array
loop i = 1 while i < 61
a = RANDOM(1,6)
dice.a = dice.a + 1
end
loop i = 1 while i < 7
dice.7 = dice.7 + (dice.i - 10) ** 2
end
say dice.7 / 10 -- if value < 11.07 Ok (test square chi with 5 degrees of freedom)
对象可以通过调用对象的动作来运作,即通过发送消息,其中“消息发送”符号是 ~
,称为 twiddle
。对象通过执行动作并可能返回数据或对象来响应这些消息。
Web 服务器的更改
在上述文章中描述的 WEB 服务器脚本 tryNodeJS.js 中,已添加了 REXX 脚本管理。
...
} else if (type == "rex") {
var r = [__basedir + pathName];
for(q in parms) {r[r.length] = q; r[r.length] = parms[q].replace(/ /g,"+");}
var spawnRex = spawn('rexx',r);
spawnRex.stdout.on('data',function (data) {
response.writeHead(200, {'Content-Type': cType});
response.end(data);
});
spawnRex.stderr.on('data',function (data) {
console.log("Horror: " + data);
});
...
在上面的片段中,REXX 解释器的参数是一组从表单获取的键值对,例如,一个请求类似于:rexx getdata.rex Type Cite Author Adam+Smith
。
NodeJS 演示
演示页面是一个简单的页面,用户可以选择显示一句格言或一张图片(由一个查询 SQLite 数据库的 REXX 脚本提供),以及选择一些通过 PHP 脚本管理的 SQLite 数据库中的交叉数据[3]。
REXX 脚本
REXX 解释器以语法 rexx REXXscript parm<sub>1</sub> ...
启动。该脚本处理关于格言作者列表、作者的格言和图片列表的请求。
下面将分析脚本的主要部分,完整源代码已附上。
恢复请求参数
...
parms = arg(1) -- arg(1) contains all parameters separated by space
do while parms \= ""
parse var parms key value parms
value = changestr("+",value," ") -- restore spaces
dizParms.key = value
end
...
dizParms.
是一个 REXX stem
,用于存储键值对象;parse var
是一个语句,它将 parms
(一个以空格分隔的参数字符串)拆分成 key
和 value
(字符串中剩余的部分会存储在 parms
中)。
请求分析
这通过 SELECT
指令完成,该指令具有以下结构:
SELECT
When Condition Then
Statement
When Condition Then Do
Statements
End
Otherwise
...
End
在 index.html 中,组合框是由一个表单生成器(请参阅 CodeProject 文章 A JavaScript Form Generator)构建的,该生成器通过 Ajax 调用组合框项列表。
When dizParms.key == "Images" Then do
f = .File~new(curdir || "\images")~list~sortwith(.caselesscomparator~new)
myRE = .RegularExpression~new("?*(.gif|.png|.jpg)")
images = .array~of()
loop k over f
if myRE~match(k~lower) == 1 Then images~append(k)
end k
n = CHAROUT(,images~toString(,","))
exit
end
这相当繁琐,但这是只获取所需文件的必要步骤;如果没有这个限制,它将非常简单(可以说):say .File~new(curdir || "\images")~list~sortwith(.caselesscomparator~new)~toString(,",")
。
对于引用请求,SQLite 引擎会启动一个数据库名称和一个 SQL SELECT
语句,查询 dove(哪里)、Data(日期)和 Citazione(引言)字段;答案类似于:
The Wealth of Nations Book V Chapter I|1776|Wherever there is great property, there is great inequality.
.
When dizParms.key == "Cite" Then do
table = "Citazioni"
authorGroup = "Author_Group"
Author = "Author"
if dizParms.authorGroup == "IT Aphorisms" Then table = "InforCitazioni"
sql = "SELECT Dove,Data,Citazione FROM " || table || " WHERE Autore = '" || dizParms.Author || "'"
'sqlite3 condor.sqlite "' sql '"> ' || flname
response = "<table><caption>" || dizParms.Author || "</caption>" -- response string
do while lines(flname) > 0
line = linein(flname)
response = response || "<tr><td>" || _
Changestr("|",line,"</td><td>") || "</td></tr>"
end
n = CHAROUT(,response||"</table>")
end
临时文件管理
signal on notready -- handle file errors
curdir = directory()
flname = SysTempFileName(curdir||"\tempfile.???")
...
CALL STREAM flname, 'C', 'CLOSE'
"del" flname
...
结论
REXX 可以轻松地在 NodeJS 中使用,只需考虑一些(小的)限制,其中包括:
- 必须通过包含一个特殊类来激活正则表达式:
::requires "rxregexp.cls"
;其功能是相当有限的子集,并且与 JavaScript 或 PHP 中的功能不完全兼容。 - 参数中可能存在的空格必须被“屏蔽”:
r[r.length] = parms[q].replace(/ /g,"+")
。另一个障碍是,我尚未解决的、传递带有特殊字符(如 Author Dom Hélder Câmara)的参数的难度。 - 数据库通过 Rexx/SQL 支持,这是一组外部函数,用于处理 Oracle、DB2、MySQL、SQLite 和 ODBC 数据源。
注意
- ^参见 NodeJS WEB Server running PHP
- ^JavaScript 数组(1995 年)与 REXX stem(1979 年)非常相似。
- ^ 参见 CodeProject 文章 通过 PDO 访问数据库表中字段的交叉