У меня есть функция compile
, которая принимает AST и создает строку с инструкциями по сборке. Внутри я создаю объект StringBuilder. Также внутри compile
есть множество локальных функций, таких как emitIf
, emitLet
и т. Д. Причина определения локальных функций заключается в том, что объект StringBuilder
не нужно передавать функциям emit
в качестве дополнительного параметра. Но мне кажется, что это решение несколько неудобно.
module Compile
let compile ast =
let sb = new StringBuilder()
let emitn s = sb.AppendLine s |> ignore
let emitfn f = Printf.kprintf emitn f
let emitLoadNumber (n:int) =
emitfn " mov $%d, %%rax" n
let rec emitExpr env si =
//...
and emitIf isTail env si cond th el =
//...
В качестве другого решения я мог бы создать StringBuilder
в области видимости модуля, а также переместить локальную функцию в область видимости модуля.
Мой вопрос: есть ли лучший способ определить набор функций, которые используют общий объект, например поток или StringBuilder
, не передавая его каждой из функций?
1 ответ
В вашей ситуации я бы, вероятно, определил в модуле набор функций, которые принимают явный параметр StringBuilder, а затем использовал бы частичное приложение для определения группы локальных функций, закрывающих один конкретный экземпляр StringBuilder. Например.,
module Compile
let emitn sb s = sb.AppendLine s |> ignore
let emitfn sb f = Printf.kprintf (emitn sb) f
let emitLoadNumber sb (n:int) =
emitfn sb " mov $%d, %%rax" n
let compile ast =
let sb = new StringBuilder()
let emitn = emitn sb
let emitfn = emitfn sb
let emitLoadNumber = emitLoadNumber sb
let rec emitExpr env si =
//...
and emitIf isTail env si cond th el =
//...
Теперь внутри функции compile
и ее подфункций (emitExpr
, emitIf
и т. Д.) Вы можете использовать emitn "foo"
, и он добавит строку "foo \ n" к Экземпляр StringBuilder, созданный вами в начале compile
. (Конечно, каждый раз, когда вы вызываете функцию, будет другой экземпляр). Но у вас также есть общедоступные версии emitn
, emitfn
и т. Д., Что упрощает модульное тестирование FAR.
Похожие вопросы
Новые вопросы
compilation
Компиляция - это преобразование исходного текста в другую форму или представление. Наиболее распространенное использование этого тега - для вопросов, касающихся преобразования языка программирования в машинный код. Этот тег обычно используется с другим тегом, указывающим тип исходного текста, таким как тег языка программирования (C, C ++, Go и т. Д.) И тегом, указывающим инструмент или компилятор, используемый для преобразования (gcc, Visual Studio, и т.д.).