*** empty log message ***

This commit is contained in:
hyung-hwan 2006-08-03 15:50:04 +00:00
parent aaad83e199
commit 40c5fef59c
7 changed files with 110 additions and 47 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h,v 1.86 2006-08-03 09:53:42 bacon Exp $
* $Id: awk.h,v 1.87 2006-08-03 15:49:37 bacon Exp $
*/
#ifndef _XP_AWK_AWK_H_
@ -146,6 +146,8 @@ enum
XP_AWK_EWHILE, /* keyword 'while' is expected */
XP_AWK_EASSIGNMENT, /* assignment statement expected */
XP_AWK_EIDENT, /* identifier expected */
XP_AWK_EBEGINBLOCK, /* BEGIN requires an action block */
XP_AWK_EENDBLOCK, /* END requires an action block */
XP_AWK_EDUPBEGIN, /* duplicate BEGIN */
XP_AWK_EDUPEND, /* duplicate END */
XP_AWK_EDUPFUNC, /* duplicate function name */
@ -175,6 +177,8 @@ enum
XP_AWK_ENOTSCALARIZABLE, /* not scalarizable variable */
XP_AWK_EVALTYPE, /* wrong value type */
XP_AWK_EPIPE, /* pipe operation error */
XP_AWK_ENEXTCALL, /* next called from BEGIN or END */
XP_AWK_ENEXTFILECALL, /* nextfile called from BEGIN or END */
XP_AWK_EIOIMPL, /* wrong implementation of user io handler */
XP_AWK_EINTERNAL /* internal error */
};

View File

