Как сделать процесс доступным во время компиляции и во время выполнения

У меня есть NIM-процесс, который отступает многострочную строку на основе пробела первой строки с отступом:

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: dedent

Я посмотрел на источник splitLines в strutils.nim чтобы увидеть, есть ли какая-то другая прагма, которую я мог бы применить, но я не нашел ничего, что могло бы работать.

Я сейчас о static утверждение, но я бы предпочел, чтобы компилятор оптимизировал это во время компиляции, не прибегая к этому.

Как я могу заставить это работать как во время компиляции, так и во время выполнения, не возвращаясь к использованию static? Нужно ли скомпилировать проц из отдельного .nim модуль? Или мне не хватает опции компилятора, прагмы, чего-то еще?

1 ответ

Решение

Вам нужно пройти --implicitStatic:on флаг компилятору Nim для включения неявной оценки времени компиляции процедур.

Эти процедуры не могут иметь compileTime Прагма.

Для принудительной оценки любого выражения во время компиляции вы можете использовать static следующим образом:

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

        dog:
          - bark
          - drool
        """)

Все выражения, присвоенные константам, также оцениваются во время компиляции, так что это еще один способ добиться того же.

Другие вопросы по тегам