grabapl_syntax 0.0.4

Parsing support for grabapl.
Documentation
fn max_heap_remove(sentinel: Object) -> (max_value: Integer) {
    // ! syntax: take the single return value of the operation and bind to it.
    // alternative is let map = add_node(...); and then map.new is the returned node.
    let! max_value = add_node`-1`();
    if shape [
        root: Integer,
        sentinel -> root: *
    ] {
        // if we have a root, we can proceed
        max_heap_remove_helper(root, max_value);
    } else {
        // do nothing
    }
    return (max_value: max_value);
}


fn max_heap_remove_helper(root: Integer, max_value: Integer) {
    // return the value of the root node
    copy_value_from_to(root, max_value);
    if shape [
        left: Integer,
        root -> left: *,
        right: Integer,
        root -> right: *
    ] {
        // we have two children, check which is larger
        // method[] syntax: pass arguments to builtin operations
        if cmp_fst_snd`>`(left, right) {
            // left is larger, recurse on left
            let! temp_max = add_node`-1`();
            max_heap_remove_helper(left, temp_max);
            copy_value_from_to(temp_max, root);
            remove_node(temp_max);
        } else {
            // right is larger or equal, recurse on right
            let! temp_max = add_node`-1`();
            max_heap_remove_helper(right, temp_max);
            copy_value_from_to(temp_max, root);
            remove_node(temp_max);
        }
    } else if shape [
        child: Integer,
        root -> child: *
    ] {
        // we have one child, recurse on it
        let! temp_max = add_node`-1`();
        max_heap_remove_helper(child, temp_max);
        copy_value_from_to(temp_max, root);
        remove_node(temp_max);
    } else {
        // no children, we can delete the root node
        remove_node(root);
    }
}


// some more syntax:

// ?ident marks a node as a context node that will implicitly be matched.
//fn takes_context_nodes(child: Integer, ?parent: Object, child -> parent: "child") {
//
//}

// actually, maybe this?
// since this way we have a match of (arg1, arg2) to (param1, param2) for explicitly passed params,
// and [ ] for implicitly matched graphs, like with `if shape`.
fn takes_context_nodes(child: Integer) [
    parent: Object,
    child -> parent: "child"
] -> (
    new_node: Integer,
    child -> new_node: "grandchild"
) {
    let map = add_node();
    return (new_node: map.new);
}