*** empty log message ***

This commit is contained in:
hyung-hwan 2006-01-30 14:34:47 +00:00
parent 6c25664a7e
commit c4a635d425
7 changed files with 141 additions and 48 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c,v 1.12 2006-01-29 18:28:14 bacon Exp $ * $Id: awk.c,v 1.13 2006-01-30 14:34:47 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -9,6 +9,8 @@
#include <xp/bas/assert.h> #include <xp/bas/assert.h>
#endif #endif
static void __free_func (void* func);
xp_awk_t* xp_awk_open (xp_awk_t* awk) xp_awk_t* xp_awk_open (xp_awk_t* awk)
{ {
if (awk == XP_NULL) { if (awk == XP_NULL) {
@ -23,12 +25,19 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
return XP_NULL; return XP_NULL;
} }
if (xp_awk_tab_open(&awk->parse.func) == XP_NULL) { if (xp_awk_hash_open(&awk->tree.funcs, 256, __free_func) == XP_NULL) {
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 XP_NULL; return XP_NULL;
} }
if (xp_awk_tab_open(&awk->parse.funcs) == 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 = 0;
awk->errnum = XP_AWK_ENOERR; awk->errnum = XP_AWK_ENOERR;
@ -57,7 +66,8 @@ int xp_awk_close (xp_awk_t* awk)
xp_awk_clear (awk); xp_awk_clear (awk);
if (xp_awk_detsrc(awk) == -1) return -1; if (xp_awk_detsrc(awk) == -1) return -1;
xp_awk_tab_close(&awk->parse.func); xp_awk_hash_close (&awk->tree.funcs);
xp_awk_tab_close (&awk->parse.funcs);
xp_str_close (&awk->token.name); xp_str_close (&awk->token.name);
if (awk->__dynamic) xp_free (awk); if (awk->__dynamic) xp_free (awk);
@ -71,6 +81,8 @@ int xp_awk_close (xp_awk_t* awk)
void xp_awk_clear (xp_awk_t* awk) void xp_awk_clear (xp_awk_t* awk)
{ {
/* clear parse trees */ /* clear parse trees */
xp_awk_hash_clear (&awk->tree.funcs);
if (awk->tree.begin != XP_NULL) { if (awk->tree.begin != XP_NULL) {
xp_assert (awk->tree.begin->next == XP_NULL); xp_assert (awk->tree.begin->next == XP_NULL);
xp_awk_clrpt (awk->tree.begin); xp_awk_clrpt (awk->tree.begin);
@ -128,3 +140,13 @@ int xp_awk_detsrc (xp_awk_t* awk)
return 0; return 0;
} }
static void __free_func (void* func)
{
xp_awk_func_t* f = (xp_awk_func_t*) func;
/* f->name doesn't have to be freed */
/*xp_free (f->name);*/
xp_awk_clrpt (f->body);
xp_free (f);
}

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.21 2006-01-29 18:28:14 bacon Exp $ * $Id: awk.h,v 1.22 2006-01-30 14:34:47 bacon Exp $
*/ */
#ifndef _XP_AWK_AWK_H_ #ifndef _XP_AWK_AWK_H_
@ -15,6 +15,7 @@
#include <xp/awk/tree.h> #include <xp/awk/tree.h>
#include <xp/awk/tab.h> #include <xp/awk/tab.h>
#include <xp/awk/hash.h>
enum enum
{ {
@ -87,7 +88,7 @@ struct xp_awk_t
/* parse tree */ /* parse tree */
struct struct
{ {
//xp_awk_hash_t* funcs; xp_awk_hash_t funcs;
xp_awk_node_t* begin; xp_awk_node_t* begin;
xp_awk_node_t* end; xp_awk_node_t* end;
xp_awk_node_t* unnamed; xp_awk_node_t* unnamed;
@ -96,7 +97,7 @@ struct xp_awk_t
/* temporary information that the parser needs */ /* temporary information that the parser needs */
struct struct
{ {
xp_awk_tab_t func; xp_awk_tab_t funcs;
// TODO: locals, globals??? // TODO: locals, globals???
xp_char_t* vars; /* global and local variable names... */ xp_char_t* vars; /* global and local variable names... */
xp_char_t* args; /* function arguments */ xp_char_t* args; /* function arguments */

View File

@ -1,5 +1,5 @@
/* /*
* $Id: hash.c,v 1.2 2006-01-30 13:25:26 bacon Exp $ * $Id: hash.c,v 1.3 2006-01-30 14:34:47 bacon Exp $
*/ */
#include <xp/awk/hash.h> #include <xp/awk/hash.h>
@ -9,7 +9,16 @@
static xp_size_t __hash (const xp_char_t* key); static xp_size_t __hash (const xp_char_t* key);
xp_awk_hash_t* xp_awk_hash_open (xp_awk_hash_t* hash, xp_size_t capa) #define FREE_PAIR(hash,pair) \
do { \
xp_free ((pair)->key); \
if ((hash)->free_value != XP_NULL) \
(hash)->free_value ((pair)->value); \
xp_free (pair); \
} while (0)
xp_awk_hash_t* xp_awk_hash_open (
xp_awk_hash_t* hash, xp_size_t capa, void (*free_value) (void*))
{ {
if (hash == XP_NULL) { if (hash == XP_NULL) {
hash = (xp_awk_hash_t*) xp_malloc (xp_sizeof(xp_awk_hash_t)); hash = (xp_awk_hash_t*) xp_malloc (xp_sizeof(xp_awk_hash_t));
@ -26,6 +35,7 @@ xp_awk_hash_t* xp_awk_hash_open (xp_awk_hash_t* hash, xp_size_t capa)
hash->capa = capa; hash->capa = capa;
hash->size = 0; hash->size = 0;
hash->free_value = free_value;
while (capa > 0) hash->buck[--capa] = XP_NULL; while (capa > 0) hash->buck[--capa] = XP_NULL;
return hash; return hash;
@ -48,16 +58,20 @@ void xp_awk_hash_clear (xp_awk_hash_t* hash)
while (pair != XP_NULL) { while (pair != XP_NULL) {
next = pair->next; next = pair->next;
xp_free (pair);
FREE_PAIR (hash, pair);
hash->size--; hash->size--;
pair = next; pair = next;
} }
hash->buck[i] = XP_NULL; hash->buck[i] = XP_NULL;
} }
xp_assert (hash->size == 0);
} }
xp_awk_pair_t* xp_awk_hash_get (xp_awk_hash_t* hash, const xp_char_t* key) xp_awk_pair_t* xp_awk_hash_get (xp_awk_hash_t* hash, xp_char_t* key)
{ {
xp_awk_pair_t* pair; xp_awk_pair_t* pair;
xp_size_t hc; xp_size_t hc;
@ -73,7 +87,7 @@ xp_awk_pair_t* xp_awk_hash_get (xp_awk_hash_t* hash, const xp_char_t* key)
return XP_NULL; return XP_NULL;
} }
xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, const xp_char_t* key, void* value) xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, xp_char_t* key, void* value)
{ {
xp_awk_pair_t* pair; xp_awk_pair_t* pair;
xp_size_t hc; xp_size_t hc;
@ -83,7 +97,16 @@ xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, const xp_char_t* key, void*
while (pair != XP_NULL) { while (pair != XP_NULL) {
if (xp_strcmp(pair->key,key) == 0) { if (xp_strcmp(pair->key,key) == 0) {
if (pair->key != key) {
xp_free (pair->key);
pair->key = key;
}
if (hash->free_value != XP_NULL) {
hash->free_value (pair->value);
}
pair->value = value; pair->value = value;
return pair; return pair;
} }
pair = pair->next; pair = pair->next;
@ -101,7 +124,7 @@ xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, const xp_char_t* key, void*
return pair; return pair;
} }
xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, const xp_char_t* key, void* value) xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, xp_char_t* key, void* value)
{ {
xp_awk_pair_t* pair; xp_awk_pair_t* pair;
xp_size_t hc; xp_size_t hc;
@ -111,7 +134,16 @@ xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, const xp_char_t* key, void*
while (pair != XP_NULL) { while (pair != XP_NULL) {
if (xp_strcmp(pair->key,key) == 0) { if (xp_strcmp(pair->key,key) == 0) {
if (pair->key != key) {
xp_free (pair->key);
pair->key = key;
}
if (hash->free_value != XP_NULL) {
hash->free_value (pair->value);
}
pair->value = value; pair->value = value;
return pair; return pair;
} }
pair = pair->next; pair = pair->next;
@ -120,7 +152,7 @@ xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, const xp_char_t* key, void*
return XP_NULL; return XP_NULL;
} }
int xp_awk_hash_remove (xp_awk_hash_t* hash, const xp_char_t* key) int xp_awk_hash_remove (xp_awk_hash_t* hash, xp_char_t* key)
{ {
xp_awk_pair_t* pair, * prev; xp_awk_pair_t* pair, * prev;
xp_size_t hc; xp_size_t hc;
@ -135,8 +167,9 @@ int xp_awk_hash_remove (xp_awk_hash_t* hash, const xp_char_t* key)
hash->buck[hc] = pair->next; hash->buck[hc] = pair->next;
else prev->next = pair->next; else prev->next = pair->next;
xp_free (pair); FREE_PAIR (hash, pair);
hash->size--; hash->size--;
return 0; return 0;
} }
@ -147,6 +180,24 @@ int xp_awk_hash_remove (xp_awk_hash_t* hash, const xp_char_t* key)
return -1; return -1;
} }
int xp_awk_hash_walk (xp_awk_hash_t* hash, int (*walker) (xp_awk_pair_t*))
{
xp_size_t i;
xp_awk_pair_t* pair, * next;
for (i = 0; i < hash->capa; i++) {
pair = hash->buck[i];
while (pair != XP_NULL) {
next = pair->next;
if (walker(pair) == -1) return -1;
pair = next;
}
}
return 0;
}
static xp_size_t __hash (const xp_char_t* key) static xp_size_t __hash (const xp_char_t* key)
{ {
xp_size_t n = 0, i; xp_size_t n = 0, i;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: hash.h,v 1.3 2006-01-30 13:25:26 bacon Exp $ * $Id: hash.h,v 1.4 2006-01-30 14:34:47 bacon Exp $
*/ */
#ifndef _XP_AWK_HASH_H_ #ifndef _XP_AWK_HASH_H_
@ -17,7 +17,7 @@ typedef struct xp_awk_pair_t xp_awk_pair_t;
struct xp_awk_pair_t struct xp_awk_pair_t
{ {
const xp_char_t* key; xp_char_t* key;
void* value; void* value;
xp_awk_pair_t* next; xp_awk_pair_t* next;
}; };
@ -27,6 +27,7 @@ struct xp_awk_hash_t
xp_size_t size; xp_size_t size;
xp_size_t capa; xp_size_t capa;
xp_awk_pair_t** buck; xp_awk_pair_t** buck;
void (*free_value) (void*);
xp_bool_t __dynamic; xp_bool_t __dynamic;
}; };
@ -34,16 +35,18 @@ struct xp_awk_hash_t
extern "C" { extern "C" {
#endif #endif
xp_awk_hash_t* xp_awk_hash_open (xp_awk_hash_t* hash, xp_size_t capa); xp_awk_hash_t* xp_awk_hash_open (
xp_awk_hash_t* hash, xp_size_t capa, void (*free_value) (void*));
void xp_awk_hash_close (xp_awk_hash_t* hash); void xp_awk_hash_close (xp_awk_hash_t* hash);
void xp_awk_hash_clear (xp_awk_hash_t* hash); void xp_awk_hash_clear (xp_awk_hash_t* hash);
xp_awk_pair_t* xp_awk_hash_get (xp_awk_hash_t* hash, const xp_char_t* key); xp_awk_pair_t* xp_awk_hash_get (xp_awk_hash_t* hash, xp_char_t* key);
xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, const xp_char_t* key, void* value); xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, xp_char_t* key, void* value);
xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, const xp_char_t* key, void* value); xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, xp_char_t* key, void* value);
int xp_awk_hash_remove (xp_awk_hash_t* hash, const xp_char_t* key); int xp_awk_hash_remove (xp_awk_hash_t* hash, xp_char_t* key);
int xp_awk_hash_walk (xp_awk_hash_t* hash, int (*walker) (xp_awk_pair_t*));
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.38 2006-01-30 13:25:26 bacon Exp $ * $Id: parse.c,v 1.39 2006-01-30 14:34:47 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -188,6 +188,34 @@ 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);
static int __dump_func (xp_awk_pair_t* pair)
{
xp_awk_func_t* func = (xp_awk_func_t*)pair->value;
xp_assert (xp_strcmp(pair->key, func->name) == 0);
xp_printf (XP_TEXT("function %s (nargs=>%u)\n"), func->name, func->nargs);
xp_awk_prnpt (func->body);
xp_printf (XP_TEXT("\n"));
return 0;
}
static void __dump (xp_awk_t* awk)
{
xp_awk_hash_walk (&awk->tree.funcs, __dump_func);
if (awk->tree.begin != NULL) {
xp_printf (XP_TEXT("BEGIN "));
xp_awk_prnpt (awk->tree.begin);
xp_printf (XP_TEXT("\n"));
}
if (awk->tree.end != NULL) {
xp_printf (XP_TEXT("END "));
xp_awk_prnpt (awk->tree.end);
}
}
int xp_awk_parse (xp_awk_t* awk) int xp_awk_parse (xp_awk_t* awk)
{ {
/* if you want to parse anew, call xp_awk_clear first. /* if you want to parse anew, call xp_awk_clear first.
@ -197,23 +225,20 @@ int xp_awk_parse (xp_awk_t* awk)
GET_TOKEN (awk); GET_TOKEN (awk);
while (1) { while (1) {
xp_awk_node_t* unit;
if (MATCH(awk,TOKEN_EOF)) break; if (MATCH(awk,TOKEN_EOF)) break;
unit = __parse_progunit(awk); if (__parse_progunit(awk) == XP_NULL) {
if (unit == 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); xp_printf (XP_TEXT("error - %d\n"), awk->errnum);
return -1; return -1;
} }
xp_awk_prnpt(unit);
} }
xp_printf (XP_TEXT("-----------------------------\n"));
xp_printf (XP_TEXT("sucessful end - %d\n"), awk->errnum); xp_printf (XP_TEXT("sucessful end - %d\n"), awk->errnum);
__dump (awk);
return 0; return 0;
} }
@ -263,6 +288,7 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
xp_char_t* name; xp_char_t* name;
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_size_t fnpos; xp_size_t fnpos;
xp_size_t nargs = 0; xp_size_t nargs = 0;
@ -386,10 +412,10 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
return XP_NULL; return XP_NULL;
} }
/*
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); __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;
@ -399,15 +425,14 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
func->nargs = nargs; func->nargs = nargs;
func->body = body; func->body = body;
xp_assert (xp_awk_hash_get(&awk->tree.func, name_dup) == XP_NULL); xp_assert (xp_awk_hash_get(&awk->tree.funcs, name_dup) == XP_NULL);
if (xp_awk_hash_put(&awk->tree.func, name_dup, func) == XP_NULL) { if (xp_awk_hash_put(&awk->tree.funcs, name_dup, func) == XP_NULL) {
__remove_func_name (awk, fnpos); __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);
PANIC (awk, XP_AWK_ENOMEM); PANIC (awk, XP_AWK_ENOMEM);
} }
*/
return body; return body;
} }
@ -1744,17 +1769,17 @@ 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); xp_assert (__find_func_name(awk,name) == (xp_size_t)-1);
return xp_awk_tab_adddatum(&awk->parse.func, name); return xp_awk_tab_adddatum(&awk->parse.funcs, name);
} }
static INLINE int __remove_func_name (xp_awk_t* awk, xp_size_t index) static INLINE int __remove_func_name (xp_awk_t* awk, xp_size_t index)
{ {
return xp_awk_tab_remrange (&awk->parse.func, index, 1); 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) static INLINE xp_size_t __find_func_name (xp_awk_t* awk, const xp_char_t* name)
{ {
return xp_awk_tab_find(&awk->parse.func, name, 0); 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.h,v 1.18 2006-01-25 16:11:43 bacon Exp $ * $Id: tree.h,v 1.19 2006-01-30 14:34:47 bacon Exp $
*/ */
#ifndef _XP_AWK_TREE_H_ #ifndef _XP_AWK_TREE_H_
@ -32,6 +32,8 @@ enum
XP_AWK_NODE_FOR XP_AWK_NODE_FOR
}; };
typedef struct xp_awk_func_t xp_awk_func_t;
typedef struct xp_awk_node_t xp_awk_node_t; typedef struct xp_awk_node_t xp_awk_node_t;
typedef struct xp_awk_node_sgv_t xp_awk_node_sgv_t; typedef struct xp_awk_node_sgv_t xp_awk_node_sgv_t;
typedef struct xp_awk_node_block_t xp_awk_node_block_t; typedef struct xp_awk_node_block_t xp_awk_node_block_t;
@ -46,7 +48,6 @@ typedef struct xp_awk_node_if_t xp_awk_node_if_t;
typedef struct xp_awk_node_while_t xp_awk_node_while_t; typedef struct xp_awk_node_while_t xp_awk_node_while_t;
typedef struct xp_awk_node_for_t xp_awk_node_for_t; typedef struct xp_awk_node_for_t xp_awk_node_for_t;
struct xp_awk_func_t struct xp_awk_func_t
{ {
xp_char_t* name; xp_char_t* name;

View File

@ -76,16 +76,6 @@ int xp_main (int argc, xp_char_t* argv[])
return -1; return -1;
} }
xp_printf (XP_TEXT("-----------------------------------------------\n"));
if (awk.tree.begin != XP_NULL) {
xp_printf (XP_TEXT("BEGIN "));
xp_awk_prnpt (awk.tree.begin);
}
if (awk.tree.end != XP_NULL) {
xp_printf (XP_TEXT("END "));
xp_awk_prnpt (awk.tree.end);
}
xp_awk_close (&awk); xp_awk_close (&awk);
return 0; return 0;
} }