forth - 如何在 Forth 中输入数字
问题描述
Forthinput
的 Basic 或C 中是否有类似的东西?scanf("%d")
可能会是这样的:
200 buffer: buf
: input ( -- n ) buf 200 accept
some-magic-filter
buf swap evaluate ;
上面代码中的问题是,如何定义一个只传递数字而不传递任何单词、定义等的过滤器?
解决方案
该标准仅指定一个低级>NUMBER
字来解释整数。OTOHEVALUATE
用于将字符串转换为数字是一种快速而肮脏的方式。要么不检查就使用它(在可信输入的情况下),要么根本不使用它。尝试过滤之前的字符串EVALUATE
是一个坏主意:它本身具有单词成本>NUMBER
和低重用因子。
注意:既不>NUMBER
也不EVALUATE
检测数字溢出。
在任何情况下,您输入单格整数的单词都可以定义为:
: accept-number ( -- n )
PAD DUP 80 ACCEPT ( addr u ) StoN ( n )
;
在可信输入的情况下,您可以定义StoN
如下
: StoN ( addr u -- x )
STATE @ ABORT" This naive StoN should not be used in compilation state"
DEPTH 2- >R
EVALUATE
DEPTH 1- R> <> IF -24 THROW THEN
\ check depth to accept the single-cell numbers only
;
否则(在输入不受信任的情况下)您有两个选择:依赖特定 Forth 系统的特定单词或使用某些(可能是您自己的)库。
我使用以下词典来定义StoN
:
\ ---
\ The words from Substring Matching library
\ (where length is counted in address units)
: MATCH-HEAD ( a u a-key u-key -- a-right u-right true | a u false )
2 PICK OVER U< IF 2DROP FALSE EXIT THEN
DUP >R
3 PICK R@ COMPARE IF RDROP FALSE EXIT THEN
SWAP R@ + SWAP R> - TRUE
;
\ ---
\ The words from Literals interpreting library
\ (where prefix 'I-' is shortcut for Interpret)
: I-DLIT ( a u -- x x true | a u false )
2DUP S" -" MATCH-HEAD >R
DUP 0= IF NIP RDROP EXIT THEN
0 0 2SWAP >NUMBER NIP IF RDROP 2DROP FALSE EXIT THEN
R> IF DNEGATE THEN 2SWAP 2DROP TRUE
;
: I-LIT ( a u -- x true | a u false )
I-DLIT IF D>S TRUE EXIT THEN FALSE
;
之后StoN
可以定义为:
: StoN ( a u -- x ) I-LIT IF EXIT THEN -24 THROW ;
提到的库可以在 GitHub 上找到:
推荐阅读
- f# - F# interactive 不与输入交互
- javascript - Firebase auth Jest 测试
- android - Android 数据绑定:示例与现实
- php - 如何使用 MAMP 将我的 phpmyadmin 链接到我的 php?
- powershell - 通过 powershell true CSV 导入用户
- python - 如果标签内有其他html,如何从div标签中提取python中的文本?
- php - 获取PHP数组中属性值最高的对象
- mongodb - 如果 $unset 数组不存在,MongoDB 不会抛出
- android - JobSchedulerService 中的 RoomDB
- c# - 确定矩形的中心点并将新矩形移动到中心