*** empty log message ***

This commit is contained in:
hyung-hwan 2006-07-01 16:07:06 +00:00
parent 976c12d2bf
commit ea31037b6d
12 changed files with 148 additions and 116 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h,v 1.75 2006-06-30 11:31:50 bacon Exp $
* $Id: awk.h,v 1.76 2006-07-01 16:07:06 bacon Exp $
*/
#ifndef _XP_AWK_AWK_H_
@ -132,8 +132,9 @@ enum
XP_AWK_EOPERAND, /* invalid operand */
XP_AWK_ENOSUCHFUNC, /* no such function */
XP_AWK_ENOTASSIGNABLE, /* value not assignable */
XP_AWK_ENOTINDEXABLE, /* not indexable value */
XP_AWK_ENOTDELETABLE, /* not deletable value */
XP_AWK_ENOTINDEXABLE, /* not indexable variable */
XP_AWK_ENOTDELETABLE, /* not deletable variable */
XP_AWK_ENOTSCALARIZABLE, /* not scalarizable variable */
XP_AWK_EVALTYPE, /* wrong value type */
XP_AWK_EPIPE, /* pipe operation error */
XP_AWK_EIOIMPL, /* wrong implementation of user io handler */

View File

@ -1,5 +1,5 @@
/*
* $Id: awk_i.h,v 1.23 2006-06-30 04:18:47 bacon Exp $
* $Id: awk_i.h,v 1.24 2006-07-01 16:07:06 bacon Exp $
*/
#ifndef _XP_AWK_AWKI_H_
@ -151,8 +151,8 @@ struct xp_awk_run_t
xp_size_t stack_limit;
int exit_level;
xp_awk_val_int_t* icache[100]; /* TODO: ... */
xp_awk_val_real_t* rcache[100]; /* TODO: ... */
xp_awk_val_int_t* icache[100]; /* TODO: choose the optimal size */
xp_awk_val_real_t* rcache[100]; /* TODO: choose the optimal size */
xp_size_t icache_count;
xp_size_t rcache_count;

View File

