summaryrefslogtreecommitdiff
path: root/src/commit.c
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2015-10-04 11:40:30 -0400
committerAdrian Thurston <thurston@complang.org>2015-10-04 11:40:30 -0400
commit514d1771d7956df29ea8e9f0c5f0a35d47bc8bc4 (patch)
treeb076ba176a640396c63f8986442ad5613fef893e /src/commit.c
parent672040140417c53b278aa79ac91b8e89a1a3d634 (diff)
downloadcolm-514d1771d7956df29ea8e9f0c5f0a35d47bc8bc4.tar.gz
working on a commit that can execute reduction actions
First track if the result is used. If not, we can remove parse trees at commit points. This is also the time to execute reduction actions so we can load as we parse. Not currently enabled (by way of omitting setting of not-used bit).
Diffstat (limited to 'src/commit.c')
-rw-r--r--src/commit.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/commit.c b/src/commit.c
new file mode 100644
index 00000000..473f4bbb
--- /dev/null
+++ b/src/commit.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2015 Adrian Thurston <thurston@complang.org>
+ */
+
+/* This file is part of Colm.
+ *
+ * Colm is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Colm is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Colm; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#include "debug.h"
+#include "pdarun.h"
+#include "bytecode.h"
+#include "tree.h"
+#include "pool.h"
+
+#include "internal.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+//#define true 1
+//#define false 0
+
+static void commit_clear_parse_tree( program_t *prg, tree_t **sp, parse_tree_t *pt )
+{
+ tree_t **top = vm_ptop();
+
+ if ( pt == 0 )
+ return;
+
+free_tree:
+ if ( pt->next != 0 ) {
+ vm_push_ptree( pt->next );
+ }
+
+ if ( pt->left_ignore != 0 ) {
+ vm_push_ptree( pt->left_ignore );
+ }
+
+ if ( pt->child != 0 ) {
+ vm_push_ptree( pt->child );
+ }
+
+ if ( pt->right_ignore != 0 ) {
+ vm_push_ptree( pt->right_ignore );
+ }
+
+ if ( pt->shadow != 0 ) {
+ colm_tree_downref( prg, sp, pt->shadow->tree );
+ kid_free( prg, pt->shadow );
+ }
+
+ //printf( "commit_parse_tree_free %p\n", pt );
+ parse_tree_free( prg, pt );
+
+ /* Any trees to downref? */
+ if ( sp != top ) {
+ pt = vm_pop_ptree();
+ goto free_tree;
+ }
+}
+
+static int been_committed( parse_tree_t *parse_tree )
+{
+ return parse_tree->flags & PF_COMMITTED;
+}
+
+
+static void commit_forward_recurse( program_t *prg, tree_t **root, parse_tree_t *pt )
+{
+ tree_t **sp = root;
+
+ parse_tree_t *lel = pt;
+
+recurse:
+
+ if ( lel->child != 0 ) {
+ /* There are children. Must process all children first. */
+ vm_push_ptree( lel );
+
+ lel = lel->child;
+ while ( lel != 0 ) {
+ goto recurse;
+ resume:
+ lel = lel->next;
+ }
+
+ lel = vm_pop_ptree();
+ }
+
+ /* Now can execute the reduction action. */
+
+ commit_clear_parse_tree( prg, sp, lel->child );
+ lel->child = 0;
+ pt->flags |= PF_COMMITTED;
+
+ if ( sp != root )
+ goto resume;
+}
+
+void commit_clear( program_t *prg, tree_t **root, struct pda_run *pda_run )
+{
+ tree_t **sp = root;
+ parse_tree_t *pt = pda_run->stack_top;
+
+ /* The top level of the stack is linked right to left. This is the
+ * traversal order we need for committing. */
+ while ( pt != 0 && !been_committed( pt ) ) {
+ vm_push_ptree( pt );
+ pt = pt->next;
+ }
+
+ while ( sp != root ) {
+ pt = vm_pop_ptree();
+
+ commit_forward_recurse( prg, sp, pt );
+
+ pt->flags |= PF_COMMITTED;
+ pt = pt->next;
+ }
+}
+
+void commit_reduce( program_t *prg, tree_t **root, struct pda_run *pda_run )
+{
+ tree_t **sp = root;
+ parse_tree_t *pt = pda_run->stack_top;
+
+ /* The top level of the stack is linked right to left. This is the
+ * traversal order we need for committing. */
+ while ( pt != 0 && !been_committed( pt ) ) {
+ vm_push_ptree( pt );
+ pt = pt->next;
+ }
+
+ while ( sp != root ) {
+ pt = vm_pop_ptree();
+
+ commit_clear_parse_tree( prg, sp, pt->child );
+ pt->child = 0;
+
+ pt->flags |= PF_COMMITTED;
+ pt = pt->next;
+ }
+}