*** empty log message ***

This commit is contained in:
hyung-hwan 2006-03-26 16:36:30 +00:00
parent 67d7ca36ff
commit 55043320b8
5 changed files with 142 additions and 32 deletions

View File

@ -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> #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_top = 0;
awk->run.stack_base = 0; awk->run.stack_base = 0;
awk->run.stack_limit = 0; awk->run.stack_limit = 0;
awk->run.exit_level = 0;
awk->lex.curc = XP_CHAR_EOF; awk->lex.curc = XP_CHAR_EOF;
awk->lex.ungotc_count = 0; awk->lex.ungotc_count = 0;

View File

@ -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_ #ifndef _XP_AWK_AWK_H_
@ -97,6 +97,7 @@ struct xp_awk_t
xp_size_t stack_top; xp_size_t stack_top;
xp_size_t stack_base; xp_size_t stack_base;
xp_size_t stack_limit; xp_size_t stack_limit;
int exit_level;
} run; } run;
/* source buffer management */ /* source buffer management */

View File

@ -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> #include <xp/awk/awk.h>
@ -16,6 +16,11 @@
#define STACK_NARGS(awk) ((xp_size_t)STACK_AT(awk,3)) #define STACK_NARGS(awk) ((xp_size_t)STACK_AT(awk,3))
#define STACK_ARG(awk,n) STACK_AT(awk,3+1+(n)) #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_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_block (xp_awk_t* awk, xp_awk_nde_blk_t* nde);
static int __run_statement (xp_awk_t* awk, xp_awk_nde_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 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_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) 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) 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) if (awk->tree.begin != XP_NULL)
{ {
xp_assert (awk->tree.begin->type == XP_AWK_NDE_BLK); 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")); //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; if (__run_statement(awk,p) == -1) return -1;
p = p->next; 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")); //xp_printf (XP_TEXT("returning....\n"));
val = __eval_expression(awk, nde->val); val = __eval_expression(awk, nde->val);
if (val == XP_NULL) return -1; 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")); //xp_printf (XP_TEXT("set return value....\n"));
} }
// TODO: make the function exit....
awk->run.exit_level = EXIT_FUNCTION;
return 0; 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) 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) else if (tgt->type == XP_AWK_NDE_LOCAL)
{ {
xp_awk_refdownval(STACK_LOCAL(awk,tgt->id.idxa));
STACK_LOCAL(awk,tgt->id.idxa) = val; STACK_LOCAL(awk,tgt->id.idxa) = val;
xp_awk_refupval (val); xp_awk_refupval (val);
} }
else if (tgt->type == XP_AWK_NDE_ARG) else if (tgt->type == XP_AWK_NDE_ARG)
{ {
xp_awk_refdownval(STACK_ARG(awk,tgt->id.idxa));
STACK_ARG(awk,tgt->id.idxa) = val; STACK_ARG(awk,tgt->id.idxa) = val;
xp_awk_refupval (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_long_t r =
((xp_awk_val_int_t*)left)->val + ((xp_awk_val_int_t*)left)->val +
((xp_awk_val_int_t*)right)->val; ((xp_awk_val_int_t*)right)->val;
res = xp_awk_makeintval (r);
// 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) 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_long_t r =
((xp_awk_val_int_t*)left)->val - ((xp_awk_val_int_t*)left)->val -
((xp_awk_val_int_t*)right)->val; ((xp_awk_val_int_t*)right)->val;
res = xp_awk_makeintval (r);
/*
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);
//}
} }
} }
xp_awk_refdownval(left); /*
xp_awk_refdownval(right); 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; 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
* --------------------- * ---------------------
* .... * ....
* --------------------- * ---------------------
@ -593,7 +666,7 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde)
* --------------------- * ---------------------
* previous stack top * previous stack top
* --------------------- * ---------------------
* previous stack base <- stack base * previous stack base <- stack base
* --------------------- * ---------------------
*/ */
@ -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_printf (XP_TEXT("running function body\n"));
xp_assert (func->body->type == XP_AWK_NDE_BLK); 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")); //xp_printf (XP_TEXT("block run complete\n"));
/* refdown args in the run.stack */ /* 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_awk_refdownval (STACK_ARG(awk,i));
} }
//xp_printf (XP_TEXT("got return value\n")); //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_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]; 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); //xp_printf (XP_TEXT("returning from function stack_top=%ld, stack_base=%ld\n"), awk->run.stack_top, awk->run.stack_base);
return v; return v;
} }
@ -696,7 +784,7 @@ static int __raw_push (xp_awk_t* awk, void* val)
return 0; 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); xp_assert (awk->run.stack_top > awk->run.stack_base);
awk->run.stack_top--; awk->run.stack_top--;

View File

@ -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> #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; if (val == XP_NULL) return XP_NULL;
val->type = XP_AWK_VAL_INT; val->type = XP_AWK_VAL_INT;
val->ref = 0;
val->val = v; val->val = v;
return (xp_awk_val_t*)val; 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; if (val == XP_NULL) return XP_NULL;
val->type = XP_AWK_VAL_REAL; val->type = XP_AWK_VAL_REAL;
val->ref = 0;
val->val = v; val->val = v;
return (xp_awk_val_t*)val; 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; if (val == XP_NULL) return XP_NULL;
val->type = XP_AWK_VAL_STR; val->type = XP_AWK_VAL_STR;
val->ref = 0;
val->len = len; val->len = len;
val->buf = xp_strxdup (str, len); val->buf = xp_strxdup (str, len);
if (val->buf == XP_NULL) { 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; 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) void xp_awk_freeval (xp_awk_val_t* val)
{ {
if (val == XP_NULL || val == xp_awk_val_nil) return; if (xp_awk_isbuiltinval(val)) return;
if (val >= (xp_awk_val_t*)&__awk_int[0] &&
val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]) return;
switch (val->type) 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) void xp_awk_refupval (xp_awk_val_t* val)
{ {
if (val == XP_NULL || val == xp_awk_val_nil) return; if (xp_awk_isbuiltinval(val)) return;
if (val >= (xp_awk_val_t*)&__awk_int[0] &&
val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]) return;
/* /*
xp_printf (XP_TEXT("ref up ")); xp_printf (XP_TEXT("ref up "));
xp_awk_printval (val); xp_awk_printval (val);
xp_printf (XP_TEXT("\n")); xp_printf (XP_TEXT("\n"));
*/ */
val->ref++; val->ref++;
} }
void xp_awk_refdownval (xp_awk_val_t* val) void xp_awk_refdownval (xp_awk_val_t* val)
{ {
if (val == XP_NULL || val == xp_awk_val_nil) return; if (xp_awk_isbuiltinval(val)) return;
if (val >= (xp_awk_val_t*)&__awk_int[0] &&
val <= (xp_awk_val_t*)&__awk_int[xp_countof(__awk_int)-1]) return;
/* /*
xp_printf (XP_TEXT("ref down ")); xp_printf (XP_TEXT("ref down [count=>%d]\n"), val->ref);
xp_awk_printval (val); xp_awk_printval (val);
xp_printf (XP_TEXT("\n")); xp_printf (XP_TEXT("\n"));
*/ */
xp_assert (val->ref > 0); xp_assert (val->ref > 0);
val->ref--; 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) xp_awk_val_t* xp_awk_cloneval (xp_awk_val_t* val)

View File

@ -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_ #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_makeintval (xp_long_t v);
xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len); 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_freeval (xp_awk_val_t* val);
void xp_awk_refupval (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 (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_awk_val_t* xp_awk_cloneval (xp_awk_val_t* val);
xp_bool_t xp_awk_isvaltrue (xp_awk_val_t* val); xp_bool_t xp_awk_isvaltrue (xp_awk_val_t* val);