*** empty log message ***
This commit is contained in:
parent
67d7ca36ff
commit
55043320b8
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.c,v 1.31 2006-03-24 06:33:36 bacon Exp $
|
||||
* $Id: awk.c,v 1.32 2006-03-26 16:36:30 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <xp/awk/awk.h>
|
||||
@ -89,6 +89,7 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
|
||||
awk->run.stack_top = 0;
|
||||
awk->run.stack_base = 0;
|
||||
awk->run.stack_limit = 0;
|
||||
awk->run.exit_level = 0;
|
||||
|
||||
awk->lex.curc = XP_CHAR_EOF;
|
||||
awk->lex.ungotc_count = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.h,v 1.35 2006-03-25 17:04:36 bacon Exp $
|
||||
* $Id: awk.h,v 1.36 2006-03-26 16:36:30 bacon Exp $
|
||||
*/
|
||||
|
||||
#ifndef _XP_AWK_AWK_H_
|
||||
@ -97,6 +97,7 @@ struct xp_awk_t
|
||||
xp_size_t stack_top;
|
||||
xp_size_t stack_base;
|
||||
xp_size_t stack_limit;
|
||||
int exit_level;
|
||||
} run;
|
||||
|
||||
/* source buffer management */
|
||||
|
106
ase/awk/run.c
106
ase/awk/run.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: run.c,v 1.18 2006-03-26 14:03:08 bacon Exp $
|
||||
* $Id: run.c,v 1.19 2006-03-26 16:36:30 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <xp/awk/awk.h>
|
||||
@ -16,6 +16,11 @@
|
||||
#define STACK_NARGS(awk) ((xp_size_t)STACK_AT(awk,3))
|
||||
#define STACK_ARG(awk,n) STACK_AT(awk,3+1+(n))
|
||||
#define STACK_LOCAL(awk,n) STACK_AT(awk,3+STACK_NARGS(awk)+1+(n))
|
||||
#define STACK_RETVAL(awk) STACK_AT(awk,2)
|
||||
|
||||
#define EXIT_NONE 0
|
||||
#define EXIT_FUNCTION 1
|
||||
#define EXIT_GLOBAL 2
|
||||
|
||||
static int __run_block (xp_awk_t* awk, xp_awk_nde_blk_t* nde);
|
||||
static int __run_statement (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
@ -33,7 +38,7 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde);
|
||||
static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde);
|
||||
|
||||
static int __raw_push (xp_awk_t* awk, void* val);
|
||||
static int __raw_pop (xp_awk_t* awk);
|
||||
static void __raw_pop (xp_awk_t* awk);
|
||||
|
||||
int __printval (xp_awk_pair_t* pair)
|
||||
{
|
||||
@ -45,6 +50,9 @@ int __printval (xp_awk_pair_t* pair)
|
||||
|
||||
int xp_awk_run (xp_awk_t* awk)
|
||||
{
|
||||
// TODO: clear run stack/exit_level
|
||||
awk->run.exit_level = EXIT_NONE;
|
||||
|
||||
if (awk->tree.begin != XP_NULL)
|
||||
{
|
||||
xp_assert (awk->tree.begin->type == XP_AWK_NDE_BLK);
|
||||
@ -89,7 +97,7 @@ static int __run_block (xp_awk_t* awk, xp_awk_nde_blk_t* nde)
|
||||
}
|
||||
|
||||
//xp_printf (XP_TEXT("executing block statements\n"));
|
||||
while (p != XP_NULL)
|
||||
while (p != XP_NULL && awk->run.exit_level == EXIT_NONE)
|
||||
{
|
||||
if (__run_statement(awk,p) == -1) return -1;
|
||||
p = p->next;
|
||||
@ -336,10 +344,14 @@ static int __run_return_statement (xp_awk_t* awk, xp_awk_nde_return_t* nde)
|
||||
//xp_printf (XP_TEXT("returning....\n"));
|
||||
val = __eval_expression(awk, nde->val);
|
||||
if (val == XP_NULL) return -1;
|
||||
awk->run.stack[awk->run.stack_base+2] = val;
|
||||
|
||||
STACK_RETVAL(awk) = val;
|
||||
xp_awk_refupval (val); /* see run_funccall for the trick */
|
||||
|
||||
//xp_printf (XP_TEXT("set return value....\n"));
|
||||
}
|
||||
// TODO: make the function exit....
|
||||
|
||||
awk->run.exit_level = EXIT_FUNCTION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -480,14 +492,21 @@ static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_ass_t* nde)
|
||||
}
|
||||
else if (tgt->type == XP_AWK_NDE_GLOBAL)
|
||||
{
|
||||
/*
|
||||
xp_awk_refdownval(STACK_GLOBAL(awk,tgt->id.idxa));
|
||||
STACK_GLOBAL(awk,tgt->id.idxa) = val;
|
||||
xp_awk_refupval (val);
|
||||
*/
|
||||
}
|
||||
else if (tgt->type == XP_AWK_NDE_LOCAL)
|
||||
{
|
||||
xp_awk_refdownval(STACK_LOCAL(awk,tgt->id.idxa));
|
||||
STACK_LOCAL(awk,tgt->id.idxa) = val;
|
||||
xp_awk_refupval (val);
|
||||
}
|
||||
else if (tgt->type == XP_AWK_NDE_ARG)
|
||||
{
|
||||
xp_awk_refdownval(STACK_ARG(awk,tgt->id.idxa));
|
||||
STACK_ARG(awk,tgt->id.idxa) = val;
|
||||
xp_awk_refupval (val);
|
||||
}
|
||||
@ -544,7 +563,24 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
xp_long_t r =
|
||||
((xp_awk_val_int_t*)left)->val +
|
||||
((xp_awk_val_int_t*)right)->val;
|
||||
|
||||
// TODO: consider the code segement commented out below for optimization....
|
||||
/*
|
||||
if (!xp_awk_isbuiltinval(left) && left->ref <= 1)
|
||||
{
|
||||
((xp_awk_val_int_t*)left)->val = r;
|
||||
res = left;
|
||||
}
|
||||
else if (!xp_awk_isbuiltinval(right) && right->ref <= 1)
|
||||
{
|
||||
((xp_awk_val_int_t*)right)->val = r;
|
||||
res = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
res = xp_awk_makeintval (r);
|
||||
//}
|
||||
}
|
||||
}
|
||||
else if (nde->opcode == XP_AWK_BINOP_MINUS)
|
||||
@ -555,12 +591,43 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
xp_long_t r =
|
||||
((xp_awk_val_int_t*)left)->val -
|
||||
((xp_awk_val_int_t*)right)->val;
|
||||
|
||||
/*
|
||||
if (!xp_awk_isbuiltinval(left) && left->ref <= 1)
|
||||
{
|
||||
((xp_awk_val_int_t*)left)->val = r;
|
||||
res = left;
|
||||
}
|
||||
else if (!xp_awk_isbuiltinval(right) && right->ref <= 1)
|
||||
{
|
||||
((xp_awk_val_int_t*)right)->val = r;
|
||||
res = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
res = xp_awk_makeintval (r);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (res == left)
|
||||
{
|
||||
xp_awk_refdownval_nofree (left);
|
||||
xp_awk_refdownval (right);
|
||||
}
|
||||
else if (res == right)
|
||||
{
|
||||
xp_awk_refdownval (left);
|
||||
xp_awk_refdownval_nofree (right);
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
xp_awk_refdownval (left);
|
||||
xp_awk_refdownval (right);
|
||||
//}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -579,7 +646,13 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde)
|
||||
|
||||
/*
|
||||
* ---------------------
|
||||
* argn <- stack top
|
||||
* locn <- stack top
|
||||
* ---------------------
|
||||
* ....
|
||||
* ---------------------
|
||||
* loc0 local variables are pushed by __run_block
|
||||
* ---------------------
|
||||
* argn
|
||||
* ---------------------
|
||||
* ....
|
||||
* ---------------------
|
||||
@ -657,7 +730,12 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde)
|
||||
//xp_printf (XP_TEXT("running function body\n"));
|
||||
|
||||
xp_assert (func->body->type == XP_AWK_NDE_BLK);
|
||||
if (__run_block(awk,(xp_awk_nde_blk_t*)func->body) == -1) return XP_NULL;
|
||||
if (__run_block(awk,(xp_awk_nde_blk_t*)func->body) == -1)
|
||||
{
|
||||
// TODO: handle error properly....
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
//xp_printf (XP_TEXT("block run complete\n"));
|
||||
|
||||
/* refdown args in the run.stack */
|
||||
@ -668,11 +746,21 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde)
|
||||
xp_awk_refdownval (STACK_ARG(awk,i));
|
||||
}
|
||||
//xp_printf (XP_TEXT("got return value\n"));
|
||||
v = awk->run.stack[awk->run.stack_base+2];
|
||||
|
||||
/* adjust the reference count of the return value.
|
||||
* the value must not be freeed event if the reference count
|
||||
* is decremented to zero. */
|
||||
v = STACK_RETVAL(awk);
|
||||
xp_awk_refdownval_nofree (v);
|
||||
|
||||
awk->run.stack_top = (xp_size_t)awk->run.stack[awk->run.stack_base+1];
|
||||
awk->run.stack_base = (xp_size_t)awk->run.stack[awk->run.stack_base+0];
|
||||
|
||||
if (awk->run.exit_level == EXIT_FUNCTION)
|
||||
{
|
||||
awk->run.exit_level = EXIT_NONE;
|
||||
}
|
||||
|
||||
//xp_printf (XP_TEXT("returning from function stack_top=%ld, stack_base=%ld\n"), awk->run.stack_top, awk->run.stack_base);
|
||||
return v;
|
||||
}
|
||||
@ -696,7 +784,7 @@ static int __raw_push (xp_awk_t* awk, void* val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __raw_pop (xp_awk_t* awk)
|
||||
static void __raw_pop (xp_awk_t* awk)
|
||||
{
|
||||
xp_assert (awk->run.stack_top > awk->run.stack_base);
|
||||
awk->run.stack_top--;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: val.c,v 1.9 2006-03-23 15:36:20 bacon Exp $
|
||||
* $Id: val.c,v 1.10 2006-03-26 16:36:30 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <xp/awk/awk.h>
|
||||
@ -41,6 +41,7 @@ xp_awk_val_t* xp_awk_makeintval (xp_long_t v)
|
||||
if (val == XP_NULL) return XP_NULL;
|
||||
|
||||
val->type = XP_AWK_VAL_INT;
|
||||
val->ref = 0;
|
||||
val->val = v;
|
||||
|
||||
return (xp_awk_val_t*)val;
|
||||
@ -54,6 +55,7 @@ xp_awk_val_t* xp_awk_makerealval (xp_real_t v)
|
||||
if (val == XP_NULL) return XP_NULL;
|
||||
|
||||
val->type = XP_AWK_VAL_REAL;
|
||||
val->ref = 0;
|
||||
val->val = v;
|
||||
|
||||
return (xp_awk_val_t*)val;
|
||||
@ -67,6 +69,7 @@ xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len)
|
||||
if (val == XP_NULL) return XP_NULL;
|
||||
|
||||
val->type = XP_AWK_VAL_STR;
|
||||
val->ref = 0;
|
||||
val->len = len;
|
||||
val->buf = xp_strxdup (str, len);
|
||||
if (val->buf == XP_NULL) {
|
||||
@ -77,11 +80,16 @@ xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len)
|
||||
return (xp_awk_val_t*)val;
|
||||
}
|
||||
|
||||
xp_bool_t xp_awk_isbuiltinval (xp_awk_val_t* val)
|
||||
{
|
||||
return val == XP_NULL || val == xp_awk_val_nil ||
|
||||
(val >= (xp_awk_val_t*)&__awk_int[0] &&
|
||||
val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]);
|
||||
}
|
||||
|
||||
void xp_awk_freeval (xp_awk_val_t* val)
|
||||
{
|
||||
if (val == XP_NULL || val == xp_awk_val_nil) return;
|
||||
if (val >= (xp_awk_val_t*)&__awk_int[0] &&
|
||||
val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]) return;
|
||||
if (xp_awk_isbuiltinval(val)) return;
|
||||
|
||||
switch (val->type)
|
||||
{
|
||||
@ -94,34 +102,44 @@ void xp_awk_freeval (xp_awk_val_t* val)
|
||||
|
||||
void xp_awk_refupval (xp_awk_val_t* val)
|
||||
{
|
||||
if (val == XP_NULL || val == xp_awk_val_nil) return;
|
||||
if (val >= (xp_awk_val_t*)&__awk_int[0] &&
|
||||
val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]) return;
|
||||
|
||||
if (xp_awk_isbuiltinval(val)) return;
|
||||
/*
|
||||
xp_printf (XP_TEXT("ref up "));
|
||||
xp_awk_printval (val);
|
||||
xp_printf (XP_TEXT("\n"));
|
||||
*/
|
||||
|
||||
val->ref++;
|
||||
}
|
||||
|
||||
void xp_awk_refdownval (xp_awk_val_t* val)
|
||||
{
|
||||
if (val == XP_NULL || val == xp_awk_val_nil) return;
|
||||
if (val >= (xp_awk_val_t*)&__awk_int[0] &&
|
||||
val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]) return;
|
||||
if (xp_awk_isbuiltinval(val)) return;
|
||||
|
||||
/*
|
||||
xp_printf (XP_TEXT("ref down "));
|
||||
xp_printf (XP_TEXT("ref down [count=>%d]\n"), val->ref);
|
||||
xp_awk_printval (val);
|
||||
xp_printf (XP_TEXT("\n"));
|
||||
*/
|
||||
|
||||
xp_assert (val->ref > 0);
|
||||
val->ref--;
|
||||
if (val->ref <= 0) xp_awk_freeval(val);
|
||||
if (val->ref <= 0)
|
||||
{
|
||||
/*
|
||||
xp_printf (XP_TEXT("**FREEING "));
|
||||
xp_awk_printval (val);
|
||||
xp_printf (XP_TEXT("\n"));
|
||||
*/
|
||||
xp_awk_freeval(val);
|
||||
}
|
||||
}
|
||||
|
||||
void xp_awk_refdownval_nofree (xp_awk_val_t* val)
|
||||
{
|
||||
if (xp_awk_isbuiltinval(val)) return;
|
||||
|
||||
xp_assert (val->ref > 0);
|
||||
val->ref--;
|
||||
}
|
||||
|
||||
xp_awk_val_t* xp_awk_cloneval (xp_awk_val_t* val)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: val.h,v 1.7 2006-03-23 13:26:04 bacon Exp $
|
||||
* $Id: val.h,v 1.8 2006-03-26 16:36:30 bacon Exp $
|
||||
*/
|
||||
|
||||
#ifndef _XP_AWK_VAL_H_
|
||||
@ -69,9 +69,11 @@ extern xp_awk_val_t* xp_awk_val_nil;
|
||||
xp_awk_val_t* xp_awk_makeintval (xp_long_t v);
|
||||
xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len);
|
||||
|
||||
xp_bool_t xp_awk_isbuiltinval (xp_awk_val_t* val);
|
||||
void xp_awk_freeval (xp_awk_val_t* val);
|
||||
void xp_awk_refupval (xp_awk_val_t* val);
|
||||
void xp_awk_refdownval (xp_awk_val_t* val);
|
||||
void xp_awk_refdownval_nofree (xp_awk_val_t* val);
|
||||
|
||||
xp_awk_val_t* xp_awk_cloneval (xp_awk_val_t* val);
|
||||
xp_bool_t xp_awk_isvaltrue (xp_awk_val_t* val);
|
||||
|
Loading…
Reference in New Issue
Block a user