@ -1,5 +1,5 @@
/*
* $Id: awk_i.h,v 1.37 2006-08-02 14:36:22 bacon Exp $
* $Id: awk_i.h,v 1.38 2006-08-03 15:49:37 bacon Exp $
*/
#ifndef _XP_AWK_AWKI_H_
@ -177,6 +177,8 @@ struct xp_awk_run_t
xp_size_t icache_count;
xp_size_t rcache_count;
xp_awk_nde_blk_t* active_block;
struct
{
xp_char_t buf[1024];

View File

@ -1,5 +1,5 @@
/*
* $Id: err.c,v 1.30 2006-08-03 09:53:42 bacon Exp $
* $Id: err.c,v 1.31 2006-08-03 15:49:37 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -64,6 +64,8 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
XP_T("keyword 'while' expected"),
XP_T("assignment statement expected"),
XP_T("identifier expected"),
XP_T("BEGIN requires an action block"),
XP_T("END requires an action block"),
XP_T("duplicate BEGIN"),
XP_T("duplicate END"),
XP_T("duplicate function name"),
@ -92,8 +94,9 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk)
XP_T("variable not scalarizable"),
XP_T("wrong value type"),
XP_T("pipe operation error"),
XP_T("next cannot be called from the BEGIN or END block"),
XP_T("nextfile cannot be called from the BEGIN or END block"),
XP_T("wrong implementation of user-defined io handler"),
XP_T("internal error that should never have happened")
};

View File

@ -1,5 +1,5 @@
/*
* $Id: parse.c,v 1.154 2006-08-03 09:58:15 bacon Exp $
* $Id: parse.c,v 1.155 2006-08-03 15:49:37 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -102,12 +102,14 @@ enum
enum
{
PARSE_BLOCK_GLOBAL,
PARSE_BLOCK_FUNCTION,
PARSE_BLOCK_BEGIN,
PARSE_BLOCK_END,
PARSE_BLOCK_PATTERN,
PARSE_BLOCK_ACTION
PARSE_GLOBAL,
PARSE_FUNCTION,
PARSE_BEGIN,
PARSE_END,
PARSE_BEGIN_BLOCK,
PARSE_END_BLOCK,
PARSE_PATTERN,
PARSE_ACTION_BLOCK
};
enum
@ -139,7 +141,6 @@ static xp_awk_nde_t* __parse_end (xp_awk_t* awk);
static xp_awk_chain_t* __parse_pattern_block (
xp_awk_t* awk, xp_awk_nde_t* ptn, xp_bool_t blockless);
static xp_awk_nde_t* __parse_action (xp_awk_t* awk);
static xp_awk_nde_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top);
static xp_awk_nde_t* __parse_statement (xp_awk_t* awk);
static xp_awk_nde_t* __parse_statement_nb (xp_awk_t* awk);
@ -456,7 +457,7 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
{
xp_size_t nglobals;
awk->parse.id.block = PARSE_BLOCK_GLOBAL;
awk->parse.id.block = PARSE_GLOBAL;
if (__get_token(awk) == -1) return XP_NULL;
@ -471,23 +472,49 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
}
else if (MATCH(awk,TOKEN_FUNCTION))
{
awk->parse.id.block = PARSE_BLOCK_FUNCTION;
awk->parse.id.block = PARSE_FUNCTION;
if (__parse_function (awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_BEGIN))
{
awk->parse.id.block = PARSE_BLOCK_BEGIN;
awk->parse.id.block = PARSE_BEGIN;
if (__get_token(awk) == -1) return XP_NULL;
if ((awk->opt.parse & XP_AWK_BLOCKLESS) &&
(MATCH(awk,TOKEN_NEWLINE) || MATCH(awk,TOKEN_EOF)))
{
/* when the blockless pattern is supported
* BEGIN and { should be located on the same line */
PANIC (awk, XP_AWK_EBEGINBLOCK);
}
if (!MATCH(awk,TOKEN_LBRACE)) PANIC (awk, XP_AWK_ELBRACE);
awk->parse.id.block = PARSE_BEGIN_BLOCK;
if (__parse_begin (awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_END))
{
awk->parse.id.block = PARSE_BLOCK_END;
awk->parse.id.block = PARSE_END;
if (__get_token(awk) == -1) return XP_NULL;
if ((awk->opt.parse & XP_AWK_BLOCKLESS) &&
(MATCH(awk,TOKEN_NEWLINE) || MATCH(awk,TOKEN_EOF)))
{
/* when the blockless pattern is supported
* END and { should be located on the same line */
PANIC (awk, XP_AWK_EENDBLOCK);
}
if (!MATCH(awk,TOKEN_LBRACE)) PANIC (awk, XP_AWK_ELBRACE);
awk->parse.id.block = PARSE_END_BLOCK;
if (__parse_end (awk) == XP_NULL) return XP_NULL;
}
else if (MATCH(awk,TOKEN_LBRACE))
{
/* patternless block */
awk->parse.id.block = PARSE_BLOCK_ACTION;
awk->parse.id.block = PARSE_ACTION_BLOCK;
if (__parse_pattern_block (
awk, XP_NULL, xp_false) == XP_NULL) return XP_NULL;
}
@ -504,7 +531,7 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
*/
xp_awk_nde_t* ptn;
awk->parse.id.block = PARSE_BLOCK_PATTERN;
awk->parse.id.block = PARSE_PATTERN;
ptn = __parse_expression (awk);
if (ptn == XP_NULL) return XP_NULL;
@ -531,10 +558,9 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
(MATCH(awk,TOKEN_NEWLINE) || MATCH(awk,TOKEN_EOF)))
{
/* blockless pattern */
xp_bool_t newline = MATCH(awk,TOKEN_NEWLINE);
awk->parse.id.block = PARSE_BLOCK_ACTION;
awk->parse.id.block = PARSE_ACTION_BLOCK;
if (__parse_pattern_block (
awk, ptn, xp_true) == XP_NULL)
{
@ -554,14 +580,13 @@ static xp_awk_t* __parse_progunit (xp_awk_t* awk)
else
{
/* parse the action block */
if (!MATCH(awk,TOKEN_LBRACE))
{
xp_awk_clrpt (ptn);
PANIC (awk, XP_AWK_ELBRACE);
}
awk->parse.id.block = PARSE_BLOCK_ACTION;
awk->parse.id.block = PARSE_ACTION_BLOCK;
if (__parse_pattern_block (
awk, ptn, xp_false) == XP_NULL)
{
@ -586,6 +611,7 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk)
int n;
/* eat up the keyword 'function' and get the next token */
xp_assert (MATCH(awk,TOKEN_FUNCTION));
if (__get_token(awk) == -1) return XP_NULL;
/* match a function name */
@ -802,10 +828,10 @@ static xp_awk_nde_t* __parse_begin (xp_awk_t* awk)
{
xp_awk_nde_t* nde;
if (awk->tree.begin != XP_NULL) PANIC (awk, XP_AWK_EDUPBEGIN);
if (__get_token(awk) == -1) return XP_NULL;
xp_assert (MATCH(awk,TOKEN_LBRACE));
nde = __parse_action (awk);
if (__get_token(awk) == -1) return XP_NULL;
nde = __parse_block(awk, xp_true);
if (nde == XP_NULL) return XP_NULL;
awk->tree.begin = nde;
@ -816,10 +842,10 @@ static xp_awk_nde_t* __parse_end (xp_awk_t* awk)
{
xp_awk_nde_t* nde;
if (awk->tree.end != XP_NULL) PANIC (awk, XP_AWK_EDUPEND);
if (__get_token(awk) == -1) return XP_NULL;
xp_assert (MATCH(awk,TOKEN_LBRACE));
nde = __parse_action (awk);
if (__get_token(awk) == -1) return XP_NULL;
nde = __parse_block(awk, xp_true);
if (nde == XP_NULL) return XP_NULL;
awk->tree.end = nde;
@ -835,7 +861,9 @@ static xp_awk_chain_t* __parse_pattern_block (
if (blockless) nde = XP_NULL;
else
{
nde = __parse_action (awk);
xp_assert (MATCH(awk,TOKEN_LBRACE));
if (__get_token(awk) == -1) return XP_NULL;
nde = __parse_block(awk, xp_true);
if (nde == XP_NULL) return XP_NULL;
}
@ -865,13 +893,6 @@ static xp_awk_chain_t* __parse_pattern_block (
return chain;
}
static xp_awk_nde_t* __parse_action (xp_awk_t* awk)
{
if (!MATCH(awk,TOKEN_LBRACE)) PANIC (awk, XP_AWK_ELBRACE);
if (__get_token(awk) == -1) return XP_NULL;
return __parse_block(awk, xp_true);
}
static xp_awk_nde_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top)
{
xp_awk_nde_t* head, * curr, * nde;
@ -3160,8 +3181,8 @@ static xp_awk_nde_t* __parse_next (xp_awk_t* awk)
{
xp_awk_nde_next_t* nde;
if (awk->parse.id.block == PARSE_BLOCK_BEGIN ||
awk->parse.id.block == PARSE_BLOCK_END)
if (awk->parse.id.block == PARSE_BEGIN_BLOCK ||
awk->parse.id.block == PARSE_END_BLOCK)
{
PANIC (awk, XP_AWK_ENEXT);
}
@ -3178,8 +3199,8 @@ static xp_awk_nde_t* __parse_nextfile (xp_awk_t* awk)
{
xp_awk_nde_nextfile_t* nde;
if (awk->parse.id.block == PARSE_BLOCK_BEGIN ||
awk->parse.id.block == PARSE_BLOCK_END)
if (awk->parse.id.block == PARSE_BEGIN_BLOCK ||
awk->parse.id.block == PARSE_END_BLOCK)
{
PANIC (awk, XP_AWK_ENEXTFILE);
}
@ -3207,13 +3228,14 @@ static int __get_token (xp_awk_t* awk)
}
while (n == 1);
xp_str_clear (&awk->token.name);
awk->token.line = awk->lex.line;
awk->token.column = awk->lex.column;
if (line != 0 && (awk->opt.parse & XP_AWK_BLOCKLESS) &&
awk->parse.id.block == PARSE_BLOCK_PATTERN)
(awk->parse.id.block == PARSE_PATTERN ||
awk->parse.id.block == PARSE_BEGIN ||
awk->parse.id.block == PARSE_END))
{
if (awk->token.line != line)
{

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c,v 1.158 2006-08-03 09:53:45 bacon Exp $
* $Id: run.c,v 1.159 2006-08-03 15:49:37 bacon Exp $
*/
#include <xp/awk/awk_i.h>
@ -458,6 +458,7 @@ static int __run_main (xp_awk_run_t* run)
blk = (xp_awk_nde_blk_t*)run->awk->tree.begin;
xp_assert (blk->type == XP_AWK_NDE_BLK);
run->active_block = blk;
run->exit_level = EXIT_NONE;
if (__run_block (run, blk) == -1) n = -1;
}
@ -474,6 +475,7 @@ static int __run_main (xp_awk_run_t* run)
blk = (xp_awk_nde_blk_t*)run->awk->tree.end;
xp_assert (blk->type == XP_AWK_NDE_BLK);
run->active_block = blk;
run->exit_level = EXIT_NONE;
if (__run_block (run, blk) == -1) n = -1;
}
@ -619,6 +621,7 @@ static int __run_pattern_block (xp_awk_run_t* run, xp_awk_chain_t* chain)
if (ptn == XP_NULL)
{
/* just execute the block */
run->active_block = blk;
if (__run_block (run, blk) == -1) return -1;
}
else
@ -635,6 +638,7 @@ static int __run_pattern_block (xp_awk_run_t* run, xp_awk_chain_t* chain)
if (xp_awk_valtobool(v1))
{
run->active_block = blk;
if (__run_block (run, blk) == -1)
{
xp_awk_refdownval (run, v1);
@ -659,6 +663,7 @@ static int __run_pattern_block (xp_awk_run_t* run, xp_awk_chain_t* chain)
if (xp_awk_valtobool(v1))
{
run->active_block = blk;
if (__run_block (run, blk) == -1)
{
xp_awk_refdownval (run, v1);
@ -678,6 +683,7 @@ static int __run_pattern_block (xp_awk_run_t* run, xp_awk_chain_t* chain)
if (v2 == XP_NULL) return -1;
xp_awk_refupval (v2);
run->active_block = blk;
if (__run_block (run, blk) == -1)
{
xp_awk_refdownval (run, v2);
@ -1164,7 +1170,6 @@ static int __run_continue (xp_awk_run_t* run, xp_awk_nde_continue_t* nde)
static int __run_return (xp_awk_run_t* run, xp_awk_nde_return_t* nde)
{
if (nde->val != XP_NULL)
{
xp_awk_val_t* val;
@ -1212,19 +1217,33 @@ static int __run_exit (xp_awk_run_t* run, xp_awk_nde_exit_t* nde)
static int __run_next (xp_awk_run_t* run, xp_awk_nde_next_t* nde)
{
/* TODO: trigger an error if "next" is called from BEGIN or END */
/* the parser checks if next has been called in the begin/end
* block or whereever inappropriate. so the runtime doesn't
* check that explicitly */
if (run->active_block == (xp_awk_nde_blk_t*)run->awk->tree.begin ||
run->active_block == (xp_awk_nde_blk_t*)run->awk->tree.end)
{
PANIC_I (run, XP_AWK_ENEXTCALL);
}
run->exit_level = EXIT_NEXT;
return 0;
}
static int __run_nextfile (xp_awk_run_t* run, xp_awk_nde_nextfile_t* nde)
{
/* TODO: trigger an error if "nextfile" is called from BEGIN or END */
/* TODO: some extentions such as nextfile "in/out";
* what about awk -i in1,in2,in3 -o out1,out2,out3 ?
*/
int n, errnum;
if (run->active_block == (xp_awk_nde_blk_t*)run->awk->tree.begin ||
run->active_block == (xp_awk_nde_blk_t*)run->awk->tree.end)
{
PANIC_I (run, XP_AWK_ENEXTFILECALL);
}
n = xp_awk_nextextio_read (
run, XP_AWK_IN_CONSOLE, XP_T(""), &errnum);
if (n == -1)

13
ase/test/awk/t26.awk Normal file
View File

@ -0,0 +1,13 @@
function call_next ()
{
next;
}
BEGIN {
//call_next ();
}
END {
call_next ();
}