*** empty log message ***
This commit is contained in:
parent
3acfc556bd
commit
86a65e2e67
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.h,v 1.44 2006-04-07 04:23:11 bacon Exp $
|
||||
* $Id: awk.h,v 1.45 2006-04-07 16:52:42 bacon Exp $
|
||||
*/
|
||||
|
||||
#ifndef _XP_AWK_AWK_H_
|
||||
@ -69,7 +69,8 @@ enum
|
||||
|
||||
/* run time error */
|
||||
XP_AWK_EDIVBYZERO, /* divide by zero */
|
||||
XP_AWK_EOPERAND /* invalid operand */
|
||||
XP_AWK_EOPERAND, /* invalid operand */
|
||||
XP_AWK_EINTERNAL /* internal error */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: err.c,v 1.6 2006-04-07 04:23:11 bacon Exp $
|
||||
* $Id: err.c,v 1.7 2006-04-07 16:52:42 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <xp/awk/awk_i.h>
|
||||
@ -43,7 +43,9 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
|
||||
XP_TEXT("l-value required"),
|
||||
|
||||
XP_TEXT("divide by zero"),
|
||||
XP_TEXT("invalid operand")
|
||||
XP_TEXT("invalid operand"),
|
||||
|
||||
XP_TEXT("internal error that should never have happened")
|
||||
};
|
||||
|
||||
if (awk->errnum >= 0 && awk->errnum < xp_countof(__errstr)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: parse.c,v 1.73 2006-04-07 04:23:11 bacon Exp $
|
||||
* $Id: parse.c,v 1.74 2006-04-07 16:52:42 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <xp/awk/awk_i.h>
|
||||
|
385
ase/awk/run.c
385
ase/awk/run.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: run.c,v 1.37 2006-04-07 04:23:11 bacon Exp $
|
||||
* $Id: run.c,v 1.38 2006-04-07 16:52:42 bacon Exp $
|
||||
*/
|
||||
|
||||
#include <xp/awk/awk_i.h>
|
||||
@ -40,11 +40,11 @@ static int __run_return_statement (xp_awk_t* awk, xp_awk_nde_return_t* nde);
|
||||
static int __run_exit_statement (xp_awk_t* awk, xp_awk_nde_exit_t* nde);
|
||||
|
||||
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_assignment (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __do_assignment (
|
||||
xp_awk_t* awk, xp_awk_nde_var_t* var, xp_awk_val_t* val);
|
||||
|
||||
static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde);
|
||||
static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_binop_lor (
|
||||
xp_awk_t* awk, xp_awk_val_t* left, xp_awk_val_t* right);
|
||||
static xp_awk_val_t* __eval_binop_land (
|
||||
@ -82,16 +82,29 @@ static xp_awk_val_t* __eval_binop_div (
|
||||
static xp_awk_val_t* __eval_binop_mod (
|
||||
xp_awk_t* awk, xp_awk_val_t* left, xp_awk_val_t* right);
|
||||
|
||||
static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde);
|
||||
static xp_awk_val_t* __eval_incpre (xp_awk_t* awk, xp_awk_nde_exp_t* nde);
|
||||
static xp_awk_val_t* __eval_incpst (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_unary (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_incpre (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_incpst (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_call (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_int (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_real (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_str (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_named (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_global (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_local (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_arg (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_namedidx (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_globalidx (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_localidx (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_argidx (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
static xp_awk_val_t* __eval_pos (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
|
||||
static int __raw_push (xp_awk_t* awk, void* val);
|
||||
static void __raw_pop (xp_awk_t* awk);
|
||||
|
||||
typedef xp_awk_val_t* (*binop_func_t) (
|
||||
xp_awk_t* awk, xp_awk_val_t* left, xp_awk_val_t* right);
|
||||
typedef xp_awk_val_t* (*eval_expr_t) (xp_awk_t* awk, xp_awk_nde_t* nde);
|
||||
|
||||
int __printval (xp_awk_pair_t* pair)
|
||||
{
|
||||
@ -485,44 +498,81 @@ static int __run_exit_statement (xp_awk_t* awk, xp_awk_nde_exit_t* nde)
|
||||
|
||||
static xp_awk_val_t* __eval_expression (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
static eval_expr_t __eval_func[] =
|
||||
{
|
||||
/* the order of functions here should match the order
|
||||
* of node types declared in tree.h */
|
||||
__eval_assignment,
|
||||
__eval_binary,
|
||||
__eval_unary,
|
||||
__eval_incpre,
|
||||
__eval_incpst,
|
||||
__eval_call,
|
||||
__eval_int,
|
||||
__eval_real,
|
||||
__eval_str,
|
||||
__eval_named,
|
||||
__eval_global,
|
||||
__eval_local,
|
||||
__eval_arg,
|
||||
__eval_namedidx,
|
||||
__eval_globalidx,
|
||||
__eval_localidx,
|
||||
__eval_argidx,
|
||||
__eval_pos
|
||||
};
|
||||
|
||||
xp_assert (nde->type >= XP_AWK_NDE_ASS &&
|
||||
(nde->type - XP_AWK_NDE_ASS) < xp_countof(__eval_func));
|
||||
return __eval_func[nde->type-XP_AWK_NDE_ASS] (awk, nde);
|
||||
|
||||
#if 0
|
||||
xp_awk_val_t* val;
|
||||
|
||||
switch (nde->type)
|
||||
{
|
||||
case XP_AWK_NDE_ASS:
|
||||
val = __eval_assignment (awk, (xp_awk_nde_ass_t*)nde);
|
||||
if (val == XP_NULL) return XP_NULL;
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_EXP_BIN:
|
||||
val = __eval_binary (awk, (xp_awk_nde_exp_t*)nde);
|
||||
if (val == XP_NULL) return XP_NULL;
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_EXP_UNR:
|
||||
val = __eval_unary (awk, (xp_awk_nde_exp_t*)nde);
|
||||
if (val == XP_NULL) return XP_NULL;
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_EXP_INCPRE:
|
||||
val = __eval_incpre (awk, (xp_awk_nde_exp_t*)nde);
|
||||
if (val == XP_NULL) return XP_NULL;
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_EXP_INCPST:
|
||||
val = __eval_incpst (awk, (xp_awk_nde_exp_t*)nde);
|
||||
if (val == XP_NULL) return XP_NULL;
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_INT:
|
||||
val = xp_awk_makeintval (
|
||||
awk, ((xp_awk_nde_int_t*)nde)->val);
|
||||
if (val == XP_NULL) PANIC (awk, XP_ENOMEM);
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_REAL:
|
||||
val = xp_awk_makerealval (
|
||||
awk, ((xp_awk_nde_real_t*)nde)->val);
|
||||
if (val == XP_NULL) PANIC (awk, XP_ENOMEM);
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_STR:
|
||||
val = xp_awk_makestrval (
|
||||
((xp_awk_nde_str_t*)nde)->buf,
|
||||
((xp_awk_nde_str_t*)nde)->len);
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_INT:
|
||||
val = xp_awk_makeintval (
|
||||
awk, ((xp_awk_nde_int_t*)nde)->val);
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_REAL:
|
||||
val = xp_awk_makerealval (
|
||||
awk, ((xp_awk_nde_real_t*)nde)->val);
|
||||
if (val == XP_NULL) PANIC (awk, XP_ENOMEM);
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_NAMED:
|
||||
@ -557,42 +607,48 @@ static xp_awk_val_t* __eval_expression (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_NAMEDIDX:
|
||||
// TODO:
|
||||
break;
|
||||
case XP_AWK_NDE_GLOBALIDX:
|
||||
// TODO:
|
||||
break;
|
||||
case XP_AWK_NDE_LOCALIDX:
|
||||
// TODO:
|
||||
break;
|
||||
case XP_AWK_NDE_ARGIDX:
|
||||
// TODO:
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_POS:
|
||||
// TODO:
|
||||
break;
|
||||
|
||||
case XP_AWK_NDE_CALL:
|
||||
val = __eval_funccall(awk, (xp_awk_nde_call_t*)nde);
|
||||
val = __eval_call (awk, (xp_awk_nde_call_t*)nde);
|
||||
if (val == XP_NULL) return XP_NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* somthing wrong. internal error */
|
||||
/* TODO: set the error code instead of assertion below */
|
||||
xp_assert (!"should never happen");
|
||||
return XP_NULL;
|
||||
xp_assert (!"should never happen - invalid node type");
|
||||
PANIC (awk, XP_AWK_EINTERNAL);
|
||||
}
|
||||
|
||||
|
||||
return val;
|
||||
#endif
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_ass_t* nde)
|
||||
static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_val_t* val;
|
||||
xp_awk_nde_ass_t* ass = (xp_awk_nde_ass_t*)nde;
|
||||
|
||||
xp_assert (nde->left != XP_NULL && nde->right != XP_NULL);
|
||||
xp_assert (ass->left != XP_NULL && ass->right != XP_NULL);
|
||||
|
||||
val = __eval_expression(awk, nde->right);
|
||||
val = __eval_expression(awk, ass->right);
|
||||
if (val == XP_NULL) return XP_NULL;
|
||||
|
||||
return __do_assignment (awk, (xp_awk_nde_var_t*)nde->left, val);
|
||||
return __do_assignment (awk, (xp_awk_nde_var_t*)ass->left, val);
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __do_assignment (
|
||||
@ -649,29 +705,31 @@ static xp_awk_val_t* __do_assignment (
|
||||
}
|
||||
else if (var->type == XP_AWK_NDE_NAMEDIDX)
|
||||
{
|
||||
// TODO:
|
||||
}
|
||||
else if (var->type == XP_AWK_NDE_GLOBALIDX)
|
||||
{
|
||||
// TODO:
|
||||
}
|
||||
else if (var->type == XP_AWK_NDE_LOCALIDX)
|
||||
{
|
||||
// TODO:
|
||||
}
|
||||
else if (var->type == XP_AWK_NDE_ARGIDX)
|
||||
{
|
||||
// TODO:
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this should never be reached. something wrong */
|
||||
// TODO: set errnum .... error handling
|
||||
return XP_NULL;
|
||||
xp_assert (!"should never happen - invalid variable type");
|
||||
PANIC (awk, XP_AWK_EINTERNAL);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_val_t* left, * right, * res;
|
||||
static binop_func_t __binop_func[] =
|
||||
{
|
||||
__eval_binop_lor,
|
||||
@ -696,15 +754,17 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
__eval_binop_div,
|
||||
__eval_binop_mod
|
||||
};
|
||||
xp_awk_nde_exp_t* exp = (xp_awk_nde_exp_t*)nde;
|
||||
xp_awk_val_t* left, * right, * res;
|
||||
|
||||
xp_assert (nde->type == XP_AWK_NDE_EXP_BIN);
|
||||
xp_assert (exp->type == XP_AWK_NDE_EXP_BIN);
|
||||
|
||||
left = __eval_expression (awk, nde->left);
|
||||
left = __eval_expression (awk, exp->left);
|
||||
if (left == XP_NULL) return XP_NULL;
|
||||
|
||||
xp_awk_refupval (left);
|
||||
|
||||
right = __eval_expression (awk, nde->right);
|
||||
right = __eval_expression (awk, exp->right);
|
||||
if (right == XP_NULL)
|
||||
{
|
||||
xp_awk_refdownval (awk, left);
|
||||
@ -713,11 +773,10 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
|
||||
xp_awk_refupval (right);
|
||||
|
||||
xp_assert (nde->opcode >= 0 &&
|
||||
nde->opcode < xp_countof(__binop_func));
|
||||
xp_assert (exp->opcode >= 0 &&
|
||||
exp->opcode < xp_countof(__binop_func));
|
||||
|
||||
res = __binop_func[nde->opcode] (awk, left, right);
|
||||
// TODO: do i need to handle error here or in binop_func???
|
||||
res = __binop_func[exp->opcode] (awk, left, right);
|
||||
|
||||
xp_awk_refdownval (awk, left);
|
||||
xp_awk_refdownval (awk, right);
|
||||
@ -1382,20 +1441,21 @@ static xp_awk_val_t* __eval_binop_mod (
|
||||
return res;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_val_t* left, * res;
|
||||
xp_awk_nde_exp_t* exp = (xp_awk_nde_exp_t*)nde;
|
||||
|
||||
xp_assert (nde->type == XP_AWK_NDE_EXP_UNR);
|
||||
xp_assert (nde->left != XP_NULL && nde->right == XP_NULL);
|
||||
xp_assert (exp->type == XP_AWK_NDE_EXP_UNR);
|
||||
xp_assert (exp->left != XP_NULL && exp->right == XP_NULL);
|
||||
|
||||
left = __eval_expression (awk, nde->left);
|
||||
left = __eval_expression (awk, exp->left);
|
||||
if (left == XP_NULL) return XP_NULL;
|
||||
|
||||
xp_awk_refupval (left);
|
||||
|
||||
// TODO: a lot of things to do....
|
||||
if (nde->opcode == XP_AWK_UNROP_PLUS)
|
||||
if (exp->opcode == XP_AWK_UNROP_PLUS)
|
||||
{
|
||||
if (left->type == XP_AWK_VAL_INT)
|
||||
{
|
||||
@ -1416,7 +1476,7 @@ static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
return XP_NULL;
|
||||
}
|
||||
}
|
||||
else if (nde->opcode == XP_AWK_UNROP_MINUS)
|
||||
else if (exp->opcode == XP_AWK_UNROP_MINUS)
|
||||
{
|
||||
if (left->type == XP_AWK_VAL_INT)
|
||||
{
|
||||
@ -1437,7 +1497,7 @@ static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
return XP_NULL;
|
||||
}
|
||||
}
|
||||
else if (nde->opcode == XP_AWK_UNROP_NOT)
|
||||
else if (exp->opcode == XP_AWK_UNROP_NOT)
|
||||
{
|
||||
if (left->type == XP_AWK_VAL_INT)
|
||||
{
|
||||
@ -1458,7 +1518,7 @@ static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
return XP_NULL;
|
||||
}
|
||||
}
|
||||
else if (nde->opcode == XP_AWK_UNROP_BNOT)
|
||||
else if (exp->opcode == XP_AWK_UNROP_BNOT)
|
||||
{
|
||||
if (left->type == XP_AWK_VAL_INT)
|
||||
{
|
||||
@ -1478,184 +1538,203 @@ static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
return res;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_incpre (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
static xp_awk_val_t* __eval_incpre (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_val_t* left, * res;
|
||||
xp_awk_nde_exp_t* exp = (xp_awk_nde_exp_t*)nde;
|
||||
|
||||
xp_assert (nde->type == XP_AWK_NDE_EXP_INCPRE);
|
||||
xp_assert (nde->left != XP_NULL && nde->right == XP_NULL);
|
||||
xp_assert (exp->type == XP_AWK_NDE_EXP_INCPRE);
|
||||
xp_assert (exp->left != XP_NULL && exp->right == XP_NULL);
|
||||
|
||||
/* ugly. but let's keep going this way for the time being */
|
||||
if (nde->left->type != XP_AWK_NDE_ARG &&
|
||||
nde->left->type != XP_AWK_NDE_ARGIDX &&
|
||||
nde->left->type != XP_AWK_NDE_NAMED &&
|
||||
nde->left->type != XP_AWK_NDE_NAMEDIDX &&
|
||||
nde->left->type != XP_AWK_NDE_GLOBAL &&
|
||||
nde->left->type != XP_AWK_NDE_GLOBALIDX &&
|
||||
nde->left->type != XP_AWK_NDE_LOCAL &&
|
||||
nde->left->type != XP_AWK_NDE_LOCALIDX)
|
||||
if (exp->left->type != XP_AWK_NDE_ARG &&
|
||||
exp->left->type != XP_AWK_NDE_ARGIDX &&
|
||||
exp->left->type != XP_AWK_NDE_NAMED &&
|
||||
exp->left->type != XP_AWK_NDE_NAMEDIDX &&
|
||||
exp->left->type != XP_AWK_NDE_GLOBAL &&
|
||||
exp->left->type != XP_AWK_NDE_GLOBALIDX &&
|
||||
exp->left->type != XP_AWK_NDE_LOCAL &&
|
||||
exp->left->type != XP_AWK_NDE_LOCALIDX)
|
||||
{
|
||||
// TOOD: error handling..
|
||||
return XP_NULL;
|
||||
PANIC (awk, XP_AWK_EOPERAND);
|
||||
}
|
||||
|
||||
left = __eval_expression (awk, nde->left); // TODO: do it differently
|
||||
left = __eval_expression (awk, exp->left); // TODO: do it differently
|
||||
if (left == XP_NULL) return XP_NULL;
|
||||
|
||||
xp_awk_refupval (left);
|
||||
|
||||
if (nde->opcode == XP_AWK_UNROP_PLUS)
|
||||
if (exp->opcode == XP_AWK_INCOP_PLUS)
|
||||
{
|
||||
if (left->type == XP_AWK_VAL_INT)
|
||||
{
|
||||
xp_long_t r = ((xp_awk_val_int_t*)left)->val;
|
||||
res = xp_awk_makeintval (awk, r + 1);
|
||||
// TODO: error handling
|
||||
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
}
|
||||
else if (left->type == XP_AWK_VAL_REAL)
|
||||
{
|
||||
xp_real_t r = ((xp_awk_val_real_t*)left)->val;
|
||||
res = xp_awk_makerealval (awk, r + 1.0);
|
||||
// TODO: error handling
|
||||
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TOOD: error handling..
|
||||
xp_awk_refdownval (awk, left);
|
||||
return XP_NULL;
|
||||
PANIC (awk, XP_AWK_EOPERAND);
|
||||
}
|
||||
}
|
||||
else if (nde->opcode == XP_AWK_UNROP_MINUS)
|
||||
else if (exp->opcode == XP_AWK_INCOP_MINUS)
|
||||
{
|
||||
if (left->type == XP_AWK_VAL_INT)
|
||||
{
|
||||
xp_long_t r = ((xp_awk_val_int_t*)left)->val;
|
||||
res = xp_awk_makeintval (awk, r - 1);
|
||||
// TODO: error handling
|
||||
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
}
|
||||
else if (left->type == XP_AWK_VAL_REAL)
|
||||
{
|
||||
xp_real_t r = ((xp_awk_val_real_t*)left)->val;
|
||||
res = xp_awk_makerealval (awk, r - 1.0);
|
||||
// TODO: error handling
|
||||
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TOOD: error handling..
|
||||
xp_awk_refdownval (awk, left);
|
||||
return XP_NULL;
|
||||
PANIC (awk, XP_AWK_EOPERAND);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xp_assert (!"should never happen - invalid opcode");
|
||||
xp_awk_refdownval (awk, left);
|
||||
PANIC (awk, XP_AWK_EINTERNAL);
|
||||
}
|
||||
|
||||
if (__do_assignment (awk,
|
||||
(xp_awk_nde_var_t*)nde->left, res) == XP_NULL)
|
||||
(xp_awk_nde_var_t*)exp->left, res) == XP_NULL)
|
||||
{
|
||||
// TODO: error handling
|
||||
xp_awk_refdownval (awk, left);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
xp_awk_refdownval (awk, left);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_incpst (xp_awk_t* awk, xp_awk_nde_exp_t* nde)
|
||||
static xp_awk_val_t* __eval_incpst (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_val_t* left, * res, * res2;
|
||||
xp_awk_nde_exp_t* exp = (xp_awk_nde_exp_t*)nde;
|
||||
|
||||
xp_assert (nde->type == XP_AWK_NDE_EXP_INCPST);
|
||||
xp_assert (nde->left != XP_NULL && nde->right == XP_NULL);
|
||||
xp_assert (exp->type == XP_AWK_NDE_EXP_INCPST);
|
||||
xp_assert (exp->left != XP_NULL && exp->right == XP_NULL);
|
||||
|
||||
/* ugly. but let's keep going this way for the time being */
|
||||
if (nde->left->type != XP_AWK_NDE_ARG &&
|
||||
nde->left->type != XP_AWK_NDE_ARGIDX &&
|
||||
nde->left->type != XP_AWK_NDE_NAMED &&
|
||||
nde->left->type != XP_AWK_NDE_NAMEDIDX &&
|
||||
nde->left->type != XP_AWK_NDE_GLOBAL &&
|
||||
nde->left->type != XP_AWK_NDE_GLOBALIDX &&
|
||||
nde->left->type != XP_AWK_NDE_LOCAL &&
|
||||
nde->left->type != XP_AWK_NDE_LOCALIDX) // TODO: what about NDE_POS?
|
||||
if (exp->left->type != XP_AWK_NDE_ARG &&
|
||||
exp->left->type != XP_AWK_NDE_ARGIDX &&
|
||||
exp->left->type != XP_AWK_NDE_NAMED &&
|
||||
exp->left->type != XP_AWK_NDE_NAMEDIDX &&
|
||||
exp->left->type != XP_AWK_NDE_GLOBAL &&
|
||||
exp->left->type != XP_AWK_NDE_GLOBALIDX &&
|
||||
exp->left->type != XP_AWK_NDE_LOCAL &&
|
||||
exp->left->type != XP_AWK_NDE_LOCALIDX)
|
||||
{
|
||||
// TOOD: error handling..
|
||||
return XP_NULL;
|
||||
PANIC (awk, XP_AWK_EOPERAND);
|
||||
}
|
||||
|
||||
left = __eval_expression (awk, nde->left); // TODO: do it differently
|
||||
left = __eval_expression (awk, exp->left); // TODO: do it differently
|
||||
if (left == XP_NULL) return XP_NULL;
|
||||
|
||||
xp_awk_refupval (left);
|
||||
|
||||
left = __eval_expression (awk, nde->left); // TODO: get the actual target...
|
||||
if (left == XP_NULL) return XP_NULL;
|
||||
|
||||
xp_awk_refupval (left);
|
||||
|
||||
if (nde->opcode == XP_AWK_UNROP_PLUS)
|
||||
if (exp->opcode == XP_AWK_INCOP_PLUS)
|
||||
{
|
||||
if (left->type == XP_AWK_VAL_INT)
|
||||
{
|
||||
xp_long_t r = ((xp_awk_val_int_t*)left)->val;
|
||||
res = xp_awk_makeintval (awk, r);
|
||||
// TODO: error handling
|
||||
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
|
||||
res2 = xp_awk_makeintval (awk, r + 1);
|
||||
// TODO: error handling
|
||||
if (res2 == XP_NULL)
|
||||
{
|
||||
xp_awk_freeval (awk, res);
|
||||
PANIC (awk, XP_AWK_ENOMEM);
|
||||
}
|
||||
}
|
||||
else if (left->type == XP_AWK_VAL_REAL)
|
||||
{
|
||||
xp_real_t r = ((xp_awk_val_real_t*)left)->val;
|
||||
res = xp_awk_makerealval (awk, r);
|
||||
// TODO: error handling
|
||||
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
|
||||
res2 = xp_awk_makerealval (awk, r + 1.0);
|
||||
// TODO: error handling
|
||||
if (res2 == XP_NULL)
|
||||
{
|
||||
xp_awk_freeval (awk, res);
|
||||
PANIC (awk, XP_AWK_ENOMEM);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xp_awk_refdownval (awk, left);
|
||||
return XP_NULL;
|
||||
PANIC (awk, XP_AWK_EOPERAND);
|
||||
}
|
||||
}
|
||||
else if (nde->opcode == XP_AWK_UNROP_MINUS)
|
||||
else if (exp->opcode == XP_AWK_INCOP_MINUS)
|
||||
{
|
||||
if (left->type == XP_AWK_VAL_INT)
|
||||
{
|
||||
xp_long_t r = ((xp_awk_val_int_t*)left)->val;
|
||||
res = xp_awk_makeintval (awk, r);
|
||||
// TODO: error handling
|
||||
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
|
||||
res2 = xp_awk_makeintval (awk, r - 1);
|
||||
// TODO: error handling
|
||||
if (res2 == XP_NULL)
|
||||
{
|
||||
xp_awk_freeval (awk, res);
|
||||
PANIC (awk, XP_AWK_ENOMEM);
|
||||
}
|
||||
}
|
||||
else if (left->type == XP_AWK_VAL_REAL)
|
||||
{
|
||||
xp_real_t r = ((xp_awk_val_real_t*)left)->val;
|
||||
res = xp_awk_makerealval (awk, r);
|
||||
// TODO: error handling
|
||||
if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
|
||||
res2 = xp_awk_makerealval (awk, r - 1.0);
|
||||
// TODO: error handling
|
||||
if (res2 == XP_NULL)
|
||||
{
|
||||
xp_awk_freeval (awk, res);
|
||||
PANIC (awk, XP_AWK_ENOMEM);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xp_awk_refdownval (awk, left);
|
||||
return XP_NULL;
|
||||
PANIC (awk, XP_AWK_EOPERAND);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xp_assert (!"should never happen - invalid opcode");
|
||||
xp_awk_refdownval (awk, left);
|
||||
PANIC (awk, XP_AWK_EINTERNAL);
|
||||
}
|
||||
|
||||
if (__do_assignment (awk,
|
||||
(xp_awk_nde_var_t*)nde->left, res2) == XP_NULL)
|
||||
(xp_awk_nde_var_t*)exp->left, res2) == XP_NULL)
|
||||
{
|
||||
// TODO: error handling
|
||||
xp_awk_refdownval (awk, left);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
xp_awk_refdownval (awk, left);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde)
|
||||
static xp_awk_val_t* __eval_call (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_func_t* func;
|
||||
xp_awk_pair_t* pair;
|
||||
@ -1663,8 +1742,9 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde)
|
||||
xp_size_t nargs, i;
|
||||
xp_awk_val_t* v;
|
||||
xp_size_t saved_stack_top;
|
||||
xp_awk_nde_call_t* call = (xp_awk_nde_call_t*)nde;
|
||||
|
||||
pair = xp_awk_map_get (&awk->tree.funcs, nde->name);
|
||||
pair = xp_awk_map_get (&awk->tree.funcs, call->name);
|
||||
if (pair == XP_NULL) return XP_NULL; /* no such function */
|
||||
|
||||
/*
|
||||
@ -1721,7 +1801,7 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde)
|
||||
}
|
||||
|
||||
nargs = 0;
|
||||
p = nde->args;
|
||||
p = call->args;
|
||||
while (p != XP_NULL)
|
||||
{
|
||||
v = __eval_expression(awk,p);
|
||||
@ -1788,6 +1868,91 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde)
|
||||
return v;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_int (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_val_t* val;
|
||||
val = xp_awk_makeintval (
|
||||
awk, ((xp_awk_nde_int_t*)nde)->val);
|
||||
if (val == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
return val;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_real (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_val_t* val;
|
||||
val = xp_awk_makerealval (
|
||||
awk, ((xp_awk_nde_real_t*)nde)->val);
|
||||
if (val == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
return val;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_str (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_val_t* val;
|
||||
val = xp_awk_makestrval (
|
||||
((xp_awk_nde_str_t*)nde)->buf,
|
||||
((xp_awk_nde_str_t*)nde)->len);
|
||||
if (val == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
return val;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_named (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_pair_t* pair;
|
||||
xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde;
|
||||
|
||||
pair = xp_awk_map_get(&awk->run.named,tgt->id.name);
|
||||
return (pair == XP_NULL)? xp_awk_val_nil: pair->val;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_global (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde;
|
||||
return STACK_GLOBAL(awk,tgt->id.idxa);
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_local (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde;
|
||||
return STACK_LOCAL(awk,tgt->id.idxa);
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_arg (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde;
|
||||
return STACK_ARG(awk,tgt->id.idxa);
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_namedidx (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
// TODO:
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_globalidx (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
// TODO:
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_localidx (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
// TODO:
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_argidx (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
// TODO:
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
static xp_awk_val_t* __eval_pos (xp_awk_t* awk, xp_awk_nde_t* nde)
|
||||
{
|
||||
// TODO:
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
static int __raw_push (xp_awk_t* awk, void* val)
|
||||
{
|
||||
if (awk->run.stack_top >= awk->run.stack_limit)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: tree.h,v 1.29 2006-04-02 12:41:14 bacon Exp $
|
||||
* $Id: tree.h,v 1.30 2006-04-07 16:52:42 bacon Exp $
|
||||
*/
|
||||
|
||||
#ifndef _XP_AWK_TREE_H_
|
||||
@ -13,28 +13,8 @@ enum
|
||||
{
|
||||
XP_AWK_NDE_NULL,
|
||||
|
||||
/* statement */
|
||||
XP_AWK_NDE_BLK,
|
||||
XP_AWK_NDE_ASS,
|
||||
|
||||
XP_AWK_NDE_EXP_BIN,
|
||||
XP_AWK_NDE_EXP_UNR,
|
||||
XP_AWK_NDE_EXP_INCPRE,
|
||||
XP_AWK_NDE_EXP_INCPST,
|
||||
|
||||
XP_AWK_NDE_INT,
|
||||
XP_AWK_NDE_REAL,
|
||||
XP_AWK_NDE_STR,
|
||||
XP_AWK_NDE_NAMED,
|
||||
XP_AWK_NDE_NAMEDIDX,
|
||||
XP_AWK_NDE_GLOBAL,
|
||||
XP_AWK_NDE_GLOBALIDX,
|
||||
XP_AWK_NDE_LOCAL,
|
||||
XP_AWK_NDE_LOCALIDX,
|
||||
XP_AWK_NDE_ARG,
|
||||
XP_AWK_NDE_ARGIDX,
|
||||
XP_AWK_NDE_POS,
|
||||
XP_AWK_NDE_CALL,
|
||||
|
||||
XP_AWK_NDE_IF,
|
||||
XP_AWK_NDE_WHILE,
|
||||
XP_AWK_NDE_DOWHILE,
|
||||
@ -43,9 +23,28 @@ enum
|
||||
XP_AWK_NDE_CONTINUE,
|
||||
XP_AWK_NDE_RETURN,
|
||||
XP_AWK_NDE_EXIT,
|
||||
|
||||
XP_AWK_NDE_NEXT,
|
||||
XP_AWK_NDE_NEXTFILE
|
||||
XP_AWK_NDE_NEXTFILE,
|
||||
|
||||
/* expression */
|
||||
XP_AWK_NDE_ASS,
|
||||
XP_AWK_NDE_EXP_BIN,
|
||||
XP_AWK_NDE_EXP_UNR,
|
||||
XP_AWK_NDE_EXP_INCPRE,
|
||||
XP_AWK_NDE_EXP_INCPST,
|
||||
XP_AWK_NDE_CALL,
|
||||
XP_AWK_NDE_INT,
|
||||
XP_AWK_NDE_REAL,
|
||||
XP_AWK_NDE_STR,
|
||||
XP_AWK_NDE_NAMED,
|
||||
XP_AWK_NDE_GLOBAL,
|
||||
XP_AWK_NDE_LOCAL,
|
||||
XP_AWK_NDE_ARG,
|
||||
XP_AWK_NDE_NAMEDIDX,
|
||||
XP_AWK_NDE_GLOBALIDX,
|
||||
XP_AWK_NDE_LOCALIDX,
|
||||
XP_AWK_NDE_ARGIDX,
|
||||
XP_AWK_NDE_POS
|
||||
};
|
||||
|
||||
typedef struct xp_awk_func_t xp_awk_func_t;
|
||||
|
Loading…
Reference in New Issue
Block a user