*** empty log message ***

This commit is contained in:
hyung-hwan 2006-01-14 14:09:52 +00:00
parent e4f41654d6
commit cb8c7535bc
6 changed files with 454 additions and 196 deletions

View File

@ -1,4 +1,4 @@
SRCS = awk.c parse.c
SRCS = awk.c parse.c tree.c
OBJS = $(SRCS:.c=.obj)
OUT = xpawk.lib

View File

@ -1,4 +1,4 @@
SRCS = awk.c parse.c
SRCS = awk.c parse.c tree.c
OBJS = $(SRCS:.c=.obj)
OUT = xpawk.lib

View File

@ -1,16 +1,14 @@
/*
* $Id: parse.c,v 1.18 2006-01-13 14:16:56 bacon Exp $
* $Id: parse.c,v 1.19 2006-01-14 14:08:57 bacon Exp $
*/
#include <xp/awk/awk.h>
#include <xp/awk/tree.h>
#include <xp/awk/tree.h>
#include <xp/bas/memory.h>
#include <xp/bas/ctype.h>
#include <xp/bas/string.h>
#include <xp/bas/assert.h>
#include <xp/bas/stdio.h>
enum
{
TOKEN_EOF,
@ -68,21 +66,12 @@ enum {
BINOP_MOD
};
static xp_char_t __binop_char[] =
{
XP_CHAR('+'),
XP_CHAR('-'),
XP_CHAR('*'),
XP_CHAR('/'),
XP_CHAR('%')
};
static xp_awk_node_t* __parse_program (xp_awk_t* awk);
static xp_awk_node_t* __parse_funcdcl (xp_awk_t* awk);
static xp_awk_node_t* __parse_patnact (xp_awk_t* awk);
static xp_awk_node_t* __parse_block (xp_awk_t* awk);
static xp_awk_node_t* __parse_stat (xp_awk_t* awk);
static xp_awk_node_t* __parse_expr (xp_awk_t* awk);
static xp_awk_node_t* __parse_statement (xp_awk_t* awk);
static xp_awk_node_t* __parse_expression (xp_awk_t* awk);
static xp_awk_node_t* __parse_assignment (xp_awk_t* awk, xp_char_t* ident);
static xp_awk_node_t* __parse_basic_expr (xp_awk_t* awk, xp_char_t* ident);
static xp_awk_node_t* __parse_additive (xp_awk_t* awk, xp_char_t* ident);
@ -96,6 +85,8 @@ static xp_awk_node_t* __parse_for (xp_awk_t* awk);
static xp_awk_node_t* __parse_do (xp_awk_t* awk);
static xp_awk_node_t* __parse_break (xp_awk_t* awk);
static xp_awk_node_t* __parse_continue (xp_awk_t* awk);
static xp_awk_node_t* __parse_return (xp_awk_t* awk);
static xp_awk_node_t* __parse_exit (xp_awk_t* awk);
static int __get_token (xp_awk_t* awk);
static int __get_char (xp_awk_t* awk);
@ -160,75 +151,8 @@ static struct __kwent __kwtab[] =
#define PANIC(awk,code) do { (awk)->errnum = (code); return XP_NULL; } while (0);
void __print_tabs (int depth)
{
int i;
for (i = 0; i < depth; i++) xp_printf (XP_TEXT("\t"));
}
void __print_parse_tree (xp_awk_node_t* tree, int depth)
{
xp_awk_node_t* p;
p = tree;
while (p != XP_NULL) {
if (p->type == XP_AWK_NODE_BLOCK) {
__print_tabs (depth);
xp_printf (XP_TEXT("{\n"));
__print_parse_tree (((xp_awk_node_block_t*)p)->body, depth + 1);
__print_tabs (depth);
xp_printf (XP_TEXT("}\n"));
}
else if (p->type == XP_AWK_NODE_BREAK) {
__print_tabs (depth);
xp_printf (XP_TEXT("break;\n"));
}
else if (p->type == XP_AWK_NODE_CONTINUE) {
__print_tabs (depth);
xp_printf (XP_TEXT("continue;\n"));
}
else if (p->type == XP_AWK_NODE_ASSIGN) {
__print_tabs (depth);
xp_printf (XP_TEXT("%s = "), ((xp_awk_node_assign_t*)p)->left);
__print_parse_tree (((xp_awk_node_assign_t*)p)->right, 0);
xp_printf (XP_TEXT(";\n"));
}
else if (p->type == XP_AWK_NODE_BINARY) {
xp_printf (XP_TEXT("("));
__print_parse_tree (((xp_awk_node_expr_t*)p)->left, 0);
xp_printf (XP_TEXT(" %c "), __binop_char[((xp_awk_node_expr_t*)p)->opcode]);
__print_parse_tree (((xp_awk_node_expr_t*)p)->right, 0);
xp_printf (XP_TEXT(")"));
}
else if (p->type == XP_AWK_NODE_UNARY) {
xp_printf (XP_TEXT("unary basic expression\n"));
}
else if (p->type == XP_AWK_NODE_STR) {
xp_printf (XP_TEXT("\"%s\""), ((xp_awk_node_term_t*)p)->value);
}
else if (p->type == XP_AWK_NODE_NUM) {
xp_printf (XP_TEXT("%s"), ((xp_awk_node_term_t*)p)->value);
}
else if (p->type == XP_AWK_NODE_VAR) {
xp_printf (XP_TEXT("%s"), ((xp_awk_node_term_t*)p)->value);
}
else if (p->type == XP_AWK_NODE_CALL) {
xp_printf (XP_TEXT("%s ("), ((xp_awk_node_call_t*)p)->name);
__print_parse_tree (((xp_awk_node_call_t*)p)->args, 0); // TODO: improve this... comman-separated...
xp_printf (XP_TEXT(")"));
}
p = p->next;
}
}
void print_parse_tree (xp_awk_node_t* tree)
{
__print_parse_tree (tree, 0);
}
// TODO remove stdio.h
#include <xp/bas/stdio.h>
int xp_awk_parse (xp_awk_t* awk)
{
@ -272,7 +196,6 @@ break;
return node;
}
static xp_awk_node_t* __parse_funcdcl (xp_awk_t* awk)
{
return XP_NULL;
@ -295,152 +218,160 @@ static xp_awk_node_t* __parse_patnact (xp_awk_t* awk)
xp_awk_node_t* node;
if (MATCH(awk,TOKEN_BEGIN)) {
CONSUME (awk);
if (__get_token(awk) == -1) return XP_NULL;
}
else if (MATCH(awk,TOKEN_END)) {
CONSUME (awk);
if (__get_token(awk) == -1) return XP_NULL;
}
/* patterns ...
* etc */
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;
CONSUME (awk);
node = __parse_block(awk);
if (node == XP_NULL) return XP_NULL;
return node;
}
/* 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_awk_node_block_t* blk;
xp_awk_node_t* node, * prev;
xp_awk_node_t* head, * curr, * node;
xp_awk_node_block_t* block;
blk = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t));
if (blk == XP_NULL) {
/* TODO: do some clean-up */
PANIC (awk, XP_AWK_ENOMEM);
}
blk->type = XP_AWK_NODE_BLOCK;
blk->next = XP_NULL;
blk->body = prev = XP_NULL;
head = XP_NULL; curr = XP_NULL;
while (1) {
if (MATCH(awk,TOKEN_EOF)) {
/* TODO: do come clean-up */
if (curr != XP_NULL) xp_awk_clrpt (curr);
PANIC (awk, XP_AWK_EENDSRC);
}
if (MATCH(awk,TOKEN_RBRACE)) {
/* TODO: should finalize a block */
CONSUME (awk);
if (__get_token(awk) == -1) {
if (curr != XP_NULL) xp_awk_clrpt (curr);
return XP_NULL;
}
break;
}
if (MATCH(awk, TOKEN_SEMICOLON)) {
if (MATCH(awk,TOKEN_SEMICOLON)) {
/* null statement */
CONSUME (awk);
if (__get_token(awk) == -1) {
if (curr != XP_NULL) xp_awk_clrpt (curr);
return XP_NULL;
}
continue;
}
if (MATCH(awk,TOKEN_LBRACE)) {
/* nested block */
CONSUME (awk);
node = __parse_block(awk);
if (__get_token(awk) == -1) {
if (curr != XP_NULL) xp_awk_clrpt (curr);
return XP_NULL;
}
else node = __parse_stat (awk);
node = __parse_block (awk);
}
else node = __parse_statement (awk);
if (node == XP_NULL) return XP_NULL;
if (prev == XP_NULL) blk->body = node;
else prev->next = node;
prev = node;
if (node == XP_NULL) {
if (curr != XP_NULL) xp_awk_clrpt (curr);
return XP_NULL;
}
return (xp_awk_node_t*)blk;
if (curr == XP_NULL) head = node;
else curr->next = node;
curr = node;
}
block = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t));
if (block == XP_NULL) {
xp_awk_clrpt (head);
PANIC (awk, XP_AWK_ENOMEM);
}
block->type = XP_AWK_NODE_BLOCK;
block->next = XP_NULL;
block->body = head;
return (xp_awk_node_t*)block;
}
static xp_awk_node_t* __parse_stat (xp_awk_t* awk)
static xp_awk_node_t* __parse_statement (xp_awk_t* awk)
{
xp_awk_node_t* node;
if (MATCH(awk,TOKEN_IF)) {
CONSUME (awk);
if (__get_token(awk) == -1) return XP_NULL;
node = __parse_if(awk);
}
else if (MATCH(awk,TOKEN_WHILE)) {
CONSUME (awk);
if (__get_token(awk) == -1) return XP_NULL;
node = __parse_while(awk);
}
else if (MATCH(awk,TOKEN_FOR)) {
CONSUME (awk);
if (__get_token(awk) == -1) return XP_NULL;
node = __parse_for(awk);
}
else if (MATCH(awk,TOKEN_DO)) {
CONSUME (awk);
if (__get_token(awk) == -1) return XP_NULL;
node = __parse_do(awk);
}
else if (MATCH(awk,TOKEN_BREAK)) {
CONSUME (awk);
if (__get_token(awk) == -1) return XP_NULL;
node = __parse_break(awk);
}
else if (MATCH(awk,TOKEN_CONTINUE)) {
CONSUME (awk);
if (__get_token(awk) == -1) return XP_NULL;
node = __parse_continue(awk);
}
else if (MATCH(awk,TOKEN_RETURN)) {
CONSUME (awk);
/* TOOD: */
node = XP_NULL;
if (__get_token(awk) == -1) return XP_NULL;
node = __parse_return(awk);
}
else if (MATCH(awk,TOKEN_EXIT)) {
CONSUME (awk);
/* TOOD: */
node = XP_NULL;
if (__get_token(awk) == -1) return XP_NULL;
node = __parse_exit(awk);
}
/*
TODO:
else if (MATCH(awk,TOKEN_DELETE)) {
CONSUME (awk);
/* TOOD: */
if (__get_token(awk) == -1) return XP_NULL;
node = XP_NULL;
}
else if (MATCH(awk,TOKEN_NEXT)) {
CONSUME (awk);
/* TOOD: */
if (__get_token(awk) == -1) return XP_NULL;
node = XP_NULL;
}
else if (MATCH(awk,TOKEN_NEXTFILE)) {
CONSUME (awk);
/* TOOD: */
if (__get_token(awk) == -1) return XP_NULL;
node = XP_NULL;
}
*/
else {
node = __parse_expr(awk);
node = __parse_expression(awk);
}
if (node == XP_NULL) {
// TODO: clean-up
return XP_NULL;
}
if (node == XP_NULL) return XP_NULL;
/* check if a statement ends with a semicolon */
if (!MATCH(awk,TOKEN_SEMICOLON)) {
/* TODO: do some clean-up */
if (node != XP_NULL) xp_awk_clrpt (node);
PANIC (awk, XP_AWK_ESEMICOLON);
}
/* eat up the semicolon and read in the next token */
CONSUME (awk);
if (__get_token(awk) == -1) {
if (node != XP_NULL) xp_awk_clrpt (node);
return XP_NULL;
}
return node;
}
static xp_awk_node_t* __parse_expr (xp_awk_t* awk)
static xp_awk_node_t* __parse_expression (xp_awk_t* awk)
{
/*
* <expression> ::= <assignment> | <basic expression>
@ -448,29 +379,38 @@ static xp_awk_node_t* __parse_expr (xp_awk_t* awk)
* assignmentOperator ::= '='
* <basic expression> ::=
*/
xp_awk_node_t* x;
if (MATCH(awk,TOKEN_IDENT)) {
// TODO: use a different approach later...
xp_char_t* ident = xp_strdup (XP_STR_BUF(&awk->token.name));
if (ident == XP_NULL) {
// TODO: memory clean up
PANIC (awk, XP_AWK_ENOMEM);
}
/* the expression starts with an identifier */
CONSUME (awk);
xp_char_t* ident = xp_strdup (XP_STR_BUF(&awk->token.name));
if (ident == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
if (__get_token(awk) == -1) {
xp_free (ident);
return XP_NULL;
}
if (MATCH(awk,TOKEN_ASSIGN)) {
CONSUME (awk);
x = __parse_assignment(awk, ident);
if (__get_token(awk) == -1) {
xp_free (ident);
return XP_NULL;
}
x = __parse_assignment (awk, ident);
}
else x = __parse_basic_expr (awk, ident);
xp_free (ident);
return x; // TODO: anything to clearn when x is XP_NULL????
}
else {
/* the expression starts with a non-identifier */
// TODO: maybe this should be an error ->>> just an expression without assignment */
x = __parse_basic_expr (awk, XP_NULL);
}
// TODO: maybe this shoudl be an error ->>> just an expression without assignment */
return __parse_basic_expr (awk, XP_NULL);
return x;
}
static xp_awk_node_t* __parse_assignment (xp_awk_t* awk, xp_char_t* ident)
@ -535,20 +475,20 @@ static xp_awk_node_t* __parse_additive (xp_awk_t* awk, xp_char_t* ident)
else break;
if (__get_token(awk) == -1) {
// TODO: cleanup left...
xp_awk_clrpt (left);
return XP_NULL;
}
right = __parse_multiplicative (awk, XP_NULL);
if (right == XP_NULL) {
// TOOD: cleanup left if necessary
xp_awk_clrpt (left);
return XP_NULL;
}
node = (xp_awk_node_expr_t*)xp_malloc(xp_sizeof(xp_awk_node_expr_t));
if (node == XP_NULL) {
// TODO: cleanup previous tmp (maybe current left) if necessary
// TOOD: cleanup left if necessary
xp_awk_clrpt (right);
xp_awk_clrpt (left);
PANIC (awk, XP_AWK_ENOMEM);
}
@ -579,17 +519,21 @@ static xp_awk_node_t* __parse_multiplicative (xp_awk_t* awk, xp_char_t* ident)
else if (MATCH(awk,TOKEN_MOD)) opcode = BINOP_MOD;
else break;
CONSUME (awk);
if (__get_token(awk) == -1) {
xp_awk_clrpt (left);
return XP_NULL;
}
right = __parse_unary (awk, XP_NULL);
if (right == XP_NULL) {
// TOOD: cleanup left if necessary
xp_awk_clrpt (left);
return XP_NULL;
}
node = (xp_awk_node_expr_t*)xp_malloc(xp_sizeof(xp_awk_node_expr_t));
if (node == XP_NULL) {
// TODO: cleanup previous tmp (maybe current left) if necessary
// TOOD: cleanup left if necessary
xp_awk_clrpt (right);
xp_awk_clrpt (left);
PANIC (awk, XP_AWK_ENOMEM);
}
@ -622,7 +566,11 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk, xp_char_t* ident)
else {
name = (xp_char_t*)xp_strdup(XP_STR_BUF(&awk->token.name));
if (name == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
CONSUME (awk); // error handling... replace it by get_token...
if (__get_token(awk) == -1) {
xp_free (name);
return XP_NULL;
}
}
if (MATCH(awk,TOKEN_LPAREN)) {
@ -663,7 +611,12 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk, xp_char_t* ident)
PANIC (awk, XP_AWK_ENOMEM);
}
CONSUME (awk);
if (__get_token(awk) == -1) {
xp_free (node->value);
xp_free (node);
return XP_NULL;
}
return (xp_awk_node_t*)node;
}
else if (MATCH(awk,TOKEN_STRING)) {
@ -680,21 +633,34 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk, xp_char_t* ident)
PANIC (awk, XP_AWK_ENOMEM);
}
CONSUME (awk);
if (__get_token(awk) == -1) {
xp_free (node->value);
xp_free (node);
return XP_NULL;
}
return (xp_awk_node_t*)node;
}
else if (MATCH(awk,TOKEN_LPAREN)) {
xp_awk_node_t* node;
CONSUME (awk);
node = __parse_expr (awk);
/* eat up the left parenthesis */
if (__get_token(awk) == -1) return XP_NULL;
/* parse the sub-expression inside the parentheses */
node = __parse_expression (awk);
if (node == XP_NULL) return XP_NULL;
/* check for the closing parenthesis */
if (!MATCH(awk,TOKEN_RPAREN)) {
// TODO: free tmp...
xp_awk_clrpt (node);
PANIC (awk, XP_AWK_ERPAREN);
}
CONSUME (awk);
if (__get_token(awk) == -1) {
xp_awk_clrpt (node);
return XP_NULL;
}
return node;
}
@ -705,9 +671,12 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk, xp_char_t* ident)
static xp_awk_node_t* __parse_funcall (xp_awk_t* awk, xp_char_t* name)
{
xp_awk_node_t* head, * curr, * tmp;
xp_awk_node_call_t* node;
xp_awk_node_t* tmp, * cur;
if (__get_token(awk) == -1) return XP_NULL;
if (MATCH(awk,TOKEN_RPAREN)) {
node = (xp_awk_node_call_t*)xp_malloc (xp_sizeof(xp_awk_node_call_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
@ -716,27 +685,28 @@ static xp_awk_node_t* __parse_funcall (xp_awk_t* awk, xp_char_t* name)
node->name = name;
node->args = XP_NULL;
CONSUME (awk);
if (MATCH(awk,TOKEN_RPAREN)) {
CONSUME (awk);
if (__get_token(awk) == -1) return XP_NULL;
return (xp_awk_node_t*)node;
}
cur = XP_NULL;
head = curr = XP_NULL;
while (1) {
tmp = __parse_expr (awk);
tmp = __parse_expression (awk);
if (tmp == XP_NULL) {
// TODO: free all other nodes associated into node->args
if (cur != XP_NULL) xp_awk_clrpt (cur);
xp_free (node);
return XP_NULL;
}
if (cur == XP_NULL) node->args = tmp;
else cur->next = tmp;
cur = tmp;
if (head == XP_NULL) head = tmp;
else curr->next = tmp;
curr = tmp;
if (MATCH(awk,TOKEN_RPAREN)) {
CONSUME (awk);
if (__get_token(awk) == -1) {
// TODO cleanup.
return XP_NULL;
}
break;
}
@ -746,8 +716,19 @@ static xp_awk_node_t* __parse_funcall (xp_awk_t* awk, xp_char_t* name)
PANIC (awk, XP_AWK_ECOMMA);
}
CONSUME (awk);
if (__get_token(awk) == -1) {
// TODO cleanup.
return XP_NULL;
}
}
node = (xp_awk_node_call_t*)xp_malloc (xp_sizeof(xp_awk_node_call_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_CALL;
node->next = XP_NULL;
node->name = name;
node->args = head;
return (xp_awk_node_t*)node;
}
@ -781,7 +762,6 @@ static xp_awk_node_t* __parse_break (xp_awk_t* awk)
node->type = XP_AWK_NODE_BREAK;
node->next = XP_NULL;
/* TODO: do i have to consume a semicolon here???? */
return node;
}
@ -794,10 +774,49 @@ static xp_awk_node_t* __parse_continue (xp_awk_t* awk)
node->type = XP_AWK_NODE_CONTINUE;
node->next = XP_NULL;
/* TODO: do i have to consume a semicolon here???? */
return node;
}
static xp_awk_node_t* __parse_return (xp_awk_t* awk)
{
xp_awk_node_block_t* node;
xp_awk_node_t* val;
node = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_RETURN;
node->next = XP_NULL;
val = __parse_expression (awk);
if (val == XP_NULL) {
xp_free (node);
return XP_NULL;
}
node->body = val;
return (xp_awk_node_t*)node;
}
static xp_awk_node_t* __parse_exit (xp_awk_t* awk)
{
xp_awk_node_block_t* node;
xp_awk_node_t* val;
node = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_EXIT;
node->next = XP_NULL;
val = __parse_expression (awk);
if (val == XP_NULL) {
xp_free (node);
return XP_NULL;
}
node->body = val;
return (xp_awk_node_t*)node;
}
static int __get_token (xp_awk_t* awk)
{
xp_cint_t c;

226
ase/awk/tree.c Normal file
View File

@ -0,0 +1,226 @@
/*
* $Id: tree.c,v 1.1 2006-01-14 14:09:52 bacon Exp $
*/
#include <xp/awk/awk.h>
#include <xp/bas/memory.h>
#include <xp/bas/assert.h>
#include <xp/bas/stdio.h>
static xp_char_t __binop_char[] =
{
XP_CHAR('+'),
XP_CHAR('-'),
XP_CHAR('*'),
XP_CHAR('/'),
XP_CHAR('%')
};
static void __print_tabs (int depth);
static int __print_expr_node (xp_awk_node_t* node);
static int __print_expr_node_list (xp_awk_node_t* tree);
static void __print_statements (xp_awk_node_t* tree, int depth);
static void __print_tabs (int depth)
{
int i;
for (i = 0; i < depth; i++) xp_printf (XP_TEXT("\t"));
}
static int __print_expr_node (xp_awk_node_t* node)
{
switch (node->type) {
case XP_AWK_NODE_ASSIGN:
xp_printf (XP_TEXT("%s = "), ((xp_awk_node_assign_t*)node)->left);
if (__print_expr_node (((xp_awk_node_assign_t*)node)->right) == -1) return -1;
xp_assert ((((xp_awk_node_assign_t*)node)->right)->next == XP_NULL);
break;
case XP_AWK_NODE_BINARY:
xp_printf (XP_TEXT("("));
if (__print_expr_node (((xp_awk_node_expr_t*)node)->left) == -1) return -1;
xp_assert ((((xp_awk_node_expr_t*)node)->left)->next == XP_NULL);
xp_printf (XP_TEXT(" %c "), __binop_char[((xp_awk_node_expr_t*)node)->opcode]);
if (__print_expr_node (((xp_awk_node_expr_t*)node)->right) == -1) return -1;
xp_assert ((((xp_awk_node_expr_t*)node)->right)->next == XP_NULL);
xp_printf (XP_TEXT(")"));
break;
case XP_AWK_NODE_UNARY:
// TODO:
xp_printf (XP_TEXT("unary basic expression\n"));
break;
case XP_AWK_NODE_STR:
xp_printf (XP_TEXT("\"%s\""), ((xp_awk_node_term_t*)node)->value);
break;
case XP_AWK_NODE_NUM:
xp_printf (XP_TEXT("%s"), ((xp_awk_node_term_t*)node)->value);
break;
case XP_AWK_NODE_VAR:
xp_printf (XP_TEXT("%s"), ((xp_awk_node_term_t*)node)->value);
break;
case XP_AWK_NODE_CALL:
xp_printf (XP_TEXT("%s ("), ((xp_awk_node_call_t*)node)->name);
if (__print_expr_node_list (((xp_awk_node_call_t*)node)->args) == -1) return -1;
xp_printf (XP_TEXT(")"));
break;
default:
return -1;
}
return 0;
}
static int __print_expr_node_list (xp_awk_node_t* tree)
{
xp_awk_node_t* p = tree;
while (p != XP_NULL) {
if (__print_expr_node (p) == -1) return -1;
p = p->next;
if (p != XP_NULL) xp_printf (XP_TEXT(","));
}
return 0;
}
static void __print_statements (xp_awk_node_t* tree, int depth)
{
xp_awk_node_t* p = tree;
while (p != XP_NULL) {
switch (p->type) {
case XP_AWK_NODE_BLOCK:
__print_tabs (depth);
xp_printf (XP_TEXT("{\n"));
__print_statements (((xp_awk_node_block_t*)p)->body, depth + 1);
__print_tabs (depth);
xp_printf (XP_TEXT("}\n"));
break;
case XP_AWK_NODE_BREAK:
__print_tabs (depth);
xp_printf (XP_TEXT("break;\n"));
break;
case XP_AWK_NODE_CONTINUE:
__print_tabs (depth);
xp_printf (XP_TEXT("continue;\n"));
break;
case XP_AWK_NODE_RETURN:
__print_tabs (depth);
xp_printf (XP_TEXT("return "));
xp_assert (((xp_awk_node_block_t*)p)->body->next == XP_NULL);
if (__print_expr_node(((xp_awk_node_block_t*)p)->body) == 0) {
xp_printf (XP_TEXT(";\n"));
}
else {
xp_awk_node_block_t* x = (xp_awk_node_block_t*)p;
xp_printf (XP_TEXT("***INTERNAL ERROR: unknown node type - %d\n"), x->type);
}
break;
case XP_AWK_NODE_EXIT:
__print_tabs (depth);
xp_printf (XP_TEXT("exit "));
xp_assert (((xp_awk_node_block_t*)p)->body->next == XP_NULL);
if (__print_expr_node(((xp_awk_node_block_t*)p)->body) == 0) {
xp_printf (XP_TEXT(";\n"));
}
else {
xp_awk_node_block_t* x = (xp_awk_node_block_t*)p;
xp_printf (XP_TEXT("***INTERNAL ERROR: unknown node type - %d\n"), x->type);
}
break;
default:
__print_tabs (depth);
if (__print_expr_node(p) == 0) {
xp_printf (XP_TEXT(";\n"));
}
else {
xp_printf (XP_TEXT("***INTERNAL ERROR: unknown type - %d\n"), p->type);
}
}
p = p->next;
}
}
void xp_awk_prnpt (xp_awk_node_t* tree)
{
__print_statements (tree, 0);
}
void xp_awk_clrpt (xp_awk_node_t* tree)
{
xp_awk_node_t* p = tree;
xp_awk_node_t* next;
while (p != XP_NULL) {
next = p->next;
switch (p->type) {
case XP_AWK_NODE_BLOCK:
xp_awk_clrpt (((xp_awk_node_block_t*)p)->body);
xp_free (p);
break;
case XP_AWK_NODE_BREAK:
case XP_AWK_NODE_CONTINUE:
xp_free (p);
break;
case XP_AWK_NODE_RETURN:
case XP_AWK_NODE_EXIT:
xp_awk_clrpt (((xp_awk_node_block_t*)p)->body);
xp_free (p);
break;
case XP_AWK_NODE_ASSIGN:
xp_free (((xp_awk_node_assign_t*)p)->left);
xp_awk_clrpt (((xp_awk_node_assign_t*)p)->right);
xp_free (p);
break;
case XP_AWK_NODE_BINARY:
xp_assert ((((xp_awk_node_expr_t*)p)->left)->next == XP_NULL);
xp_assert ((((xp_awk_node_expr_t*)p)->right)->next == XP_NULL);
xp_awk_clrpt (((xp_awk_node_expr_t*)p)->left);
xp_awk_clrpt (((xp_awk_node_expr_t*)p)->right);
xp_free (p);
break;
case XP_AWK_NODE_UNARY:
// TODO: clear unary expression...
xp_free (p);
break;
case XP_AWK_NODE_STR:
case XP_AWK_NODE_NUM:
case XP_AWK_NODE_VAR:
xp_free (((xp_awk_node_term_t*)p)->value);
xp_free (p);
break;
case XP_AWK_NODE_CALL:
xp_free (((xp_awk_node_call_t*)p)->name);
xp_awk_clrpt (((xp_awk_node_call_t*)p)->args);
xp_free (p);
break;
default:
xp_assert (XP_TEXT("shoud not happen") == XP_TEXT(" here"));
}
p = next;
}
}

View File

@ -1,5 +1,5 @@
/*
* $Id: tree.h,v 1.7 2006-01-13 14:16:56 bacon Exp $
* $Id: tree.h,v 1.8 2006-01-14 14:08:58 bacon Exp $
*/
#ifndef _XP_AWK_TREE_H_
@ -10,6 +10,8 @@ enum
XP_AWK_NODE_BLOCK,
XP_AWK_NODE_BREAK,
XP_AWK_NODE_CONTINUE,
XP_AWK_NODE_RETURN,
XP_AWK_NODE_EXIT,
XP_AWK_NODE_ASSIGN,
XP_AWK_NODE_BINARY,
XP_AWK_NODE_UNARY,
@ -94,4 +96,15 @@ struct xp_awk_node_do_t
xp_awk_node_t* test;
};
#ifdef __cplusplus
extern "C" {
#endif
void xp_awk_prnpt (xp_awk_node_t* tree);
void xp_awk_clrpt (xp_awk_node_t* tree);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -50,8 +50,8 @@ int xp_main (int argc, xp_char_t* argv[])
return -1;
}
xp_printf (XP_TEXT("-----------------------------------------------\n"));
print_parse_tree (awk.tree);
xp_printf (XP_TEXT("-----------------------------------------------\n"));
xp_awk_prnpt (awk.tree);
xp_awk_close (&awk);
return 0;