reworked on the variable scoping for awk

This commit is contained in:
hyung-hwan 2007-12-22 03:57:26 +00:00
parent 730e8cc9c5
commit b46fd5ab5c
12 changed files with 79 additions and 47 deletions

View File

@ -1178,8 +1178,6 @@ int Awk::open ()
int opt =
OPT_IMPLICIT |
OPT_UNIQUEFN |
OPT_SHADING |
OPT_EXTIO |
OPT_BLOCKLESS |
OPT_BASEONE |

View File

@ -462,6 +462,7 @@ public:
ERR_AFNRED = ASE_AWK_EAFNRED,
ERR_GBLRED = ASE_AWK_EGBLRED,
ERR_PARRED = ASE_AWK_EPARRED,
ERR_VARRED = ASE_AWK_EVARRED,
ERR_DUPPAR = ASE_AWK_EDUPPAR,
ERR_DUPGBL = ASE_AWK_EDUPGBL,
ERR_DUPLCL = ASE_AWK_EDUPLCL,
@ -538,8 +539,6 @@ public:
{
OPT_IMPLICIT = ASE_AWK_IMPLICIT,
OPT_EXPLICIT = ASE_AWK_EXPLICIT,
OPT_UNIQUEFN = ASE_AWK_UNIQUEFN,
OPT_SHADING = ASE_AWK_SHADING,
OPT_SHIFT = ASE_AWK_SHIFT,
OPT_IDIV = ASE_AWK_IDIV,
OPT_STRCONCAT = ASE_AWK_STRCONCAT,

View File

@ -33,8 +33,6 @@ public abstract class Awk
// options
public static final int OPTION_IMPLICIT = (1 << 0);
public static final int OPTION_EXPLICIT = (1 << 1);
public static final int OPTION_UNIQUEFN = (1 << 2);
public static final int OPTION_SHADING = (1 << 3);
public static final int OPTION_SHIFT = (1 << 4);
public static final int OPTION_IDIV = (1 << 5);
public static final int OPTION_STRCONCAT = (1 << 6);

View File

@ -96,7 +96,8 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data)
return ASE_NULL;
}
if (ase_awk_tab_open (&awk->parse.afns, awk) == ASE_NULL)
awk->parse.afns = ase_awk_map_open (awk, 256, 70, ASE_NULL, ASE_NULL, awk);
if (awk->parse.afns == ASE_NULL)
{
ase_awk_map_close (awk->tree.afns);
ase_awk_map_close (awk->rwtab);
@ -106,9 +107,22 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data)
return ASE_NULL;
}
awk->parse.named = ase_awk_map_open (awk, 256, 70, ASE_NULL, ASE_NULL, awk);
if (awk->parse.named == ASE_NULL)
{
ase_awk_map_close (awk->parse.afns);
ase_awk_map_close (awk->tree.afns);
ase_awk_map_close (awk->rwtab);
ase_awk_map_close (awk->wtab);
ase_str_close (&awk->token.name);
ASE_AWK_FREE (awk, awk);
return ASE_NULL;
}
if (ase_awk_tab_open (&awk->parse.globals, awk) == ASE_NULL)
{
ase_awk_tab_close (&awk->parse.afns);
ase_awk_map_close (awk->parse.named);
ase_awk_map_close (awk->parse.afns);
ase_awk_map_close (awk->tree.afns);
ase_awk_map_close (awk->rwtab);
ase_awk_map_close (awk->wtab);
@ -120,7 +134,8 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data)
if (ase_awk_tab_open (&awk->parse.locals, awk) == ASE_NULL)
{
ase_awk_tab_close (&awk->parse.globals);
ase_awk_tab_close (&awk->parse.afns);
ase_awk_map_close (awk->parse.named);
ase_awk_map_close (awk->parse.afns);
ase_awk_map_close (awk->tree.afns);
ase_awk_map_close (awk->rwtab);
ase_awk_map_close (awk->wtab);
@ -133,7 +148,8 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data)
{
ase_awk_tab_close (&awk->parse.locals);
ase_awk_tab_close (&awk->parse.globals);
ase_awk_tab_close (&awk->parse.afns);
ase_awk_map_close (awk->parse.named);
ase_awk_map_close (awk->parse.afns);
ase_awk_map_close (awk->tree.afns);
ase_awk_map_close (awk->rwtab);
ase_awk_map_close (awk->wtab);
@ -181,7 +197,8 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data)
ase_awk_tab_close (&awk->parse.params);
ase_awk_tab_close (&awk->parse.locals);
ase_awk_tab_close (&awk->parse.globals);
ase_awk_tab_close (&awk->parse.afns);
ase_awk_map_close (awk->parse.named);
ase_awk_map_close (awk->parse.afns);
ase_awk_map_close (awk->tree.afns);
ase_awk_map_close (awk->rwtab);
ase_awk_map_close (awk->wtab);
@ -209,7 +226,8 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data)
ase_awk_tab_close (&awk->parse.params);
ase_awk_tab_close (&awk->parse.locals);
ase_awk_tab_close (&awk->parse.globals);
ase_awk_tab_close (&awk->parse.afns);
ase_awk_map_close (awk->parse.named);
ase_awk_map_close (awk->parse.afns);
ase_awk_map_close (awk->tree.afns);
ase_awk_map_close (awk->rwtab);
ase_awk_map_close (awk->wtab);
@ -254,7 +272,8 @@ int ase_awk_close (ase_awk_t* awk)
ase_awk_tab_close (&awk->parse.params);
ase_awk_tab_close (&awk->parse.locals);
ase_awk_tab_close (&awk->parse.globals);
ase_awk_tab_close (&awk->parse.afns);
ase_awk_map_close (awk->parse.named);
ase_awk_map_close (awk->parse.afns);
ase_awk_map_close (awk->tree.afns);
ase_awk_map_close (awk->rwtab);
@ -297,7 +316,8 @@ int ase_awk_clear (ase_awk_t* awk)
ase_awk_tab_clear (&awk->parse.locals);
ase_awk_tab_clear (&awk->parse.params);
ase_awk_tab_clear (&awk->parse.afns);
ase_awk_map_clear (awk->parse.named);
ase_awk_map_clear (awk->parse.afns);
awk->parse.nlocals_max = 0;
awk->parse.depth.cur.block = 0;

