summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2020-12-22 15:24:51 -0800
committerAdrian Thurston <thurston@colm.net>2020-12-23 08:25:28 -0800
commitb8827e38f676a9eb45a1120ecd0b0d7d7e454e57 (patch)
treecfc30685ca51a7b98b8c90fe9d49b9d8408310af /src
parente2408c401b3f82742f7b7c03ff1ef5f461081e22 (diff)
downloadcolm-b8827e38f676a9eb45a1120ecd0b0d7d7e454e57.tar.gz
added with_ignore(tree) iterator
This is identical to the basic tree iterator, except it visits ignore tokens. This makes it possible to rewrite comments, albeit, primitively. Constructors for tokens don't work right. Though we can set the data field. The following code can be used to turn comments into newlines: for I1: comment in with_ignore(Flux) { I1.data = "\n" }
Diffstat (limited to 'src')
-rw-r--r--src/bytecode.c14
-rw-r--r--src/bytecode.h1
-rw-r--r--src/declare.cc10
-rw-r--r--src/iter.c13
-rw-r--r--src/parsetree.h4
-rw-r--r--src/synthesis.cc18
-rw-r--r--src/tree.c22
-rw-r--r--src/tree.h3
8 files changed, 73 insertions, 12 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 39aee070..f9a90d4f 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -2155,7 +2155,19 @@ again:
debug( prg, REALM_BYTECODE, "IN_TRITER_ADVANCE\n" );
tree_iter_t *iter = (tree_iter_t*) vm_get_plocal(exec, field);
- tree_t *res = tree_iter_advance( prg, &sp, iter );
+ tree_t *res = tree_iter_advance( prg, &sp, iter, false );
+ //colm_tree_upref( prg, res );
+ vm_push_tree( res );
+ break;
+ }
+ case IN_TRITER_WIG_ADVANCE: {
+ short field;
+ read_half( field );
+
+ debug( prg, REALM_BYTECODE, "IN_TRITER_WIG_ADVANCE\n" );
+
+ tree_iter_t *iter = (tree_iter_t*) vm_get_plocal(exec, field);
+ tree_t *res = tree_iter_advance( prg, &sp, iter, true );
//colm_tree_upref( prg, res );
vm_push_tree( res );
break;
diff --git a/src/bytecode.h b/src/bytecode.h
index 02cd78f4..06d463e9 100644
--- a/src/bytecode.h
+++ b/src/bytecode.h
@@ -155,6 +155,7 @@ typedef unsigned char uchar;
#define IN_TRITER_FROM_REF 0x41
#define IN_TRITER_ADVANCE 0x42
+#define IN_TRITER_WIG_ADVANCE 0x84
#define IN_TRITER_NEXT_CHILD 0x43
#define IN_TRITER_GET_CUR_R 0x44
#define IN_TRITER_GET_CUR_WC 0x45
diff --git a/src/declare.cc b/src/declare.cc
index 5102746c..5d153a9b 100644
--- a/src/declare.cc
+++ b/src/declare.cc
@@ -693,6 +693,16 @@ void Compiler::makeDefaultIterators()
objMethod->iterDef = triter;
}
+ {
+ UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl );
+ ObjectMethod *objMethod = initFunction( uniqueTypeAny, rootNamespace, globalObjectDef,
+ ObjectMethod::Call, "with_ignore", IN_HALT, IN_HALT, anyRefUT, true );
+
+ IterDef *triter = findIterDef( IterDef::WithIgnore );
+ objMethod->iterDef = triter;
+ }
+
+
/* Child iterator. */
{
UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl );
diff --git a/src/iter.c b/src/iter.c
index 66974f4a..f3df16af 100644
--- a/src/iter.c
+++ b/src/iter.c
@@ -354,7 +354,7 @@ void split_iter_cur( program_t *prg, tree_t ***psp, tree_iter_t *iter )
split_ref( prg, psp, &iter->ref );
}
-void iter_find( program_t *prg, tree_t ***psp, tree_iter_t *iter, int try_first )
+void iter_find( program_t *prg, tree_t ***psp, tree_iter_t *iter, int try_first, int with_ignore )
{
int any_tree = iter->search_id == prg->rtd->any_id;
tree_t **top = iter->stack_root;
@@ -367,7 +367,7 @@ rec_call:
return;
}
else {
- child = tree_child( prg, iter->ref.kid->tree );
+ child = tree_child_maybe_ignore( prg, iter->ref.kid->tree, with_ignore );
if ( child != 0 ) {
vm_contiguous( 2 );
vm_push_ref( iter->ref.next );
@@ -392,7 +392,7 @@ rec_call:
*psp = sp;
}
-tree_t *tree_iter_advance( program_t *prg, tree_t ***psp, tree_iter_t *iter )
+tree_t *tree_iter_advance( program_t *prg, tree_t ***psp, tree_iter_t *iter, int with_ignore )
{
tree_t **sp = *psp;
assert( iter->yield_size == (vm_ssize() - iter->root_size) );
@@ -400,11 +400,11 @@ tree_t *tree_iter_advance( program_t *prg, tree_t ***psp, tree_iter_t *iter )
if ( iter->ref.kid == 0 ) {
/* kid_t is zero, start from the root. */
iter->ref = iter->root_ref;
- iter_find( prg, psp, iter, true );
+ iter_find( prg, psp, iter, true, with_ignore );
}
else {
/* Have a previous item, continue searching from there. */
- iter_find( prg, psp, iter, false );
+ iter_find( prg, psp, iter, false, with_ignore );
}
sp = *psp;
@@ -643,6 +643,3 @@ tree_t *tree_iter_prev_repeat( program_t *prg, tree_t ***psp, tree_iter_t *iter
return (iter->ref.kid ? prg->true_val : prg->false_val );
}
-
-
-
diff --git a/src/parsetree.h b/src/parsetree.h
index 1890bbae..14e92c24 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -1934,7 +1934,7 @@ struct IterDef
{
enum Type { Tree, Child, RevChild, Repeat,
RevRepeat, User, ListEl,
- RevListVal, MapEl };
+ RevListVal, MapEl, WithIgnore };
IterDef( Type type, Function *func );
IterDef( Type type );
@@ -1948,7 +1948,7 @@ struct IterImpl
{
enum Type { Tree, Child, RevChild, Repeat,
RevRepeat, User, ListEl, ListVal,
- RevListVal, MapEl, MapVal };
+ RevListVal, MapEl, MapVal, WithIgnore };
IterImpl( Type type, Function *func );
IterImpl( Type type );
diff --git a/src/synthesis.cc b/src/synthesis.cc
index d049e40d..bac12b20 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -201,6 +201,19 @@ IterImpl::IterImpl( Type type ) :
useGenericId = true;
break;
+ case WithIgnore:
+ inCreateWV = IN_TRITER_FROM_REF;
+ inCreateWC = IN_TRITER_FROM_REF;
+ inUnwind = IN_TRITER_UNWIND;
+ inDestroy = IN_TRITER_DESTROY;
+ inAdvance = IN_TRITER_WIG_ADVANCE;
+
+ inGetCurR = IN_TRITER_GET_CUR_R;
+ inGetCurWC = IN_TRITER_GET_CUR_WC;
+ inSetCurWC = IN_TRITER_SET_CUR_WC;
+ inRefFromCur = IN_TRITER_REF_FROM_CUR;
+ useSearchUT = true;
+ break;
case User:
assert(false);
}
@@ -331,6 +344,7 @@ long sizeOfField( UniqueType *fieldUT )
/* Select on the iterator type. */
switch ( fieldUT->iterDef->type ) {
case IterDef::Tree:
+ case IterDef::WithIgnore:
case IterDef::Child:
case IterDef::Repeat:
case IterDef::RevRepeat:
@@ -2476,6 +2490,9 @@ void LangStmt::compileForIter( Compiler *pd, CodeVect &code ) const
iterImpl = iterCall->langTerm->varRef->chooseTriterCall( pd,
searchUT, iterCall->langTerm->args );
break;
+ case IterDef::WithIgnore:
+ iterImpl = new IterImpl( IterImpl::WithIgnore );
+ break;
case IterDef::Child:
iterImpl = new IterImpl( IterImpl::Child );
break;
@@ -2760,6 +2777,7 @@ void Compiler::findLocals( ObjectDef *localFrame, CodeBlock *block )
LocalType type = LT_Tree;
switch ( ut->iterDef->type ) {
case IterDef::Tree:
+ case IterDef::WithIgnore:
case IterDef::Child:
case IterDef::Repeat:
case IterDef::RevRepeat:
diff --git a/src/tree.c b/src/tree.c
index e05681b9..c355720d 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -1039,6 +1039,28 @@ kid_t *tree_child( program_t *prg, const tree_t *tree )
return kid;
}
+/* Find the first child of a tree. */
+kid_t *tree_child_maybe_ignore( program_t *prg, const tree_t *tree, int with_ignore )
+{
+ struct lang_el_info *lel_info = prg->rtd->lel_info;
+ kid_t *kid = tree->child;
+
+ if ( !with_ignore ) {
+ if ( tree->flags & AF_LEFT_IGNORE )
+ kid = kid->next;
+ if ( tree->flags & AF_RIGHT_IGNORE )
+ kid = kid->next;
+ }
+
+ /* Skip over attributes. */
+ long object_length = lel_info[tree->id].object_length;
+ long a;
+ for ( a = 0; a < object_length; a++ )
+ kid = kid->next;
+
+ return kid;
+}
+
/* Detach at the first real child of a tree. */
kid_t *tree_extract_child( program_t *prg, tree_t *tree )
{
diff --git a/src/tree.h b/src/tree.h
index 97833c6f..f12eeb5a 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -234,6 +234,7 @@ tree_t *tree_right_ignore( struct colm_program *prg, tree_t *tree );
kid_t *tree_left_ignore_kid( struct colm_program *prg, tree_t *tree );
kid_t *tree_right_ignore_kid( struct colm_program *prg, tree_t *tree );
kid_t *tree_child( struct colm_program *prg, const tree_t *tree );
+kid_t *tree_child_maybe_ignore( struct colm_program *prg, const tree_t *tree, int with_ignore );
kid_t *tree_attr( struct colm_program *prg, const tree_t *tree );
kid_t *kid_list_concat( kid_t *list1, kid_t *list2 );
kid_t *tree_extract_child( struct colm_program *prg, tree_t *tree );
@@ -292,7 +293,7 @@ tree_t *list_remove_head( struct colm_program *prg, list_t *list );
tree_t *get_list_mem_split( struct colm_program *prg, list_t *list, word_t field );
tree_t *get_parser_mem( parser_t *parser, word_t field );
-tree_t *tree_iter_advance( struct colm_program *prg, tree_t ***psp, tree_iter_t *iter );
+tree_t *tree_iter_advance( struct colm_program *prg, tree_t ***psp, tree_iter_t *iter, int with_ignore );
tree_t *tree_iter_next_child( struct colm_program *prg, tree_t ***psp, tree_iter_t *iter );
tree_t *tree_rev_iter_prev_child( struct colm_program *prg, tree_t ***psp, rev_tree_iter_t *iter );
tree_t *tree_iter_next_repeat( struct colm_program *prg, tree_t ***psp, tree_iter_t *iter );