Как использовать строки из библиотек, враждебных 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
У меня есть некоторые проблемы с этим решением:
после определения, что strptr равен NULL, мне все равно придется передать его в free(), так как линейное значение должно быть завершено. Есть ли лучший способ справиться с этим? Можно ли заменить
strptr_isnot_null
с функцией, которая завершает NULL, но не любой другойstrptr
?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)