View File

@ -164,10 +164,10 @@ enum ase_awk_option_t
ASE_AWK_EXPLICIT = (1 << 1),
/* a function name should not coincide to be a variable name */
ASE_AWK_UNIQUEFN = (1 << 2),
/*ASE_AWK_UNIQUEFN = (1 << 2),*/
/* allow variable shading */
ASE_AWK_SHADING = (1 << 3),
/*ASE_AWK_SHADING = (1 << 3),*/
/* support shift operators */
ASE_AWK_SHIFT = (1 << 4),
@ -301,6 +301,7 @@ enum ase_awk_errnum_t
ASE_AWK_EAFNRED, /* function redefined */
ASE_AWK_EGBLRED, /* global variable redefined */
ASE_AWK_EPARRED, /* parameter redefined */
ASE_AWK_EVARRED, /* named variable redefined */
ASE_AWK_EDUPPAR, /* duplicate parameter name */
ASE_AWK_EDUPGBL, /* duplicate global variable name */
ASE_AWK_EDUPLCL, /* duplicate local variable name */

View File

@ -118,7 +118,10 @@ struct ase_awk_t
} depth;
/* function calls */
ase_awk_tab_t afns;
ase_awk_map_t* afns;
/* named variables */
ase_awk_map_t* named;
/* global variables */
ase_awk_tab_t globals;

View File

@ -80,6 +80,7 @@ static const ase_char_t* __geterrstr (int errnum)
ASE_T("function '%.*s' redefined"),
ASE_T("global variable '%.*s' redefined"),
ASE_T("parameter '%.*s' redefined"),
ASE_T("variable '%.*s' redefined"),
ASE_T("duplicate parameter name '%.*s'"),
ASE_T("duplicate global variable '%.*s'"),
ASE_T("duplicate local variable '%.*s'"),

View File

@ -524,8 +524,6 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_open (JNIEnv* env, jobject obj)
(*env)->SetLongField (env, obj, handle, (jlong)awk);
opt = ASE_AWK_IMPLICIT |
ASE_AWK_UNIQUEFN |
ASE_AWK_SHADING |
ASE_AWK_EXTIO |
ASE_AWK_BLOCKLESS |
ASE_AWK_BASEONE |

