Unpack an array to the stack at runtime

本秂侑毒 提交于 2019-12-11 10:46:29

问题


I have an array:

{ 1 2 3 4 }

I want to push its contents to the stack.

I tried:

(sc) { 1 2 3 4 } dup length firstn
1
2
3
4

Great!

Inside a word, though:

: explode ( a -- * ) dup length firstn ; inline

Throws an error Cannot apply “firstn” to a run-time computed value, because firstn calls call and

Words which call an input parameter must be declared inline so that a caller which passes in a literal quotation can have a static stack effect.

... and because of call 's semantics it's hard to compute quotations at runtime.

There must be a way to accomplish this. What is it?


回答1:


As Björn Lindqvist said, Factor won't let you do that1, but there are some workarounds.

The most direct way is perhaps using a vector as a stack:

: explode ( v s -- v ) dupd [ swap push ] with each ;
V{ } "somestring" explode
==> V{ 115 111 109 101 115 116 114 105 110 103 }

Of course, this means redesigning all related functions to work with this.

Maybe better than vectors, there are also string buffers, that can behave like a stack too.

"somestring" >sbuf
==> SBUF" somestring"
"-abcd" [ over push ] each
==> "somestring-abcd"

(Alternatively SBUF" somesbuf")

If you need to keep working with the content as if it were the input to some other words passed on the stack, you can use with-datastack:

"somestring-abcd" [ 5 ndrop 3dup ] with-datastack >string
==> "somestringing"

But think of this as if it where a regular non-stack-based language. Each word takes a fixed number of parameters and outputs a fixed number of results.

[1]. There must be some metaprogramming ways to do this. I don't imagine there's an easy practical way, though.




回答2:


No. There is no way to write such a word. If you think you need a word like that, you must rethink how you approach the problem.



来源:https://stackoverflow.com/questions/36047593/unpack-an-array-to-the-stack-at-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!