应该如何使用与 BoehmGC 敌对的库中的字符串?

How should strings from libraries hostile to BoehmGC be used?

在进行一些使用 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(),因为线性值必须终止。有更好的方法来处理这个吗?是否可以用 终止 NULL 而不是任何其他 strptr 的函数替换 strptr_isnot_null

  2. 在这种情况下,
  3. Strptr1 是我想要的 99%。这是一种非常方便的类型。但是,strptr_free()Strptr1 的有效终止符——但不是 这些 值,因为 editline 库在 GC 之外进行自己的分配。什么是处理这个的好方法?也许,创建一个新类型并重新实现它所需的一切。也许,创建一个新类型,但主要使用零成本 castfnstrptr ...调用者可能仍然搞砸了,并尝试使用 strptr_free().

关于 1:

我没有找到避免对空字符串调用 'free' 的简单方法。 ATS2 目前非常明确。我希望更多的元编程 支持可以内置到 ATS3 中。

也许你可以尝试定义一个宏:

macdef if_line(x, _then) = 如果 strptr_isnot_null(,(x)) then ,(_then) else freeline(,(x))

关于 2:

我要介绍一个抽象类型:

absvtype readline(l:addr) = ptr

fun readline(提示:字符串):[l:addr] readline(l)