aboutsummaryrefslogtreecommitdiffstats
path: root/awkgram.y
diff options
context:
space:
mode:
Diffstat (limited to 'awkgram.y')
-rw-r--r--awkgram.y110
1 files changed, 61 insertions, 49 deletions
diff --git a/awkgram.y b/awkgram.y
index 322088b7..7e8dcac1 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -597,7 +597,7 @@ statement
}
| LEX_FOR '(' NAME LEX_IN simple_variable r_paren opt_nls statement
{
-
+ INSTRUCTION *ip;
char *var_name = $3->lextok;
if ($8 != NULL
@@ -621,8 +621,8 @@ statement
* and that both the loop var and array names match.
*/
NODE *arr = NULL;
- INSTRUCTION *ip = $8->nexti->nexti;
+ ip = $8->nexti->nexti;
if ($5->nexti->opcode == Op_push && $5->lasti == $5->nexti)
arr = $5->nexti->memory;
if (arr != NULL
@@ -640,7 +640,8 @@ statement
bcfree($4);
bcfree($5);
$$ = $8;
- }
+ } else
+ goto regular_loop;
} else {
/* [ Op_push_array a ]
@@ -655,8 +656,7 @@ statement
* y: [Op_pop_loop ]
* w: [Op_arrayfor_final ]
*/
- INSTRUCTION *ip;
-
+regular_loop:
ip = $5;
ip->nexti->opcode = Op_push_array;
$3->opcode = Op_arrayfor_init;
@@ -2063,7 +2063,7 @@ mk_program()
else
(void) list_prepend(end_block, ip_end);
- if (get_context()->level > 0) {
+ if (! in_main_context()) {
if (begin_block != NULL && prog_block != NULL)
cp = list_merge(begin_block, prog_block);
else
@@ -2169,7 +2169,7 @@ parse_program(INSTRUCTION **pcode)
*/
ip_end = instruction(Op_no_op);
- if (get_context()->level > 0)
+ if (! in_main_context())
ip_newfile = ip_rec = ip_atexit = ip_beginfile = ip_endfile = NULL;
else {
ip_endfile = instruction(Op_no_op);
@@ -3413,7 +3413,7 @@ retry:
want_source = TRUE;
break;
case LEX_EVAL:
- if (get_context()->level == 0)
+ if (in_main_context())
goto out;
emalloc(tokkey, char *, tok - tokstart + 1, "yylex");
tokkey[0] = '@';
@@ -4259,7 +4259,7 @@ check_funcs()
struct fdesc *fp, *next;
int i;
- if (get_context()->level > 0)
+ if (! in_main_context())
goto free_mem;
for (i = 0; i < HASHSIZE; i++) {
@@ -5056,7 +5056,7 @@ optimize_assignment(INSTRUCTION *exp)
/*
* N.B.: do not append Op_pop instruction to the returned
* instruction list if optimized. None of these
- * optimized instructions push the r-value of assignment
+ * optimized instructions pushes the r-value of assignment
* onto the runtime stack.
*/
@@ -5483,6 +5483,8 @@ append_symbol(char *name)
symbol_list->hnext = hp;
}
+/* release_symbol --- free symbol list and optionally remove symbol from symbol table */
+
void
release_symbols(NODE *symlist, int keep_globals)
{
@@ -5553,6 +5555,7 @@ destroy_symbol(char *name)
static INSTRUCTION *pool_list;
static CONTEXT *curr_ctxt = NULL;
+/* new_context --- create a new execution context. */
CONTEXT *
new_context()
@@ -5564,63 +5567,70 @@ new_context()
ctxt->srcfiles.next = ctxt->srcfiles.prev = &ctxt->srcfiles;
ctxt->rule_list.opcode = Op_list;
ctxt->rule_list.lasti = &ctxt->rule_list;
- if (curr_ctxt == NULL) {
- ctxt->level = 0;
- pool_list = &ctxt->pools;
- symbol_list = &ctxt->symbols;
- srcfiles = &ctxt->srcfiles;
- rule_list = &ctxt->rule_list;
- install_func = ctxt->install_func;
- curr_ctxt = ctxt;
- } else
- ctxt->level = curr_ctxt->level + 1; /* this assumes contexts don't overlap each other ? */
-
return ctxt;
}
+/* set_context --- change current execution context. */
-/* N.B.: new context (level > 0) inherits all command line options;
- * probably should restore defaults for lint etc.
- */
-
-CONTEXT *
+static void
set_context(CONTEXT *ctxt)
{
- assert(curr_ctxt != NULL);
- if (curr_ctxt == ctxt)
- goto update;
+ pool_list = &ctxt->pools;
+ symbol_list = &ctxt->symbols;
+ srcfiles = &ctxt->srcfiles;
+ rule_list = &ctxt->rule_list;
+ install_func = ctxt->install_func;
+ curr_ctxt = ctxt;
+}
+
+/*
+ * push_context:
+ *
+ * Switch to the given context after saving the current one. The set
+ * of active execution contexts forms a stack; the global or main context
+ * is at the bottom of the stack.
+ */
+void
+push_context(CONTEXT *ctxt)
+{
+ ctxt->prev = curr_ctxt;
/* save current source and sourceline */
- curr_ctxt->sourceline = sourceline;
- curr_ctxt->source = source;
+ if (curr_ctxt != NULL) {
+ curr_ctxt->sourceline = sourceline;
+ curr_ctxt->source = source;
+ }
+ sourceline = 0;
+ source = NULL;
+ set_context(ctxt);
+}
- if (ctxt == NULL) {
- assert(curr_ctxt->prev != NULL);
- ctxt = curr_ctxt->prev;
- } else
- ctxt->prev = curr_ctxt;
+/* pop_context --- switch to previous execution context. */
+void
+pop_context()
+{
+ CONTEXT *ctxt;
+
+ assert(curr_ctxt != NULL);
+ ctxt = curr_ctxt->prev;
/* restore source and sourceline */
sourceline = ctxt->sourceline;
source = ctxt->source;
-
-update:
- pool_list = &ctxt->pools;
- symbol_list = &ctxt->symbols;
- srcfiles = &ctxt->srcfiles;
- rule_list = &ctxt->rule_list;
- install_func = ctxt->install_func;
- curr_ctxt = ctxt;
- return curr_ctxt;
+ set_context(ctxt);
}
-CONTEXT *
-get_context()
+/* in_main_context --- are we in the main context ? */
+
+int
+in_main_context()
{
assert(curr_ctxt != NULL);
- return curr_ctxt;
+ return (curr_ctxt->prev == NULL);
}
+/* free_context --- free context structure and related data. */
+
void
free_context(CONTEXT *ctxt, int keep_globals)
{
@@ -5646,6 +5656,8 @@ free_context(CONTEXT *ctxt, int keep_globals)
efree(ctxt);
}
+/* free_bc_internal --- free internal memory of an instruction. */
+
static void
free_bc_internal(INSTRUCTION *cp)
{
@@ -5713,7 +5725,6 @@ bcfree(INSTRUCTION *cp)
pool_list->freei = cp;
}
-
/* bcalloc --- allocate a new instruction */
INSTRUCTION *
@@ -5757,6 +5768,7 @@ bcalloc(OPCODE op, int size, int srcline)
return cp;
}
+/* free_bcpool --- free list of instruction memory pools */
static void
free_bcpool(INSTRUCTION *pl)