Как сделать процесс доступным во время компиляции и во время выполнения
У меня есть 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
""")
Все выражения, присвоенные константам, также оцениваются во время компиляции, так что это еще один способ добиться того же.