*** empty log message ***

This commit is contained in:
hyung-hwan 2006-06-16 14:31:42 +00:00
parent 0e1bcf8db5
commit be264c5638
7 changed files with 226 additions and 124 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk_i.h,v 1.13 2006-06-16 07:35:07 bacon Exp $ * $Id: awk_i.h,v 1.14 2006-06-16 14:31:42 bacon Exp $
*/ */
#ifndef _XP_AWK_AWKI_H_ #ifndef _XP_AWK_AWKI_H_
@ -16,6 +16,7 @@ typedef struct xp_awk_cmd_t xp_awk_cmd_t;
#include <xp/awk/map.h> #include <xp/awk/map.h>
#include <xp/awk/val.h> #include <xp/awk/val.h>
#include <xp/awk/run.h> #include <xp/awk/run.h>
#include <xp/awk/func.h>
#ifdef XP_AWK_STAND_ALONE #ifdef XP_AWK_STAND_ALONE
#include <xp/awk/sa.h> #include <xp/awk/sa.h>

36
ase/awk/func.c Normal file
View File

@ -0,0 +1,36 @@
/*
* $Id: func.c,v 1.1 2006-06-16 14:31:42 bacon Exp $
*/
#include <xp/awk/awk_i.h>
#ifndef XP_AWK_STAND_ALONE
#include <xp/bas/memory.h>
#include <xp/bas/string.h>
#endif
enum
{
BFN_SYSTEM,
BFN_CLOSE
};
static xp_awk_bfn_t __bfn[] =
{
{ XP_T("system"), BFN_SYSTEM, 0, 1, 1, XP_NULL },
{ XP_T("close"), BFN_CLOSE, 0, 1, 2, XP_NULL },
{ XP_NULL, 0, 0, 0, 0, XP_NULL }
};
xp_awk_bfn_t* xp_awk_getbfn (const xp_char_t* name)
{
xp_awk_bfn_t* p = __bfn;
while (p->name != XP_NULL)
{
if (xp_strcmp (p->name, name) == 0) return p;
p++;
}
return XP_NULL;
}

36
ase/awk/func.h Normal file
View File

