*** empty log message ***

This commit is contained in:
hyung-hwan 2006-01-31 16:57:45 +00:00
parent af6626d66a
commit 63fbbfedec
5 changed files with 205 additions and 102 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c,v 1.14 2006-01-30 14:45:12 bacon Exp $ * $Id: awk.c,v 1.15 2006-01-31 16:57:45 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -31,14 +31,15 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
return XP_NULL; return XP_NULL;
} }
if (xp_awk_tab_open(&awk->parse.funcs) == XP_NULL) { if (xp_awk_tab_open(&awk->parse.params) == XP_NULL) {
xp_str_close (&awk->token.name); xp_str_close (&awk->token.name);
xp_awk_hash_close (&awk->tree.funcs); xp_awk_hash_close (&awk->tree.funcs);
if (awk->__dynamic) xp_free (awk); if (awk->__dynamic) xp_free (awk);
return XP_NULL; return XP_NULL;
} }
awk->opt = 0; awk->opt.parse = 0;
awk->opt.run = 0;
awk->errnum = XP_AWK_ENOERR; awk->errnum = XP_AWK_ENOERR;
awk->src_func = XP_NULL; awk->src_func = XP_NULL;
@ -65,13 +66,58 @@ int xp_awk_close (xp_awk_t* awk)
if (xp_awk_detsrc(awk) == -1) return -1; if (xp_awk_detsrc(awk) == -1) return -1;
xp_awk_hash_close (&awk->tree.funcs); xp_awk_hash_close (&awk->tree.funcs);
xp_awk_tab_close (&awk->parse.funcs); xp_awk_tab_close (&awk->parse.params);
xp_str_close (&awk->token.name); xp_str_close (&awk->token.name);
if (awk->__dynamic) xp_free (awk); if (awk->__dynamic) xp_free (awk);
return 0; return 0;
} }
int xp_awk_geterrnum (xp_awk_t* awk)
{
return awk->errnum;
}
const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
{
static const xp_char_t* __errstr[] =
{
XP_TEXT("no error"),
XP_TEXT("out of memory"),
XP_TEXT("cannot open source"),
XP_TEXT("cannot close source"),
XP_TEXT("cannot read source"),
XP_TEXT("invalid character"),
XP_TEXT("cannot unget character"),
XP_TEXT("unexpected end of source"),
XP_TEXT("left brace expected"),
XP_TEXT("left parenthesis expected"),
XP_TEXT("right parenthesis expected"),
XP_TEXT("right bracket expected"),
XP_TEXT("comma expected"),
XP_TEXT("semicolon expected"),
XP_TEXT("expression expected"),
XP_TEXT("keyword 'while' expected"),
XP_TEXT("assignment statement expected"),
XP_TEXT("identifier expected"),
XP_TEXT("duplicate BEGIN"),
XP_TEXT("duplicate END"),
XP_TEXT("duplicate function name"),
XP_TEXT("duplicate parameter name"),
XP_TEXT("duplicate name"),
};
if (awk->errnum >= 0 && awk->errnum < xp_countof(__errstr)) {
return __errstr[awk->errnum];
}
return XP_TEXT("unknown error");
}
// TODO: write a function to clear awk->parse data structure. // TODO: write a function to clear awk->parse data structure.
// this would be need either as a separate function or as a part of xp_awk_clear... // this would be need either as a separate function or as a part of xp_awk_clear...
// do i have to pass an option to xp_awk_clear to do this??? // do i have to pass an option to xp_awk_clear to do this???
@ -148,3 +194,4 @@ static void __free_func (void* func)
xp_awk_clrpt (f->body); xp_awk_clrpt (f->body);
xp_free (f); xp_free (f);
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.22 2006-01-30 14:34:47 bacon Exp $ * $Id: awk.h,v 1.23 2006-01-31 16:57:45 bacon Exp $
*/ */
#ifndef _XP_AWK_AWK_H_ #ifndef _XP_AWK_AWK_H_
@ -21,6 +21,7 @@ enum
{ {
XP_AWK_ENOERR, XP_AWK_ENOERR,
XP_AWK_ENOMEM, /* out of memory */ XP_AWK_ENOMEM, /* out of memory */
XP_AWK_ESRCOP, XP_AWK_ESRCOP,
XP_AWK_ESRCCL, XP_AWK_ESRCCL,
XP_AWK_ESRCDT, /* error in reading source */ XP_AWK_ESRCDT, /* error in reading source */
@ -43,6 +44,7 @@ enum
XP_AWK_EDUPBEGIN, /* duplicate BEGIN */ XP_AWK_EDUPBEGIN, /* duplicate BEGIN */
XP_AWK_EDUPEND, /* duplicate END */ XP_AWK_EDUPEND, /* duplicate END */
XP_AWK_EDUPFUNC, /* duplicate function name */ XP_AWK_EDUPFUNC, /* duplicate function name */
XP_AWK_EDUPPARAM, /* duplicate parameter name */
XP_AWK_EDUPNAME /* duplicate name - function, variable, etc */ XP_AWK_EDUPNAME /* duplicate name - function, variable, etc */
}; };
@ -65,16 +67,21 @@ enum
XP_AWK_IO_DATA XP_AWK_IO_DATA
}; };
/* options */ /* parse options */
enum enum
{ {
XP_AWK_ASSIGN_ONLY /* a non-assignment expression cannot be used as a statement */ XP_AWK_EXPLICIT = (1 << 0), /* variable requires explicit declaration */
XP_AWK_UNIQUE = (1 << 1) /* a function name should not coincide to be a variable name */
}; };
struct xp_awk_t struct xp_awk_t
{ {
/* options */ /* options */
int opt; struct
{
int parse;
int run;
} opt;
/* io functions */ /* io functions */
xp_awk_io_t src_func; xp_awk_io_t src_func;
@ -97,10 +104,9 @@ struct xp_awk_t
/* temporary information that the parser needs */ /* temporary information that the parser needs */
struct struct
{ {
xp_awk_tab_t funcs;
// TODO: locals, globals??? // TODO: locals, globals???
xp_char_t* vars; /* global and local variable names... */ //xp_awk_tab_t vars; /* global and local variable names... */
xp_char_t* args; /* function arguments */ xp_awk_tab_t params;
} parse; } parse;
/* source buffer management */ /* source buffer management */
@ -137,6 +143,10 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk);
*/ */
int xp_awk_close (xp_awk_t* awk); int xp_awk_close (xp_awk_t* awk);
int xp_awk_geterrnum (xp_awk_t* awk);
const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk);
/* /*
* FUNCTION: xp_awk_clear * FUNCTION: xp_awk_clear
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.40 2006-01-30 14:45:12 bacon Exp $ * $Id: parse.c,v 1.41 2006-01-31 16:57:45 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -118,10 +118,6 @@ static int __classfy_ident (const xp_char_t* ident);
static xp_long_t __str_to_long (const xp_char_t* name); static xp_long_t __str_to_long (const xp_char_t* name);
static INLINE xp_size_t __add_func_name (xp_awk_t* awk, const xp_char_t* name);
static INLINE xp_size_t __find_func_name (xp_awk_t* awk, const xp_char_t* name);
static INLINE int __remove_func_name (xp_awk_t* awk, xp_size_t index);
static INLINE xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name); static INLINE xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name);
static INLINE xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name); static INLINE xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name);
@ -233,9 +229,8 @@ int xp_awk_parse (xp_awk_t* awk)
if (MATCH(awk,TOKEN_EOF)) break; if (MATCH(awk,TOKEN_EOF)) break;
if (__parse_progunit(awk) == XP_NULL) { if (__parse_progunit(awk) == XP_NULL) {
// TODO: cleanup the parse tree created so far.... // TODO: cleanup the parse tree created so far....
// function tables also etc... // function tables also etc...
xp_printf (XP_TEXT("error - %d\n"), awk->errnum);
return -1; return -1;
} }
} }
@ -294,62 +289,60 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
xp_char_t* name_dup; xp_char_t* name_dup;
xp_awk_node_t* body; xp_awk_node_t* body;
xp_awk_func_t* func; xp_awk_func_t* func;
xp_size_t fnpos; xp_size_t nargs;
xp_size_t nargs = 0;
/* eat up the keyword 'function' and get the next token */
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
/* function name */ /* match a function name */
if (!MATCH(awk,TOKEN_IDENT)) PANIC (awk, XP_AWK_EIDENT); if (!MATCH(awk,TOKEN_IDENT)) {
/* cannot find a valid identifier for a function name */
PANIC (awk, XP_AWK_EIDENT);
}
name = XP_STR_BUF(&awk->token.name); name = XP_STR_BUF(&awk->token.name);
if (__find_func_name(awk,name) != (xp_size_t)-1) { if (xp_awk_hash_get(&awk->tree.funcs, name) != XP_NULL) {
// TODO: do i have to tell DUPFUNC from DUPNAME??? /* the function is defined previously */
//PANIC (awk, XP_AWK_EDUPFUNC); PANIC (awk, XP_AWK_EDUPFUNC);
PANIC (awk, XP_AWK_EDUPNAME);
} }
// TODO: make this feature optional.. if (awk->opt.parse & XP_AWK_UNIQUE) {
// find in the global variable list... /* check if it coincides to be a variable name */
if (__find_variable(awk,name) != (xp_size_t)-1) { if (__find_variable(awk,name) != (xp_size_t)-1) {
PANIC (awk, XP_AWK_EDUPNAME); PANIC (awk, XP_AWK_EDUPNAME);
}
} }
fnpos = __add_func_name (awk, name); /* clone the function name before it is overwritten */
if (fnpos == -1) PANIC (awk, XP_AWK_ENOMEM);
// TODO: move this strdup down the function....
// maybe just before func_t is allocated...
name_dup = xp_strdup (name); name_dup = xp_strdup (name);
if (name_dup == XP_NULL) { if (name_dup == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
__remove_func_name (awk, fnpos);
PANIC (awk, XP_AWK_ENOMEM);
}
/* skip the function name */ /* get the next token */
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
__remove_func_name (awk, fnpos);
xp_free (name_dup); xp_free (name_dup);
return XP_NULL; return XP_NULL;
} }
/* match a left parenthesis */
if (!MATCH(awk,TOKEN_LPAREN)) { if (!MATCH(awk,TOKEN_LPAREN)) {
__remove_func_name (awk, fnpos); /* a function name is not followed by a left parenthesis */
xp_free (name_dup); xp_free (name_dup);
PANIC (awk, XP_AWK_ELPAREN); PANIC (awk, XP_AWK_ELPAREN);
} }
/* get the next token */
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
__remove_func_name (awk, fnpos);
xp_free (name_dup); xp_free (name_dup);
return XP_NULL; return XP_NULL;
} }
/* parameter name list */ /* make sure that parameter table is empty */
xp_assert (xp_awk_tab_getsize(&awk->parse.params) == 0);
/* read parameter list */
if (MATCH(awk,TOKEN_RPAREN)) { if (MATCH(awk,TOKEN_RPAREN)) {
/* no function parameter */ /* no function parameter found. get the next token */
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
__remove_func_name (awk, fnpos);
xp_free (name_dup); xp_free (name_dup);
return XP_NULL; return XP_NULL;
} }
@ -357,70 +350,83 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
else { else {
while (1) { while (1) {
if (!MATCH(awk,TOKEN_IDENT)) { if (!MATCH(awk,TOKEN_IDENT)) {
__remove_func_name (awk, fnpos);
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
PANIC (awk, XP_AWK_EIDENT); PANIC (awk, XP_AWK_EIDENT);
} }
nargs++; // TODO: check duplicates againt variables if shading is not supported
// TODO: push args to param list... // global x; function f (x) { print x; } -> x in print x is a parameter
if (xp_awk_tab_find (&awk->parse.params,
XP_STR_BUF(&awk->token.name), 0) != (xp_size_t)-1) {
xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
PANIC (awk, XP_AWK_EDUPPARAM);
}
if (xp_awk_tab_adddatum (&awk->parse.params,
XP_STR_BUF(&awk->token.name)) == (xp_size_t)-1) {
xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
PANIC (awk, XP_AWK_ENOMEM);
}
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
__remove_func_name (awk, fnpos);
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
return XP_NULL; return XP_NULL;
} }
if (MATCH(awk,TOKEN_RPAREN)) break; if (MATCH(awk,TOKEN_RPAREN)) break;
if (!MATCH(awk,TOKEN_COMMA)) { if (!MATCH(awk,TOKEN_COMMA)) {
__remove_func_name (awk, fnpos);
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
PANIC (awk, XP_AWK_ECOMMA); PANIC (awk, XP_AWK_ECOMMA);
} }
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
__remove_func_name (awk, fnpos);
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
return XP_NULL; return XP_NULL;
} }
} }
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
__remove_func_name (awk, fnpos);
// TODO: cleanup parameter name list
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
return XP_NULL; return XP_NULL;
} }
} }
/* check if the function body starts with a left brace */ /* check if the function body starts with a left brace */
if (!MATCH(awk,TOKEN_LBRACE)) { if (!MATCH(awk,TOKEN_LBRACE)) {
__remove_func_name (awk, fnpos);
// TODO: cleanup parameter name list
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
PANIC (awk, XP_AWK_ELBRACE); PANIC (awk, XP_AWK_ELBRACE);
} }
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
__remove_func_name (awk, fnpos);
// TODO: cleanup parameter name list
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
return XP_NULL; return XP_NULL;
} }
/* actual function body */ /* actual function body */
body = __parse_block (awk); body = __parse_block (awk);
if (body == XP_NULL) { if (body == XP_NULL) {
__remove_func_name (awk, fnpos);
// TODO: cleanup parameter name list
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
return XP_NULL; return XP_NULL;
} }
// TODO: consider if the parameters 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);
func = (xp_awk_func_t*) xp_malloc (xp_sizeof(xp_awk_func_t)); func = (xp_awk_func_t*) xp_malloc (xp_sizeof(xp_awk_func_t));
if (func == XP_NULL) { if (func == XP_NULL) {
__remove_func_name (awk, fnpos);
// TODO: cleanup parameter name list
xp_free (name_dup); xp_free (name_dup);
xp_awk_clrpt (body); xp_awk_clrpt (body);
return XP_NULL; return XP_NULL;
@ -432,7 +438,6 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
xp_assert (xp_awk_hash_get(&awk->tree.funcs, name_dup) == XP_NULL); xp_assert (xp_awk_hash_get(&awk->tree.funcs, name_dup) == XP_NULL);
if (xp_awk_hash_put(&awk->tree.funcs, name_dup, func) == XP_NULL) { if (xp_awk_hash_put(&awk->tree.funcs, name_dup, func) == XP_NULL) {
__remove_func_name (awk, fnpos);
xp_free (name_dup); xp_free (name_dup);
xp_awk_clrpt (body); xp_awk_clrpt (body);
xp_free (func); xp_free (func);
@ -696,10 +701,11 @@ static xp_awk_node_t* __parse_expression (xp_awk_t* awk)
if (!MATCH(awk,TOKEN_ASSIGN)) return x; if (!MATCH(awk,TOKEN_ASSIGN)) return x;
xp_assert (x->next == XP_NULL); xp_assert (x->next == XP_NULL);
if (x->type != XP_AWK_NODE_VAR && if (x->type != XP_AWK_NODE_ARG &&
x->type != XP_AWK_NODE_ARGIDX &&
x->type != XP_AWK_NODE_VAR &&
x->type != XP_AWK_NODE_VARIDX && x->type != XP_AWK_NODE_VARIDX &&
x->type != XP_AWK_NODE_POS) { x->type != XP_AWK_NODE_POS) {
// TODO: XP_AWK_NODE_ARG, XP_AWK_NODE_ARGIDX
xp_awk_clrpt (x); xp_awk_clrpt (x);
PANIC (awk, XP_AWK_EASSIGN); PANIC (awk, XP_AWK_EASSIGN);
} }
@ -880,27 +886,27 @@ static xp_awk_node_t* __parse_unary (xp_awk_t* awk)
static xp_awk_node_t* __parse_primary (xp_awk_t* awk) static xp_awk_node_t* __parse_primary (xp_awk_t* awk)
{ {
if (MATCH(awk,TOKEN_IDENT)) { if (MATCH(awk,TOKEN_IDENT)) {
xp_char_t* name; xp_char_t* name_dup;
name = (xp_char_t*)xp_strdup(XP_STR_BUF(&awk->token.name)); name_dup = (xp_char_t*)xp_strdup(XP_STR_BUF(&awk->token.name));
if (name == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); if (name_dup == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
xp_free (name); xp_free (name_dup);
return XP_NULL; return XP_NULL;
} }
if (MATCH(awk,TOKEN_LBRACK)) { if (MATCH(awk,TOKEN_LBRACK)) {
xp_awk_node_t* node; xp_awk_node_t* node;
node = __parse_hashidx (awk, name); node = __parse_hashidx (awk, name_dup);
if (node == XP_NULL) xp_free (name); if (node == XP_NULL) xp_free (name_dup);
return (xp_awk_node_t*)node; return (xp_awk_node_t*)node;
} }
else if (MATCH(awk,TOKEN_LPAREN)) { else if (MATCH(awk,TOKEN_LPAREN)) {
/* function call */ /* function call */
xp_awk_node_t* node; xp_awk_node_t* node;
node = __parse_funcall (awk, name); node = __parse_funcall (awk, name_dup);
if (node == XP_NULL) xp_free (name); if (node == XP_NULL) xp_free (name_dup);
return (xp_awk_node_t*)node; return (xp_awk_node_t*)node;
} }
else { else {
@ -910,24 +916,37 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk)
node = (xp_awk_node_var_t*)xp_malloc(xp_sizeof(xp_awk_node_var_t)); node = (xp_awk_node_var_t*)xp_malloc(xp_sizeof(xp_awk_node_var_t));
if (node == XP_NULL) { if (node == XP_NULL) {
xp_free (name); xp_free (name_dup);
PANIC (awk, XP_AWK_ENOMEM); PANIC (awk, XP_AWK_ENOMEM);
} }
/* search the parameter name list */
idxa = xp_awk_tab_find (&awk->parse.params, name_dup, 0);
if (idxa != (xp_size_t)-1) {
node->type = XP_AWK_NODE_ARG;
node->next = XP_NULL;
//node->id.name = XP_NULL;
node->id.name = name_dup;
node->id.idxa = idxa;
return (xp_awk_node_t*)node;
}
/* search the variable name list */
// TODO: // TODO:
idxa = __find_variable (awk, name); idxa = __find_variable (awk, name_dup);
if (idxa == (xp_size_t)-1) { if (idxa == (xp_size_t)-1) {
idxa = __find_func_arg (awk, name); idxa = __find_func_arg (awk, name_dup);
if (idxa == (xp_size_t)-1) { if (idxa == (xp_size_t)-1) {
node->type = XP_AWK_NODE_VAR; node->type = XP_AWK_NODE_VAR;
node->next = XP_NULL; node->next = XP_NULL;
node->id.name = name; node->id.name = name_dup;
} }
else { else {
node->type = XP_AWK_NODE_ARG; node->type = XP_AWK_NODE_ARG;
node->next = XP_NULL; node->next = XP_NULL;
// TODO: do i need to store the name here??? // TODO: do i need to store the name here???
node->id.name = name; node->id.name = name_dup;
node->id.idxa = idxa; node->id.idxa = idxa;
} }
} }
@ -936,7 +955,7 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk)
node->type = XP_AWK_NODE_VAR; node->type = XP_AWK_NODE_VAR;
node->next = XP_NULL; node->next = XP_NULL;
// TODO: do i need to store the name here??? // TODO: do i need to store the name here???
node->id.name = name; node->id.name = name_dup;
node->id.idxa = idxa; node->id.idxa = idxa;
} }
@ -1040,6 +1059,7 @@ static xp_awk_node_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name)
{ {
xp_awk_node_t* idx; xp_awk_node_t* idx;
xp_awk_node_idx_t* node; xp_awk_node_idx_t* node;
xp_size_t idxa;
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
@ -1062,6 +1082,20 @@ static xp_awk_node_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name)
PANIC (awk, XP_AWK_ENOMEM); PANIC (awk, XP_AWK_ENOMEM);
} }
/* search the parameter name list */
idxa = xp_awk_tab_find (&awk->parse.params, name, 0);
if (idxa != (xp_size_t)-1) {
node->type = XP_AWK_NODE_ARGIDX;
node->next = XP_NULL;
//node->id.name = XP_NULL;
node->id.name = name;
node->id.idxa = idxa;
node->idx = idx;
return (xp_awk_node_t*)node;
}
// TODO: search variable list
node->type = XP_AWK_NODE_VARIDX; node->type = XP_AWK_NODE_VARIDX;
node->next = XP_NULL; node->next = XP_NULL;
node->id.name = name; node->id.name = name;
@ -1770,23 +1804,6 @@ static xp_long_t __str_to_long (const xp_char_t* name)
return n; return n;
} }
static INLINE xp_size_t __add_func_name (xp_awk_t* awk, const xp_char_t* name)
{
xp_assert (__find_func_name(awk,name) == (xp_size_t)-1);
return xp_awk_tab_adddatum(&awk->parse.funcs, name);
}
static INLINE int __remove_func_name (xp_awk_t* awk, xp_size_t index)
{
return xp_awk_tab_remrange (&awk->parse.funcs, index, 1);
}
static INLINE xp_size_t __find_func_name (xp_awk_t* awk, const xp_char_t* name)
{
return xp_awk_tab_find(&awk->parse.funcs, name, 0);
}
static INLINE xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name) static INLINE xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name)
{ {
/* /*

View File

@ -1,5 +1,5 @@
/* /*
* $Id: tree.c,v 1.13 2006-01-28 06:38:01 bacon Exp $ * $Id: tree.c,v 1.14 2006-01-31 16:57:45 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -65,6 +65,18 @@ static int __print_expr_node (xp_awk_node_t* node)
xp_printf (XP_TEXT("%s"), ((xp_awk_node_term_t*)node)->value); xp_printf (XP_TEXT("%s"), ((xp_awk_node_term_t*)node)->value);
break; break;
case XP_AWK_NODE_ARG:
xp_printf (XP_TEXT("__arg%u"),
(unsigned int)((xp_awk_node_var_t*)node)->id.idxa);
break;
case XP_AWK_NODE_ARGIDX:
xp_printf (XP_TEXT("__arg%u["),
(unsigned int)((xp_awk_node_idx_t*)node)->id.idxa);
__print_expr_node (((xp_awk_node_idx_t*)node)->idx);
xp_printf (XP_TEXT("]"));
break;
case XP_AWK_NODE_VAR: case XP_AWK_NODE_VAR:
xp_printf (XP_TEXT("%s"), ((xp_awk_node_var_t*)node)->id.name); xp_printf (XP_TEXT("%s"), ((xp_awk_node_var_t*)node)->id.name);
break; break;
@ -360,14 +372,29 @@ void xp_awk_clrpt (xp_awk_node_t* tree)
xp_free (p); xp_free (p);
break; break;
case XP_AWK_NODE_ARG:
if (((xp_awk_node_var_t*)p)->id.name != XP_NULL)
xp_free (((xp_awk_node_var_t*)p)->id.name);
xp_free (p);
break;
case XP_AWK_NODE_ARGIDX:
xp_awk_clrpt (((xp_awk_node_idx_t*)p)->idx);
if (((xp_awk_node_var_t*)p)->id.name != XP_NULL)
xp_free (((xp_awk_node_var_t*)p)->id.name);
xp_free (p);
break;
case XP_AWK_NODE_VAR: case XP_AWK_NODE_VAR:
xp_free (((xp_awk_node_var_t*)p)->id.name); if (((xp_awk_node_var_t*)p)->id.name != XP_NULL)
xp_free (((xp_awk_node_var_t*)p)->id.name);
xp_free (p); xp_free (p);
break; break;
case XP_AWK_NODE_VARIDX: case XP_AWK_NODE_VARIDX:
xp_awk_clrpt (((xp_awk_node_idx_t*)p)->idx); xp_awk_clrpt (((xp_awk_node_idx_t*)p)->idx);
xp_free (((xp_awk_node_idx_t*)p)->id.name); if (((xp_awk_node_var_t*)p)->id.name != XP_NULL)
xp_free (((xp_awk_node_var_t*)p)->id.name);
xp_free (p); xp_free (p);
break; break;

View File

@ -79,8 +79,10 @@ int xp_main (int argc, xp_char_t* argv[])
} }
if (xp_awk_parse(&awk) == -1) { if (xp_awk_parse(&awk) == -1) {
xp_printf (
XP_TEXT("error: cannot parse program - [%d] %s\n"),
xp_awk_geterrnum(&awk), xp_awk_geterrstr(&awk));
xp_awk_close (&awk); xp_awk_close (&awk);
xp_printf (XP_TEXT("error: cannot parse program\n"));
return -1; return -1;
} }