什么是块的反转:以rebol / red加载文本

时间:2018-04-20 20:44:30

标签: rebol red

我们说我有一些rebol / red代码。如果我加载源文本,我会得到一个块,但如何从块中获取源文本?我尝试过form block但它没有回复源文本。

    text: {
        Red [Title: "Red Pretty Printer"]

        out: none   ; output text
        spaced: off ; add extra bracket spacing
        indent: ""  ; holds indentation tabs

        emit-line: func [] [append out newline]

        emit-space: func [pos] [
            append out either newline = last out [indent] [
                pick [#" " ""] found? any [
                    spaced
                    not any [find "[(" last out find ")]" first pos]
                ]
            ]
        ]

        emit: func [from to] [emit-space from append out copy/part from to]

        clean-script: func [
            "Returns new script text with standard spacing."
            script "Original Script text"
            /spacey "Optional spaces near brackets and parens"
            /local str new
        ] [
            spaced: found? spacey
            clear indent
            out: append clear copy script newline
            parse script blk-rule: [
                some [
                    str:
                    newline (emit-line) |
                    #";" [thru newline | to end] new: (emit str new) |
                    [#"[" | #"("] (emit str 1 append indent tab) blk-rule |
                    [#"]" | #")"] (remove indent emit str 1) break |
                    skip (set [value new] load/next str emit str new) :new
                ]
            ]
            remove out ; remove first char
        ]

        print clean-script read %clean-script.r
    }

    block: load text

1 个答案:

答案 0 :(得分:6)

LOAD是一种具有复杂行为的高级操作,例如它可以带一个文件!,一个STRING!或一个块!因为它做了很多不同的事情,所以很难说它作为一种操作的确切补充。 (例如,当你从文件中加载时,SAVE似乎是"反向")

但你的例子是专门处理STRING!:

  

如果我加载源文本,我会得到一个块,但如何从块中取回源文本?

总的来说,非常相关的事情:你不能回来"源文本

在上面的示例中,源文本包含注释,在LOAD之后它们将消失。此外,以每个值携带的NEW-LINE标志的形式保留非常有限量的空白信息。然而,您使用的具体缩进样式 - 或者您是否使用了制表符或空格 - 并未保留。

更微妙地说,少量的符号区分会丢失。串!加载的文字将失去你是否写下"with quotes"{with curly braces}的知识...... Rebol和Red都没有保留这一点。 (即使他们这样做了,也不会回答突变后或新字符串后要做什么的问题。)日期有变化!输入格式,并不记得您使用的具体格式。等

但是当谈到将代码往返作为文本时,与绑定相比,格式化是微不足道的。考虑一下你可以构建如下结构:

>> o1: make object! [a: 1]
>> o2: make object! [a: 2]
>> o3: make object! [a: 3]

>> b: compose [(in o1 'a) (in o2 'a) (in o3 'a)]
== [a a a]

>> reduce b
[1 2 3]

>> mold b
"[a a a]"

您不能简单地将 b 序列化为字符串"[a a a]",并且有足够的信息来获取等效的来源。 Red比Rebol更能掩盖这种影响 - 因为甚至像STR to block!这样的操作!并且system/lexer/transcode似乎绑定到用户上下文。但是,除了最微不足道的例子之外,你将面临的问题是什么。

Rebol2和Red有一些二进制格式试图解决这个问题。例如在" RedBin" a WORD! saves its context (以及该上下文的索引)。但是,您必须考虑要将多少加载环境拖入文件以保留上下文。所以它肯定会打开一堆蠕虫。

这并不是说模仿出来的能力并没有帮助。但是没有免费午餐......所以Rebol和Red程序最终不得不像其他人一样考虑序列化。如果您正在考虑对任何源代码进行处理 - 出于注释保存的原因(如果没有别的话) - 那么PARSE应该是您要达到的第一件事。