added a new pragma pedantic to make syntax check stricter - for now. it flags about unused local and global variables
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-12-13 22:09:05 +09:00
parent 3d64e38f5a
commit d3b90da1e7
11 changed files with 203 additions and 74 deletions

View File

@@ -33,7 +33,7 @@
#define keeper_t hawk_arr_keeper_t
#define walker_t hawk_arr_walker_t
#define TOB(arr,len) ((len)*(arr)->scale)
#define TOB(arr,len) ((len) * (arr)->scale)
#define DPTR(slot) ((slot)->val.ptr)
#define DLEN(slot) ((slot)->val.len)
@@ -71,11 +71,13 @@ static HAWK_INLINE slot_t* alloc_slot (hawk_arr_t* arr, void* dptr, hawk_oow_t d
}
else if (arr->style->copier == HAWK_ARR_COPIER_INLINE)
{
n = (slot_t*)hawk_gem_allocmem(arr->gem, HAWK_SIZEOF(slot_t) + TOB(arr,dlen));
hawk_oow_t nbytes = TOB(arr, dlen);
n = (slot_t*)hawk_gem_allocmem(arr->gem, HAWK_SIZEOF(slot_t) + nbytes + arr->inline_slot_xtnsize);
if (HAWK_UNLIKELY(!n)) return HAWK_NULL;
HAWK_MEMCPY (n + 1, dptr, TOB(arr,dlen)); /* copy data contents */
HAWK_MEMCPY(n + 1, dptr, nbytes); /* copy data contents */
DPTR(n) = n + 1;
if (arr->inline_slot_xtnsize > 0)
HAWK_MEMSET((hawk_uint8_t*)DPTR(n) + nbytes, 0, arr->inline_slot_xtnsize);
}
else
{
@@ -103,17 +105,17 @@ hawk_arr_t* hawk_arr_open (hawk_gem_t* gem, hawk_oow_t xtnsize, hawk_oow_t capa)
if (hawk_arr_init(arr, gem, capa) <= -1)
{
hawk_gem_freemem (gem, arr);
hawk_gem_freemem(gem, arr);
return HAWK_NULL;
}
HAWK_MEMSET (arr + 1, 0, xtnsize);
HAWK_MEMSET(arr + 1, 0, xtnsize);
return arr;
}
void hawk_arr_close (hawk_arr_t* arr)
{
hawk_arr_fini (arr);
hawk_arr_fini(arr);
hawk_gem_freemem(arr->gem, arr);
}
@@ -160,7 +162,7 @@ int hawk_arr_init (hawk_arr_t* arr, hawk_gem_t* gem, hawk_oow_t capa)
void hawk_arr_fini (hawk_arr_t* arr)
{
hawk_arr_clear (arr);
hawk_arr_clear(arr);
if (arr->slot)
{
@@ -181,7 +183,7 @@ void hawk_arr_setscale (hawk_arr_t* arr, int scale)
{
/* The scale should be larger than 0 and less than or equal to the
* maximum value that the hawk_uint8_t type can hold */
HAWK_ASSERT (scale > 0 && scale <= HAWK_TYPE_MAX(hawk_uint8_t));
HAWK_ASSERT(scale > 0 && scale <= HAWK_TYPE_MAX(hawk_uint8_t));
if (scale <= 0) scale = 1;
if (scale > HAWK_TYPE_MAX(hawk_uint8_t)) scale = HAWK_TYPE_MAX(hawk_uint8_t);
@@ -196,7 +198,7 @@ const hawk_arr_style_t* hawk_arr_getstyle (hawk_arr_t* arr)
void hawk_arr_setstyle (hawk_arr_t* arr, const hawk_arr_style_t* style)
{
HAWK_ASSERT (style != HAWK_NULL);
HAWK_ASSERT(style != HAWK_NULL);
arr->style = style;
}
@@ -238,8 +240,8 @@ hawk_arr_t* hawk_arr_setcapa (hawk_arr_t* arr, hawk_oow_t capa)
tmp = HAWK_NULL;
HAWK_ASSERT (arr->size == 0);
HAWK_ASSERT (arr->tally == 0);
HAWK_ASSERT(arr->size == 0);
HAWK_ASSERT(arr->tally == 0);
}
arr->slot = tmp;
@@ -287,6 +289,7 @@ hawk_oow_t hawk_arr_upsert (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo
return hawk_arr_insert(arr, pos, dptr, dlen);
}
hawk_oow_t hawk_arr_insert (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oow_t dlen)
{
hawk_oow_t i;
@@ -314,7 +317,7 @@ hawk_oow_t hawk_arr_insert (hawk_arr_t* arr, hawk_oow_t pos, void* dptr, hawk_oo
{
if (arr->capa <= 0)
{
HAWK_ASSERT (arr->size <= 0);
HAWK_ASSERT(arr->size <= 0);
capa = HAWK_ALIGN_POW2(pos + 1, 64);
}
else
@@ -692,7 +695,7 @@ hawk_oow_t hawk_arr_pushheap (hawk_arr_t* arr, void* dptr, hawk_oow_t dlen)
if (hawk_arr_insert(arr, index, dptr, dlen) == HAWK_ARR_NIL) return HAWK_ARR_NIL;
HEAP_UPDATE_POS(arr, index);
HAWK_ASSERT (arr->size == index + 1);
HAWK_ASSERT(arr->size == index + 1);
/* move the item upto the top if it's greater than the parent items */
sift_up(arr, index);
@@ -701,7 +704,7 @@ hawk_oow_t hawk_arr_pushheap (hawk_arr_t* arr, void* dptr, hawk_oow_t dlen)
void hawk_arr_popheap (hawk_arr_t* arr)
{
HAWK_ASSERT (arr->size > 0);
HAWK_ASSERT(arr->size > 0);
hawk_arr_deleteheap(arr, 0);
}
@@ -709,8 +712,8 @@ void hawk_arr_deleteheap (hawk_arr_t* arr, hawk_oow_t index)
{
slot_t* tmp;
HAWK_ASSERT (arr->size > 0);
HAWK_ASSERT (index < arr->size);
HAWK_ASSERT(arr->size > 0);
HAWK_ASSERT(index < arr->size);
/* remember the item to destroy */
tmp = arr->slot[index];
@@ -746,7 +749,7 @@ hawk_oow_t hawk_arr_updateheap (hawk_arr_t* arr, hawk_oow_t index, void* dptr, h
int n;
tmp = arr->slot[index];
HAWK_ASSERT (tmp != HAWK_NULL);
HAWK_ASSERT(tmp != HAWK_NULL);
n = arr->style->comper(arr, dptr, dlen, DPTR(tmp), DLEN(tmp));
if (n)

View File

@@ -129,6 +129,7 @@ const hawk_ooch_t* hawk_dfl_errstr (hawk_errnum_t errnum)
HAWK_T("include level too deep"),
HAWK_T("word after @ not recognized"),
HAWK_T("@ not followed by a valid word"),
HAWK_T("unused element"),
HAWK_T("stack full"),
HAWK_T("divide by zero"),

View File

@@ -180,6 +180,7 @@ struct hawk_arr_t
hawk_gem_t* gem;
const hawk_arr_style_t* style;
hawk_uint8_t scale; /* scale factor */
hawk_uint16_t inline_slot_xtnsize;
hawk_oow_t heap_pos_offset; /* offset in the data element where position
* is stored when heap operation is performed. */
hawk_oow_t size; /* number of items */
@@ -262,14 +263,13 @@ HAWK_EXPORT int hawk_arr_getscale (
*/
HAWK_EXPORT void hawk_arr_setscale (
hawk_arr_t* arr /**< array */,
int scale /**< scale factor - 1 to 255 */
int scale /**< scale factor - 1 to 255 */
);
HAWK_EXPORT hawk_arr_copier_t hawk_arr_getcopier (
hawk_arr_t* arr /* array */
);
HAWK_EXPORT void hawk_arr_setstyle (
hawk_arr_t* arr,
const hawk_arr_style_t* style

View File

@@ -1014,6 +1014,7 @@ enum hawk_errnum_t
HAWK_EINCLTD, /**< include level too deep */
HAWK_EXKWNR, /**< word after @ not recognized */
HAWK_EXKWEM, /**< @ not followed by a valid word */
HAWK_EUNUSED, /**< unused element */
/* hawk run time error */
HAWK_ESTACK, /**< stack error */

View File

@@ -395,6 +395,14 @@ struct hawk_bctos_b_t
hawk_bchu_t c[2]; /* ensure the unsigned type to hold not only a byte character but also a free slot index */
};
typedef struct hawk_var_xinfo_t hawk_var_xinfo_t;
struct hawk_var_xinfo_t
{
hawk_uint8_t used;
hawk_loc_t loc;
};
struct hawk_rtx_t
{
HAWK_RTX_HDR;

View File

@@ -239,30 +239,32 @@ int hawk_init (hawk_t* hawk, hawk_mmgr_t* mmgr, hawk_cmgr_t* cmgr, const hawk_pr
}
*(hawk_t**)(hawk->tree.funs + 1) = hawk;
hawk_htb_setstyle (hawk->tree.funs, &treefuncbs);
hawk_htb_setstyle(hawk->tree.funs, &treefuncbs);
*(hawk_t**)(hawk->parse.funs + 1) = hawk;
hawk_htb_setstyle (hawk->parse.funs, hawk_get_htb_style(HAWK_HTB_STYLE_INLINE_KEY_COPIER));
hawk_htb_setstyle(hawk->parse.funs, hawk_get_htb_style(HAWK_HTB_STYLE_INLINE_KEY_COPIER));
*(hawk_t**)(hawk->parse.named + 1) = hawk;
hawk_htb_setstyle (hawk->parse.named, hawk_get_htb_style(HAWK_HTB_STYLE_INLINE_KEY_COPIER));
hawk_htb_setstyle(hawk->parse.named, hawk_get_htb_style(HAWK_HTB_STYLE_INLINE_KEY_COPIER));
*(hawk_t**)(hawk->parse.gbls + 1) = hawk;
hawk_arr_setscale (hawk->parse.gbls, HAWK_SIZEOF(hawk_ooch_t));
hawk_arr_setstyle (hawk->parse.gbls, hawk_get_arr_style(HAWK_ARR_STYLE_INLINE_COPIER));
hawk_arr_setscale(hawk->parse.gbls, HAWK_SIZEOF(hawk_ooch_t));
hawk_arr_setstyle(hawk->parse.gbls, hawk_get_arr_style(HAWK_ARR_STYLE_INLINE_COPIER));
hawk->parse.gbls->inline_slot_xtnsize = HAWK_SIZEOF(hawk_var_xinfo_t);
*(hawk_t**)(hawk->parse.lcls + 1) = hawk;
hawk_arr_setscale (hawk->parse.lcls, HAWK_SIZEOF(hawk_ooch_t));
hawk_arr_setstyle (hawk->parse.lcls, hawk_get_arr_style(HAWK_ARR_STYLE_INLINE_COPIER));
hawk_arr_setscale(hawk->parse.lcls, HAWK_SIZEOF(hawk_ooch_t));
hawk_arr_setstyle(hawk->parse.lcls, hawk_get_arr_style(HAWK_ARR_STYLE_INLINE_COPIER));
hawk->parse.lcls->inline_slot_xtnsize = HAWK_SIZEOF(hawk_var_xinfo_t);
*(hawk_t**)(hawk->parse.params + 1) = hawk;
hawk_arr_setscale (hawk->parse.params, HAWK_SIZEOF(hawk_ooch_t));
hawk_arr_setstyle (hawk->parse.params, hawk_get_arr_style(HAWK_ARR_STYLE_INLINE_COPIER));
hawk_arr_setscale(hawk->parse.params, HAWK_SIZEOF(hawk_ooch_t));
hawk_arr_setstyle(hawk->parse.params, hawk_get_arr_style(HAWK_ARR_STYLE_INLINE_COPIER));
*(hawk_t**)(hawk->fnc.user + 1) = hawk;
hawk_htb_setstyle (hawk->fnc.user, &fncusercbs);
hawk_htb_setstyle(hawk->fnc.user, &fncusercbs);
hawk_rbt_setstyle (hawk->modtab, hawk_get_rbt_style(HAWK_RBT_STYLE_INLINE_COPIERS));
hawk_rbt_setstyle(hawk->modtab, hawk_get_rbt_style(HAWK_RBT_STYLE_INLINE_COPIERS));
if (hawk_initgbls(hawk) <= -1) goto oops;
return 0;
@@ -417,7 +419,7 @@ void hawk_clear (hawk_t* hawk)
hawk->parse.depth.loop = 0;
hawk->parse.depth.expr = 0;
hawk->parse.depth.incl = 0;
hawk->parse.pragma.trait = (hawk->opt.trait & (HAWK_IMPLICIT | HAWK_MULTILINESTR | HAWK_RWPIPE | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC)); /* implicit on if you didn't mask it off in hawk->opt.trait with hawk_setopt */
hawk->parse.pragma.trait = (hawk->opt.trait & (HAWK_IMPLICIT | HAWK_MULTILINESTR | HAWK_PEDANTIC | HAWK_RWPIPE | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC)); /* implicit on if you didn't mask it off in hawk->opt.trait with hawk_setopt */
hawk->parse.pragma.rtx_stack_limit = 0;
hawk->parse.pragma.entry[0] = '\0';

View File

@@ -38,7 +38,7 @@
#include <stdarg.h>
/** \file
* An embeddable AWK interpreter is defined in this header file.
* An embeddable HAWK interpreter is defined in this header file.
*
* \todo
* - make enhancement to treat a function as a value
@@ -47,11 +47,11 @@
*/
/** \struct hawk_t
* The #hawk_t type defines an AWK interpreter. It provides an interface
* to parse an AWK script and run it to manipulate input and output data.
* The #hawk_t type defines an HAWK interpreter. It provides an interface
* to parse an HAWK script and run it to manipulate input and output data.
*
* In brief, you need to call APIs with user-defined handlers to run a typical
* AWK script as shown below:
* HAWK script as shown below:
*
* \code
* hawk_t* hawk;
@@ -61,7 +61,7 @@
* hawk = hawk_open(mmgr, 0, hawk_get_cmgr_by_id(HAWK_CMGR_UTF8), prm, HAWK_NULL); // create an interpreter
* hawk_parse(hawk, &sio); // parse a script
* rtx = hawk_rtx_open(hawk, 0, &rio); // create a runtime context
* retv = hawk_rtx_loop(rtx); // run a standard AWK loop
* retv = hawk_rtx_loop(rtx); // run a standard HAWK loop
* if (retv) hawk_rtx_refdownval(rtx, retv); // free return value
* hawk_rtx_close(rtx); // destroy the runtime context
* hawk_close(hawk); // destroy the interpreter
@@ -88,7 +88,7 @@ struct hawk_alt_t
/** \struct hawk_rtx_t
* The #hawk_rtx_t type defines a runtime context. A runtime context
* maintains runtime state for a running script. You can create multiple
* runtime contexts out of a single AWK interpreter; in other words, you
* runtime contexts out of a single HAWK interpreter; in other words, you
* can run the same script with different input and output data by providing
* customized I/O handlers when creating a runtime context with
* hawk_rtx_open().
@@ -1365,7 +1365,7 @@ enum hawk_trait_t
HAWK_STRICTNAMING = (1 << 15),
/**
* makes AWK more fault-tolerant.
* makes HAWK more fault-tolerant.
* - prevents termination due to print and printf failure.
* - achieves this by handling print and printf as if
* they are functions like getline.
@@ -1377,12 +1377,18 @@ enum hawk_trait_t
*/
HAWK_TOLERANT = (1 << 17),
/*
* detect a numeric string and convert to a numeric type
/**
* detects a numeric string and convert to a numeric type
* automatically
*/
HAWK_NUMSTRDETECT = (1 << 18),
/**
* makes HAWK more picky about the syntax:
* - it complains about unused local variables
*/
HAWK_PEDANTIC = (1 << 19),
/**
* makes #hawk_t to behave compatibly with classical AWK
* implementations
@@ -1394,7 +1400,7 @@ enum hawk_trait_t
HAWK_MODERN =
HAWK_CLASSIC | HAWK_FLEXMAP | HAWK_REXBOUND |
HAWK_RWPIPE | HAWK_TOLERANT | HAWK_NEXTOFILE | HAWK_NUMSTRDETECT /*| HAWK_NCMPONSTR*/
HAWK_RWPIPE | HAWK_TOLERANT | HAWK_NEXTOFILE | HAWK_NUMSTRDETECT /*| HAWK_NCMPONSTR*/
};
typedef enum hawk_trait_t hawk_trait_t;
@@ -1446,7 +1452,7 @@ enum hawk_gbl_id_t
typedef enum hawk_gbl_id_t hawk_gbl_id_t;
/**
* The hawk_val_type_t type defines types of AWK values. Each value
* The hawk_val_type_t type defines types of HAWK values. Each value
* allocated is tagged with a value type in the \a type field.
* \sa hawk_val_t HAWK_VAL_HDR
*/
@@ -2476,7 +2482,7 @@ static HAWK_INLINE void hawk_rtx_setcmgr (hawk_rtx_t* rtx, hawk_cmgr_t* cmgr) {
/**
* The hawk_rtx_loop() function executes the BEGIN block, pattern-action
* blocks and the END blocks in an AWK program. It returns the global return
* blocks and the END blocks in an HAWK program. It returns the global return
* value of which the reference count must be decremented when not necessary.
* Multiple invocations of the function for the lifetime of a runtime context
* is not desirable.
@@ -2525,7 +2531,7 @@ HAWK_EXPORT hawk_fun_t* hawk_rtx_findfunwithucstr (
#endif
/**
* The hawk_rtx_callfun() function invokes an AWK function described by
* The hawk_rtx_callfun() function invokes an HAWK function described by
* the structure pointed to by \a fun.
* \sa hawk_rtx_call
*/
@@ -2537,7 +2543,7 @@ HAWK_EXPORT hawk_val_t* hawk_rtx_callfun (
);
/**
* The hawk_rtx_callwithucstr() function invokes an AWK function named \a name.
* The hawk_rtx_callwithucstr() function invokes an HAWK function named \a name.
* However, it is not able to invoke an intrinsic function such as split().
* The #HAWK_PABLOCK option can be turned off to make illegal the BEGIN
* blocks, the pattern-action blocks, and the END blocks.
@@ -2565,7 +2571,7 @@ HAWK_EXPORT hawk_val_t* hawk_rtx_callwithucstr (
);
/**
* The hawk_rtx_callwithbcstr() function invokes an AWK function named \a name.
* The hawk_rtx_callwithbcstr() function invokes an HAWK function named \a name.
* However, it is not able to invoke an intrinsic function such as split().
* The #HAWK_PABLOCK option can be turned off to make illegal the BEGIN
* blocks, the pattern-action blocks, and the END blocks.

View File

@@ -606,6 +606,25 @@ static int parse (hawk_t* hawk)
}
}
if (hawk->parse.pragma.trait & HAWK_PEDANTIC)
{
hawk_oow_t i;
for (i = hawk->tree.ngbls_base ; i < HAWK_ARR_SIZE(hawk->parse.gbls); i++)
{
const hawk_ptl_t* ptl;
hawk_var_xinfo_t vxi;
ptl = HAWK_ARR_DPTL(hawk->parse.gbls, i);
HAWK_MEMCPY(&vxi, (const hawk_ooch_t*)ptl->ptr + ptl->len, HAWK_SIZEOF(vxi));
if (!vxi.used)
{
hawk_seterrbfmt(hawk, &vxi.loc, HAWK_EUNUSED, "unused global variable '%.*js'", ptl->len, ptl->ptr);
goto oops;
}
}
}
HAWK_ASSERT(hawk->tree.ngbls == HAWK_ARR_SIZE(hawk->parse.gbls));
HAWK_ASSERT(hawk->sio.inp == &hawk->sio.arg);
ret = 0;
@@ -879,7 +898,7 @@ static int begin_include (hawk_t* hawk, int once)
arg->pragma_trait = hawk->parse.pragma.trait;
/* but don't change hawk->parse.pragma.trait. it means the included file inherits
* the existing progma values.
hawk->parse.pragma.trait = (hawk->opt.trait & (HAWK_IMPLICIT | HAWK_MULTILINESTR | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC));
hawk->parse.pragma.trait = (hawk->opt.trait & (HAWK_IMPLICIT | HAWK_MULTILINESTR | HAWK_PEDANTIC | HAWK_RWPIPE | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC));
*/
/* update the current pointer after opening is successful */
@@ -1022,12 +1041,15 @@ static int parse_progunit (hawk_t* hawk)
/* NOTE: trait = is an intended assignment */
else if (((trait = HAWK_IMPLICIT) && hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("implicit"), 0) == 0) ||
((trait = HAWK_MULTILINESTR) && hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("multilinestr"), 0) == 0) ||
((trait = HAWK_PEDANTIC) && hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("pedantic"), 0) == 0) ||
((trait = HAWK_RWPIPE) && hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("rwpipe"), 0) == 0))
{
/* @pragma implicit on
* @pragma implicit off
* @pragma multilinestr on
* @pragma multilinestr off
* @pragma pedantic on
* @pragma pedantic off
* @pragma rwpipe on
* @pragma rwpipe off
*
@@ -1835,6 +1857,27 @@ static hawk_nde_t* parse_block (hawk_t* hawk, const hawk_loc_t* xloc, int flags)
}
}
if (hawk->parse.pragma.trait & HAWK_PEDANTIC)
{
hawk_oow_t i;
for (i = nlcls_outer ; i < HAWK_ARR_SIZE(hawk->parse.lcls); i++)
{
const hawk_ptl_t* ptl;
hawk_var_xinfo_t vxi;
ptl = HAWK_ARR_DPTL(hawk->parse.lcls, i);
HAWK_MEMCPY(&vxi, (const hawk_ooch_t*)ptl->ptr + ptl->len, HAWK_SIZEOF(vxi));
if (!vxi.used)
{
hawk_seterrbfmt(hawk, &vxi.loc, HAWK_EUNUSED, "unused local variable '%.*js'", ptl->len, ptl->ptr);
hawk_arr_delete(hawk->parse.lcls, nlcls_outer, HAWK_ARR_SIZE(hawk->parse.lcls) - nlcls_outer);
hawk_clrpt(hawk, head);
return HAWK_NULL;
}
}
}
block = (hawk_nde_blk_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*block));
if (HAWK_UNLIKELY(!block))
{
@@ -1980,6 +2023,7 @@ static hawk_oow_t find_global (hawk_t* hawk, const hawk_oocs_t* name)
static int add_global (hawk_t* hawk, const hawk_oocs_t* name, hawk_loc_t* xloc, int disabled)
{
hawk_oow_t ngbls;
hawk_oow_t n;
/* check if it is a keyword */
if (classify_ident(hawk, name) != TOK_IDENT)
@@ -2042,7 +2086,8 @@ static int add_global (hawk_t* hawk, const hawk_oocs_t* name, hawk_loc_t* xloc,
return -1;
}
if (hawk_arr_insert(hawk->parse.gbls, HAWK_ARR_SIZE(hawk->parse.gbls), (hawk_ooch_t*)name->ptr, name->len) == HAWK_ARR_NIL)
n = hawk_arr_insert(hawk->parse.gbls, HAWK_ARR_SIZE(hawk->parse.gbls), (hawk_ooch_t*)name->ptr, name->len);
if (n == HAWK_ARR_NIL)
{
const hawk_ooch_t* bem = hawk_backuperrmsg(hawk);
hawk_seterrfmt(hawk, xloc, hawk_geterrnum(hawk),
@@ -2050,6 +2095,16 @@ static int add_global (hawk_t* hawk, const hawk_oocs_t* name, hawk_loc_t* xloc,
name->len, name->ptr, bem);
return -1;
}
else if (hawk->parse.pragma.trait & HAWK_PEDANTIC) /* a variable collected when pendatic on will xinfo */
{
const hawk_ptl_t* ptl;
hawk_var_xinfo_t* vxi;
/* remember location information of each local variable collected */
ptl = HAWK_ARR_DPTL(hawk->parse.gbls, n); /* n is the position of the inserted name */
vxi = (hawk_var_xinfo_t*)((hawk_ooch_t*)ptl->ptr + ptl->len);
if (xloc) vxi->loc = *xloc;
else vxi->used = 1; /* if xloc is not given, it's not declared with @global. set used to 1 for simple check */
}
HAWK_ASSERT(ngbls == HAWK_ARR_SIZE(hawk->parse.gbls) - 1);
@@ -2459,11 +2514,21 @@ static hawk_t* collect_locals (hawk_t* hawk, hawk_oow_t nlcls, int flags)
return HAWK_NULL;
}
if (hawk_arr_insert(hawk->parse.lcls, HAWK_ARR_SIZE(hawk->parse.lcls), lcl.ptr, lcl.len) == HAWK_ARR_NIL)
n = hawk_arr_insert(hawk->parse.lcls, HAWK_ARR_SIZE(hawk->parse.lcls), lcl.ptr, lcl.len);
if (n == HAWK_ARR_NIL)
{
ADJERR_LOC(hawk, &hawk->tok.loc);
return HAWK_NULL;
}
else if (hawk->parse.pragma.trait & HAWK_PEDANTIC)
{
const hawk_ptl_t* ptl;
hawk_var_xinfo_t* vxi;
/* remember location information of each local variable collected */
ptl = HAWK_ARR_DPTL(hawk->parse.lcls, n); /* n is the position of the inserted name */
vxi = (hawk_var_xinfo_t*)((hawk_ooch_t*)ptl->ptr + ptl->len);
vxi->loc = hawk->tok.loc;
}
if (get_token(hawk) <= -1) return HAWK_NULL;
@@ -5943,6 +6008,17 @@ static hawk_nde_t* parse_primary_ident_noseg (hawk_t* hawk, const hawk_loc_t* xl
else if ((idxa = hawk_arr_rsearch(hawk->parse.lcls, HAWK_ARR_SIZE(hawk->parse.lcls), name->ptr, name->len)) != HAWK_ARR_NIL)
{
/* local variable */
if (hawk->parse.pragma.trait & HAWK_PEDANTIC)
{
const hawk_ptl_t* ptl;
hawk_var_xinfo_t* vxi;
/* note an extra space has been reserved in each slot value
* when initializing hawk->parser.lcls */
ptl = HAWK_ARR_DPTL(hawk->parse.lcls, idxa);
vxi = (hawk_var_xinfo_t*)((hawk_ooch_t*)ptl->ptr + ptl->len);
vxi->used = 1; /* mark that the variable has been referenced */
}
nde = parse_variable(hawk, xloc, HAWK_NDE_LCL, name, idxa);
}
else if ((idxa = hawk_arr_search(hawk->parse.params, 0, name->ptr, name->len)) != HAWK_ARR_NIL)
@@ -5953,6 +6029,17 @@ static hawk_nde_t* parse_primary_ident_noseg (hawk_t* hawk, const hawk_loc_t* xl
else if ((idxa = get_global(hawk, name)) != HAWK_ARR_NIL)
{
/* global variable */
if (hawk->parse.pragma.trait & HAWK_PEDANTIC)
{
const hawk_ptl_t* ptl;
hawk_var_xinfo_t* vxi;
/* note an extra space has been reserved in each slot value
* when initializing hawk->parser.gbls */
ptl = HAWK_ARR_DPTL(hawk->parse.gbls, idxa);
vxi = (hawk_var_xinfo_t*)((hawk_ooch_t*)ptl->ptr + ptl->len);
vxi->used = 1; /* mark that the variable has been referenced */
}
nde = parse_variable(hawk, xloc, HAWK_NDE_GBL, name, idxa);
}
else
@@ -6309,6 +6396,16 @@ more_idx:
nde->id.idxa = idxa;
nde->idx = idx;
if (hawk->parse.pragma.trait & HAWK_PEDANTIC)
{
const hawk_ptl_t* ptl;
hawk_var_xinfo_t* vxi;
ptl = HAWK_ARR_DPTL(hawk->parse.lcls, idxa);
vxi = (hawk_var_xinfo_t*)((hawk_ooch_t*)ptl->ptr + ptl->len);
vxi->used = 1;
if (xloc) vxi->loc = *xloc;
}
return (hawk_nde_t*)nde;
}
@@ -6339,6 +6436,16 @@ more_idx:
nde->id.idxa = idxa;
nde->idx = idx;
if (hawk->parse.pragma.trait & HAWK_PEDANTIC)
{
const hawk_ptl_t* ptl;
hawk_var_xinfo_t* vxi;
ptl = HAWK_ARR_DPTL(hawk->parse.gbls, idxa);
vxi = (hawk_var_xinfo_t*)((hawk_ooch_t*)ptl->ptr + ptl->len);
vxi->used = 1;
if (xloc) vxi->loc = *xloc;
}
return (hawk_nde_t*)nde;
}