///|
fn control_word(word : String) -> Bool {
[
"if", "else", "then", "begin", "while", "repeat", "until", "again", "do", "?do",
"loop", "+loop",
].contains(word)
}
///|
fn Machine::postpone_into(
self : Machine,
name : String,
output : Array[String],
) -> Unit raise ForthError {
if self.words.get(name) is Some(_) {
let xt = self.capture_xt(name)
output.push(xt.to_string())
output.push(
if self.immediate_words.get(name) == Some(true) {
"\u0001execute"
} else {
"\u0001compile,"
},
)
} else if control_word(name) ||
primitive_word(name) ||
name == "literal" ||
name == "does>" ||
name == "[']" {
output.push("\u0002" + name)
} else {
raise Invalid("unsupported POSTPONE target: " + name)
}
}
///|
fn Machine::emit_postponed(
self : Machine,
name : String,
) -> Unit raise ForthError {
let output = match self.compile_output {
Some(output) => output
None => raise Invalid("postponed compilation outside definition")
}
if output.length() >= 65536 {
raise Invalid("compiled definition limit")
}
if string_word(name) {
for token in self.string_code(name) {
output.push(token)
}
} else if name == "[']" {
let target = self.source_name().to_lower()
output.push(self.capture_xt(target).to_string())
} else if name == "literal" {
output.push(self.pop().to_string())
} else if control_word(name) {
output.push(name)
} else {
output.push("\u0001" + name)
}
}