@ -1,5 +1,5 @@
/*
* $Id: err.c,v 1.24 2006-06-30 11:31:50 bacon Exp $
* $Id: err.c,v 1.25 2006-07-01 16:07:06 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -64,8 +64,9 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
XP_T("invalid operand"),
XP_T("no such function"),
XP_T("value not assignable"),
XP_T("value not indexable"),
XP_T("value not deletable"),
XP_T("variable not indexable"),
XP_T("variable not deletable"),
XP_T("variable not scalarizable"),
XP_T("wrong value type"),
XP_T("pipe operation error"),
XP_T("wrong implementation of user-defined io handler"),

View File

@ -1,5 +1,5 @@
/*
* $Id: extio.c,v 1.16 2006-06-29 14:38:01 bacon Exp $
* $Id: extio.c,v 1.17 2006-07-01 16:07:06 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -240,7 +240,8 @@ int xp_awk_writeextio (
return -1;
}
/* TODO: optimize the buffer management. each xp_awk_run_t have a buffer for this operation??? */
/* TODO: optimize the buffer management.
* each xp_awk_run_t may have a buffer for this. */
if (xp_str_open (&buf, 256) == XP_NULL)
{
*errnum = XP_AWK_ENOMEM;

View File

@ -1,5 +1,5 @@
/*
* $Id: parse.c,v 1.130 2006-06-30 03:53:16 bacon Exp $
* $Id: parse.c,v 1.131 2006-07-01 16:07:06 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -81,9 +81,9 @@ enum
TOKEN_CONTINUE,
TOKEN_RETURN,
TOKEN_EXIT,
TOKEN_DELETE,
TOKEN_NEXT,
TOKEN_NEXTFILE,
TOKEN_DELETE,
TOKEN_PRINT,
TOKEN_PRINTF,
@ -157,11 +157,11 @@ static xp_awk_nde_t* __parse_break (xp_awk_t* awk);
static xp_awk_nde_t* __parse_continue (xp_awk_t* awk);
static xp_awk_nde_t* __parse_return (xp_awk_t* awk);
static xp_awk_nde_t* __parse_exit (xp_awk_t* awk);
static xp_awk_nde_t* __parse_next (xp_awk_t* awk);
static xp_awk_nde_t* __parse_nextfile (xp_awk_t* awk);
static xp_awk_nde_t* __parse_delete (xp_awk_t* awk);
static xp_awk_nde_t* __parse_print (xp_awk_t* awk);
static xp_awk_nde_t* __parse_printf (xp_awk_t* awk);
static xp_awk_nde_t* __parse_next (xp_awk_t* awk);
static xp_awk_nde_t* __parse_nextfile (xp_awk_t* awk);
static int __get_token (xp_awk_t* awk);
static int __get_number (xp_awk_t* awk);
@ -208,9 +208,9 @@ static struct __kwent __kwtab[] =
{ XP_T("continue"), TOKEN_CONTINUE, 0 },
{ XP_T("return"), TOKEN_RETURN, 0 },
{ XP_T("exit"), TOKEN_EXIT, 0 },
{ XP_T("delete"), TOKEN_DELETE, 0 },
{ XP_T("next"), TOKEN_NEXT, 0 },
{ XP_T("nextfile"), TOKEN_NEXTFILE, 0 },
{ XP_T("delete"), TOKEN_DELETE, 0 },
{ XP_T("print"), TOKEN_PRINT, XP_AWK_EXTIO },
{ XP_T("printf"), TOKEN_PRINTF, XP_AWK_EXTIO },
@ -667,7 +667,8 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk)
return XP_NULL;
}
/* TODO: consider if the parameter names should be saved for some reasons.. */
/* TODO: study furthur if the parameter names should be saved
* for some reasons */
nargs = xp_awk_tab_getsize (&awk->parse.params);
/* parameter names are not required anymore. clear them */
xp_awk_tab_clear (&awk->parse.params);
@ -1084,11 +1085,6 @@ static xp_awk_nde_t* __parse_statement_nb (xp_awk_t* awk)
if (__get_token(awk) == -1) return XP_NULL;
nde = __parse_exit (awk);
}
else if (MATCH(awk,TOKEN_DELETE))
{
if (__get_token(awk) == -1) return XP_NULL;
nde = __parse_delete(awk);
}
else if (MATCH(awk,TOKEN_NEXT))
{
if (__get_token(awk) == -1) return XP_NULL;
@ -1099,6 +1095,11 @@ static xp_awk_nde_t* __parse_statement_nb (xp_awk_t* awk)
if (__get_token(awk) == -1) return XP_NULL;
nde = __parse_nextfile (awk);
}
else if (MATCH(awk,TOKEN_DELETE))
{
if (__get_token(awk) == -1) return XP_NULL;
nde = __parse_delete (awk);
}
else if (MATCH(awk,TOKEN_PRINT))
{
if (__get_token(awk) == -1) return XP_NULL;
@ -1542,7 +1543,7 @@ static xp_awk_nde_t* __parse_bitwise_or_with_extio (xp_awk_t* awk)
return XP_NULL;
}
/* TODO: some constant folding */
/* TODO: do constant folding */
nde = (xp_awk_nde_exp_t*)
xp_malloc (xp_sizeof(xp_awk_nde_exp_t));
@ -1635,7 +1636,7 @@ static xp_awk_nde_t* __parse_concat (xp_awk_t* awk)
if (left == XP_NULL) return XP_NULL;
/* TODO: write a better code to do this....
* first of all, is the following check sufficient??? */
* first of all, is the following check sufficient? */
while (MATCH(awk,TOKEN_LPAREN) || awk->token.type >= TOKEN_GETLINE)
{
right = __parse_additive (awk);
@ -3492,7 +3493,7 @@ static int __get_string (xp_awk_t* awk)
if (c == XP_T('n')) c = XP_T('\n');
else if (c == XP_T('r')) c = XP_T('\r');
else if (c == XP_T('t')) c = XP_T('\t');
/* TODO: more escape characters */
/* TODO: add more escape characters */
escaped = xp_false;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c,v 1.120 2006-07-01 07:57:10 bacon Exp $
* $Id: run.c,v 1.121 2006-07-01 16:07:06 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -26,12 +26,16 @@
/*#define STACK_RETVAL_GLOBAL(run) ((run)->stack[(run)->nglobals+2])*/
#define STACK_RETVAL_GLOBAL(run) ((run)->stack[(run)->awk->tree.nglobals+2])
#define EXIT_NONE 0
#define EXIT_BREAK 1
#define EXIT_CONTINUE 2
#define EXIT_FUNCTION 3
#define EXIT_GLOBAL 4
#define EXIT_ABORT 5
enum
{
EXIT_NONE,
EXIT_BREAK,
EXIT_CONTINUE,
EXIT_FUNCTION,
EXIT_NEXT,
EXIT_GLOBAL,
EXIT_ABORT,
};
#define PANIC(run,code) \
do { (run)->errnum = (code); return XP_NULL; } while (0)
@ -415,12 +419,13 @@ static int __run_main (xp_awk_run_t* run)
/* stack set up properly. ready to exeucte statement blocks */
if (n == 0 && run->awk->tree.begin != XP_NULL)
{
xp_assert (run->awk->tree.begin->type == XP_AWK_NDE_BLK);
xp_awk_nde_blk_t* blk;
blk = (xp_awk_nde_blk_t*)run->awk->tree.begin;
xp_assert (blk->type == XP_AWK_NDE_BLK);
run->exit_level = EXIT_NONE;
if (__run_block (run,
(xp_awk_nde_blk_t*)run->awk->tree.begin) == -1) n = -1;
if (__run_block (run, blk) == -1) n = -1;
}
if (n == 0 && run->txtio != XP_NULL)
@ -430,12 +435,13 @@ static int __run_main (xp_awk_run_t* run)
if (n == 0 && run->awk->tree.end != XP_NULL)
{
xp_assert (run->awk->tree.end->type == XP_AWK_NDE_BLK);
xp_awk_nde_blk_t* blk;
blk = (xp_awk_nde_blk_t*)run->awk->tree.end;
xp_assert (blk->type == XP_AWK_NDE_BLK);
run->exit_level = EXIT_NONE;
if (__run_block (run,
(xp_awk_nde_blk_t*)run->awk->tree.end) == -1) n = -1;
if (__run_block (run, blk) == -1) n = -1;
}
/* restore stack */
@ -511,12 +517,6 @@ static int __run_pattern_blocks (xp_awk_run_t* run)
if (x == 0) break; /* end of input */
/*
xp_printf (XP_T("**** line [%s]\n"), XP_STR_BUF(&run->input.line));
*/
/* for each block { run it }
* TODO: handle according if next and nextfile has been called
*/
if (__run_pattern_block_chain (run, run->awk->tree.chain) == -1)
{
/* don't care about the result of input close */
@ -536,14 +536,24 @@ static int __run_pattern_block_chain (xp_awk_run_t* run, xp_awk_chain_t* chain)
{
xp_awk_nde_t* ptn;
while (chain != XP_NULL)
while (run->exit_level != EXIT_GLOBAL &&
run->exit_level != EXIT_ABORT && chain != XP_NULL)
{
if (run->exit_level == EXIT_NEXT)
{
run->exit_level = EXIT_NONE;
break;
}
ptn = chain->pattern;
if (ptn == XP_NULL)
{
/* just execute the block */
if (__run_block (run, (xp_awk_nde_blk_t*)chain->action) == -1) return -1;
xp_awk_nde_blk_t* blk;
blk = (xp_awk_nde_blk_t*)chain->action;
if (__run_block (run, blk) == -1) return -1;
}
else
{
@ -558,7 +568,9 @@ static int __run_pattern_block_chain (xp_awk_run_t* run, xp_awk_chain_t* chain)
{
if (xp_awk_valtobool(v1))
{
if (__run_block (run, (xp_awk_nde_blk_t*)chain->action) == -1)
xp_awk_nde_blk_t* blk;
blk = (xp_awk_nde_blk_t*)chain->action;
if (__run_block (run, blk) == -1)
{
xp_awk_refdownval (run, v1);
return -1;
@ -1074,15 +1086,16 @@ static int __run_exit (xp_awk_run_t* run, xp_awk_nde_exit_t* nde)
static int __run_next (xp_awk_run_t* run, xp_awk_nde_next_t* nde)
{
/* TODO */
xp_printf (XP_T("**** next NOT IMPLEMENTED...\n"));
return -1;
/* TODO: trigger an error if "next" is called from BEGIN or END */
run->exit_level = EXIT_NEXT;
return 0;
}
static int __run_nextfile (xp_awk_run_t* run, xp_awk_nde_nextfile_t* nde)
{
xp_ssize_t n;
/* TODO: implement this properly */
/* TODO: how to pass opt properly for IO_NEXT??? -> READ? WRITE? */
n = run->txtio (XP_AWK_IO_NEXT, 0, run->txtio_arg, XP_NULL, 0);
if (n == -1) PANIC_I (run, XP_AWK_ETXTINNEXT);
@ -1095,7 +1108,6 @@ static int __run_delete (xp_awk_run_t* run, xp_awk_nde_delete_t* nde)
var = (xp_awk_nde_var_t*) nde->var;
xp_printf (XP_T("********** __run_delete **************\n"));
if (var->type == XP_AWK_NDE_NAMED ||
var->type == XP_AWK_NDE_NAMEDIDX)
{
@ -1137,7 +1149,6 @@ xp_printf (XP_T("********** __run_delete **************\n"));
if (val->type != XP_AWK_VAL_MAP)
PANIC_I (run, XP_AWK_ENOTDELETABLE);
xp_printf (XP_T("clearing map...\n"));
map = ((xp_awk_val_map_t*)val)->map;
if (var->type == XP_AWK_NDE_NAMEDIDX)
{
@ -1174,7 +1185,6 @@ xp_printf (XP_T("clearing map...\n"));
{
xp_awk_val_t* val;
xp_printf (XP_T("clearing global/local/arg...\n"));
if (var->type == XP_AWK_NDE_GLOBAL ||
var->type == XP_AWK_NDE_GLOBALIDX)
val = STACK_GLOBAL (run,var->id.idxa);
@ -1214,7 +1224,6 @@ xp_printf (XP_T("clearing global/local/arg...\n"));
if (val->type != XP_AWK_VAL_MAP)
PANIC_I (run, XP_AWK_ENOTDELETABLE);
xp_printf (XP_T("clearing map...\n"));
map = ((xp_awk_val_map_t*)val)->map;
if (var->type == XP_AWK_NDE_GLOBALIDX ||
var->type == XP_AWK_NDE_LOCALIDX ||
@ -1494,9 +1503,18 @@ static xp_awk_val_t* __do_assignment (
if (var->type == XP_AWK_NDE_NAMED)
{
xp_awk_pair_t* pair;
int n;
/* TODO: need to check if the old value is a map?? prevent the assignment? */
pair = xp_awk_map_get (&run->named, var->id.name);
if (pair != XP_NULL &&
((xp_awk_val_t*)pair->val)->type == XP_AWK_VAL_MAP)
{
/* once a variable becomes an array,
* it cannot be changed to a scalar variable */
PANIC (run, XP_AWK_ENOTSCALARIZABLE);
}
n = xp_awk_map_putx (
&run->named, var->id.name, val, XP_NULL);
if (n < 0) PANIC (run, XP_AWK_ENOMEM);
@ -1505,22 +1523,43 @@ static xp_awk_val_t* __do_assignment (
}
else if (var->type == XP_AWK_NDE_GLOBAL)
{
/* TODO: need to check if the old value is a map?? prevent the assignment? */
xp_awk_refdownval (run, STACK_GLOBAL(run,var->id.idxa));
xp_awk_val_t* old = STACK_GLOBAL(run,var->id.idxa);
if (old->type == XP_AWK_VAL_MAP)
{
/* once a variable becomes an array,
* it cannot be changed to a scalar variable */
PANIC (run, XP_AWK_ENOTSCALARIZABLE);
}
xp_awk_refdownval (run, old);
STACK_GLOBAL(run,var->id.idxa) = val;
xp_awk_refupval (val);
}
else if (var->type == XP_AWK_NDE_LOCAL)
{
/* TODO: need to check if the old value is a map?? prevent the assignment? */
xp_awk_refdownval (run, STACK_LOCAL(run,var->id.idxa));
xp_awk_val_t* old = STACK_LOCAL(run,var->id.idxa);
if (old->type == XP_AWK_VAL_MAP)
{
/* once the variable becomes an array,
* it cannot be changed to a scalar variable */
PANIC (run, XP_AWK_ENOTSCALARIZABLE);
}
xp_awk_refdownval (run, old);
STACK_LOCAL(run,var->id.idxa) = val;
xp_awk_refupval (val);
}
else if (var->type == XP_AWK_NDE_ARG)
{
/* TODO: need to check if the old value is a map?? prevent the assignment? */
xp_awk_refdownval (run, STACK_ARG(run,var->id.idxa));
xp_awk_val_t* old = STACK_ARG(run,var->id.idxa);
if (old->type == XP_AWK_VAL_MAP)
{
/* once the variable becomes an array,
* it cannot be changed to a scalar variable */
PANIC (run, XP_AWK_ENOTSCALARIZABLE);
}
xp_awk_refdownval (run, old);
STACK_ARG(run,var->id.idxa) = val;
xp_awk_refupval (val);
}
@ -3306,7 +3345,7 @@ static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde)
dst = (in == XP_NULL)? XP_T(""): in;
/* TODO: optimization in line buffer management */
/* TODO: optimize the line buffer management */
if (xp_str_open (&buf, DEF_BUF_CAPA) == XP_NULL)
{
if (in != XP_NULL) xp_free (in);

View File

@ -1,5 +1,5 @@
/*
* $Id: tree.c,v 1.62 2006-07-01 07:57:10 bacon Exp $
* $Id: tree.c,v 1.63 2006-07-01 16:07:06 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -367,7 +367,6 @@ static int __print_expression (xp_awk_nde_t* nde)
case XP_AWK_NDE_GETLINE:
{
/* TODO */
xp_awk_nde_getline_t* px = (xp_awk_nde_getline_t*)nde;
if (px->in != XP_NULL &&
(px->in_type == XP_AWK_IN_PIPE ||

View File

@ -1,5 +1,5 @@
/*
* $Id: tree.h,v 1.56 2006-07-01 07:57:10 bacon Exp $
* $Id: tree.h,v 1.57 2006-07-01 16:07:06 bacon Exp $
*/
#ifndef _XP_AWK_TREE_H_
@ -204,7 +204,7 @@ struct xp_awk_nde_str_t
struct xp_awk_nde_rex_t
{
XP_AWK_NDE_HDR;
/* TODO: */
/* TODO: implement the regular expression value node */
xp_char_t* buf;
xp_size_t len;
};

View File

@ -1,5 +1,5 @@
/*
* $Id: val.c,v 1.34 2006-06-30 16:46:34 bacon Exp $
* $Id: val.c,v 1.35 2006-07-01 16:07:06 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -129,7 +129,7 @@ xp_awk_val_t* xp_awk_makerexval (const xp_char_t* str, xp_size_t len)
{
xp_awk_val_rex_t* val;
/* TDOO: XXXXXXXXXXXXXX */
/* TDOO: implement the regular expression value */
val = (xp_awk_val_rex_t*) xp_malloc (xp_sizeof(xp_awk_val_rex_t));
if (val == XP_NULL) return XP_NULL;
@ -222,7 +222,7 @@ xp_printf (XP_T("\n"));*/
return;
case XP_AWK_VAL_REX:
/* TODO: XXXX */
/* TODO: implement the regular expression value properly */
xp_free (((xp_awk_val_rex_t*)val)->buf);
xp_free (val);
return;
@ -279,31 +279,6 @@ void xp_awk_refdownval_nofree (xp_awk_run_t* run, xp_awk_val_t* val)
val->ref--;
}
xp_awk_val_t* xp_awk_cloneval (xp_awk_run_t* run, xp_awk_val_t* val)
{
if (val == XP_NULL) return xp_awk_val_nil;
switch (val->type)
{
case XP_AWK_VAL_NIL:
return xp_awk_val_nil;
case XP_AWK_VAL_INT:
return xp_awk_makeintval (run, ((xp_awk_val_int_t*)val)->val);
case XP_AWK_VAL_REAL:
return xp_awk_makerealval (run, ((xp_awk_val_real_t*)val)->val);
case XP_AWK_VAL_STR:
return xp_awk_makestrval (
((xp_awk_val_str_t*)val)->buf,
((xp_awk_val_str_t*)val)->len);
case XP_AWK_VAL_MAP:
/* TODO: .... */
return XP_NULL;
}
xp_assert (!"should never happen - invalid value type");
return XP_NULL;
}
xp_bool_t xp_awk_valtobool (xp_awk_val_t* val)
{
if (val == XP_NULL) return xp_false;

View File

@ -1,5 +1,5 @@
/*
* $Id: val.h,v 1.26 2006-06-30 16:46:34 bacon Exp $
* $Id: val.h,v 1.27 2006-07-01 16:07:06 bacon Exp $
*/
#ifndef _XP_AWK_VAL_H_
@ -111,8 +111,6 @@ void xp_awk_refupval (xp_awk_val_t* val);
void xp_awk_refdownval (xp_awk_run_t* run, xp_awk_val_t* val);
void xp_awk_refdownval_nofree (xp_awk_run_t* run, xp_awk_val_t* val);
xp_awk_val_t* xp_awk_cloneval (xp_awk_run_t* run, xp_awk_val_t* val);
xp_bool_t xp_awk_valtobool (xp_awk_val_t* val);
xp_char_t* xp_awk_valtostr (xp_awk_val_t* val, int* errnum, xp_str_t* buf);

View File

@ -7,6 +7,7 @@ BEGIN
//a[1] = 20;
//a[2] = 30;
/*
b["xxx"] = 20;
b["yyy"] = 30;
b[1] = 30;
@ -14,5 +15,9 @@ BEGIN
delete a;
delete b["1"];
*/
c[1] = 20;
c[1] = "aaa";
c = 30;
}

12
ase/test/awk/t14.awk Normal file
View File

@ -0,0 +1,12 @@
{
print "1111111111111";
}
{
print "22222222222222";
next;
}
{
print "33333333333333333";
}