@ -0,0 +1,36 @@
/*
* $Id: func.h,v 1.1 2006-06-16 14:31:42 bacon Exp $
*/
#ifndef _XP_AWK_FUNC_H_
#define _XP_AWK_FUNC_H_
#ifndef _XP_AWK_AWK_H_
#error Never include this file directly. Include <xp/awk/awk.h> instead
#endif
typedef struct xp_awk_bfn_t xp_awk_bfn_t;
struct xp_awk_bfn_t
{
const xp_char_t* name;
int type;
int valid; /* the entry is valid when this option is set */
int max_args;
int min_args;
xp_awk_val_t* (*handler) ();
};
#ifdef __cplusplus
extern "C" {
#endif
xp_awk_bfn_t* xp_awk_getbfn (const xp_char_t* name);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,4 +1,4 @@
SRCS = awk.c err.c tree.c tab.c map.c parse.c run.c sa.c val.c misc.c extio.c SRCS = awk.c err.c tree.c tab.c map.c parse.c run.c sa.c val.c func.c misc.c extio.c
OBJS = $(SRCS:.c=.obj) OBJS = $(SRCS:.c=.obj)
OUT = xpawk OUT = xpawk

View File

@ -1,5 +1,5 @@
/* /*
* $Id: map.h,v 1.11 2006-04-30 17:10:30 bacon Exp $ * $Id: map.h,v 1.12 2006-06-16 14:31:42 bacon Exp $
*/ */
#ifndef _XP_AWK_MAP_H_ #ifndef _XP_AWK_MAP_H_
@ -9,13 +9,6 @@
#error Never include this file directly. Include <xp/awk/awk.h> instead #error Never include this file directly. Include <xp/awk/awk.h> instead
#endif #endif
#ifdef XP_AWK_STAND_ALONE
#include <xp/awk/sa.h>
#else
#include <xp/types.h>
#include <xp/macros.h>
#endif
typedef struct xp_awk_map_t xp_awk_map_t; typedef struct xp_awk_map_t xp_awk_map_t;
typedef struct xp_awk_pair_t xp_awk_pair_t; typedef struct xp_awk_pair_t xp_awk_pair_t;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.113 2006-06-13 15:11:39 bacon Exp $ * $Id: parse.c,v 1.114 2006-06-16 14:31:42 bacon Exp $
*/ */
#include <xp/awk/awk_i.h> #include <xp/awk/awk_i.h>
@ -140,6 +140,7 @@ static xp_awk_nde_t* __parse_multiplicative (xp_awk_t* awk);
static xp_awk_nde_t* __parse_unary (xp_awk_t* awk); static xp_awk_nde_t* __parse_unary (xp_awk_t* awk);
static xp_awk_nde_t* __parse_increment (xp_awk_t* awk); static xp_awk_nde_t* __parse_increment (xp_awk_t* awk);
static xp_awk_nde_t* __parse_primary (xp_awk_t* awk); static xp_awk_nde_t* __parse_primary (xp_awk_t* awk);
static xp_awk_nde_t* __parse_primary_ident (xp_awk_t* awk);
static xp_awk_nde_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name); static xp_awk_nde_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name);
static xp_awk_nde_t* __parse_funcall (xp_awk_t* awk, xp_char_t* name); static xp_awk_nde_t* __parse_funcall (xp_awk_t* awk, xp_char_t* name);
@ -204,7 +205,7 @@ static struct __kwent __kwtab[] =
{ XP_T("in"), TOKEN_IN, 0 }, { XP_T("in"), TOKEN_IN, 0 },
{ XP_NULL, 0, 0 } { XP_NULL, 0, 0 }
}; };
/* TODO: /* TODO:
@ -231,7 +232,7 @@ static struct __kwent __bvtab[] =
{ XP_T("RSTART"), TOKEN_RSTART, 0 }, { XP_T("RSTART"), TOKEN_RSTART, 0 },
{ XP_T("RLENGTH"), TOKEN_RLENGTH, 0 }, { XP_T("RLENGTH"), TOKEN_RLENGTH, 0 },
{ XP_T("SUBSEP"), TOKEN_SUBSEP, 0 }, { XP_T("SUBSEP"), TOKEN_SUBSEP, 0 },
{ XP_NULL, 0, 0 } { XP_NULL, 0, 0 }
}; };
*/ */
@ -1723,104 +1724,7 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk)
{ {
if (MATCH(awk,TOKEN_IDENT)) if (MATCH(awk,TOKEN_IDENT))
{ {
xp_char_t* name_dup; return __parse_primary_ident (awk);
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_dup);
return XP_NULL;
}
if (MATCH(awk,TOKEN_LBRACK))
{
xp_awk_nde_t* nde;
nde = __parse_hashidx (awk, name_dup);
if (nde == XP_NULL) xp_free (name_dup);
return (xp_awk_nde_t*)nde;
}
else if (MATCH(awk,TOKEN_LPAREN))
{
/* function call */
xp_awk_nde_t* nde;
nde = __parse_funcall (awk, name_dup);
if (nde == XP_NULL) xp_free (name_dup);
return (xp_awk_nde_t*)nde;
}
else
{
/* normal variable */
xp_awk_nde_var_t* nde;
xp_size_t idxa;
nde = (xp_awk_nde_var_t*)
xp_malloc (xp_sizeof(xp_awk_nde_var_t));
if (nde == XP_NULL)
{
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)
{
nde->type = XP_AWK_NDE_ARG;
nde->next = XP_NULL;
/*nde->id.name = XP_NULL;*/
nde->id.name = name_dup;
nde->id.idxa = idxa;
nde->idx = XP_NULL;
return (xp_awk_nde_t*)nde;
}
/* search the local variable list */
idxa = xp_awk_tab_rrfind(&awk->parse.locals, name_dup, 0);
if (idxa != (xp_size_t)-1)
{
nde->type = XP_AWK_NDE_LOCAL;
nde->next = XP_NULL;
/*nde->id.name = XP_NULL;*/
nde->id.name = name_dup;
nde->id.idxa = idxa;
nde->idx = XP_NULL;
return (xp_awk_nde_t*)nde;
}
/* search the global variable list */
idxa = xp_awk_tab_rrfind(&awk->parse.globals, name_dup, 0);
if (idxa != (xp_size_t)-1)
{
nde->type = XP_AWK_NDE_GLOBAL;
nde->next = XP_NULL;
/*nde->id.name = XP_NULL;*/
nde->id.name = name_dup;
nde->id.idxa = idxa;
nde->idx = XP_NULL;
return (xp_awk_nde_t*)nde;
}
if (awk->opt.parse & XP_AWK_IMPLICIT)
{
nde->type = XP_AWK_NDE_NAMED;
nde->next = XP_NULL;
nde->id.name = name_dup;
nde->id.idxa = (xp_size_t)-1;
nde->idx = XP_NULL;
return (xp_awk_nde_t*)nde;
}
/* undefined variable */
xp_free (name_dup);
xp_free (nde);
PANIC (awk, XP_AWK_EUNDEF);
}
} }
else if (MATCH(awk,TOKEN_INT)) else if (MATCH(awk,TOKEN_INT))
{ {
@ -2094,6 +1998,139 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk)
PANIC (awk, XP_AWK_EEXPRESSION); PANIC (awk, XP_AWK_EEXPRESSION);
} }
static xp_awk_nde_t* __parse_primary_ident (xp_awk_t* awk)
{
xp_char_t* name_dup;
xp_awk_bfn_t* bfn;
xp_assert (MATCH(awk,TOKEN_IDENT));
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_dup);
return XP_NULL;
}
/* what if name_dup is a built-in function name */
bfn = xp_awk_getbfn (name_dup);
if (bfn != XP_NULL)
{
xp_awk_nde_t* nde;
if (!MATCH(awk,TOKEN_LPAREN))
{
/* built-in function should be in the form
* of the function call */
xp_free (name_dup);
PANIC (awk, XP_AWK_ELPAREN);
}
/* bfn->handler... */
nde = __parse_funcall (awk, name_dup);
if (nde == XP_NULL) xp_free (name_dup);
return (xp_awk_nde_t*)nde;
}
/* TODO: user-defined functions */
/*
if (__is_ufname (name_dup))
{
}
*/
/* now we know that name_dup is a normal identifier. */
if (MATCH(awk,TOKEN_LBRACK))
{
xp_awk_nde_t* nde;
nde = __parse_hashidx (awk, name_dup);
if (nde == XP_NULL) xp_free (name_dup);
return (xp_awk_nde_t*)nde;
}
else if (MATCH(awk,TOKEN_LPAREN))
{
/* function call */
xp_awk_nde_t* nde;
nde = __parse_funcall (awk, name_dup);
if (nde == XP_NULL) xp_free (name_dup);
return (xp_awk_nde_t*)nde;
}
else
{
/* normal variable */
xp_awk_nde_var_t* nde;
xp_size_t idxa;
nde = (xp_awk_nde_var_t*)
xp_malloc (xp_sizeof(xp_awk_nde_var_t));
if (nde == XP_NULL)
{
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)
{
nde->type = XP_AWK_NDE_ARG;
nde->next = XP_NULL;
/*nde->id.name = XP_NULL;*/
nde->id.name = name_dup;
nde->id.idxa = idxa;
nde->idx = XP_NULL;
return (xp_awk_nde_t*)nde;
}
/* search the local variable list */
idxa = xp_awk_tab_rrfind(&awk->parse.locals, name_dup, 0);
if (idxa != (xp_size_t)-1)
{
nde->type = XP_AWK_NDE_LOCAL;
nde->next = XP_NULL;
/*nde->id.name = XP_NULL;*/
nde->id.name = name_dup;
nde->id.idxa = idxa;
nde->idx = XP_NULL;
return (xp_awk_nde_t*)nde;
}
/* search the global variable list */
idxa = xp_awk_tab_rrfind(&awk->parse.globals, name_dup, 0);
if (idxa != (xp_size_t)-1)
{
nde->type = XP_AWK_NDE_GLOBAL;
nde->next = XP_NULL;
/*nde->id.name = XP_NULL;*/
nde->id.name = name_dup;
nde->id.idxa = idxa;
nde->idx = XP_NULL;
return (xp_awk_nde_t*)nde;
}
if (awk->opt.parse & XP_AWK_IMPLICIT)
{
nde->type = XP_AWK_NDE_NAMED;
nde->next = XP_NULL;
nde->id.name = name_dup;
nde->id.idxa = (xp_size_t)-1;
nde->idx = XP_NULL;
return (xp_awk_nde_t*)nde;
}
/* undefined variable */
xp_free (name_dup);
xp_free (nde);
PANIC (awk, XP_AWK_EUNDEF);
}
}
static xp_awk_nde_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name) static xp_awk_nde_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name)
{ {
xp_awk_nde_t* idx, * tmp, * last; xp_awk_nde_t* idx, * tmp, * last;
@ -2832,6 +2869,8 @@ static int __get_token (xp_awk_t* awk)
} }
else if (xp_isalpha(c) || c == XP_T('_')) else if (xp_isalpha(c) || c == XP_T('_'))
{ {
int type;
/* identifier */ /* identifier */
do do
{ {
@ -2840,7 +2879,8 @@ static int __get_token (xp_awk_t* awk)
} }
while (xp_isalpha(c) || c == XP_T('_') || xp_isdigit(c)); while (xp_isalpha(c) || c == XP_T('_') || xp_isdigit(c));
SET_TOKEN_TYPE (awk, __classify_ident(awk,XP_STR_BUF(&awk->token.name))); type = __classify_ident (awk,XP_STR_BUF(&awk->token.name));
SET_TOKEN_TYPE (awk, type);
} }
else if (c == XP_T('\"')) else if (c == XP_T('\"'))
{ {
@ -3482,12 +3522,15 @@ static int __skip_comment (xp_awk_t* awk)
static int __classify_ident (xp_awk_t* awk, const xp_char_t* ident) static int __classify_ident (xp_awk_t* awk, const xp_char_t* ident)
{ {
struct __kwent* p; struct __kwent* kwp;
for (p = __kwtab; p->name != XP_NULL; p++) for (kwp = __kwtab; kwp->name != XP_NULL; kwp++)
{ {
if (p->valid != 0 && (awk->opt.parse & p->valid) == 0) continue; if (kwp->valid != 0 && (awk->opt.parse & kwp->valid) == 0)
if (xp_strcmp(p->name, ident) == 0) return p->type; {
continue;
}
if (xp_strcmp(kwp->name, ident) == 0) return kwp->type;
} }
return TOKEN_IDENT; return TOKEN_IDENT;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: tab.h,v 1.7 2006-04-16 04:31:38 bacon Exp $ * $Id: tab.h,v 1.8 2006-06-16 14:31:42 bacon Exp $
*/ */
#ifndef _XP_AWK_TAB_H_ #ifndef _XP_AWK_TAB_H_
@ -9,13 +9,6 @@
#error Never include this file directly. Include <xp/awk/awk.h> instead #error Never include this file directly. Include <xp/awk/awk.h> instead
#endif #endif
#ifdef XP_AWK_STAND_ALONE
#include <xp/awk/sa.h>
#else
#include <xp/types.h>
#include <xp/macros.h>
#endif
/* TODO: you have to turn this into a hash table. /* TODO: you have to turn this into a hash table.
as of now, this is an arrayed table. */ as of now, this is an arrayed table. */