summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--src/bytecode.c86
-rw-r--r--src/bytecode.h8
-rw-r--r--src/input.c4
-rw-r--r--src/pdarun.c5
-rw-r--r--src/synthesis.cc1
-rw-r--r--test/colm.d/balance1.lm33
-rw-r--r--test/colm.d/balance2.lm38
-rw-r--r--test/colm.d/balance3.lm32
9 files changed, 154 insertions, 57 deletions
diff --git a/configure.ac b/configure.ac
index f0f9282b..30e37b76 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,8 +20,8 @@ dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM
dnl OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
dnl SOFTWARE.
-AC_INIT(colm, 0.14.4)
-PUBDATE="December 2020"
+AC_INIT(colm, 0.14.6)
+PUBDATE="January 2021"
AM_INIT_AUTOMAKE([foreign])
diff --git a/src/bytecode.c b/src/bytecode.c
index f9a90d4f..8ef848b0 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -200,35 +200,6 @@ static head_t *tree_to_str_postfix( program_t *prg, tree_t **sp, tree_t *tree, i
return ret;
}
-static void input_push_text( struct colm_program *prg, struct input_impl *is,
- struct colm_location *loc, const char *data, long length )
-{
- is->funcs->prepend_data( prg, is, loc, colm_alph_from_cstr( data ), length );
-}
-
-static void colm_stream_push_tree( struct colm_program *prg, struct input_impl *is,
- tree_t *tree, int ignore )
-{
- is->funcs->prepend_tree( prg, is, tree, ignore );
-}
-
-static void colm_stream_push_stream( struct colm_program *prg, struct input_impl *is, stream_t *stream )
-{
- is->funcs->prepend_stream( prg, is, stream );
-}
-
-static void colm_undo_stream_push( program_t *prg, tree_t **sp, struct input_impl *is, long length )
-{
- if ( length < 0 ) {
- /* tree_t *tree = */ is->funcs->undo_prepend_tree( prg, is );
- // colm_tree_downref( prg, sp, tree );
- }
- else {
- is->funcs->undo_prepend_data( prg, is, length );
- }
-}
-
-
static word_t stream_append_text( program_t *prg, tree_t **sp, input_t *dest, tree_t *input, int trim )
{
long length = 0;
@@ -316,7 +287,6 @@ static tree_t *stream_pull_bc( program_t *prg, tree_t **sp, struct pda_run *pda_
return construct_string( prg, tokdata );
}
-
static void undo_stream_pull( struct colm_program *prg, struct input_impl *is,
const char *data, long length )
{
@@ -332,6 +302,18 @@ static void undo_pull( program_t *prg, input_t *input, tree_t *str )
undo_stream_pull( prg, impl, data, length );
}
+static void input_push_text( struct colm_program *prg, struct input_impl *is,
+ struct colm_location *loc, const char *data, long length )
+{
+ is->funcs->prepend_data( prg, is, loc, colm_alph_from_cstr( data ), length );
+}
+
+static void colm_stream_push_tree( struct colm_program *prg, struct input_impl *is,
+ tree_t *tree, int ignore )
+{
+ is->funcs->prepend_tree( prg, is, tree, ignore );
+}
+
static long input_push( program_t *prg, tree_t **sp, struct input_impl *in, tree_t *tree, int ignore )
{
long length = -1;
@@ -360,11 +342,26 @@ static long input_push( program_t *prg, tree_t **sp, struct input_impl *in, tree
return length;
}
-static long input_push_stream( program_t *prg, tree_t **sp,
+static void input_undo_push( program_t *prg, tree_t **sp, struct input_impl *is, long length )
+{
+ if ( length < 0 ) {
+ tree_t *tree = is->funcs->undo_prepend_tree( prg, is );
+ colm_tree_downref( prg, sp, tree );
+ }
+ else {
+ is->funcs->undo_prepend_data( prg, is, length );
+ }
+}
+
+static void input_push_stream( program_t *prg, tree_t **sp,
struct input_impl *in, stream_t *stream )
{
- colm_stream_push_stream( prg, in, stream );
- return -1;
+ in->funcs->prepend_stream( prg, in, stream );
+}
+
+static void input_undo_push_stream( program_t *prg, tree_t **sp, struct input_impl *is )
+{
+ is->funcs->undo_prepend_stream( prg, is );
}
static void set_local( execution_t *exec, long field, tree_t *tree )
@@ -2806,7 +2803,6 @@ again:
break;
}
-
case IN_INPUT_PULL_WV: {
debug( prg, REALM_BYTECODE, "IN_INPUT_PULL_WV\n" );
@@ -2874,7 +2870,7 @@ again:
long len = input_push( prg, sp, input_to_impl( input ), tree, true );
vm_push_tree( 0 );
- /* Single unit. */
+ /* Single unit end. */
rcode_code( exec, IN_INPUT_PUSH_BKT );
rcode_word( exec, len );
rcode_unit_term( exec );
@@ -2889,7 +2885,7 @@ again:
debug( prg, REALM_BYTECODE, "IN_INPUT_PUSH_BKT %d\n", len );
input_t *input = vm_pop_input();
- colm_undo_stream_push( prg, sp, input_to_impl( input ), len );
+ input_undo_push( prg, sp, input_to_impl( input ), len );
break;
}
case IN_INPUT_PUSH_STREAM_WV: {
@@ -2897,23 +2893,19 @@ again:
input_t *input = vm_pop_input();
stream_t *to_push = vm_pop_stream();
- long len = input_push_stream( prg, sp, input_to_impl( input ), to_push );
+ input_push_stream( prg, sp, input_to_impl( input ), to_push );
vm_push_tree( 0 );
- /* Single unit. */
- rcode_code( exec, IN_INPUT_PUSH_BKT );
- rcode_word( exec, len );
+ /* Single unit end. */
+ rcode_code( exec, IN_INPUT_PUSH_STREAM_BKT );
rcode_unit_term( exec );
break;
}
case IN_INPUT_PUSH_STREAM_BKT: {
- word_t len;
- read_word( len );
-
- debug( prg, REALM_BYTECODE, "IN_INPUT_PUSH_STREAM_BKT %d\n", len );
+ debug( prg, REALM_BYTECODE, "IN_INPUT_PUSH_STREAM_BKT\n" );
input_t *input = vm_pop_input();
- colm_undo_stream_push( prg, sp, input_to_impl( input ), len );
+ input_undo_push_stream( prg, sp, input_to_impl( input ) );
break;
}
case IN_CONS_GENERIC: {
@@ -4841,6 +4833,10 @@ again:
debug( prg, REALM_BYTECODE, "IN_INPUT_PUSH_BKT\n" );
break;
}
+ case IN_INPUT_PUSH_STREAM_BKT: {
+ debug( prg, REALM_BYTECODE, "IN_INPUT_PUSH_STREAM_BKT\n" );
+ break;
+ }
case IN_LOAD_GLOBAL_BKT: {
debug( prg, REALM_BYTECODE, "IN_LOAD_GLOBAL_BKT\n" );
break;
diff --git a/src/bytecode.h b/src/bytecode.h
index 06d463e9..ff626bba 100644
--- a/src/bytecode.h
+++ b/src/bytecode.h
@@ -259,17 +259,15 @@ typedef unsigned char uchar;
#define IN_PARSE_INIT_BKT 0xa1
#define IN_PARSE_FRAG_BKT 0xa6
+#define IN_PRINT_TREE 0xa3
+
#define IN_SEND_NOTHING 0xa0
#define IN_SEND_TEXT_W 0x89
#define IN_SEND_TEXT_BKT 0x8a
-#define IN_PRINT_TREE 0xa3
-
#define IN_SEND_TREE_W 0xa9
#define IN_SEND_TREE_BKT 0xaa
-#define IN_REPLACE_STREAM 0x88
-
#define IN_SEND_STREAM_W 0x90
#define IN_SEND_STREAM_BKT 0x1c
@@ -520,7 +518,7 @@ enum LEL_ID {
( ( (sp-(n)) < prg->sb_beg ? (sp = vm_bs_add(prg, sp, n)) : 0 ), (sp -= (n)) )
#define vm_pop_type(type) \
- ({ SW r = *sp; (sp+1) >= prg->sb_end ? (sp = vm_bs_pop(prg, sp, 1)) : (sp += 1); (type)r; })
+ ({ type r = *((type*)sp); (sp+1) >= prg->sb_end ? (sp = vm_bs_pop(prg, sp, 1)) : (sp += 1); r; })
#define vm_push_tree(i) vm_push_type(tree_t*, i)
#define vm_push_input(i) vm_push_type(input_t*, i)
diff --git a/src/input.c b/src/input.c
index 043791f2..564cdee1 100644
--- a/src/input.c
+++ b/src/input.c
@@ -540,8 +540,8 @@ static tree_t *input_undo_prepend_tree( struct colm_program *prg, struct input_i
{
debug( prg, REALM_INPUT, "input_undo_prepend_tree: stream %p undo prepend tree\n", si );
- assert( si->queue.head != 0 && ( si->queue.head->type == SB_TOKEN ||
- si->queue.head->type == SB_IGNORE ) );
+ assert( si->queue.head != 0 );
+ assert( si->queue.head->type == SB_TOKEN || si->queue.head->type == SB_IGNORE );
struct seq_buf *seq_buf = input_stream_seq_pop_head( si );
diff --git a/src/pdarun.c b/src/pdarun.c
index f1885ec6..c958273e 100644
--- a/src/pdarun.c
+++ b/src/pdarun.c
@@ -180,8 +180,10 @@ static void send_back_ignore( program_t *prg, tree_t **sp,
int artificial = parse_tree->flags & PF_ARTIFICIAL;
if ( head != 0 ) {
- if ( artificial )
+ if ( artificial ) {
+ colm_tree_upref( prg, parse_tree->shadow->tree );
send_back_tree( prg, is, parse_tree->shadow->tree );
+ }
else
send_back_text( prg, is, colm_alph_from_cstr( string_data( head ) ), head->length );
}
@@ -240,7 +242,6 @@ static void send_back( program_t *prg, tree_t **sp, struct pda_run *pda_run,
}
colm_tree_upref( prg, parse_tree->shadow->tree );
-
send_back_tree( prg, is, parse_tree->shadow->tree );
}
else {
diff --git a/src/synthesis.cc b/src/synthesis.cc
index bac12b20..9d1dbd38 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -1750,7 +1750,6 @@ void LangTerm::evaluateSendParser( Compiler *pd, CodeVect &code, bool strings )
parseFrag( pd, code, 0 );
}
else {
-
/* Assign bind ids to the variables in the replacement. */
for ( ConsItemList::Iter item = *parserText->list; item.lte(); item++ ) {
bool isStream = false;
diff --git a/test/colm.d/balance1.lm b/test/colm.d/balance1.lm
new file mode 100644
index 00000000..e5ec8e6b
--- /dev/null
+++ b/test/colm.d/balance1.lm
@@ -0,0 +1,33 @@
+lex
+ token id /[a-z]+/
+ ignore /[ \t\n]/
+
+ literal `;
+
+ token PLUS /'+'/ {
+ input->pull( match_length )
+
+ parse S: stmt "there is more;"
+ input->push( S )
+ input->push( "; " )
+ }
+end
+
+def stmt
+ [id* `;]
+
+def main
+ [stmt+]
+
+parse M: main [stdin]
+
+print
+ "parsed tree
+ [M]
+ "<-
+##### IN #####
+a b + c d;
+##### EXP #####
+parsed tree
+a b ; there is more; c d;
+<-
diff --git a/test/colm.d/balance2.lm b/test/colm.d/balance2.lm
new file mode 100644
index 00000000..962df3cb
--- /dev/null
+++ b/test/colm.d/balance2.lm
@@ -0,0 +1,38 @@
+lex
+ token id /[a-z]+/
+ ignore WS /[ \t\n]/
+
+ literal `; `! `@
+
+ token PLUS /'+'/ {
+ # input->pull( match_length )
+ input->push_ignore( make_token( typeid<WS>, input->pull(match_length) ) )
+
+ parse S: stmt "there is more;"
+ input->push( S )
+ input->push( "; " )
+ }
+end
+
+def E1 []
+def E2 []
+
+def stmt
+ [id* `;]
+
+def main
+ [E1 stmt+ `!]
+| [E2 stmt+ `@]
+
+parse M: main [stdin]
+
+print
+ "parsed tree
+ [M]
+ "<-
+##### IN #####
+a b + c d; @
+##### EXP #####
+parsed tree
+a b ; there is more;+ c d; @
+<-
diff --git a/test/colm.d/balance3.lm b/test/colm.d/balance3.lm
new file mode 100644
index 00000000..aae049b7
--- /dev/null
+++ b/test/colm.d/balance3.lm
@@ -0,0 +1,32 @@
+lex
+ token id /[a-z]+/
+ ignore /[ \t\n]/
+
+ literal `;
+
+ token PLUS /'+'/ {
+ input->pull( match_length )
+
+ parse M: main "there is more;"
+ input->push( M )
+ input->push( "; " )
+ }
+end
+
+def stmt
+ [id* `;]
+
+def main
+ [stmt+]
+
+parse M: main [stdin]
+
+print
+ "parsed tree
+ [M]
+ "<-
+##### IN #####
+a b + c d; @
+##### EXP #####
+parsed tree
+NIL<-