diff --git a/ase/awk/run.c b/ase/awk/run.c index a02387ab..00fd0015 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.12 2006-03-15 15:34:59 bacon Exp $ + * $Id: run.c,v 1.13 2006-03-22 16:05:49 bacon Exp $ */ #include @@ -19,6 +19,9 @@ static xp_awk_val_t* __eval_expression (xp_awk_t* awk, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_ass_t* nde); static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde); +static void __refup (xp_awk_val_t* val); +static void __refdown (xp_awk_val_t* val); + int __printval (xp_awk_pair_t* pair) { xp_printf (XP_TEXT("%s = "), (const xp_char_t*)pair->key); @@ -137,7 +140,7 @@ static int __run_if_statement (xp_awk_t* awk, xp_awk_nde_if_t* nde) n = __run_statement (awk, nde->else_part); } -//TODO: how should i destroy test? + xp_awk_freeval (test); // TODO: is this correct? return n; } @@ -156,6 +159,8 @@ static xp_awk_val_t* __eval_expression (xp_awk_t* awk, xp_awk_nde_t* nde) break; case XP_AWK_NDE_EXP_UNR: + // TODO: ....................... + break; case XP_AWK_NDE_STR: val = xp_awk_makestrval( @@ -251,6 +256,7 @@ static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_ass_t* nde) return XP_NULL; } + __refup (new); v = new; } else if (tgt->type == XP_AWK_NDE_GLOBAL) @@ -287,7 +293,7 @@ static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_ass_t* nde) static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) { - xp_awk_val_t* left, * right; + xp_awk_val_t* left, * right, * res; xp_assert (nde->type == XP_AWK_NDE_EXP_BIN); @@ -301,17 +307,47 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) return XP_NULL; } + res = XP_NULL; + // TODO: a lot of things to do.... if (nde->opcode == XP_AWK_BINOP_PLUS) { if (left->type == XP_AWK_VAL_INT && right->type == XP_AWK_VAL_INT) { - ((xp_awk_val_int_t*)left)->val += - ((xp_awk_val_int_t*)right)->val; + xp_long_t r = + ((xp_awk_val_int_t*)left)->val + + ((xp_awk_val_int_t*)right)->val; + res = xp_awk_makeintval (r); + } + } + else if (nde->opcode == XP_AWK_BINOP_MINUS) + { + if (left->type == XP_AWK_VAL_INT && + right->type == XP_AWK_VAL_INT) + { + xp_long_t r = + ((xp_awk_val_int_t*)left)->val - + ((xp_awk_val_int_t*)right)->val; + res = xp_awk_makeintval (r); } } + xp_awk_freeval(left); xp_awk_freeval(right); - return left; + + return res; +} + +static void __refup (xp_awk_val_t* val) +{ + val->ref++; +} + +static void __refdown (xp_awk_val_t* val) +{ + xp_assert (val->ref > 0); + + val->ref--; + if (val->ref <= 0) xp_awk_freeval(val); } diff --git a/ase/awk/val.c b/ase/awk/val.c index ffbb4e7f..64f929c6 100644 --- a/ase/awk/val.c +++ b/ase/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c,v 1.6 2006-03-15 15:34:59 bacon Exp $ + * $Id: val.c,v 1.7 2006-03-22 16:05:50 bacon Exp $ */ #include @@ -9,13 +9,34 @@ #include #endif -static xp_awk_val_nil_t __awk_nil = { XP_AWK_VAL_NIL }; +static xp_awk_val_nil_t __awk_nil = { XP_AWK_VAL_NIL, 0 }; xp_awk_val_t* xp_awk_val_nil = (xp_awk_val_t*)&__awk_nil; +static xp_awk_val_int_t __awk_int[] = +{ + { XP_AWK_VAL_INT, 0, -1 }, + { XP_AWK_VAL_INT, 0, 0 }, + { XP_AWK_VAL_INT, 0, 1 }, + { XP_AWK_VAL_INT, 0, 2 }, + { XP_AWK_VAL_INT, 0, 3 }, + { XP_AWK_VAL_INT, 0, 4 }, + { XP_AWK_VAL_INT, 0, 5 }, + { XP_AWK_VAL_INT, 0, 6 }, + { XP_AWK_VAL_INT, 0, 7 }, + { XP_AWK_VAL_INT, 0, 8 }, + { XP_AWK_VAL_INT, 0, 9 }, +}; + xp_awk_val_t* xp_awk_makeintval (xp_long_t v) { xp_awk_val_int_t* val; + if (v >= __awk_int[0].val && + v <= __awk_int[xp_countof(__awk_int)-1].val) + { + return (xp_awk_val_t*)&__awk_int[v-__awk_int[0].val]; + } + val = (xp_awk_val_int_t*)xp_malloc(xp_sizeof(xp_awk_val_int_t)); if (val == XP_NULL) return XP_NULL; @@ -58,6 +79,10 @@ xp_awk_val_t* xp_awk_makestrval (const xp_char_t* str, xp_size_t len) void xp_awk_freeval (xp_awk_val_t* val) { + if (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; + switch (val->type) { case XP_AWK_VAL_STR: @@ -105,6 +130,8 @@ xp_bool_t xp_awk_isvaltrue (xp_awk_val_t* val) return (((xp_awk_val_str_t*)val)->len == 0)? xp_false: xp_true; } + /* this should never happen */ + return xp_false; } void xp_awk_printval (xp_awk_val_t* val) diff --git a/ase/awk/val.h b/ase/awk/val.h index c9396db0..36102367 100644 --- a/ase/awk/val.h +++ b/ase/awk/val.h @@ -1,5 +1,5 @@ /* - * $Id: val.h,v 1.5 2006-03-15 15:34:59 bacon Exp $ + * $Id: val.h,v 1.6 2006-03-22 16:05:50 bacon Exp $ */ #ifndef _XP_AWK_VAL_H_ @@ -24,7 +24,8 @@ typedef struct xp_awk_val_real_t xp_awk_val_real_t; typedef struct xp_awk_val_str_t xp_awk_val_str_t; #define XP_AWK_VAL_HDR \ - int type + int type: 2; \ + int ref: 30 struct xp_awk_val_t {