diff --git a/ase/awk/Awk.cpp b/ase/awk/Awk.cpp index c1a73c0d..486b586c 100644 --- a/ase/awk/Awk.cpp +++ b/ase/awk/Awk.cpp @@ -1178,8 +1178,6 @@ int Awk::open () int opt = OPT_IMPLICIT | - OPT_UNIQUEFN | - OPT_SHADING | OPT_EXTIO | OPT_BLOCKLESS | OPT_BASEONE | diff --git a/ase/awk/Awk.hpp b/ase/awk/Awk.hpp index 65cce213..208cf653 100644 --- a/ase/awk/Awk.hpp +++ b/ase/awk/Awk.hpp @@ -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, diff --git a/ase/awk/Awk.java b/ase/awk/Awk.java index b7eadcd8..13966756 100644 --- a/ase/awk/Awk.java +++ b/ase/awk/Awk.java @@ -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); diff --git a/ase/awk/awk.c b/ase/awk/awk.c index f167f71a..cb7e4fb6 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -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; diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 488ffa5e..e3381c6d 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -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 */ diff --git a/ase/awk/awk_i.h b/ase/awk/awk_i.h index 91210ad7..05ba2ef8 100644 --- a/ase/awk/awk_i.h +++ b/ase/awk/awk_i.h @@ -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; diff --git a/ase/awk/err.c b/ase/awk/err.c index d592b8c1..deecba57 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -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'"), diff --git a/ase/awk/jni.c b/ase/awk/jni.c index 59942a48..17a5db77 100644 --- a/ase/awk/jni.c +++ b/ase/awk/jni.c @@ -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 | diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 85020391..4a455141 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -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); diff --git a/ase/test/awk/AseAwkPanel.java b/ase/test/awk/AseAwkPanel.java index 1ecc87e9..6062e882 100644 --- a/ase/test/awk/AseAwkPanel.java +++ b/ase/test/awk/AseAwkPanel.java @@ -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), diff --git a/ase/test/awk/Awk.cpp b/ase/test/awk/Awk.cpp index 0a179fbb..5f066900 100644 --- a/ase/test/awk/Awk.cpp +++ b/ase/test/awk/Awk.cpp @@ -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 }, diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 9eaa0278..fbc8b305 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -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 |