3656
Periodic cleanup to replace 'reply' with 'return' everywhere in the repo. I use 'reply' for students to help reinforce the metaphor of function calls as being like messages through a pipe. But that causes 'reply' to get into my muscle memory when writing Mu code for myself, and I worry that that makes Mu seem unnecessarily alien to anybody reading on Github. Perhaps I should just give it up? I'll try using 'return' with my next student.
This commit is contained in:
parent
b771d375d3
commit
f116818c7c
|
@ -4,10 +4,23 @@
|
|||
def main [
|
||||
1:num, 2:num <- f 34
|
||||
]
|
||||
def f [
|
||||
12:num <- next-ingredient
|
||||
13:num <- add 1, 12:num
|
||||
return 12:num, 13:num
|
||||
]
|
||||
+mem: storing 34 in location 1
|
||||
+mem: storing 35 in location 2
|
||||
|
||||
:(scenario reply)
|
||||
def main [
|
||||
1:num, 2:num <- f 34
|
||||
]
|
||||
def f [
|
||||
12:num <- next-ingredient
|
||||
13:num <- add 1, 12:num
|
||||
reply 12:num, 13:num
|
||||
$dump-trace
|
||||
]
|
||||
+mem: storing 34 in location 1
|
||||
+mem: storing 35 in location 2
|
||||
|
@ -25,7 +38,7 @@ case RETURN: {
|
|||
case RETURN: {
|
||||
// Starting Reply
|
||||
if (Trace_stream) {
|
||||
trace(9999, "trace") << "reply: decrementing callstack depth from " << Trace_stream->callstack_depth << end();
|
||||
trace(9999, "trace") << current_instruction().name << ": decrementing callstack depth from " << Trace_stream->callstack_depth << end();
|
||||
--Trace_stream->callstack_depth;
|
||||
if (Trace_stream->callstack_depth < 0) {
|
||||
Current_routine->calls.clear();
|
||||
|
@ -37,20 +50,20 @@ case RETURN: {
|
|||
if (Current_routine->calls.empty()) goto stop_running_current_routine;
|
||||
for (int i = 0; i < SIZE(ingredients); ++i)
|
||||
trace(9998, "run") << "result " << i << " is " << to_string(ingredients.at(i)) << end();
|
||||
// make reply products available to caller
|
||||
// make return products available to caller
|
||||
copy(ingredients.begin(), ingredients.end(), inserter(products, products.begin()));
|
||||
// End Reply
|
||||
break; // continue to process rest of *caller* instruction
|
||||
}
|
||||
|
||||
//: Types in reply instructions are checked ahead of time.
|
||||
//: Types in return instructions are checked ahead of time.
|
||||
|
||||
:(before "End Checks")
|
||||
Transform.push_back(check_types_of_reply_instructions); // idempotent
|
||||
Transform.push_back(check_types_of_return_instructions); // idempotent
|
||||
:(code)
|
||||
void check_types_of_reply_instructions(const recipe_ordinal r) {
|
||||
void check_types_of_return_instructions(const recipe_ordinal r) {
|
||||
const recipe& caller = get(Recipe, r);
|
||||
trace(9991, "transform") << "--- check types of reply instructions in recipe " << caller.name << end();
|
||||
trace(9991, "transform") << "--- check types of return instructions in recipe " << caller.name << end();
|
||||
for (int i = 0; i < SIZE(caller.steps); ++i) {
|
||||
const instruction& caller_instruction = caller.steps.at(i);
|
||||
if (caller_instruction.is_label) continue;
|
||||
|
@ -58,43 +71,43 @@ void check_types_of_reply_instructions(const recipe_ordinal r) {
|
|||
if (caller_instruction.operation < MAX_PRIMITIVE_RECIPES) continue;
|
||||
const recipe& callee = get(Recipe, caller_instruction.operation);
|
||||
for (int i = 0; i < SIZE(callee.steps); ++i) {
|
||||
const instruction& reply_inst = callee.steps.at(i);
|
||||
if (reply_inst.operation != RETURN) continue;
|
||||
const instruction& return_inst = callee.steps.at(i);
|
||||
if (return_inst.operation != RETURN) continue;
|
||||
// check types with the caller
|
||||
if (SIZE(caller_instruction.products) > SIZE(reply_inst.ingredients)) {
|
||||
if (SIZE(caller_instruction.products) > SIZE(return_inst.ingredients)) {
|
||||
raise << maybe(caller.name) << "too few values returned from " << callee.name << '\n' << end();
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < SIZE(caller_instruction.products); ++i) {
|
||||
reagent/*copy*/ lhs = reply_inst.ingredients.at(i);
|
||||
reagent/*copy*/ lhs = return_inst.ingredients.at(i);
|
||||
reagent/*copy*/ rhs = caller_instruction.products.at(i);
|
||||
// End Check RETURN Copy(lhs, rhs)
|
||||
if (!types_coercible(rhs, lhs)) {
|
||||
raise << maybe(callee.name) << reply_inst.name << " ingredient '" << lhs.original_string << "' can't be saved in '" << rhs.original_string << "'\n" << end();
|
||||
raise << maybe(callee.name) << return_inst.name << " ingredient '" << lhs.original_string << "' can't be saved in '" << rhs.original_string << "'\n" << end();
|
||||
raise << " ['" << to_string(lhs.type) << "' vs '" << to_string(rhs.type) << "']\n" << end();
|
||||
goto finish_reply_check;
|
||||
goto finish_return_check;
|
||||
}
|
||||
}
|
||||
// check that any reply ingredients with /same-as-ingredient connect up
|
||||
// check that any return ingredients with /same-as-ingredient connect up
|
||||
// the corresponding ingredient and product in the caller.
|
||||
for (int i = 0; i < SIZE(caller_instruction.products); ++i) {
|
||||
if (has_property(reply_inst.ingredients.at(i), "same-as-ingredient")) {
|
||||
string_tree* tmp = property(reply_inst.ingredients.at(i), "same-as-ingredient");
|
||||
if (has_property(return_inst.ingredients.at(i), "same-as-ingredient")) {
|
||||
string_tree* tmp = property(return_inst.ingredients.at(i), "same-as-ingredient");
|
||||
if (!tmp || !tmp->atom) {
|
||||
raise << maybe(caller.name) << "'same-as-ingredient' metadata should take exactly one value in '" << to_original_string(reply_inst) << "'\n" << end();
|
||||
goto finish_reply_check;
|
||||
raise << maybe(caller.name) << "'same-as-ingredient' metadata should take exactly one value in '" << to_original_string(return_inst) << "'\n" << end();
|
||||
goto finish_return_check;
|
||||
}
|
||||
int ingredient_index = to_integer(tmp->value);
|
||||
if (ingredient_index >= SIZE(caller_instruction.ingredients)) {
|
||||
raise << maybe(caller.name) << "too few ingredients in '" << to_original_string(caller_instruction) << "'\n" << end();
|
||||
goto finish_reply_check;
|
||||
goto finish_return_check;
|
||||
}
|
||||
if (!is_dummy(caller_instruction.products.at(i)) && !is_literal(caller_instruction.ingredients.at(ingredient_index)) && caller_instruction.products.at(i).name != caller_instruction.ingredients.at(ingredient_index).name) {
|
||||
raise << maybe(caller.name) << "'" << to_original_string(caller_instruction) << "' should write to '" << caller_instruction.ingredients.at(ingredient_index).original_string << "' rather than '" << caller_instruction.products.at(i).original_string << "'\n" << end();
|
||||
}
|
||||
}
|
||||
}
|
||||
finish_reply_check:;
|
||||
finish_return_check:;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +127,7 @@ def f [
|
|||
|
||||
//: In Mu we'd like to assume that any instruction doesn't modify its
|
||||
//: ingredients unless they're also products. The /same-as-ingredient inside
|
||||
//: the recipe's 'reply' indicates that an ingredient is intended to be
|
||||
//: the recipe's 'return' indicates that an ingredient is intended to be
|
||||
//: modified in place, and will help catch accidental misuse of such
|
||||
//: 'ingredient-products' (sometimes called in-out parameters in other
|
||||
//: languages).
|
|
@ -5,7 +5,7 @@
|
|||
//: units (containers or arrays) that may contain many different primitives at
|
||||
//: once. Containers and arrays can grow quite large in complex programs, and
|
||||
//: we'd like some way to efficiently share them between recipes without
|
||||
//: constantly having to make copies. Right now 'next-ingredient' and 'reply'
|
||||
//: constantly having to make copies. Right now 'next-ingredient' and 'return'
|
||||
//: copy data across recipe boundaries. To avoid copying large quantities of
|
||||
//: data around, we'll use *addresses*. An address is a bookmark to some
|
||||
//: arbitrary quantity of data (the *payload*). It's a primitive, so it's as
|
||||
|
|
|
@ -222,7 +222,7 @@ if (curr.name == "local-scope") {
|
|||
rewrite_default_space_instruction(curr);
|
||||
}
|
||||
|
||||
//: todo: do this in a transform, rather than magically in the reply instruction
|
||||
//: todo: do this in a transform, rather than magically in the return instruction
|
||||
:(after "Falling Through End Of Recipe")
|
||||
try_reclaim_locals();
|
||||
:(after "Starting Reply")
|
||||
|
@ -259,7 +259,7 @@ void try_reclaim_locals() {
|
|||
}
|
||||
|
||||
:(code)
|
||||
// is this reagent one of the values returned by the current (reply) instruction?
|
||||
// is this reagent one of the values returned by the current (return) instruction?
|
||||
// is the corresponding ingredient saved in the caller?
|
||||
bool escaping(const reagent& r) {
|
||||
assert(Current_routine); // run-time only
|
||||
|
@ -370,7 +370,7 @@ def main [
|
|||
def f [
|
||||
local-scope
|
||||
x:&:num <- new number:type
|
||||
reply x:&:num
|
||||
return x:&:num
|
||||
]
|
||||
def main [
|
||||
f # doesn't save result
|
||||
|
|
|
@ -322,13 +322,13 @@ def add2 x:num, y:num -> z:num [
|
|||
+error: add2: replied with the wrong type at 'return z'
|
||||
|
||||
:(before "End Checks")
|
||||
Transform.push_back(check_reply_instructions_against_header); // idempotent
|
||||
Transform.push_back(check_return_instructions_against_header); // idempotent
|
||||
|
||||
:(code)
|
||||
void check_reply_instructions_against_header(const recipe_ordinal r) {
|
||||
void check_return_instructions_against_header(const recipe_ordinal r) {
|
||||
const recipe& caller_recipe = get(Recipe, r);
|
||||
if (!caller_recipe.has_header) return;
|
||||
trace(9991, "transform") << "--- checking reply instructions against header for " << caller_recipe.name << end();
|
||||
trace(9991, "transform") << "--- checking return instructions against header for " << caller_recipe.name << end();
|
||||
for (int i = 0; i < SIZE(caller_recipe.steps); ++i) {
|
||||
const instruction& inst = caller_recipe.steps.at(i);
|
||||
if (inst.name != "reply" && inst.name != "return") continue;
|
||||
|
@ -373,7 +373,7 @@ void check_header_ingredients(const recipe_ordinal r) {
|
|||
recipe& caller_recipe = get(Recipe, r);
|
||||
if (caller_recipe.products.empty()) return;
|
||||
caller_recipe.ingredient_index.clear();
|
||||
trace(9991, "transform") << "--- checking reply instructions against header for " << caller_recipe.name << end();
|
||||
trace(9991, "transform") << "--- checking return instructions against header for " << caller_recipe.name << end();
|
||||
for (int i = 0; i < SIZE(caller_recipe.ingredients); ++i) {
|
||||
if (contains_key(caller_recipe.ingredient_index, caller_recipe.ingredients.at(i).name))
|
||||
raise << maybe(caller_recipe.name) << "'" << caller_recipe.ingredients.at(i).name << "' can't repeat in the ingredients\n" << end();
|
||||
|
@ -454,24 +454,24 @@ def add2 x:num, y:num -> z:num [
|
|||
+mem: storing 8 in location 1
|
||||
|
||||
:(after "Transform.push_back(check_header_ingredients)")
|
||||
Transform.push_back(fill_in_reply_ingredients); // idempotent
|
||||
Transform.push_back(fill_in_return_ingredients); // idempotent
|
||||
|
||||
:(code)
|
||||
void fill_in_reply_ingredients(const recipe_ordinal r) {
|
||||
void fill_in_return_ingredients(const recipe_ordinal r) {
|
||||
recipe& caller_recipe = get(Recipe, r);
|
||||
if (!caller_recipe.has_header) return;
|
||||
trace(9991, "transform") << "--- fill in reply ingredients from header for recipe " << caller_recipe.name << end();
|
||||
trace(9991, "transform") << "--- fill in return ingredients from header for recipe " << caller_recipe.name << end();
|
||||
for (int i = 0; i < SIZE(caller_recipe.steps); ++i) {
|
||||
instruction& inst = caller_recipe.steps.at(i);
|
||||
if (inst.name == "reply" || inst.name == "return")
|
||||
add_header_products(inst, caller_recipe);
|
||||
}
|
||||
// fall through reply
|
||||
// fall through return
|
||||
if (caller_recipe.steps.empty()) return; // error will be raised elsewhere if there's a product in the header; just give up
|
||||
const instruction& final_instruction = caller_recipe.steps.at(SIZE(caller_recipe.steps)-1);
|
||||
if (final_instruction.name != "reply" && final_instruction.name != "return") {
|
||||
instruction inst;
|
||||
inst.name = "reply";
|
||||
inst.name = "return";
|
||||
add_header_products(inst, caller_recipe);
|
||||
caller_recipe.steps.push_back(inst);
|
||||
}
|
||||
|
@ -493,7 +493,7 @@ void add_header_products(instruction& inst, const recipe& caller_recipe) {
|
|||
}
|
||||
}
|
||||
|
||||
:(scenario explicit_reply_ignores_header)
|
||||
:(scenario explicit_return_ignores_header)
|
||||
def main [
|
||||
1:num/raw, 2:num/raw <- add2 3, 5
|
||||
]
|
||||
|
@ -516,7 +516,7 @@ def add2 x:num, y:num -> z:num [
|
|||
load-ingredients
|
||||
z <- add x, y
|
||||
]
|
||||
+transform: instruction: reply {z: "number"}
|
||||
+transform: instruction: return {z: "number"}
|
||||
+mem: storing 8 in location 1
|
||||
|
||||
:(scenario return_on_fallthrough_already_exists)
|
||||
|
@ -530,10 +530,10 @@ def add2 x:num, y:num -> z:num [
|
|||
return z
|
||||
]
|
||||
+transform: instruction: return {z: ()}
|
||||
-transform: instruction: reply z:num
|
||||
-transform: instruction: return z:num
|
||||
+mem: storing 8 in location 1
|
||||
|
||||
:(scenario return_after_conditional_reply_based_on_header)
|
||||
:(scenario return_after_conditional_return_based_on_header)
|
||||
def main [
|
||||
1:num/raw <- add2 3, 5
|
||||
]
|
||||
|
|
|
@ -244,7 +244,7 @@ def main [
|
|||
+run: {6: ("foo" "point")} <- merge {1: "literal", "y": ()}, {23: "literal"}
|
||||
+mem: storing 1 in location 6
|
||||
+mem: storing 23 in location 7
|
||||
+run: reply
|
||||
+run: return
|
||||
# no other stores
|
||||
% CHECK_EQ(trace_count_prefix("mem", "storing"), 7);
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ def foo p:&:d1 -> q:num [
|
|||
load-ingredients
|
||||
x:&:d1 <- new d1:type
|
||||
*x <- put *x, p:offset, 34 # ignore this 'p'
|
||||
reply 36
|
||||
return 36
|
||||
]
|
||||
container d1 [
|
||||
p:num
|
||||
|
|
|
@ -13,7 +13,7 @@ def push x:_elem, l:&:list:_elem -> l:&:list:_elem [
|
|||
load-ingredients
|
||||
result:&:list:_elem <- new {(list _elem): type}
|
||||
*result <- merge x, l
|
||||
reply result
|
||||
return result
|
||||
]
|
||||
|
||||
def first in:&:list:_elem -> result:_elem [
|
||||
|
@ -264,7 +264,7 @@ scenario removing-from-singleton-list [
|
|||
def reverse list:&:list:_elem temp:&:list:_elem/contained-in:result -> result:&:list:_elem [
|
||||
local-scope
|
||||
load-ingredients
|
||||
reply-unless list, temp
|
||||
return-unless list, temp
|
||||
object:_elem <- first, list
|
||||
list <- rest list
|
||||
temp <- push object, temp
|
||||
|
|
|
@ -5,7 +5,7 @@ def random generator:&:stream:num -> result:num, fail?:bool, generator:&:stream:
|
|||
break-if generator
|
||||
# generator is 0? use real random-number generator
|
||||
result <- real-random
|
||||
reply result, 0/false
|
||||
return result, 0/false
|
||||
}
|
||||
result, fail?, generator <- read generator
|
||||
]
|
||||
|
|
|
@ -324,7 +324,7 @@ def use-space [
|
|||
n:&:num/space:1 <- next-ingredient # should decrement refcount
|
||||
*n/space:1 <- copy 34
|
||||
n2:num <- add *n/space:1, 1
|
||||
reply n2
|
||||
return n2
|
||||
]
|
||||
def main [
|
||||
local-scope
|
||||
|
@ -665,7 +665,7 @@ def f2 [
|
|||
20:num <- copy 1
|
||||
]
|
||||
# f2 runs an extra instruction for the implicit return added by the
|
||||
# fill_in_reply_ingredients transform
|
||||
# fill_in_return_ingredients transform
|
||||
+mem: storing 3 in location 11
|
||||
|
||||
:(scenario number_of_instructions_across_multiple_scheduling_intervals)
|
||||
|
@ -685,7 +685,7 @@ def f2 [
|
|||
20:num <- copy 1
|
||||
]
|
||||
# f2 runs an extra instruction for the implicit return added by the
|
||||
# fill_in_reply_ingredients transform
|
||||
# fill_in_return_ingredients transform
|
||||
+mem: storing 5 in location 11
|
||||
|
||||
//:: make sure that each routine gets a different alloc to start
|
||||
|
|
|
@ -607,7 +607,7 @@ def screen-height screen:&:screen -> height:num [
|
|||
def hide-cursor screen:&:screen -> screen:&:screen [
|
||||
local-scope
|
||||
load-ingredients
|
||||
reply-if screen # fake screen; do nothing
|
||||
return-if screen # fake screen; do nothing
|
||||
# real screen
|
||||
hide-cursor-on-display
|
||||
]
|
||||
|
@ -615,7 +615,7 @@ def hide-cursor screen:&:screen -> screen:&:screen [
|
|||
def show-cursor screen:&:screen -> screen:&:screen [
|
||||
local-scope
|
||||
load-ingredients
|
||||
reply-if screen # fake screen; do nothing
|
||||
return-if screen # fake screen; do nothing
|
||||
# real screen
|
||||
show-cursor-on-display
|
||||
]
|
||||
|
@ -623,7 +623,7 @@ def show-cursor screen:&:screen -> screen:&:screen [
|
|||
def hide-screen screen:&:screen -> screen:&:screen [
|
||||
local-scope
|
||||
load-ingredients
|
||||
reply-if screen # fake screen; do nothing
|
||||
return-if screen # fake screen; do nothing
|
||||
# real screen
|
||||
hide-display
|
||||
]
|
||||
|
@ -631,7 +631,7 @@ def hide-screen screen:&:screen -> screen:&:screen [
|
|||
def show-screen screen:&:screen -> screen:&:screen [
|
||||
local-scope
|
||||
load-ingredients
|
||||
reply-if screen # fake screen; do nothing
|
||||
return-if screen # fake screen; do nothing
|
||||
# real screen
|
||||
show-display
|
||||
]
|
||||
|
|
|
@ -86,7 +86,7 @@ def start-writing resources:&:resources, filename:text -> sink:&:sink:char, rout
|
|||
break-unless resources
|
||||
# fake file system
|
||||
routine-id <- start-running transmit-to-fake-file resources, filename, source
|
||||
reply
|
||||
return
|
||||
}
|
||||
# real file system
|
||||
file:num <- $open-file-for-writing filename
|
||||
|
@ -136,7 +136,7 @@ def transmit-to-fake-file resources:&:resources, filename:text, source:&:source:
|
|||
loop-unless found?
|
||||
put-index *data, i, new-resource
|
||||
reset lock
|
||||
reply
|
||||
return
|
||||
}
|
||||
# if file didn't already exist, make room for it
|
||||
new-len:num <- add len, 1
|
||||
|
|
|
@ -26,7 +26,7 @@ F - example-server-test: $open-server-socket failed]
|
|||
def example-handler query:text -> response:text [
|
||||
local-scope
|
||||
load-ingredients
|
||||
reply [abc]
|
||||
return [abc]
|
||||
]
|
||||
|
||||
# To test client operations, use `assume-resources` with a filename that
|
||||
|
|
|
@ -146,7 +146,7 @@ def should-attempt-copy? click-row:num, click-column:num, env:&:environment -> r
|
|||
load-ingredients
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, click-column, env
|
||||
reply-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
# narrower, is the click in the columns spanning the 'copy' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -154,7 +154,7 @@ def should-attempt-copy? click-row:num, click-column:num, env:&:environment -> r
|
|||
sandbox-right-margin:num <- get *first-sandbox, right:offset
|
||||
_, _, copy-button-left:num, copy-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin
|
||||
copy-button-vertical-area?:bool <- within-range? click-column, copy-button-left, copy-button-right
|
||||
reply-unless copy-button-vertical-area?, 0/false
|
||||
return-unless copy-button-vertical-area?, 0/false
|
||||
# finally, is sandbox editor empty?
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
result <- empty-editor? current-sandbox
|
||||
|
|
|
@ -84,7 +84,7 @@ def should-attempt-delete? click-row:num, click-column:num, env:&:environment ->
|
|||
load-ingredients
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, click-column, env
|
||||
reply-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
# narrower, is the click in the columns spanning the 'copy' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
|
|
@ -141,7 +141,7 @@ def should-attempt-edit? click-row:num, click-column:num, env:&:environment -> r
|
|||
load-ingredients
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, click-column, env
|
||||
reply-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
# narrower, is the click in the columns spanning the 'edit' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -149,7 +149,7 @@ def should-attempt-edit? click-row:num, click-column:num, env:&:environment -> r
|
|||
sandbox-right-margin:num <- get *first-sandbox, right:offset
|
||||
edit-button-left:num, edit-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin
|
||||
edit-button-vertical-area?:bool <- within-range? click-column, edit-button-left, edit-button-right
|
||||
reply-unless edit-button-vertical-area?, 0/false
|
||||
return-unless edit-button-vertical-area?, 0/false
|
||||
# finally, is sandbox editor empty?
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
result <- empty-editor? current-sandbox
|
||||
|
|
|
@ -50,14 +50,14 @@ def new-pair a:&:cell, b:&:cell -> result:&:cell [
|
|||
def is-atom? x:&:cell -> result:bool [
|
||||
local-scope
|
||||
load-ingredients
|
||||
reply-unless x, 0/false
|
||||
return-unless x, 0/false
|
||||
_, result <- maybe-convert *x, atom:variant
|
||||
]
|
||||
|
||||
def is-pair? x:&:cell -> result:bool [
|
||||
local-scope
|
||||
load-ingredients
|
||||
reply-unless x, 0/false
|
||||
return-unless x, 0/false
|
||||
_, result <- maybe-convert *x, pair:variant
|
||||
]
|
||||
|
||||
|
@ -91,7 +91,7 @@ def atom-match? x:&:cell, pat:text -> result:bool [
|
|||
local-scope
|
||||
load-ingredients
|
||||
s:text, is-atom?:bool <- maybe-convert *x, atom:variant
|
||||
reply-unless is-atom?, 0/false
|
||||
return-unless is-atom?, 0/false
|
||||
result <- equal pat, s
|
||||
]
|
||||
|
||||
|
@ -108,7 +108,7 @@ def first x:&:cell -> result:&:cell [
|
|||
local-scope
|
||||
load-ingredients
|
||||
pair:pair, pair?:bool <- maybe-convert *x, pair:variant
|
||||
reply-unless pair?, 0/nil
|
||||
return-unless pair?, 0/nil
|
||||
result <- get pair, first:offset
|
||||
]
|
||||
|
||||
|
@ -116,7 +116,7 @@ def rest x:&:cell -> result:&:cell [
|
|||
local-scope
|
||||
load-ingredients
|
||||
pair:pair, pair?:bool <- maybe-convert *x, pair:variant
|
||||
reply-unless pair?, 0/nil
|
||||
return-unless pair?, 0/nil
|
||||
result <- get pair, rest:offset
|
||||
]
|
||||
|
||||
|
@ -124,7 +124,7 @@ def set-first base:&:cell, new-first:&:cell -> base:&:cell [
|
|||
local-scope
|
||||
load-ingredients
|
||||
pair:pair, is-pair?:bool <- maybe-convert *base, pair:variant
|
||||
reply-unless is-pair?
|
||||
return-unless is-pair?
|
||||
pair <- put pair, first:offset, new-first
|
||||
*base <- merge 1/pair, pair
|
||||
]
|
||||
|
@ -133,7 +133,7 @@ def set-rest base:&:cell, new-rest:&:cell -> base:&:cell [
|
|||
local-scope
|
||||
load-ingredients
|
||||
pair:pair, is-pair?:bool <- maybe-convert *base, pair:variant
|
||||
reply-unless is-pair?
|
||||
return-unless is-pair?
|
||||
pair <- put pair, rest:offset, new-rest
|
||||
*base <- merge 1/pair, pair
|
||||
]
|
||||
|
@ -181,7 +181,7 @@ def parse in:&:stream:char -> out:&:cell, in:&:stream:char [
|
|||
# skip whitespace
|
||||
in <- skip-whitespace in
|
||||
c:char, eof?:bool <- peek in
|
||||
reply-if eof?, 0/nil
|
||||
return-if eof?, 0/nil
|
||||
pair?:bool <- equal c, 40/open-paren
|
||||
{
|
||||
break-if pair?
|
||||
|
@ -270,7 +270,7 @@ def skip-whitespace in:&:stream:char -> in:&:stream:char [
|
|||
load-ingredients
|
||||
{
|
||||
done?:bool <- end-of-stream? in
|
||||
reply-if done?, 0/null
|
||||
return-if done?, 0/null
|
||||
c:char <- peek in
|
||||
space?:bool <- space? c
|
||||
break-unless space?
|
||||
|
@ -294,14 +294,14 @@ def to-buffer x:&:cell, buf:&:buffer -> buf:&:buffer [
|
|||
{
|
||||
break-if x
|
||||
buf <- append buf, [<>]
|
||||
reply
|
||||
return
|
||||
}
|
||||
# base case: atom
|
||||
{
|
||||
s:text, atom?:bool <- maybe-convert *x, atom:variant
|
||||
break-unless atom?
|
||||
buf <- append buf, s
|
||||
reply
|
||||
return
|
||||
}
|
||||
# recursive case: pair
|
||||
buf <- append buf, [< ]
|
||||
|
|
12
nqueens.mu
12
nqueens.mu
|
@ -49,9 +49,9 @@ def conflict? curr:square, queens:&:list:square -> result:bool [
|
|||
local-scope
|
||||
load-ingredients
|
||||
result1:bool <- conflicting-file? curr, queens
|
||||
reply-if result1, result1
|
||||
return-if result1, result1
|
||||
result2:bool <- conflicting-diagonal? curr, queens
|
||||
reply result2
|
||||
return result2
|
||||
]
|
||||
|
||||
def conflicting-file? curr:square, queens:&:list:square -> result:bool [
|
||||
|
@ -63,11 +63,11 @@ def conflicting-file? curr:square, queens:&:list:square -> result:bool [
|
|||
q:square <- first queens
|
||||
qfile:num <- get q, file:offset
|
||||
file-match?:bool <- equal curr-file, qfile
|
||||
reply-if file-match?, 1/conflict-found
|
||||
return-if file-match?, 1/conflict-found
|
||||
queens <- rest queens
|
||||
loop
|
||||
}
|
||||
reply 0/no-conflict-found
|
||||
return 0/no-conflict-found
|
||||
]
|
||||
|
||||
def conflicting-diagonal? curr:square, queens:&:list:square -> result:bool [
|
||||
|
@ -85,11 +85,11 @@ def conflicting-diagonal? curr:square, queens:&:list:square -> result:bool [
|
|||
rank-delta <- abs rank-delta
|
||||
file-delta <- abs file-delta
|
||||
diagonal-match?:bool <- equal rank-delta, file-delta
|
||||
reply-if diagonal-match?, 1/conflict-found
|
||||
return-if diagonal-match?, 1/conflict-found
|
||||
queens <- rest queens
|
||||
loop
|
||||
}
|
||||
reply 0/no-conflict-found
|
||||
return 0/no-conflict-found
|
||||
]
|
||||
|
||||
def main [
|
||||
|
|
|
@ -146,7 +146,7 @@ def should-attempt-copy? click-row:num, click-column:num, env:&:environment -> r
|
|||
load-ingredients
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, env
|
||||
reply-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
# narrower, is the click in the columns spanning the 'copy' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -154,7 +154,7 @@ def should-attempt-copy? click-row:num, click-column:num, env:&:environment -> r
|
|||
sandbox-right-margin:num <- get *first-sandbox, right:offset
|
||||
_, _, copy-button-left:num, copy-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin
|
||||
copy-button-vertical-area?:bool <- within-range? click-column, copy-button-left, copy-button-right
|
||||
reply-unless copy-button-vertical-area?, 0/false
|
||||
return-unless copy-button-vertical-area?, 0/false
|
||||
# finally, is sandbox editor empty?
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
result <- empty-editor? current-sandbox
|
||||
|
|
|
@ -81,7 +81,7 @@ def should-attempt-delete? click-row:num, click-column:num, env:&:environment ->
|
|||
load-ingredients
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, env
|
||||
reply-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
# narrower, is the click in the columns spanning the 'copy' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
|
|
@ -70,7 +70,7 @@ def should-attempt-edit? click-row:num, click-column:num, env:&:environment -> r
|
|||
load-ingredients
|
||||
# are we below the sandbox editor?
|
||||
click-sandbox-area?:bool <- click-on-sandbox-area? click-row, env
|
||||
reply-unless click-sandbox-area?, 0/false
|
||||
return-unless click-sandbox-area?, 0/false
|
||||
# narrower, is the click in the columns spanning the 'edit' button?
|
||||
first-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
assert first-sandbox, [!!]
|
||||
|
@ -78,7 +78,7 @@ def should-attempt-edit? click-row:num, click-column:num, env:&:environment -> r
|
|||
sandbox-right-margin:num <- get *first-sandbox, right:offset
|
||||
edit-button-left:num, edit-button-right:num, _ <- sandbox-menu-columns sandbox-left-margin, sandbox-right-margin
|
||||
edit-button-vertical-area?:bool <- within-range? click-column, edit-button-left, edit-button-right
|
||||
reply-unless edit-button-vertical-area?, 0/false
|
||||
return-unless edit-button-vertical-area?, 0/false
|
||||
# finally, is sandbox editor empty?
|
||||
current-sandbox:&:editor <- get *env, current-sandbox:offset
|
||||
result <- empty-editor? current-sandbox
|
||||
|
|
Loading…
Reference in New Issue