как сделать процесс доступным во время компиляции и во время выполнения - PullRequest
0 голосов
/ 19 февраля 2019

У меня есть процесс 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 модуля?Или мне не хватает опции компилятора, прагмы, чего-то еще?

Ответы [ 2 ]

0 голосов
/ 06 мая 2019

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

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

        dog:
          - bark
          - drool
        """)

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

0 голосов
/ 20 февраля 2019

Вам необходимо передать флаг --implicitStatic:on компилятору Nim, чтобы включить неявную оценку времени компиляции процедур.

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

...