如何使proc可用的编译时间和运行时间

时间:2019-02-19 12:23:31

标签: compile-time nim multilinestring

我有一个nim proc,它基于空格分隔多行字符串 第一行缩进的行:

import strutils

proc dedent(s: string): string
    {.noSideEffect.} =
    var prefix = ""
    for line in s.splitLines(keepEol=true):
        if prefix == "" and line.len > 0:
            for j in 0..<line.len:
                if line[j] != ' ':
                    prefix = line[0..j-1]
                    break
        if line.startsWith(prefix):
            result.add(line[prefix.len .. high(line)])
        else:
            result.add(line)

when isMainModule:
    echo dedent """
        cat:
          - meow
          - purr

        dog:
          - bark
          - drool
        """

它很好地输出:

cat:
  - meow
  - purr

dog:
  - bark
  - drool

但是检查中间的C代码,我会看到:

STRING_LITERAL(TM_9amIjLnWbK7OR9aPA8dicbaQ_14, "        cat:\012          - meow\012          - purr\012        \012       "
" dog:\012          - bark\012          - drool\012        ", 112);

因此,缩排在运行时完成。我可以将compileTime杂注添加到proc中:

proc dedent(s: string): string
    {.noSideEffect,compileTime.} =

,然后C输出更改为:

STRING_LITERAL(TM_9amIjLnWbK7OR9aPA8dicbaQ_3, "cat:\012  - meow\012  - purr\012\012dog:\012  - bark\012  - drool\012", 48);

这正是我想要的,多行字符串缩进到每行的周围,但在可执行文件中没有多余的缩进。

但是添加了这个实用性,我无法再在运行时访问dedent,例如添加时:

    import os
    if paramCount() > 0:
        for i in 1..paramCount():
            echo dedent paramStr(i)

isMainModule,您会收到错误消息:

  

错误:请求为.compileTime过程生成代码proc:ddent

我在splitLines中查看了strutils.nim的来源,以了解是否还有其他我可以应用的语用说明,但是我没有找到任何可行的方法。

我现在谈论static语句,但希望编译器在编译时对其进行优化,而无需我将其投入其中。

如何在不恢复使用static的情况下使它既在编译时又在运行时工作? 我是否需要从单独的.nim模块编译proc?还是我缺少一个编译器选项,杂注或其他?

2 个答案:

答案 0 :(得分:1)

您需要将--implicitStatic:on标志传递给Nim编译器以启用对过程的隐式编译时评估。

这些过程不能具有compileTime编译指示。

答案 1 :(得分:1)

要在编译时强制对任何表达式求值,可以通过以下方式使用static

when isMainModule:
    echo static(dedent"""
        cat:
          - meow
          - purr

        dog:
          - bark
          - drool
        """)

所有分配给常量的表达式也在编译时求值,因此这是另一种实现方法。