*** empty log message ***

This commit is contained in:
hyung-hwan 2006-02-04 19:31:51 +00:00
parent 3f31c110cd
commit a4264220ed
6 changed files with 206 additions and 99 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c,v 1.16 2006-02-01 02:56:12 bacon Exp $ * $Id: awk.c,v 1.17 2006-02-04 19:31:51 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -31,9 +31,26 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
return XP_NULL; return XP_NULL;
} }
if (xp_awk_tab_open(&awk->parse.globals) == XP_NULL) {
xp_str_close (&awk->token.name);
xp_awk_hash_close (&awk->tree.funcs);
if (awk->__dynamic) xp_free (awk);
return XP_NULL;
}
if (xp_awk_tab_open(&awk->parse.locals) == XP_NULL) {
xp_str_close (&awk->token.name);
xp_awk_hash_close (&awk->tree.funcs);
xp_awk_tab_close (&awk->parse.globals);
if (awk->__dynamic) xp_free (awk);
return XP_NULL;
}
if (xp_awk_tab_open(&awk->parse.params) == 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);
xp_awk_tab_close (&awk->parse.globals);
xp_awk_tab_close (&awk->parse.locals);
if (awk->__dynamic) xp_free (awk); if (awk->__dynamic) xp_free (awk);
return XP_NULL; return XP_NULL;
} }
@ -50,6 +67,8 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
awk->in_arg = XP_NULL; awk->in_arg = XP_NULL;
awk->out_arg = XP_NULL; awk->out_arg = XP_NULL;
awk->parse.nlocals_max = 0;
awk->tree.begin = XP_NULL; awk->tree.begin = XP_NULL;
awk->tree.end = XP_NULL; awk->tree.end = XP_NULL;
awk->tree.unnamed = XP_NULL; awk->tree.unnamed = XP_NULL;
@ -66,6 +85,8 @@ 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.globals);
xp_awk_tab_close (&awk->parse.locals);
xp_awk_tab_close (&awk->parse.params); xp_awk_tab_close (&awk->parse.params);
xp_str_close (&awk->token.name); xp_str_close (&awk->token.name);
@ -108,6 +129,7 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
XP_TEXT("duplicate END"), XP_TEXT("duplicate END"),
XP_TEXT("duplicate function name"), XP_TEXT("duplicate function name"),
XP_TEXT("duplicate parameter name"), XP_TEXT("duplicate parameter name"),
XP_TEXT("duplicate variable name"),
XP_TEXT("duplicate name"), XP_TEXT("duplicate name"),
}; };
@ -124,6 +146,11 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
void xp_awk_clear (xp_awk_t* awk) void xp_awk_clear (xp_awk_t* awk)
{ {
xp_awk_tab_clear (&awk->parse.globals);
xp_awk_tab_clear (&awk->parse.locals);
xp_awk_tab_clear (&awk->parse.params);
awk->parse.nlocals_max = 0;
/* clear parse trees */ /* clear parse trees */
xp_awk_hash_clear (&awk->tree.funcs); xp_awk_hash_clear (&awk->tree.funcs);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.23 2006-01-31 16:57:45 bacon Exp $ * $Id: awk.h,v 1.24 2006-02-04 19:31:51 bacon Exp $
*/ */
#ifndef _XP_AWK_AWK_H_ #ifndef _XP_AWK_AWK_H_
@ -45,6 +45,7 @@ enum
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_EDUPPARAM, /* duplicate parameter name */
XP_AWK_EDUPVAR, /* duplicate variable name */
XP_AWK_EDUPNAME /* duplicate name - function, variable, etc */ XP_AWK_EDUPNAME /* duplicate name - function, variable, etc */
}; };
@ -71,7 +72,8 @@ enum
enum enum
{ {
XP_AWK_EXPLICIT = (1 << 0), /* variable requires explicit declaration */ 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 */ XP_AWK_UNIQUE = (1 << 1), /* a function name should not coincide to be a variable name */
XP_AWK_SHADING = (1 << 2) /* allow variable shading */
}; };
struct xp_awk_t struct xp_awk_t
@ -104,9 +106,10 @@ struct xp_awk_t
/* temporary information that the parser needs */ /* temporary information that the parser needs */
struct struct
{ {
// TODO: locals, globals??? xp_awk_tab_t globals;
//xp_awk_tab_t vars; /* global and local variable names... */ xp_awk_tab_t locals;
xp_awk_tab_t params; xp_awk_tab_t params;
xp_size_t nlocals_max;
} parse; } parse;
/* source buffer management */ /* source buffer management */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.42 2006-02-01 02:56:12 bacon Exp $ * $Id: parse.c,v 1.43 2006-02-04 19:31:51 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -87,7 +87,8 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk);
static xp_awk_node_t* __parse_begin (xp_awk_t* awk); static xp_awk_node_t* __parse_begin (xp_awk_t* awk);
static xp_awk_node_t* __parse_end (xp_awk_t* awk); static xp_awk_node_t* __parse_end (xp_awk_t* awk);
static xp_awk_node_t* __parse_action (xp_awk_t* awk); static xp_awk_node_t* __parse_action (xp_awk_t* awk);
static xp_awk_node_t* __parse_block (xp_awk_t* awk); static xp_awk_node_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top);
static xp_awk_t* __collect_locals (xp_awk_t* awk, xp_size_t nlocals);
static xp_awk_node_t* __parse_statement (xp_awk_t* awk); static xp_awk_node_t* __parse_statement (xp_awk_t* awk);
static xp_awk_node_t* __parse_statement_nb (xp_awk_t* awk); static xp_awk_node_t* __parse_statement_nb (xp_awk_t* awk);
static xp_awk_node_t* __parse_expression (xp_awk_t* awk); static xp_awk_node_t* __parse_expression (xp_awk_t* awk);
@ -114,43 +115,42 @@ static int __get_char (xp_awk_t* awk);
static int __unget_char (xp_awk_t* awk, xp_cint_t c); static int __unget_char (xp_awk_t* awk, xp_cint_t c);
static int __skip_spaces (xp_awk_t* awk); static int __skip_spaces (xp_awk_t* awk);
static int __skip_comment (xp_awk_t* awk); static int __skip_comment (xp_awk_t* awk);
static int __classfy_ident (const xp_char_t* ident); static int __classify_ident (xp_awk_t* awk, 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 __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);
struct __kwent struct __kwent
{ {
const xp_char_t* name; const xp_char_t* name;
int type; int type;
int valid; /* the entry is valid when this option is set */
}; };
static struct __kwent __kwtab[] = static struct __kwent __kwtab[] =
{ {
{ XP_TEXT("BEGIN"), TOKEN_BEGIN }, { XP_TEXT("BEGIN"), TOKEN_BEGIN, 0 },
{ XP_TEXT("END"), TOKEN_END }, { XP_TEXT("END"), TOKEN_END, 0 },
{ XP_TEXT("function"), TOKEN_FUNCTION }, { XP_TEXT("function"), TOKEN_FUNCTION, 0 },
{ XP_TEXT("if"), TOKEN_IF }, { XP_TEXT("if"), TOKEN_IF, 0 },
{ XP_TEXT("else"), TOKEN_ELSE }, { XP_TEXT("else"), TOKEN_ELSE, 0 },
{ XP_TEXT("while"), TOKEN_WHILE }, { XP_TEXT("while"), TOKEN_WHILE, 0 },
{ XP_TEXT("for"), TOKEN_FOR }, { XP_TEXT("for"), TOKEN_FOR, 0 },
{ XP_TEXT("do"), TOKEN_DO }, { XP_TEXT("do"), TOKEN_DO, 0 },
{ XP_TEXT("break"), TOKEN_BREAK }, { XP_TEXT("break"), TOKEN_BREAK, 0 },
{ XP_TEXT("continue"), TOKEN_CONTINUE }, { XP_TEXT("continue"), TOKEN_CONTINUE, 0 },
{ XP_TEXT("return"), TOKEN_RETURN }, { XP_TEXT("return"), TOKEN_RETURN, 0 },
{ XP_TEXT("exit"), TOKEN_EXIT }, { XP_TEXT("exit"), TOKEN_EXIT, 0 },
{ XP_TEXT("delete"), TOKEN_DELETE }, { XP_TEXT("delete"), TOKEN_DELETE, 0 },
{ XP_TEXT("next"), TOKEN_NEXT }, { XP_TEXT("next"), TOKEN_NEXT, 0 },
{ XP_TEXT("nextfile"), TOKEN_NEXTFILE }, { XP_TEXT("nextfile"), TOKEN_NEXTFILE, 0 },
// TODO: don't return TOKEN_LOCAL & TOKEN_GLOBAL when explicit variable declaration is disabled. { XP_TEXT("local"), TOKEN_LOCAL, XP_AWK_EXPLICIT },
{ XP_TEXT("local"), TOKEN_LOCAL }, { XP_TEXT("global"), TOKEN_GLOBAL, XP_AWK_EXPLICIT },
{ XP_TEXT("global"), TOKEN_GLOBAL },
{ XP_NULL, 0 }, { XP_NULL, 0, 0 }
}; };
#define GET_CHAR(awk) \ #define GET_CHAR(awk) \
@ -184,7 +184,6 @@ static struct __kwent __kwtab[] =
#define PANIC(awk,code) do { (awk)->errnum = (code); return XP_NULL; } while (0); #define PANIC(awk,code) do { (awk)->errnum = (code); return XP_NULL; } while (0);
// TODO: remove stdio.h // TODO: remove stdio.h
#ifndef __STAND_ALONE #ifndef __STAND_ALONE
#include <xp/bas/stdio.h> #include <xp/bas/stdio.h>
@ -215,6 +214,8 @@ static void __dump (xp_awk_t* awk)
xp_printf (XP_TEXT("END ")); xp_printf (XP_TEXT("END "));
xp_awk_prnpt (awk->tree.end); xp_awk_prnpt (awk->tree.end);
} }
// TODO: dump unmaed top-level blocks...
} }
int xp_awk_parse (xp_awk_t* awk) int xp_awk_parse (xp_awk_t* awk)
@ -307,8 +308,8 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
} }
if (awk->opt.parse & XP_AWK_UNIQUE) { if (awk->opt.parse & XP_AWK_UNIQUE) {
/* check if it coincides to be a variable name */ /* check if it coincides to be a global variable name */
if (__find_variable(awk,name) != (xp_size_t)-1) { if (xp_awk_tab_find(&awk->parse.globals, name, 0) != (xp_size_t)-1) {
PANIC (awk, XP_AWK_EDUPNAME); PANIC (awk, XP_AWK_EDUPNAME);
} }
} }
@ -349,24 +350,41 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
} }
else { else {
while (1) { while (1) {
xp_char_t* param;
if (!MATCH(awk,TOKEN_IDENT)) { if (!MATCH(awk,TOKEN_IDENT)) {
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params); xp_awk_tab_clear (&awk->parse.params);
PANIC (awk, XP_AWK_EIDENT); PANIC (awk, XP_AWK_EIDENT);
} }
// TODO: check duplicates againt variables if shading is not supported param = XP_STR_BUF(&awk->token.name);
// global x; function f (x) { print x; } -> x in print x is a parameter
if (xp_awk_tab_find (&awk->parse.params, if (awk->opt.parse & XP_AWK_UNIQUE) {
XP_STR_BUF(&awk->token.name), 0) != (xp_size_t)-1) { /* check if a parameter conflicts with a function */
if (xp_strcmp(name_dup, param) == 0 ||
xp_awk_hash_get(&awk->tree.funcs, param) != XP_NULL) {
xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params);
PANIC (awk, XP_AWK_EDUPNAME);
}
/* NOTE: the following is not a conflict
* global x;
* function f (x) { print x; }
* x in print x is a parameter
*/
}
/* check if a parameter conflicts with other parameters */
if (xp_awk_tab_find(&awk->parse.params, param, 0) != (xp_size_t)-1) {
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params); xp_awk_tab_clear (&awk->parse.params);
PANIC (awk, XP_AWK_EDUPPARAM); PANIC (awk, XP_AWK_EDUPPARAM);
} }
if (xp_awk_tab_adddatum (&awk->parse.params, /* push the parameter to the parameter list */
XP_STR_BUF(&awk->token.name)) == (xp_size_t)-1) { if (xp_awk_tab_adddatum(&awk->parse.params, param) == (xp_size_t)-1) {
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params); xp_awk_tab_clear (&awk->parse.params);
PANIC (awk, XP_AWK_ENOMEM); PANIC (awk, XP_AWK_ENOMEM);
@ -413,7 +431,7 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
} }
/* actual function body */ /* actual function body */
body = __parse_block (awk); body = __parse_block (awk, xp_true);
if (body == XP_NULL) { if (body == XP_NULL) {
xp_free (name_dup); xp_free (name_dup);
xp_awk_tab_clear (&awk->parse.params); xp_awk_tab_clear (&awk->parse.params);
@ -479,106 +497,164 @@ static xp_awk_node_t* __parse_action (xp_awk_t* awk)
{ {
if (!MATCH(awk,TOKEN_LBRACE)) PANIC (awk, XP_AWK_ELBRACE); if (!MATCH(awk,TOKEN_LBRACE)) PANIC (awk, XP_AWK_ELBRACE);
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
return __parse_block(awk); return __parse_block(awk, xp_true);
} }
/* TODO: what is the best name for the parsing routine for the outermost block? */ static xp_awk_node_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top)
static xp_awk_node_t* __parse_block (xp_awk_t* awk)
{ {
xp_awk_node_t* head, * curr, * node; xp_awk_node_t* head, * curr, * node;
xp_awk_node_block_t* block; xp_awk_node_block_t* block;
xp_size_t lvc = 0; xp_size_t nlocals, tmp;
/* local variable declaration */ nlocals = xp_awk_tab_getsize(&awk->parse.locals);
//TODO: if (awk->opt & XP_AWK_VARDECL) {
while (1) { /* local variable declarations */
if (MATCH(awk,TOKEN_EOF)) { if (awk->opt.parse & XP_AWK_EXPLICIT) {
// cleanup the variable name list... while (1) {
PANIC (awk, XP_AWK_EENDSRC); if (!MATCH(awk,TOKEN_LOCAL)) break;
}
if (MATCH(awk,TOKEN_RBRACE)) {
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
// TODO: cleanup the variable name list... xp_awk_tab_remrange (
&awk->parse.locals, nlocals - 1,
xp_awk_tab_getsize(&awk->parse.locals) - nlocals);
return XP_NULL; return XP_NULL;
} }
head = XP_NULL;
goto skip_block_body;
}
if (!MATCH(awk,TOKEN_LOCAL)) break; if (__collect_locals(awk, nlocals) == XP_NULL) {
xp_awk_tab_remrange (
if (__get_token(awk) == -1) { &awk->parse.locals, nlocals - 1,
// TODO: cleanup the variable name list... xp_awk_tab_getsize(&awk->parse.locals) - nlocals);
return XP_NULL; return XP_NULL;
}
} }
// TODO: collect variables...
// TODO: check duplicates with locals and globals, and maybe with the function names also depending on the awk options....
} }
// TODO: }
/* block body */ /* block body */
head = XP_NULL; curr = XP_NULL; head = XP_NULL; curr = XP_NULL;
while (1) { while (1) {
if (MATCH(awk,TOKEN_EOF)) { if (MATCH(awk,TOKEN_EOF)) {
// TODO: cleanup the variable name list... xp_awk_tab_remrange (
&awk->parse.locals, nlocals - 1,
xp_awk_tab_getsize(&awk->parse.locals) - nlocals);
if (head != XP_NULL) xp_awk_clrpt (head); if (head != XP_NULL) xp_awk_clrpt (head);
PANIC (awk, XP_AWK_EENDSRC); PANIC (awk, XP_AWK_EENDSRC);
} }
if (MATCH(awk,TOKEN_RBRACE)) { if (MATCH(awk,TOKEN_RBRACE)) {
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
// TODO: cleanup the variable name list... xp_awk_tab_remrange (
&awk->parse.locals, nlocals - 1,
xp_awk_tab_getsize(&awk->parse.locals) - nlocals);
if (head != XP_NULL) xp_awk_clrpt (head); if (head != XP_NULL) xp_awk_clrpt (head);
return XP_NULL; return XP_NULL;
} }
break; break;
} }
/* TODO: if you want to remove top-level null statement... get it here... */
/*
if (MATCH(awk,TOKEN_SEMICOLON)) {
if (__get_token(awk) == -1) {
// TODO: cleanup the variable name list...
if (head != XP_NULL) xp_awk_clrpt (head);
return XP_NULL;
}
continue;
}
*/
node = __parse_statement (awk); node = __parse_statement (awk);
if (node == XP_NULL) { if (node == XP_NULL) {
// TODO: cleanup the variable name list... xp_awk_tab_remrange (
&awk->parse.locals, nlocals - 1,
xp_awk_tab_getsize(&awk->parse.locals) - nlocals);
if (head != XP_NULL) xp_awk_clrpt (head); if (head != XP_NULL) xp_awk_clrpt (head);
return XP_NULL; return XP_NULL;
} }
/* remove unnecessary statements */
if (node->type == XP_AWK_NODE_NULL ||
(node->type == XP_AWK_NODE_BLOCK &&
((xp_awk_node_block_t*)node)->body == XP_NULL)) continue;
if (curr == XP_NULL) head = node; if (curr == XP_NULL) head = node;
else curr->next = node; else curr->next = node;
curr = node; curr = node;
} }
skip_block_body:
block = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t)); block = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t));
if (block == XP_NULL) { if (block == XP_NULL) {
// TODO: cleanup the variable name list... xp_awk_tab_remrange (
&awk->parse.locals, nlocals - 1,
xp_awk_tab_getsize(&awk->parse.locals) - nlocals);
xp_awk_clrpt (head); xp_awk_clrpt (head);
PANIC (awk, XP_AWK_ENOMEM); PANIC (awk, XP_AWK_ENOMEM);
} }
// TODO: remove empty block such as { } { ;;;; }, or { local a, b, c; ;;; }. etc tmp = xp_awk_tab_getsize(&awk->parse.locals);
xp_awk_tab_remrange (
&awk->parse.locals, nlocals - 1, tmp - nlocals);
/* adjust number of locals for a block without any statements */
if (head == NULL) tmp = 0;
block->type = XP_AWK_NODE_BLOCK; block->type = XP_AWK_NODE_BLOCK;
block->next = XP_NULL; block->next = XP_NULL;
block->lvc = lvc;
block->body = head; block->body = head;
// TODO: cleanup the variable name list... if (is_top) {
block->nlocals = awk->parse.nlocals_max - nlocals;
awk->parse.nlocals_max = nlocals;
}
else {
block->nlocals = 0;
if (tmp > awk->parse.nlocals_max) awk->parse.nlocals_max = tmp;
}
return (xp_awk_node_t*)block; return (xp_awk_node_t*)block;
} }
static xp_awk_t* __collect_locals (xp_awk_t* awk, xp_size_t nlocals)
{
xp_char_t* local;
while (1) {
if (!MATCH(awk,TOKEN_IDENT)) {
PANIC (awk, XP_AWK_EIDENT);
}
local = XP_STR_BUF(&awk->token.name);
/* NOTE: it is not checked againt globals names */
if (awk->opt.parse & XP_AWK_UNIQUE) {
/* check if it conflict with a function name */
if (xp_awk_hash_get(&awk->tree.funcs, local) != XP_NULL) {
PANIC (awk, XP_AWK_EDUPNAME);
}
}
/* check if it conflicts with a paremeter name */
if (xp_awk_tab_find(&awk->parse.params, local, 0) != (xp_size_t)-1) {
PANIC (awk, XP_AWK_EDUPNAME);
}
/* check if it conflicts with other local variable names */
if (xp_awk_tab_find(&awk->parse.locals, local,
((awk->opt.parse & XP_AWK_SHADING)? nlocals: 0)) != (xp_size_t)-1) {
PANIC (awk, XP_AWK_EDUPVAR);
}
if (xp_awk_tab_adddatum(&awk->parse.locals, local) == (xp_size_t)-1) {
PANIC (awk, XP_AWK_ENOMEM);
}
if (__get_token(awk) == -1) return XP_NULL;
if (MATCH(awk,TOKEN_SEMICOLON)) break;
if (!MATCH(awk,TOKEN_COMMA)) {
PANIC (awk, XP_AWK_ECOMMA);
}
if (__get_token(awk) == -1) return XP_NULL;
}
/* skip a semicolon */
if (__get_token(awk) == -1) return XP_NULL;
return awk;
}
static xp_awk_node_t* __parse_statement (xp_awk_t* awk) static xp_awk_node_t* __parse_statement (xp_awk_t* awk)
{ {
xp_awk_node_t* node; xp_awk_node_t* node;
@ -598,7 +674,7 @@ static xp_awk_node_t* __parse_statement (xp_awk_t* awk)
} }
else if (MATCH(awk,TOKEN_LBRACE)) { else if (MATCH(awk,TOKEN_LBRACE)) {
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
node = __parse_block (awk); node = __parse_block (awk, xp_false);
} }
else node = __parse_statement_nb (awk); else node = __parse_statement_nb (awk);
@ -1561,7 +1637,7 @@ static int __get_token (xp_awk_t* awk)
GET_CHAR_TO (awk, c); GET_CHAR_TO (awk, c);
} while (xp_isalpha(c) || c == XP_CHAR('_') || xp_isdigit(c)); } while (xp_isalpha(c) || c == XP_CHAR('_') || xp_isdigit(c));
SET_TOKEN_TYPE (awk, __classfy_ident(XP_STR_BUF(&awk->token.name))); SET_TOKEN_TYPE (awk, __classify_ident(awk, XP_STR_BUF(&awk->token.name)));
} }
else if (c == XP_CHAR('\"')) { else if (c == XP_CHAR('\"')) {
/* string */ /* string */
@ -1780,13 +1856,13 @@ static int __skip_comment (xp_awk_t* awk)
return 0; return 0;
} }
static int __classfy_ident (const xp_char_t* ident) static int __classify_ident (xp_awk_t* awk, const xp_char_t* ident)
{ {
struct __kwent* p = __kwtab; struct __kwent* p = __kwtab;
while (p->name != XP_NULL) { for (p = __kwtab; p->name != XP_NULL; p++) {
if (p->valid != 0 && (awk->opt.parse & p->valid) == 0) continue;
if (xp_strcmp(p->name, ident) == 0) return p->type; if (xp_strcmp(p->name, ident) == 0) return p->type;
p++;
} }
return TOKEN_IDENT; return TOKEN_IDENT;
@ -1806,18 +1882,13 @@ static xp_long_t __str_to_long (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_func_arg (xp_awk_t* awk, const xp_char_t* name)
{ {
/* // TODO:
if (awk->curfunc != XP_NULL) {
// TODO: finish this....
}
*/
return (xp_size_t)-1; return (xp_size_t)-1;
} }
static xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name) static xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name)
{ {
// TODO:
return (xp_size_t)-1; return (xp_size_t)-1;
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: tree.c,v 1.15 2006-02-01 02:56:12 bacon Exp $ * $Id: tree.c,v 1.16 2006-02-04 19:31:51 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -133,6 +133,11 @@ static void __print_statements (xp_awk_node_t* tree, int depth)
case XP_AWK_NODE_BLOCK: case XP_AWK_NODE_BLOCK:
__print_tabs (depth); __print_tabs (depth);
xp_printf (XP_TEXT("{\n")); xp_printf (XP_TEXT("{\n"));
if (((xp_awk_node_block_t*)p)->nlocals > 0) {
__print_tabs (depth + 1);
xp_printf (XP_TEXT("NLOCALS=>%u;\n"),
(unsigned int)((xp_awk_node_block_t*)p)->nlocals);
}
__print_statements (((xp_awk_node_block_t*)p)->body, depth + 1); __print_statements (((xp_awk_node_block_t*)p)->body, depth + 1);
__print_tabs (depth); __print_tabs (depth);
xp_printf (XP_TEXT("}\n")); xp_printf (XP_TEXT("}\n"));

View File

@ -1,5 +1,5 @@
/* /*
* $Id: tree.h,v 1.20 2006-02-01 02:56:12 bacon Exp $ * $Id: tree.h,v 1.21 2006-02-04 19:31:51 bacon Exp $
*/ */
#ifndef _XP_AWK_TREE_H_ #ifndef _XP_AWK_TREE_H_
@ -74,7 +74,7 @@ struct xp_awk_node_sgv_t
struct xp_awk_node_block_t struct xp_awk_node_block_t
{ {
XP_AWK_NODE_HDR; XP_AWK_NODE_HDR;
xp_size_t lvc; /* local variable count */ xp_size_t nlocals;
xp_awk_node_t* body; xp_awk_node_t* body;
}; };

View File

@ -78,6 +78,7 @@ int xp_main (int argc, xp_char_t* argv[])
return -1; return -1;
} }
awk.opt.parse = XP_AWK_EXPLICIT | XP_AWK_UNIQUE;
if (xp_awk_parse(&awk) == -1) { if (xp_awk_parse(&awk) == -1) {
xp_printf ( xp_printf (
XP_TEXT("error: cannot parse program - [%d] %s\n"), XP_TEXT("error: cannot parse program - [%d] %s\n"),