Как использовать строки из библиотек, враждебных BoehmGC?

Выполняя некоторые упражнения, которые использовали libedit, чтобы быстро что-то заработать, я придумал следующее:

readline.sats:

#include "share/atspre_staload.hats"

%{#
#include <editline/readline.h>
#include <editline/history.h>
%}

fun readline: string -> Strptr0 = "mac#"
fun add_history: (!Strptr1) -> void = "mac#"
fun free_readline: Strptr0 -> void = "mac#free"

Используемый:

fun input_loop(): void =
  let
    val line = readline("input: ")
  in
    if strptr_isnot_null(line) then (
      add_history(line);
      println!("you entered: ", line);
      free_readline(line);
      input_loop()
    ) else free_readline(line)
  end

У меня есть некоторые проблемы с этим решением:

  1. после определения, что strptr равен NULL, мне все равно придется передать его в free(), так как линейное значение должно быть завершено. Есть ли лучший способ справиться с этим? Можно ли заменить strptr_isnot_null с функцией, которая завершает NULL, но не любой другой strptr?

  2. Strptr1 это 99%, что я хочу в этом случае. Это очень удобный тип. Тем не мение, strptr_free() является действительным терминатором для Strptr1 - но не для этих значений, потому что библиотека editline делает свое собственное размещение вне GC. Какой хороший способ справиться с этим? Может быть, создать новый тип и переопределить все необходимое для этого. Может быть, создать новый тип, но в основном использовать нулевую стоимость castfn в strptr... с которым вызывающая сторона может все еще ошибиться, и попытаться использовать с strptr_free(),

1 ответ

Решение

Относительно 1:

Я не вижу простого способа избежать вызова 'free' для пустой строки. ATS2 очень явно на данный момент. Я надеюсь, что больше поддержки метапрограммирования может быть встроено в ATS3.

Может быть, вы могли бы попытаться определить макрос:

macdef if_line (x, _then) = если strptr_isnot_null(,(x)) затем,(_ затем) иначе freeline(,(x))

Относительно 2:

Я хотел бы ввести абстрактный тип:

absvtype readline (l: addr) = ptr

весело readline (подсказка: строка): [l:addr] readline(l)

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