*** empty log message ***
This commit is contained in:
parent
af6626d66a
commit
63fbbfedec
@ -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>
|
||||
@ -31,14 +31,15 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
|
||||
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_awk_hash_close (&awk->tree.funcs);
|
||||
if (awk->__dynamic) xp_free (awk);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
awk->opt = 0;
|
||||
awk->opt.parse = 0;
|
||||
awk->opt.run = 0;
|
||||
awk->errnum = XP_AWK_ENOERR;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
if (awk->__dynamic) xp_free (awk);
|
||||
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.
|
||||
// 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???
|
||||
@ -148,3 +194,4 @@ static void __free_func (void* func)
|
||||
xp_awk_clrpt (f->body);
|
||||
xp_free (f);
|
||||
}
|
||||
|
||||
|
@ -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_
|
||||
@ -21,6 +21,7 @@ enum
|
||||
{
|
||||
XP_AWK_ENOERR,
|
||||
XP_AWK_ENOMEM, /* out of memory */
|
||||
|
||||
XP_AWK_ESRCOP,
|
||||
XP_AWK_ESRCCL,
|
||||
XP_AWK_ESRCDT, /* error in reading source */
|
||||
@ -43,6 +44,7 @@ enum
|
||||
XP_AWK_EDUPBEGIN, /* duplicate BEGIN */
|
||||
XP_AWK_EDUPEND, /* duplicate END */
|
||||
XP_AWK_EDUPFUNC, /* duplicate function name */
|
||||
XP_AWK_EDUPPARAM, /* duplicate parameter name */
|
||||
XP_AWK_EDUPNAME /* duplicate name - function, variable, etc */
|
||||
};
|
||||
|
||||
@ -65,16 +67,21 @@ enum
|
||||
XP_AWK_IO_DATA
|
||||
};
|
||||
|
||||
/* options */
|
||||
/* parse options */
|
||||
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
|
||||
{
|
||||
/* options */
|
||||
int opt;
|
||||
struct
|
||||
{
|
||||
int parse;
|
||||
int run;
|
||||
} opt;
|
||||
|
||||
/* io functions */
|
||||
xp_awk_io_t src_func;
|
||||
@ -97,10 +104,9 @@ struct xp_awk_t
|
||||
/* temporary information that the parser needs */
|
||||
struct
|
||||
{
|
||||
xp_awk_tab_t funcs;
|
||||
// TODO: locals, globals???
|
||||
xp_char_t* vars; /* global and local variable names... */
|
||||
xp_char_t* args; /* function arguments */
|
||||
//xp_awk_tab_t vars; /* global and local variable names... */
|
||||
xp_awk_tab_t params;
|
||||
} parse;
|
||||
|
||||
/* 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_geterrnum (xp_awk_t* awk);
|
||||
const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk);
|
||||
|
||||
/*
|
||||
* FUNCTION: xp_awk_clear
|
||||
*/
|
||||
|
191
ase/awk/parse.c
191
ase/awk/parse.c
@ -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>
|
||||
@ -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 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_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 (__parse_progunit(awk) == XP_NULL) {
|
||||
// TODO: cleanup the parse tree created so far....
|
||||
// function tables also etc...
|
||||
xp_printf (XP_TEXT("error - %d\n"), awk->errnum);
|
||||
// TODO: cleanup the parse tree created so far....
|
||||
// function tables also etc...
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -294,62 +289,60 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
|
||||
xp_char_t* name_dup;
|
||||
xp_awk_node_t* body;
|
||||
xp_awk_func_t* func;
|
||||
xp_size_t fnpos;
|
||||
xp_size_t nargs = 0;
|
||||
xp_size_t nargs;
|
||||
|
||||
/* eat up the keyword 'function' and get the next token */
|
||||
if (__get_token(awk) == -1) return XP_NULL;
|
||||
|
||||
/* function name */
|
||||
if (!MATCH(awk,TOKEN_IDENT)) PANIC (awk, XP_AWK_EIDENT);
|
||||
|
||||
name = XP_STR_BUF(&awk->token.name);
|
||||
if (__find_func_name(awk,name) != (xp_size_t)-1) {
|
||||
// TODO: do i have to tell DUPFUNC from DUPNAME???
|
||||
//PANIC (awk, XP_AWK_EDUPFUNC);
|
||||
PANIC (awk, XP_AWK_EDUPNAME);
|
||||
/* match a function name */
|
||||
if (!MATCH(awk,TOKEN_IDENT)) {
|
||||
/* cannot find a valid identifier for a function name */
|
||||
PANIC (awk, XP_AWK_EIDENT);
|
||||
}
|
||||
|
||||
// TODO: make this feature optional..
|
||||
// find in the global variable list...
|
||||
name = XP_STR_BUF(&awk->token.name);
|
||||
if (xp_awk_hash_get(&awk->tree.funcs, name) != XP_NULL) {
|
||||
/* the function is defined previously */
|
||||
PANIC (awk, XP_AWK_EDUPFUNC);
|
||||
}
|
||||
|
||||
if (awk->opt.parse & XP_AWK_UNIQUE) {
|
||||
/* check if it coincides to be a variable name */
|
||||
if (__find_variable(awk,name) != (xp_size_t)-1) {
|
||||
PANIC (awk, XP_AWK_EDUPNAME);
|
||||
}
|
||||
|
||||
fnpos = __add_func_name (awk, name);
|
||||
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);
|
||||
if (name_dup == XP_NULL) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
PANIC (awk, XP_AWK_ENOMEM);
|
||||
}
|
||||
|
||||
/* skip the function name */
|
||||
/* clone the function name before it is overwritten */
|
||||
name_dup = xp_strdup (name);
|
||||
if (name_dup == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
|
||||
/* get the next token */
|
||||
if (__get_token(awk) == -1) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
xp_free (name_dup);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
/* match a left parenthesis */
|
||||
if (!MATCH(awk,TOKEN_LPAREN)) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
/* a function name is not followed by a left parenthesis */
|
||||
xp_free (name_dup);
|
||||
PANIC (awk, XP_AWK_ELPAREN);
|
||||
}
|
||||
|
||||
/* get the next token */
|
||||
if (__get_token(awk) == -1) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
xp_free (name_dup);
|
||||
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)) {
|
||||
/* no function parameter */
|
||||
/* no function parameter found. get the next token */
|
||||
if (__get_token(awk) == -1) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
xp_free (name_dup);
|
||||
return XP_NULL;
|
||||
}
|
||||
@ -357,70 +350,83 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
|
||||
else {
|
||||
while (1) {
|
||||
if (!MATCH(awk,TOKEN_IDENT)) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
xp_free (name_dup);
|
||||
xp_awk_tab_clear (&awk->parse.params);
|
||||
PANIC (awk, XP_AWK_EIDENT);
|
||||
}
|
||||
|
||||
nargs++;
|
||||
// TODO: push args to param list...
|
||||
// TODO: check duplicates againt variables if shading is not supported
|
||||
// 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) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
xp_free (name_dup);
|
||||
xp_awk_tab_clear (&awk->parse.params);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
if (MATCH(awk,TOKEN_RPAREN)) break;
|
||||
|
||||
if (!MATCH(awk,TOKEN_COMMA)) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
xp_free (name_dup);
|
||||
xp_awk_tab_clear (&awk->parse.params);
|
||||
PANIC (awk, XP_AWK_ECOMMA);
|
||||
}
|
||||
|
||||
if (__get_token(awk) == -1) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
xp_free (name_dup);
|
||||
xp_awk_tab_clear (&awk->parse.params);
|
||||
return XP_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (__get_token(awk) == -1) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
// TODO: cleanup parameter name list
|
||||
xp_free (name_dup);
|
||||
xp_awk_tab_clear (&awk->parse.params);
|
||||
return XP_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if the function body starts with a left brace */
|
||||
if (!MATCH(awk,TOKEN_LBRACE)) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
// TODO: cleanup parameter name list
|
||||
xp_free (name_dup);
|
||||
xp_awk_tab_clear (&awk->parse.params);
|
||||
PANIC (awk, XP_AWK_ELBRACE);
|
||||
}
|
||||
if (__get_token(awk) == -1) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
// TODO: cleanup parameter name list
|
||||
xp_free (name_dup);
|
||||
xp_awk_tab_clear (&awk->parse.params);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
/* actual function body */
|
||||
body = __parse_block (awk);
|
||||
if (body == XP_NULL) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
// TODO: cleanup parameter name list
|
||||
xp_free (name_dup);
|
||||
xp_awk_tab_clear (&awk->parse.params);
|
||||
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));
|
||||
if (func == XP_NULL) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
// TODO: cleanup parameter name list
|
||||
xp_free (name_dup);
|
||||
xp_awk_clrpt (body);
|
||||
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);
|
||||
if (xp_awk_hash_put(&awk->tree.funcs, name_dup, func) == XP_NULL) {
|
||||
__remove_func_name (awk, fnpos);
|
||||
xp_free (name_dup);
|
||||
xp_awk_clrpt (body);
|
||||
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;
|
||||
|
||||
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_POS) {
|
||||
// TODO: XP_AWK_NODE_ARG, XP_AWK_NODE_ARGIDX
|
||||
xp_awk_clrpt (x);
|
||||
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)
|
||||
{
|
||||
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));
|
||||
if (name == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
name_dup = (xp_char_t*)xp_strdup(XP_STR_BUF(&awk->token.name));
|
||||
if (name_dup == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
||||
|
||||
if (__get_token(awk) == -1) {
|
||||
xp_free (name);
|
||||
xp_free (name_dup);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
if (MATCH(awk,TOKEN_LBRACK)) {
|
||||
xp_awk_node_t* node;
|
||||
node = __parse_hashidx (awk, name);
|
||||
if (node == XP_NULL) xp_free (name);
|
||||
node = __parse_hashidx (awk, name_dup);
|
||||
if (node == XP_NULL) xp_free (name_dup);
|
||||
return (xp_awk_node_t*)node;
|
||||
}
|
||||
else if (MATCH(awk,TOKEN_LPAREN)) {
|
||||
/* function call */
|
||||
xp_awk_node_t* node;
|
||||
node = __parse_funcall (awk, name);
|
||||
if (node == XP_NULL) xp_free (name);
|
||||
node = __parse_funcall (awk, name_dup);
|
||||
if (node == XP_NULL) xp_free (name_dup);
|
||||
return (xp_awk_node_t*)node;
|
||||
}
|
||||
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));
|
||||
if (node == XP_NULL) {
|
||||
xp_free (name);
|
||||
xp_free (name_dup);
|
||||
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:
|
||||
idxa = __find_variable (awk, name);
|
||||
idxa = __find_variable (awk, name_dup);
|
||||
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) {
|
||||
node->type = XP_AWK_NODE_VAR;
|
||||
node->next = XP_NULL;
|
||||
node->id.name = name;
|
||||
node->id.name = name_dup;
|
||||
}
|
||||
else {
|
||||
node->type = XP_AWK_NODE_ARG;
|
||||
node->next = XP_NULL;
|
||||
// TODO: do i need to store the name here???
|
||||
node->id.name = name;
|
||||
node->id.name = name_dup;
|
||||
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->next = XP_NULL;
|
||||
// TODO: do i need to store the name here???
|
||||
node->id.name = name;
|
||||
node->id.name = name_dup;
|
||||
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_idx_t* node;
|
||||
xp_size_t idxa;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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->next = XP_NULL;
|
||||
node->id.name = name;
|
||||
@ -1770,23 +1804,6 @@ static xp_long_t __str_to_long (const xp_char_t* name)
|
||||
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)
|
||||
{
|
||||
/*
|
||||
|
@ -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>
|
||||
@ -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);
|
||||
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:
|
||||
xp_printf (XP_TEXT("%s"), ((xp_awk_node_var_t*)node)->id.name);
|
||||
break;
|
||||
@ -360,14 +372,29 @@ void xp_awk_clrpt (xp_awk_node_t* tree)
|
||||
xp_free (p);
|
||||
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:
|
||||
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_VARIDX:
|
||||
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);
|
||||
break;
|
||||
|
||||
|
@ -79,8 +79,10 @@ int xp_main (int argc, xp_char_t* argv[])
|
||||
}
|
||||
|
||||
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_printf (XP_TEXT("error: cannot parse program\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user