*** empty log message ***
This commit is contained in:
parent
e701a98406
commit
934a5da3e1
@ -1,4 +1,4 @@
|
|||||||
SRCS = awk.c tree.c parse.c run.c sa.c
|
SRCS = awk.c tree.c tab.c parse.c run.c sa.c
|
||||||
OBJS = $(SRCS:.c=.obj)
|
OBJS = $(SRCS:.c=.obj)
|
||||||
OUT = xpawk.lib
|
OUT = xpawk.lib
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk.c,v 1.11 2006-01-24 16:14:28 bacon Exp $
|
* $Id: awk.c,v 1.12 2006-01-29 18:28:14 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xp/awk/awk.h>
|
#include <xp/awk/awk.h>
|
||||||
@ -23,6 +23,12 @@ 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) {
|
||||||
|
xp_str_close (&awk->token.name);
|
||||||
|
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;
|
||||||
|
|
||||||
@ -39,6 +45,7 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
|
|||||||
awk->tree.unnamed = XP_NULL;
|
awk->tree.unnamed = XP_NULL;
|
||||||
//awk->tree.funcs = XP_NULL;
|
//awk->tree.funcs = XP_NULL;
|
||||||
|
|
||||||
|
|
||||||
awk->lex.curc = XP_CHAR_EOF;
|
awk->lex.curc = XP_CHAR_EOF;
|
||||||
awk->lex.ungotc_count = 0;
|
awk->lex.ungotc_count = 0;
|
||||||
|
|
||||||
@ -49,14 +56,21 @@ 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_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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???
|
||||||
|
|
||||||
void xp_awk_clear (xp_awk_t* awk)
|
void xp_awk_clear (xp_awk_t* awk)
|
||||||
{
|
{
|
||||||
|
/* clear parse trees */
|
||||||
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);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk.h,v 1.20 2006-01-26 15:35:20 bacon Exp $
|
* $Id: awk.h,v 1.21 2006-01-29 18:28:14 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _XP_AWK_AWK_H_
|
#ifndef _XP_AWK_AWK_H_
|
||||||
@ -14,6 +14,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <xp/awk/tree.h>
|
#include <xp/awk/tree.h>
|
||||||
|
#include <xp/awk/tab.h>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -40,7 +41,8 @@ enum
|
|||||||
XP_AWK_EIDENT, /* identifier expected */
|
XP_AWK_EIDENT, /* identifier expected */
|
||||||
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_EDUPNAME /* duplicate name - function, variable, etc */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -94,6 +96,7 @@ struct xp_awk_t
|
|||||||
/* temporary information that the parser needs */
|
/* temporary information that the parser needs */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
xp_awk_tab_t func;
|
||||||
// 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 */
|
||||||
|
@ -1,10 +1,33 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: hash.h,v 1.1 2005-11-07 16:02:44 bacon Exp $
|
* $Id: hash.h,v 1.2 2006-01-29 18:28:14 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _XP_AWK_HASH_H_
|
#ifndef _XP_AWK_HASH_H_
|
||||||
#define _XP_AWK_HASH_H_
|
#define _XP_AWK_HASH_H_
|
||||||
|
|
||||||
|
#ifdef __STAND_ALONE
|
||||||
|
#include <xp/awk/sa.h>
|
||||||
|
#else
|
||||||
|
#include <xp/types.h>
|
||||||
|
#include <xp/macros.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct xp_awk_hash_t xp_awk_hash_t;
|
||||||
|
typedef struct xp_awk_hashdatum_t xp_awk_hashdatum_t;
|
||||||
|
|
||||||
|
struct xp_awk_hashdatum_t
|
||||||
|
{
|
||||||
|
xp_char_t* key;
|
||||||
|
void* value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xp_awk_hash_t
|
||||||
|
{
|
||||||
|
xp_size_t size;
|
||||||
|
xp_size_t capa;
|
||||||
|
xp_bool_t __dynamic;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
191
ase/awk/parse.c
191
ase/awk/parse.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: parse.c,v 1.36 2006-01-28 06:38:01 bacon Exp $
|
* $Id: parse.c,v 1.37 2006-01-29 18:28:14 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xp/awk/awk.h>
|
#include <xp/awk/awk.h>
|
||||||
@ -75,6 +75,13 @@ enum {
|
|||||||
BINOP_MOD
|
BINOP_MOD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||||
|
#define INLINE
|
||||||
|
#else
|
||||||
|
#define INLINE inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static xp_awk_node_t* __parse_progunit (xp_awk_t* awk);
|
static xp_awk_node_t* __parse_progunit (xp_awk_t* awk);
|
||||||
static xp_awk_node_t* __parse_function (xp_awk_t* awk);
|
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);
|
||||||
@ -109,10 +116,14 @@ 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 __classfy_ident (const xp_char_t* ident);
|
||||||
|
|
||||||
static xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name);
|
|
||||||
static xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name);
|
|
||||||
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 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);
|
||||||
|
|
||||||
|
|
||||||
struct __kwent
|
struct __kwent
|
||||||
{
|
{
|
||||||
const xp_char_t* name;
|
const xp_char_t* name;
|
||||||
@ -188,9 +199,13 @@ int xp_awk_parse (xp_awk_t* awk)
|
|||||||
|
|
||||||
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...
|
||||||
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(node);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xp_printf (XP_TEXT("sucessful end - %d\n"), awk->errnum);
|
xp_printf (XP_TEXT("sucessful end - %d\n"), awk->errnum);
|
||||||
@ -207,24 +222,15 @@ static xp_awk_node_t* __parse_progunit (xp_awk_t* awk)
|
|||||||
|
|
||||||
if (MATCH(awk,TOKEN_FUNCTION)) {
|
if (MATCH(awk,TOKEN_FUNCTION)) {
|
||||||
node = __parse_function(awk);
|
node = __parse_function(awk);
|
||||||
if (node == XP_NULL) {
|
if (node == XP_NULL) return XP_NULL;
|
||||||
// TODO: cleanup
|
|
||||||
return XP_NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (MATCH(awk,TOKEN_BEGIN)) {
|
else if (MATCH(awk,TOKEN_BEGIN)) {
|
||||||
node = __parse_begin (awk);
|
node = __parse_begin (awk);
|
||||||
if (node == XP_NULL) {
|
if (node == XP_NULL) return XP_NULL;
|
||||||
// TODO: cleanup
|
|
||||||
return XP_NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (MATCH(awk, TOKEN_END)) {
|
else if (MATCH(awk, TOKEN_END)) {
|
||||||
node = __parse_end (awk);
|
node = __parse_end (awk);
|
||||||
if (node == XP_NULL) {
|
if (node == XP_NULL) return XP_NULL;
|
||||||
// TODO: cleanup
|
|
||||||
return XP_NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* TODO: process patterns and expressions */
|
/* TODO: process patterns and expressions */
|
||||||
/*
|
/*
|
||||||
@ -239,55 +245,67 @@ static xp_awk_node_t* __parse_progunit (xp_awk_t* awk)
|
|||||||
else {
|
else {
|
||||||
/* pattern-less actions */
|
/* pattern-less actions */
|
||||||
node = __parse_action (awk);
|
node = __parse_action (awk);
|
||||||
if (node == XP_NULL) {
|
if (node == XP_NULL) return XP_NULL;
|
||||||
// TODO: cleanup
|
|
||||||
return XP_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: weave the action block into awk->tree.actions...
|
// TODO: weave the action block into awk->tree.actions...
|
||||||
}
|
}
|
||||||
|
|
||||||
xp_awk_prnpt(node);
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xp_bool_t __function_defined (xp_awk_t* awk, const xp_char_t* name)
|
|
||||||
{
|
|
||||||
// TODO: complete this...
|
|
||||||
return xp_false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xp_awk_node_t* __parse_function (xp_awk_t* awk)
|
static xp_awk_node_t* __parse_function (xp_awk_t* awk)
|
||||||
{
|
{
|
||||||
xp_char_t* name;
|
xp_char_t* name;
|
||||||
//xp_awk_func_t* func;
|
xp_char_t* name_dup;
|
||||||
xp_awk_node_t* body;
|
xp_awk_node_t* body;
|
||||||
|
xp_size_t fnpos;
|
||||||
|
xp_size_t nargs = 0;
|
||||||
|
|
||||||
if (__get_token(awk) == -1) return XP_NULL;
|
if (__get_token(awk) == -1) return XP_NULL;
|
||||||
|
|
||||||
/* function name */
|
/* function name */
|
||||||
if (!MATCH(awk,TOKEN_IDENT)) PANIC (awk, XP_AWK_EIDENT);
|
if (!MATCH(awk,TOKEN_IDENT)) PANIC (awk, XP_AWK_EIDENT);
|
||||||
|
|
||||||
if (__function_defined(awk,XP_STR_BUF(&awk->token.name))) {
|
name = XP_STR_BUF(&awk->token.name);
|
||||||
PANIC (awk, XP_AWK_EDUPFUNC);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
name = xp_strdup (XP_STR_BUF(&awk->token.name));
|
// TODO: make this feature optional..
|
||||||
if (name == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
|
// find in the global variable list...
|
||||||
|
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 */
|
/* skip the function name */
|
||||||
if (__get_token(awk) == -1) {
|
if (__get_token(awk) == -1) {
|
||||||
xp_free (name);
|
__remove_func_name (awk, fnpos);
|
||||||
|
xp_free (name_dup);
|
||||||
return XP_NULL;
|
return XP_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MATCH(awk,TOKEN_LPAREN)) {
|
if (!MATCH(awk,TOKEN_LPAREN)) {
|
||||||
xp_free (name);
|
__remove_func_name (awk, fnpos);
|
||||||
|
xp_free (name_dup);
|
||||||
PANIC (awk, XP_AWK_ELPAREN);
|
PANIC (awk, XP_AWK_ELPAREN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__get_token(awk) == -1) {
|
if (__get_token(awk) == -1) {
|
||||||
xp_free (name);
|
__remove_func_name (awk, fnpos);
|
||||||
|
xp_free (name_dup);
|
||||||
return XP_NULL;
|
return XP_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,75 +313,97 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk)
|
|||||||
if (MATCH(awk,TOKEN_RPAREN)) {
|
if (MATCH(awk,TOKEN_RPAREN)) {
|
||||||
/* no function parameter */
|
/* no function parameter */
|
||||||
if (__get_token(awk) == -1) {
|
if (__get_token(awk) == -1) {
|
||||||
xp_free (name);
|
__remove_func_name (awk, fnpos);
|
||||||
|
xp_free (name_dup);
|
||||||
return XP_NULL;
|
return XP_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!MATCH(awk,TOKEN_IDENT)) {
|
if (!MATCH(awk,TOKEN_IDENT)) {
|
||||||
xp_free (name);
|
__remove_func_name (awk, fnpos);
|
||||||
|
xp_free (name_dup);
|
||||||
PANIC (awk, XP_AWK_EIDENT);
|
PANIC (awk, XP_AWK_EIDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nargs++;
|
||||||
|
// TODO: push args to param list...
|
||||||
|
|
||||||
if (__get_token(awk) == -1) {
|
if (__get_token(awk) == -1) {
|
||||||
xp_free (name);
|
__remove_func_name (awk, fnpos);
|
||||||
|
xp_free (name_dup);
|
||||||
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)) {
|
||||||
xp_free (name);
|
__remove_func_name (awk, fnpos);
|
||||||
|
xp_free (name_dup);
|
||||||
PANIC (awk, XP_AWK_ECOMMA);
|
PANIC (awk, XP_AWK_ECOMMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__get_token(awk) == -1) {
|
if (__get_token(awk) == -1) {
|
||||||
xp_free (name);
|
__remove_func_name (awk, fnpos);
|
||||||
|
xp_free (name_dup);
|
||||||
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
|
// TODO: cleanup parameter name list
|
||||||
xp_free (name);
|
xp_free (name_dup);
|
||||||
return XP_NULL;
|
return XP_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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
|
// TODO: cleanup parameter name list
|
||||||
xp_free (name);
|
xp_free (name_dup);
|
||||||
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
|
// TODO: cleanup parameter name list
|
||||||
xp_free (name);
|
xp_free (name_dup);
|
||||||
return XP_NULL;
|
return XP_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
// TODO: cleanup parameter name list
|
||||||
xp_free (name);
|
xp_free (name_dup);
|
||||||
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) {
|
||||||
xp_free (name);
|
__remove_func_name (awk, fnpos);
|
||||||
|
xp_free (name_dup);
|
||||||
xp_awk_clrpt (body);
|
xp_awk_clrpt (body);
|
||||||
return XP_NULL;
|
return XP_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
func->name = name;
|
func->name = name_dup;
|
||||||
func->nargs = 0;
|
func->nargs = nargs;
|
||||||
func->body = body;
|
func->body = body;
|
||||||
|
|
||||||
|
xp_assert (xp_awk_hash_get(&awk->tree.func, name_dup) == XP_NULL);
|
||||||
|
if (xp_awk_hash_put(&awk->tree.func, name_dup, func) == XP_NULL) {
|
||||||
|
__remove_func_name (awk, fnpos);
|
||||||
|
xp_free (name_dup);
|
||||||
|
xp_awk_clrpt (body);
|
||||||
|
xp_free (func);
|
||||||
|
PANIC (awk, XP_AWK_ENOMEM);
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* TODO: weave the function body into awk->tree.funcs */
|
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,6 +462,7 @@ static xp_awk_node_t* __parse_block (xp_awk_t* awk)
|
|||||||
// TODO: cleanup the variable name list...
|
// TODO: cleanup the variable name list...
|
||||||
return XP_NULL;
|
return XP_NULL;
|
||||||
}
|
}
|
||||||
|
head = XP_NULL;
|
||||||
goto skip_block_body;
|
goto skip_block_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,7 +534,7 @@ skip_block_body:
|
|||||||
block->lvc = lvc;
|
block->lvc = lvc;
|
||||||
block->body = head;
|
block->body = head;
|
||||||
|
|
||||||
// TODO: cleanup the variable name list...
|
// TODO: cleanup the variable name list...
|
||||||
|
|
||||||
return (xp_awk_node_t*)block;
|
return (xp_awk_node_t*)block;
|
||||||
}
|
}
|
||||||
@ -1682,23 +1723,6 @@ static int __classfy_ident (const xp_char_t* ident)
|
|||||||
return TOKEN_IDENT;
|
return TOKEN_IDENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name)
|
|
||||||
{
|
|
||||||
return (xp_size_t)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (awk->curfunc != XP_NULL) {
|
|
||||||
|
|
||||||
// TODO: finish this....
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return (xp_size_t)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xp_long_t __str_to_long (const xp_char_t* name)
|
static xp_long_t __str_to_long (const xp_char_t* name)
|
||||||
{
|
{
|
||||||
xp_long_t n = 0;
|
xp_long_t n = 0;
|
||||||
@ -1710,3 +1734,38 @@ 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.func, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE int __remove_func_name (xp_awk_t* awk, xp_size_t index)
|
||||||
|
{
|
||||||
|
return xp_awk_tab_remrange (&awk->parse.func, 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.func, name, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if (awk->curfunc != XP_NULL) {
|
||||||
|
|
||||||
|
// TODO: finish this....
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return (xp_size_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static xp_size_t __find_variable (xp_awk_t* awk, const xp_char_t* name)
|
||||||
|
{
|
||||||
|
return (xp_size_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sa.h,v 1.7 2006-01-25 04:27:01 bacon Exp $
|
* $Id: sa.h,v 1.8 2006-01-29 18:28:14 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _XP_AWK_SA_H_
|
#ifndef _XP_AWK_SA_H_
|
||||||
@ -31,6 +31,9 @@
|
|||||||
#define xp_strcmp wcscmp
|
#define xp_strcmp wcscmp
|
||||||
#define xp_strlen wcslen
|
#define xp_strlen wcslen
|
||||||
|
|
||||||
|
#define xp_memcpy memcpy
|
||||||
|
#define xp_memcmp memcmp
|
||||||
|
|
||||||
#define xp_va_start(pvar,param) va_start(pvar,param)
|
#define xp_va_start(pvar,param) va_start(pvar,param)
|
||||||
#define xp_va_list va_list
|
#define xp_va_list va_list
|
||||||
#define xp_va_end(pvar) va_end(pvar)
|
#define xp_va_end(pvar) va_end(pvar)
|
||||||
|
161
ase/awk/tab.c
Normal file
161
ase/awk/tab.c
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* $Id: tab.c,v 1.1 2006-01-29 18:28:14 bacon Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xp/awk/tab.h>
|
||||||
|
#ifndef __STAND_ALONE
|
||||||
|
#include <xp/bas/memory.h>
|
||||||
|
#include <xp/bas/assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
xp_awk_tab_t* xp_awk_tab_open (xp_awk_tab_t* tab)
|
||||||
|
{
|
||||||
|
if (tab == XP_NULL) {
|
||||||
|
tab = (xp_awk_tab_t*) xp_malloc (xp_sizeof(xp_awk_tab_t));
|
||||||
|
if (tab == XP_NULL) return XP_NULL;
|
||||||
|
tab->__dynamic = xp_true;
|
||||||
|
}
|
||||||
|
else tab->__dynamic = xp_false;
|
||||||
|
|
||||||
|
tab->buf = XP_NULL;
|
||||||
|
tab->size = 0;
|
||||||
|
tab->capa = 0;
|
||||||
|
|
||||||
|
return tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xp_awk_tab_close (xp_awk_tab_t* tab)
|
||||||
|
{
|
||||||
|
xp_awk_tab_clear (tab);
|
||||||
|
if (tab->buf != XP_NULL) {
|
||||||
|
xp_free (tab->buf);
|
||||||
|
tab->buf = XP_NULL;
|
||||||
|
tab->capa = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tab->__dynamic) xp_free (tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
xp_size_t xp_awk_tab_getsize (xp_awk_tab_t* tab)
|
||||||
|
{
|
||||||
|
return tab->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
xp_size_t xp_awk_tab_getcapa (xp_awk_tab_t* tab)
|
||||||
|
{
|
||||||
|
return tab->capa;
|
||||||
|
}
|
||||||
|
|
||||||
|
xp_awk_tab_t* xp_awk_tab_setcapa (xp_awk_tab_t* tab, xp_size_t capa)
|
||||||
|
{
|
||||||
|
xp_char_t** tmp;
|
||||||
|
|
||||||
|
if (tab->size > capa) {
|
||||||
|
xp_awk_tab_remrange (tab, capa, tab->size - capa);
|
||||||
|
xp_assert (tab->size <= capa);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capa > 0) {
|
||||||
|
tmp = (xp_char_t**)xp_realloc (
|
||||||
|
tab->buf, xp_sizeof(xp_char_t*) * capa);
|
||||||
|
if (tmp == XP_NULL) return XP_NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (tab->buf != XP_NULL) xp_free (tab->buf);
|
||||||
|
tmp = XP_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tab->buf = tmp;
|
||||||
|
tab->capa = capa;
|
||||||
|
|
||||||
|
return tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xp_awk_tab_clear (xp_awk_tab_t* tab)
|
||||||
|
{
|
||||||
|
xp_size_t i;
|
||||||
|
|
||||||
|
xp_assert (tab != XP_NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < tab->size; i++) {
|
||||||
|
xp_free (tab->buf[i]);
|
||||||
|
tab->buf[i] = XP_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tab->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xp_size_t xp_awk_tab_insdatum (
|
||||||
|
xp_awk_tab_t* tab, xp_size_t index, const xp_char_t* value)
|
||||||
|
{
|
||||||
|
xp_size_t i;
|
||||||
|
xp_char_t* value_dup;
|
||||||
|
|
||||||
|
value_dup = xp_strdup(value);
|
||||||
|
if (value_dup == XP_NULL) return (xp_size_t)-1;
|
||||||
|
|
||||||
|
if (index >= tab->capa) {
|
||||||
|
xp_size_t capa;
|
||||||
|
|
||||||
|
if (tab->capa <= 0) capa = (index + 1);
|
||||||
|
else {
|
||||||
|
do { capa = tab->capa * 2; } while (index >= capa);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xp_awk_tab_setcapa(tab,capa) == XP_NULL) {
|
||||||
|
xp_free (value_dup);
|
||||||
|
return (xp_size_t)-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = tab->size; i > index; i--) tab->buf[i] = tab->buf[i-1];
|
||||||
|
tab->buf[index] = value_dup;
|
||||||
|
|
||||||
|
if (index > tab->size) tab->size = index + 1;
|
||||||
|
else tab->size++;
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
xp_size_t xp_awk_tab_remrange (
|
||||||
|
xp_awk_tab_t* tab, xp_size_t index, xp_size_t count)
|
||||||
|
{
|
||||||
|
xp_size_t i, j, k;
|
||||||
|
|
||||||
|
if (index >= tab->size) return 0;
|
||||||
|
if (count > tab->size - index) count = tab->size - index;
|
||||||
|
|
||||||
|
i = index;
|
||||||
|
j = index + count;
|
||||||
|
k = index + count;
|
||||||
|
|
||||||
|
while (i < k) {
|
||||||
|
xp_free (tab->buf[i]);
|
||||||
|
if (j >= tab->size)
|
||||||
|
tab->buf[i] = (j >= tab->size)? XP_NULL: tab->buf[j];
|
||||||
|
i++; j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
tab->size -= count;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
xp_size_t xp_awk_tab_adddatum (xp_awk_tab_t* tab, const xp_char_t* value)
|
||||||
|
{
|
||||||
|
return xp_awk_tab_insdatum (tab, tab->size, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xp_size_t xp_awk_tab_find (
|
||||||
|
xp_awk_tab_t* tab, const xp_char_t* value, xp_size_t index)
|
||||||
|
{
|
||||||
|
xp_size_t i;
|
||||||
|
|
||||||
|
for (i = index; i < tab->size; i++) {
|
||||||
|
if (xp_strcmp(tab->buf[i], value) == 0) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (xp_size_t)-1;
|
||||||
|
}
|
||||||
|
|
54
ase/awk/tab.h
Normal file
54
ase/awk/tab.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* $Id: tab.h,v 1.1 2006-01-29 18:28:14 bacon Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _XP_AWK_TAB_H_
|
||||||
|
#define _XP_AWK_TAB_H_
|
||||||
|
|
||||||
|
#ifdef __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.
|
||||||
|
// as of now, this is an arrayed table.
|
||||||
|
|
||||||
|
typedef struct xp_awk_tab_t xp_awk_tab_t;
|
||||||
|
|
||||||
|
struct xp_awk_tab_t
|
||||||
|
{
|
||||||
|
xp_char_t** buf;
|
||||||
|
xp_size_t size;
|
||||||
|
xp_size_t capa;
|
||||||
|
xp_bool_t __dynamic;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
xp_awk_tab_t* xp_awk_tab_open (xp_awk_tab_t* tab);
|
||||||
|
void xp_awk_tab_close (xp_awk_tab_t* tab);
|
||||||
|
|
||||||
|
xp_size_t xp_awk_tab_getsize (xp_awk_tab_t* tab);
|
||||||
|
xp_size_t xp_awk_tab_getcapa (xp_awk_tab_t* tab);
|
||||||
|
xp_awk_tab_t* xp_awk_tab_setcapa (xp_awk_tab_t* tab, xp_size_t capa);
|
||||||
|
|
||||||
|
void xp_awk_tab_clear (xp_awk_tab_t* tab);
|
||||||
|
|
||||||
|
xp_size_t xp_awk_tab_insdatum (
|
||||||
|
xp_awk_tab_t* tab, xp_size_t index, const xp_char_t* value);
|
||||||
|
xp_size_t xp_awk_tab_remrange (
|
||||||
|
xp_awk_tab_t* tab, xp_size_t index, xp_size_t count);
|
||||||
|
|
||||||
|
xp_size_t xp_awk_tab_adddatum (xp_awk_tab_t* tab, const xp_char_t* value);
|
||||||
|
xp_size_t xp_awk_tab_find (
|
||||||
|
xp_awk_tab_t* tab, const xp_char_t* value, xp_size_t index);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user