summaryrefslogtreecommitdiff
path: root/src/iter.c
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2019-09-08 21:11:17 -0600
committerAdrian Thurston <thurston@colm.net>2019-09-08 21:11:17 -0600
commitc860c61607117582abd8f23881eed87957197484 (patch)
tree4d4e65dddc710e15f008189a9308d95924350c3f /src/iter.c
parentf37c916aed2600951b8966a86020406b0b0542cf (diff)
downloadcolm-c860c61607117582abd8f23881eed87957197484.tar.gz
moved the original colm src dir to /colm
Diffstat (limited to 'src/iter.c')
-rw-r--r--src/iter.c648
1 files changed, 0 insertions, 648 deletions
diff --git a/src/iter.c b/src/iter.c
deleted file mode 100644
index 66974f4a..00000000
--- a/src/iter.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * Copyright 2007-2018 Adrian Thurston <thurston@colm.net>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <assert.h>
-#include <stdbool.h>
-
-#include <colm/tree.h>
-#include <colm/bytecode.h>
-#include <colm/program.h>
-
-#include "internal.h"
-
-void colm_init_list_iter( generic_iter_t *list_iter, tree_t **stack_root,
- long arg_size, long root_size, const ref_t *root_ref, int generic_id )
-{
- list_iter->type = IT_Tree;
- list_iter->root_ref = *root_ref;
- list_iter->stack_root = stack_root;
- list_iter->yield_size = 0;
- list_iter->root_size = root_size;
- list_iter->ref.kid = 0;
- list_iter->ref.next = 0;
- list_iter->arg_size = arg_size;
- list_iter->generic_id = generic_id;
-}
-
-void colm_list_iter_destroy( program_t *prg, tree_t ***psp, generic_iter_t *iter )
-{
- if ( (int)iter->type != 0 ) {
- int i;
- tree_t **sp = *psp;
- long cur_stack_size = vm_ssize() - iter->root_size;
- assert( iter->yield_size == cur_stack_size );
- vm_popn( iter->yield_size );
- for ( i = 0; i < iter->arg_size; i++ ) {
- //colm_tree_downref( prg, sp, vm_pop_tree() );
- vm_pop_value();
- }
- iter->type = 0;
- *psp = sp;
- }
-}
-
-tree_t *colm_list_iter_advance( program_t *prg, tree_t ***psp, generic_iter_t *iter )
-{
- tree_t **sp = *psp;
- assert( iter->yield_size == (vm_ssize() - iter->root_size) );
-
- if ( iter->ref.kid == 0 ) {
- /* kid_t is zero, start from the root. */
- list_t *list = *((list_t**)iter->root_ref.kid);
- iter->ref.kid = (kid_t*)list->head;
- iter->ref.next = 0;
-
- //= iter->rootRef;
- //iter
- //iterFind( prg, psp, iter, true );
- }
- else {
- /* Have a previous item, continue searching from there. */
- //iterFind( prg, psp, iter, false );
-
- list_el_t *list_el = (list_el_t*)iter->ref.kid;
- list_el = list_el->list_next;
- iter->ref.kid = (kid_t*)list_el;
- iter->ref.next = 0;
- }
-
- sp = *psp;
- iter->yield_size = vm_ssize() - iter->root_size;
-
- return (iter->ref.kid ? prg->true_val : prg->false_val );
-}
-
-tree_t *colm_rev_list_iter_advance( program_t *prg, tree_t ***psp, generic_iter_t *iter )
-{
- tree_t **sp = *psp;
- assert( iter->yield_size == (vm_ssize() - iter->root_size) );
-
- if ( iter->ref.kid == 0 ) {
- /* kid_t is zero, start from the root. */
- list_t *list = *((list_t**)iter->root_ref.kid);
- iter->ref.kid = (kid_t*)list->tail;
- iter->ref.next = 0;
-
- //= iter->rootRef;
- //iter
- //iterFind( prg, psp, iter, true );
- }
- else {
- /* Have a previous item, continue searching from there. */
- //iterFind( prg, psp, iter, false );
-
- list_el_t *list_el = (list_el_t*)iter->ref.kid;
- list_el = list_el->list_prev;
- iter->ref.kid = (kid_t*)list_el;
- iter->ref.next = 0;
- }
-
- sp = *psp;
- iter->yield_size = vm_ssize() - iter->root_size;
-
- return (iter->ref.kid ? prg->true_val : prg->false_val );
-}
-
-tree_t *colm_map_iter_advance( program_t *prg, tree_t ***psp, generic_iter_t *iter )
-{
- tree_t **sp = *psp;
- assert( iter->yield_size == (vm_ssize() - iter->root_size) );
-
- if ( iter->ref.kid == 0 ) {
- /* kid_t is zero, start from the root. */
- map_t *map = *((map_t**)iter->root_ref.kid);
- iter->ref.kid = (kid_t*)map->head;
- iter->ref.next = 0;
-
- //= iter->rootRef;
- //iter
- //iterFind( prg, psp, iter, true );
- }
- else {
- /* Have a previous item, continue searching from there. */
- //iterFind( prg, psp, iter, false );
-
- map_el_t *map_el = (map_el_t*)iter->ref.kid;
- map_el = map_el->next;
- iter->ref.kid = (kid_t*)map_el;
- iter->ref.next = 0;
- }
-
- sp = *psp;
- iter->yield_size = vm_ssize() - iter->root_size;
-
- return (iter->ref.kid ? prg->true_val : prg->false_val );
-}
-
-tree_t *colm_list_iter_deref_cur( program_t *prg, generic_iter_t *iter )
-{
- struct generic_info *gi = &prg->rtd->generic_info[iter->generic_id];
- list_el_t *el = (list_el_t*)iter->ref.kid;
- struct colm_struct *s = el != 0 ?
- colm_struct_container( el, gi->el_offset ) : 0;
- return (tree_t*)s;
-}
-
-value_t colm_viter_deref_cur( program_t *prg, generic_iter_t *iter )
-{
- struct generic_info *gi = &prg->rtd->generic_info[iter->generic_id];
- list_el_t *el = (list_el_t*)iter->ref.kid;
- struct colm_struct *s = el != 0 ?
- colm_struct_container( el, gi->el_offset ) : 0;
-
- value_t value = colm_struct_get_field( s, value_t, 0 );
- if ( gi->value_type == TYPE_TREE )
- colm_tree_upref( prg, (tree_t*)value );
-
- return value;
-}
-
-void colm_init_tree_iter( tree_iter_t *tree_iter, tree_t **stack_root,
- long arg_size, long root_size,
- const ref_t *root_ref, int search_id )
-{
- tree_iter->type = IT_Tree;
- tree_iter->root_ref = *root_ref;
- tree_iter->search_id = search_id;
- tree_iter->stack_root = stack_root;
- tree_iter->yield_size = 0;
- tree_iter->root_size = root_size;
- tree_iter->ref.kid = 0;
- tree_iter->ref.next = 0;
- tree_iter->arg_size = arg_size;
-}
-
-void colm_init_rev_tree_iter( rev_tree_iter_t *rev_triter, tree_t **stack_root,
- long arg_size, long root_size,
- const ref_t *root_ref, int search_id, int children )
-{
- rev_triter->type = IT_RevTree;
- rev_triter->root_ref = *root_ref;
- rev_triter->search_id = search_id;
- rev_triter->stack_root = stack_root;
- rev_triter->yield_size = children;
- rev_triter->root_size = root_size;
- rev_triter->kid_at_yield = 0;
- rev_triter->children = children;
- rev_triter->ref.kid = 0;
- rev_triter->ref.next = 0;
- rev_triter->arg_size = arg_size;
-}
-
-void init_user_iter( user_iter_t *user_iter, tree_t **stack_root, long root_size,
- long arg_size, long search_id )
-{
- user_iter->type = IT_User;
- user_iter->stack_root = stack_root;
- user_iter->arg_size = arg_size;
- user_iter->yield_size = 0;
- user_iter->root_size = root_size;
- user_iter->resume = 0;
- user_iter->frame = 0;
- user_iter->search_id = search_id;
-
- user_iter->ref.kid = 0;
- user_iter->ref.next = 0;
-}
-
-
-user_iter_t *colm_uiter_create( program_t *prg, tree_t ***psp, struct function_info *fi, long search_id )
-{
- tree_t **sp = *psp;
-
- vm_pushn( sizeof(user_iter_t) / sizeof(word_t) );
- void *mem = vm_ptop();
- user_iter_t *uiter = mem;
-
- tree_t **stack_root = vm_ptop();
- long root_size = vm_ssize();
-
- init_user_iter( uiter, stack_root, root_size, fi->arg_size, search_id );
-
- *psp = sp;
- return uiter;
-}
-
-void uiter_init( program_t *prg, tree_t **sp, user_iter_t *uiter,
- struct function_info *fi, int revert_on )
-{
- /* Set up the first yeild so when we resume it starts at the beginning. */
- uiter->ref.kid = 0;
- uiter->yield_size = vm_ssize() - uiter->root_size;
- // uiter->frame = &uiter->stackRoot[-IFR_AA];
-
- if ( revert_on )
- uiter->resume = prg->rtd->frame_info[fi->frame_id].codeWV;
- else
- uiter->resume = prg->rtd->frame_info[fi->frame_id].codeWC;
-}
-
-
-void colm_tree_iter_destroy( program_t *prg, tree_t ***psp, tree_iter_t *iter )
-{
- if ( (int)iter->type != 0 ) {
- int i;
- tree_t **sp = *psp;
- long cur_stack_size = vm_ssize() - iter->root_size;
- assert( iter->yield_size == cur_stack_size );
- vm_popn( iter->yield_size );
- for ( i = 0; i < iter->arg_size; i++ )
- colm_tree_downref( prg, sp, vm_pop_tree() );
- iter->type = 0;
- *psp = sp;
- }
-}
-
-void colm_rev_tree_iter_destroy( struct colm_program *prg, tree_t ***psp, rev_tree_iter_t *riter )
-{
- if ( (int)riter->type != 0 ) {
- int i;
- tree_t **sp = *psp;
- long cur_stack_size = vm_ssize() - riter->root_size;
- assert( riter->yield_size == cur_stack_size );
- vm_popn( riter->yield_size );
- for ( i = 0; i < riter->arg_size; i++ )
- colm_tree_downref( prg, sp, vm_pop_tree() );
- riter->type = 0;
- *psp = sp;
- }
-}
-
-void colm_uiter_destroy( program_t *prg, tree_t ***psp, user_iter_t *uiter )
-{
- if ( uiter != 0 && (int)uiter->type != 0 ) {
- tree_t **sp = *psp;
-
- /* We should always be coming from a yield. The current stack size will be
- * nonzero and the stack size in the iterator will be correct. */
- long cur_stack_size = vm_ssize() - uiter->root_size;
- assert( uiter->yield_size == cur_stack_size );
-
- vm_popn( uiter->yield_size );
- vm_popn( sizeof(user_iter_t) / sizeof(word_t) );
-
- uiter->type = 0;
-
- *psp = sp;
- }
-}
-
-void colm_uiter_unwind( program_t *prg, tree_t ***psp, user_iter_t *uiter )
-{
- if ( uiter != 0 && (int)uiter->type != 0 ) {
- tree_t **sp = *psp;
-
- /* We should always be coming from a yield. The current stack size will be
- * nonzero and the stack size in the iterator will be correct. */
- long cur_stack_size = vm_ssize() - uiter->root_size;
- assert( uiter->yield_size == cur_stack_size );
-
- long arg_size = uiter->arg_size;
-
- vm_popn( uiter->yield_size );
- vm_popn( sizeof(user_iter_t) / sizeof(word_t) );
-
- /* The IN_PREP_ARGS stack data. */
- vm_popn( arg_size );
- vm_pop_value();
-
- uiter->type = 0;
-
- *psp = sp;
- }
-}
-
-tree_t *tree_iter_deref_cur( tree_iter_t *iter )
-{
- return iter->ref.kid == 0 ? 0 : iter->ref.kid->tree;
-}
-
-void set_triter_cur( program_t *prg, tree_iter_t *iter, tree_t *tree )
-{
- iter->ref.kid->tree = tree;
-}
-
-void set_uiter_cur( program_t *prg, user_iter_t *uiter, tree_t *tree )
-{
- uiter->ref.kid->tree = tree;
-}
-
-void split_iter_cur( program_t *prg, tree_t ***psp, tree_iter_t *iter )
-{
- if ( iter->ref.kid == 0 )
- return;
-
- split_ref( prg, psp, &iter->ref );
-}
-
-void iter_find( program_t *prg, tree_t ***psp, tree_iter_t *iter, int try_first )
-{
- int any_tree = iter->search_id == prg->rtd->any_id;
- tree_t **top = iter->stack_root;
- kid_t *child;
- tree_t **sp = *psp;
-
-rec_call:
- if ( try_first && ( iter->ref.kid->tree->id == iter->search_id || any_tree ) ) {
- *psp = sp;
- return;
- }
- else {
- child = tree_child( prg, iter->ref.kid->tree );
- if ( child != 0 ) {
- vm_contiguous( 2 );
- vm_push_ref( iter->ref.next );
- vm_push_kid( iter->ref.kid );
- iter->ref.kid = child;
- iter->ref.next = (ref_t*)vm_ptop();
- while ( iter->ref.kid != 0 ) {
- try_first = true;
- goto rec_call;
- rec_return:
- iter->ref.kid = iter->ref.kid->next;
- }
- iter->ref.kid = vm_pop_kid();
- iter->ref.next = vm_pop_ref();
- }
- }
-
- if ( top != vm_ptop() )
- goto rec_return;
-
- iter->ref.kid = 0;
- *psp = sp;
-}
-
-tree_t *tree_iter_advance( program_t *prg, tree_t ***psp, tree_iter_t *iter )
-{
- tree_t **sp = *psp;
- assert( iter->yield_size == (vm_ssize() - iter->root_size) );
-
- if ( iter->ref.kid == 0 ) {
- /* kid_t is zero, start from the root. */
- iter->ref = iter->root_ref;
- iter_find( prg, psp, iter, true );
- }
- else {
- /* Have a previous item, continue searching from there. */
- iter_find( prg, psp, iter, false );
- }
-
- sp = *psp;
- iter->yield_size = vm_ssize() - iter->root_size;
-
- return (iter->ref.kid ? prg->true_val : prg->false_val );
-}
-
-tree_t *tree_iter_next_child( program_t *prg, tree_t ***psp, tree_iter_t *iter )
-{
- tree_t **sp = *psp;
- assert( iter->yield_size == (vm_ssize() - iter->root_size) );
- kid_t *kid = 0;
-
- if ( iter->ref.kid == 0 ) {
- /* kid_t is zero, start from the first child. */
- kid_t *child = tree_child( prg, iter->root_ref.kid->tree );
-
- if ( child == 0 )
- iter->ref.next = 0;
- else {
- /* Make a reference to the root. */
- vm_contiguous( 2 );
- vm_push_ref( iter->root_ref.next );
- vm_push_kid( iter->root_ref.kid );
- iter->ref.next = (ref_t*)vm_ptop();
-
- kid = child;
- }
- }
- else {
- /* Start at next. */
- kid = iter->ref.kid->next;
- }
-
- if ( iter->search_id != prg->rtd->any_id ) {
- /* Have a previous item, go to the next sibling. */
- while ( kid != 0 && kid->tree->id != iter->search_id )
- kid = kid->next;
- }
-
- iter->ref.kid = kid;
- iter->yield_size = vm_ssize() - iter->root_size;
- *psp = sp;
- return ( iter->ref.kid ? prg->true_val : prg->false_val );
-}
-
-tree_t *tree_rev_iter_prev_child( program_t *prg, tree_t ***psp, rev_tree_iter_t *iter )
-{
- tree_t **sp = *psp;
- assert( iter->yield_size == ( vm_ssize() - iter->root_size ) );
-
- if ( iter->kid_at_yield != iter->ref.kid ) {
- /* Need to reload the kids. */
- vm_popn( iter->children );
-
- int c;
- kid_t *kid = tree_child( prg, iter->root_ref.kid->tree );
- for ( c = 0; c < iter->children; c++ ) {
- vm_push_kid( kid );
- kid = kid->next;
- }
- }
-
- if ( iter->ref.kid != 0 ) {
- vm_pop_ignore();
- iter->children -= 1;
- }
-
- if ( iter->search_id != prg->rtd->any_id ) {
- /* Have a previous item, go to the next sibling. */
- while ( iter->children > 0 && ((kid_t*)(vm_top()))->tree->id != iter->search_id ) {
- iter->children -= 1;
- vm_pop_ignore();
- }
- }
-
- if ( iter->children == 0 ) {
- iter->ref.next = 0;
- iter->ref.kid = 0;
- }
- else {
- iter->ref.next = &iter->root_ref;
- iter->ref.kid = (kid_t*)vm_top();
- }
-
- /* We will use this to detect a split above the iterated tree. */
- iter->kid_at_yield = iter->ref.kid;
-
- iter->yield_size = vm_ssize() - iter->root_size;
-
- *psp = sp;
-
- return (iter->ref.kid ? prg->true_val : prg->false_val );
-}
-
-void iter_find_repeat( program_t *prg, tree_t ***psp, tree_iter_t *iter, int try_first )
-{
- tree_t **sp = *psp;
- int any_tree = iter->search_id == prg->rtd->any_id;
- tree_t **top = iter->stack_root;
- kid_t *child;
-
-rec_call:
- if ( try_first && ( iter->ref.kid->tree->id == iter->search_id || any_tree ) ) {
- *psp = sp;
- return;
- }
- else {
- /* The repeat iterator is just like the normal top-down-left-right,
- * execept it only goes into the children of a node if the node is the
- * root of the iteration, or if does not have any neighbours to the
- * right. */
- if ( top == vm_ptop() || iter->ref.kid->next == 0 ) {
- child = tree_child( prg, iter->ref.kid->tree );
- if ( child != 0 ) {
- vm_contiguous( 2 );
- vm_push_ref( iter->ref.next );
- vm_push_kid( iter->ref.kid );
- iter->ref.kid = child;
- iter->ref.next = (ref_t*)vm_ptop();
- while ( iter->ref.kid != 0 ) {
- try_first = true;
- goto rec_call;
- rec_return:
- iter->ref.kid = iter->ref.kid->next;
- }
- iter->ref.kid = vm_pop_kid();
- iter->ref.next = vm_pop_ref();
- }
- }
- }
-
- if ( top != vm_ptop() )
- goto rec_return;
-
- iter->ref.kid = 0;
- *psp = sp;
-}
-
-tree_t *tree_iter_next_repeat( program_t *prg, tree_t ***psp, tree_iter_t *iter )
-{
- tree_t **sp = *psp;
- assert( iter->yield_size == ( vm_ssize() - iter->root_size ) );
-
- if ( iter->ref.kid == 0 ) {
- /* kid_t is zero, start from the root. */
- iter->ref = iter->root_ref;
- iter_find_repeat( prg, psp, iter, true );
- }
- else {
- /* Have a previous item, continue searching from there. */
- iter_find_repeat( prg, psp, iter, false );
- }
-
- sp = *psp;
- iter->yield_size = vm_ssize() - iter->root_size;
-
- return (iter->ref.kid ? prg->true_val : prg->false_val );
-}
-
-void iter_find_rev_repeat( program_t *prg, tree_t ***psp, tree_iter_t *iter, int try_first )
-{
- tree_t **sp = *psp;
- int any_tree = iter->search_id == prg->rtd->any_id;
- tree_t **top = iter->stack_root;
- kid_t *child;
-
- if ( try_first ) {
- while ( true ) {
- if ( top == vm_ptop() || iter->ref.kid->next == 0 ) {
- child = tree_child( prg, iter->ref.kid->tree );
-
- if ( child == 0 )
- break;
- vm_contiguous( 2 );
- vm_push_ref( iter->ref.next );
- vm_push_kid( iter->ref.kid );
- iter->ref.kid = child;
- iter->ref.next = (ref_t*)vm_ptop();
- }
- else {
- /* Not the top and not there is a next, go over to it. */
- iter->ref.kid = iter->ref.kid->next;
- }
- }
-
- goto first;
- }
-
- while ( true ) {
- if ( top == vm_ptop() ) {
- iter->ref.kid = 0;
- return;
- }
-
- if ( iter->ref.kid->next == 0 ) {
- /* Go up one and then down. Remember we can't use iter->ref.next
- * because the chain may have been split, setting it null (to
- * prevent repeated walks up). */
- ref_t *ref = (ref_t*)vm_ptop();
- iter->ref.kid = tree_child( prg, ref->kid->tree );
- }
- else {
- iter->ref.kid = vm_pop_kid();
- iter->ref.next = vm_pop_ref();
- }
-first:
- if ( iter->ref.kid->tree->id == iter->search_id || any_tree ) {
- *psp = sp;
- return;
- }
- }
- *psp = sp;
- return;
-}
-
-
-tree_t *tree_iter_prev_repeat( program_t *prg, tree_t ***psp, tree_iter_t *iter )
-{
- tree_t **sp = *psp;
- assert( iter->yield_size == (vm_ssize() - iter->root_size) );
-
- if ( iter->ref.kid == 0 ) {
- /* kid_t is zero, start from the root. */
- iter->ref = iter->root_ref;
- iter_find_rev_repeat( prg, psp, iter, true );
- }
- else {
- /* Have a previous item, continue searching from there. */
- iter_find_rev_repeat( prg, psp, iter, false );
- }
-
- sp = *psp;
- iter->yield_size = vm_ssize() - iter->root_size;
-
- return (iter->ref.kid ? prg->true_val : prg->false_val );
-}
-
-
-