*** 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>
|
#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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
189
ase/awk/parse.c
189
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>
|
#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)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user