View File

@ -524,25 +524,28 @@ static int parse (ase_awk_t* awk)
if ((awk->option & ASE_AWK_EXPLICIT) &&
!(awk->option & ASE_AWK_IMPLICIT))
{
ase_size_t sz;
ase_awk_pair_t* p;
ase_size_t buckno;
sz = awk->parse.afns.size;
while (sz > 0)
p = ase_awk_map_getfirstpair (awk->parse.afns, &buckno);
while (p != ASE_NULL)
{
sz--;
if (ase_awk_map_get (awk->tree.afns,
awk->parse.afns.buf[sz].name.ptr,
awk->parse.afns.buf[sz].name.len) == ASE_NULL)
p->key.ptr, p->key.len) == ASE_NULL)
{
/* TODO: set proper error number */
SETERRARG (awk, ASE_AWK_EFNNONE, 0,
awk->parse.afns.buf[sz].name.ptr,
awk->parse.afns.buf[sz].name.len);
/* TODO: set better error no & line */
/* this line number might be truncated as
* sizeof(line) could be > sizeof(void*) */
SETERRARG (awk, ASE_AWK_EFNNONE,
(ase_size_t)p->val,
p->key.ptr, p->key.len);
n = -1;
goto exit_parse;
}
p = ase_awk_map_getnextpair (awk->parse.afns, p, &buckno);
}
}
}
@ -1091,6 +1094,8 @@ static ase_awk_nde_t* parse_function (ase_awk_t* awk)
afn->name_len = ASE_AWK_PAIR_KEYLEN(pair);
ASE_AWK_FREE (awk, name_dup);
/* remove the undefined function call entries from parse.afn table */
ase_awk_map_remove (awk->parse.afns, afn->name, name_len);
return body;
}
@ -1465,7 +1470,7 @@ static int add_global (
/* check if it conflict with a function name
* caught in the function call table */
if (ase_awk_tab_find (&awk->parse.afns, 0, name, len) != (ase_size_t)-1)
if (ase_awk_map_get (awk->parse.afns, name, len) != ASE_NULL)
{
SETERRARG (
awk, ASE_AWK_EAFNRED, line,
@ -1655,7 +1660,7 @@ static ase_awk_t* collect_locals (
/* check if it conflict with a function name
* caught in the function call table */
if (ase_awk_tab_find (&awk->parse.afns, 0, local, local_len) != (ase_size_t)-1)
if (ase_awk_map_get (awk->parse.afns, local, local_len) != ASE_NULL)
{
SETERRARG (
awk, ASE_AWK_EAFNRED, awk->token.line,
@ -1681,7 +1686,7 @@ static ase_awk_t* collect_locals (
/* check if it conflicts with other local variable names */
n = ase_awk_tab_find (
&awk->parse.locals,
((awk->option & ASE_AWK_SHADING)? nlocals: 0),
nlocals, /*((awk->option&ASE_AWK_SHADING)? nlocals:0)*/
local, local_len);
if (n != (ase_size_t)-1)
{
@ -1704,6 +1709,7 @@ static ase_awk_t* collect_locals (
return ASE_NULL;
}
#if 0
if (!(awk->option & ASE_AWK_SHADING))
{
/* conflicting with a normal global variable */
@ -1712,6 +1718,7 @@ static ase_awk_t* collect_locals (
local, local_len);
return ASE_NULL;
}
#endif
}
if (ase_awk_tab_getsize(&awk->parse.locals) >= ASE_AWK_MAX_LOCALS)
@ -3225,7 +3232,13 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line)
if (awk->option & ASE_AWK_IMPLICIT)
{
/*TODO: check if it conflicts any named variables collected so far.... XXXX */
if (ase_awk_map_get (awk->parse.named, name_dup, name_len) != ASE_NULL)
{
/* a function call conflicts with a named variable */
SETERRARG (awk, ASE_AWK_EVARRED, line, name_dup, name_len);
ASE_AWK_FREE (awk, name_dup);
return ASE_NULL;
}
}
nde = parse_fncall (awk, name_dup, name_len, ASE_NULL, line);
@ -3277,7 +3290,7 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line)
goto exit_func;
}
if (ase_awk_tab_find (&awk->parse.afns, 0, name_dup, name_len) != (ase_size_t)-1)
if (ase_awk_map_get (awk->parse.afns, name_dup, name_len) != ASE_NULL)
{
/* is it one of the function calls found so far? */
SETERRARG (awk, ASE_AWK_EAFNRED, line, name_dup, name_len);
@ -3295,7 +3308,13 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line)
nde->id.idxa = (ase_size_t)-1;
nde->idx = ASE_NULL;
/* TODO: add this named variable to the parse.named map... XXXX */
/* collect unique instances of a named variables for reference */
if (ase_awk_map_put (awk->parse.named,
name_dup, name_len, (void*)line) == ASE_NULL)
{
SETERRLIN (awk, ASE_AWK_ENOMEM, line);
goto exit_func;
}
return (ase_awk_nde_t*)nde;
}
@ -3452,7 +3471,7 @@ static ase_awk_nde_t* parse_hashidx (
goto exit_func;
}
if (ase_awk_tab_find (&awk->parse.afns, 0, name, name_len) != (ase_size_t)-1)
if (ase_awk_map_get (awk->parse.afns, name, name_len) != ASE_NULL)
{
/* is it one of the function calls found so far? */
SETERRARG (awk, ASE_AWK_EAFNRED, line, name, name_len);
@ -3601,8 +3620,11 @@ static ase_awk_nde_t* parse_fncall (
(awk->option & ASE_AWK_UNIQUEFN)*/)
{
#endif
if (ase_awk_tab_adduniq (
&awk->parse.afns, name, name_len) == (ase_size_t)-1)
/* this line number might be truncated as
* sizeof(line) could be > sizeof(void*) */
if (ase_awk_map_put (awk->parse.afns,
name, name_len, (void*)line) == ASE_NULL)
{
ASE_AWK_FREE (awk, call);
if (head != ASE_NULL) ase_awk_clrpt (awk, head);

View File

@ -354,8 +354,6 @@ public class AseAwkPanel extends Panel implements DropTargetListener
{
new Option("IMPLICIT", StdAwk.OPTION_IMPLICIT, true),
new Option("EXPLICIT", StdAwk.OPTION_EXPLICIT, false),
new Option("UNIQUEFN", StdAwk.OPTION_UNIQUEFN, true),
new Option("SHADING", StdAwk.OPTION_SHADING, true),
new Option("SHIFT", StdAwk.OPTION_SHIFT, false),
new Option("IDIV", StdAwk.OPTION_IDIV, false),
new Option("STRCONCAT", StdAwk.OPTION_STRCONCAT, false),

View File

@ -632,8 +632,6 @@ static struct
{
{ ASE_T("implicit"), TestAwk::OPT_IMPLICIT },
{ ASE_T("explicit"), TestAwk::OPT_EXPLICIT },
{ ASE_T("uniquefn"), TestAwk::OPT_UNIQUEFN },
{ ASE_T("shading"), TestAwk::OPT_SHADING },
{ ASE_T("shift"), TestAwk::OPT_SHIFT },
{ ASE_T("idiv"), TestAwk::OPT_IDIV },
{ ASE_T("strconcat"), TestAwk::OPT_STRCONCAT },

View File

@ -842,8 +842,6 @@ static struct
{
{ ASE_T("implicit"), ASE_AWK_IMPLICIT },
{ ASE_T("explicit"), ASE_AWK_EXPLICIT },
{ ASE_T("uniquefn"), ASE_AWK_UNIQUEFN },
{ ASE_T("shading"), ASE_AWK_SHADING },
{ ASE_T("shift"), ASE_AWK_SHIFT },
{ ASE_T("idiv"), ASE_AWK_IDIV },
{ ASE_T("strconcat"), ASE_AWK_STRCONCAT },
@ -978,8 +976,6 @@ static int awk_main (int argc, ase_char_t* argv[])
int deparse = 0;
opt = ASE_AWK_IMPLICIT |
ASE_AWK_UNIQUEFN |
ASE_AWK_SHADING |
ASE_AWK_EXTIO |
ASE_AWK_BLOCKLESS |
ASE_AWK_BASEONE |