From 702696da89f14dbcd3471cc743824d0da33af645 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sat, 11 Oct 2025 01:49:08 +0900 Subject: [PATCH] trying to simplify error message handling --- bin/hak.c | 2 +- lib/err.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/exec.c | 2 +- lib/hak.c | 5 +++++ lib/hak.h | 46 ++++++++++++++++++++++++++++++++++++++++++ lib/read.c | 33 ++++++++++++++++++++---------- pas/hak.pas | 14 ++++++------- 7 files changed, 140 insertions(+), 20 deletions(-) diff --git a/bin/hak.c b/bin/hak.c index 6f2edd9..5beebaf 100644 --- a/bin/hak.c +++ b/bin/hak.c @@ -379,7 +379,7 @@ static void print_synerr (hak_t* hak) xtn_t* xtn; xtn = (xtn_t*)hak_getxtn(hak); - hak_getsynerr (hak, &synerr); + hak_getsynerr(hak, &synerr); hak_logbfmt(hak,HAK_LOG_STDERR, "ERROR: "); if (synerr.loc.file) diff --git a/lib/err.c b/lib/err.c index 8c5ba0b..c0a61ed 100644 --- a/lib/err.c +++ b/lib/err.c @@ -654,6 +654,64 @@ void hak_getsynerr (hak_t* hak, hak_synerr_t* synerr) if (synerr) *synerr = hak->c->synerr; } +void hak_getbsynerr (hak_t* hak, hak_bsynerr_t* synerr) +{ + HAK_ASSERT(hak, hak->c != HAK_NULL); + if (synerr) + { + #if defined(HAK_OOCH_IS_UCH) + hak_synerr_t* s; + const hak_ooch_t* msg; + hak_oow_t wcslen, mbslen; + + s = &hak->c->synerr; + HAK_MEMSET(synerr, 0, HAK_SIZEOF(*synerr)); + synerr->num = s->num; + synerr->loc.line = s->loc.line; + synerr->loc.colm = s->loc.colm; + if (s->loc.file) + { + mbslen = HAK_COUNTOF(hak->errmsg.xerrlocfile); + hak_conv_ucstr_to_bcstr_with_cmgr(s->loc.file, &wcslen, hak->errmsg.xerrlocfile, &mbslen, hak->_cmgr); + synerr->loc.file = hak->errmsg.xerrlocfile; /* this can be truncated and is transient */ + } + +/* + msg = (hak->errmsg.buf[0] == '\0')? hak_errnum_to_errstr(hak->errnum): hak->errmsg.buf; + mbslen = HAK_COUNTOF(synerr->tgt.val); + hak_conv_ucstr_to_bcstr_with_cmgr(msg, &wcslen, errinf->msg, &mbslen, hak->_cmgr); +*/ + +/* + synerr-> + + hak_synerrnum_t num; + hak_bloc_t loc; + struct + { + hak_bch_t val[256]; + hak_oow_t len; + } tgt; +*/ + + #else + *synerr = hak->c->synerr; + #endif + } +} + +void hak_getusynerr (hak_t* hak, hak_usynerr_t* synerr) +{ + HAK_ASSERT(hak, hak->c != HAK_NULL); + if (synerr) + { + #if defined(HAK_OOCH_IS_UCH) + *synerr = hak->c->synerr; + #else + #endif + } +} + hak_synerrnum_t hak_getsynerrnum (hak_t* hak) { HAK_ASSERT(hak, hak->c != HAK_NULL); diff --git a/lib/exec.c b/lib/exec.c index 3ace96b..d2e94ae 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -2660,7 +2660,7 @@ static HAK_INLINE int exec_syscmd (hak_t* hak, hak_ooi_t nargs) if (HAK_LIKELY(argv)) { argv[0] = cmd; -//HAK_DEBUG1 (hak, "NARG %d\n", (int)nargs); +/*HAK_DEBUG1 (hak, "NARG %d\n", (int)nargs);*/ for (i = 0; i < nargs;) { hak_oop_t ta = HAK_STACK_GETARG(hak, nargs, i); diff --git a/lib/hak.c b/lib/hak.c index 70ae278..ad2e52e 100644 --- a/lib/hak.c +++ b/lib/hak.c @@ -1021,6 +1021,11 @@ hak_pfbase_t* hak_findpfbase (hak_t* hak, hak_pfinfo_t* pfinfo, hak_oow_t pfcoun return HAK_NULL; } +hak_oow_t hak_get_sizeof_uch (void) +{ + return HAK_SIZEOF(hak_uch_t); +} + const hak_bch_t* hak_obj_type_to_bcstr (hak_obj_type_t type) { static const hak_bch_t* names[] = { diff --git a/lib/hak.h b/lib/hak.h index 5426d77..212853b 100644 --- a/lib/hak.h +++ b/lib/hak.h @@ -1621,6 +1621,7 @@ typedef struct hak_sem_tuple_t hak_sem_tuple_t; /* ========================================================================= * HAK VM * ========================================================================= */ +/* typedef struct hak_synerr_t hak_synerr_t; struct hak_synerr_t { @@ -1632,6 +1633,37 @@ struct hak_synerr_t hak_oow_t len; } tgt; }; +*/ + +typedef struct hak_bsynerr_t hak_bsynerr_t; +struct hak_bsynerr_t +{ + hak_synerrnum_t num; + hak_bloc_t loc; + struct + { + hak_bch_t val[256]; + hak_oow_t len; + } tgt; +}; + +typedef struct hak_usynerr_t hak_usynerr_t; +struct hak_usynerr_t +{ + hak_synerrnum_t num; + hak_uloc_t loc; + struct + { + hak_uch_t val[256]; + hak_oow_t len; + } tgt; +}; + +#if defined(HAK_OOCH_IS_UCH) +typedef hak_usynerr_t hak_synerr_t; +#else +typedef hak_bsynerr_t hak_synerr_t; +#endif typedef struct hak_dbgi_t hak_dbgi_t; struct hak_dbgi_t @@ -2168,6 +2200,10 @@ typedef int (*hak_xchg_writer_t) ( extern "C" { #endif +HAK_EXPORT hak_oow_t hak_get_sizeof_uch ( + void +); + HAK_EXPORT const hak_bch_t* hak_obj_type_to_bcstr ( hak_obj_type_t type ); @@ -2703,6 +2739,16 @@ static HAK_INLINE hak_ooi_t hak_getip (hak_t* hak) { return hak->ip; } /* ========================================================================= * SYNTAX ERROR HANDLING * ========================================================================= */ +HAK_EXPORT void hak_getbsynerr ( + hak_t* hak, + hak_bsynerr_t* synerr +); + +HAK_EXPORT void hak_getusynerr ( + hak_t* hak, + hak_usynerr_t* synerr +); + HAK_EXPORT void hak_getsynerr ( hak_t* hak, hak_synerr_t* synerr diff --git a/lib/read.c b/lib/read.c index 7b6f89f..0403bb4 100644 --- a/lib/read.c +++ b/lib/read.c @@ -729,9 +729,10 @@ static HAK_INLINE hak_cnode_t* leave_list (hak_t* hak, hak_loc_t* list_loc, int* } else { - hak_synerrnum_t err; - err = (fv & COMMAED)? HAK_SYNERR_COMMANOVALUE: HAK_SYNERR_COLONNOVALUE; - hak_setsynerr(hak, err, TOKEN_LOC(hak), HAK_NULL); + if (fv & COMMAED) + hak_setsynerrbfmt(hak, HAK_SYNERR_COMMANOVALUE, TOKEN_LOC(hak), HAK_NULL, "no valid token after comma"); + else + hak_setsynerrbfmt(hak, HAK_SYNERR_COMMANOVALUE, TOKEN_LOC(hak), HAK_NULL, "no valid token after colon"); } goto oops; } @@ -769,7 +770,7 @@ static HAK_INLINE hak_cnode_t* leave_list (hak_t* hak, hak_loc_t* list_loc, int* if (lval && HAK_CNODE_IS_ELIST(lval)) { /* invalid lvalue - for example, () := 20 */ - hak_setsynerrbfmt(hak, HAK_SYNERR_LVALUE, HAK_CNODE_GET_LOC(lval), HAK_CNODE_GET_TOK(lval), "bad lvalue - blank expression"); + hak_setsynerrbfmt(hak, HAK_SYNERR_LVALUE, HAK_CNODE_GET_LOC(lval), HAK_NULL, "bad lvalue - blank expression"); goto oops; } else if (lval && HAK_CNODE_IS_CONS_CONCODED(lval, HAK_CONCODE_TUPLE)) @@ -796,7 +797,10 @@ static HAK_INLINE hak_cnode_t* leave_list (hak_t* hak, hak_loc_t* list_loc, int* lcar = HAK_CNODE_CONS_CAR(tmp); if (!HAK_CNODE_IS_SYMBOL(lcar) && !HAK_CNODE_IS_DSYMBOL_CLA(lcar)) { - hak_setsynerrbfmt(hak, HAK_SYNERR_LVALUE, HAK_CNODE_GET_LOC(lval), HAK_CNODE_GET_TOK(lval), "bad lvalue - invalid identifier in tuple"); + hak_setsynerrbfmt(hak, HAK_SYNERR_LVALUE, HAK_CNODE_GET_LOC(lcar), HAK_NULL, + "bad lvalue - invalid token%hs%.*js in tuple", + (HAK_CNODE_GET_TOKLEN(lcar) > 0? " ": ""), + HAK_CNODE_GET_TOKLEN(lcar), HAK_CNODE_GET_TOKPTR(lcar)); goto oops; } } @@ -822,7 +826,10 @@ static HAK_INLINE hak_cnode_t* leave_list (hak_t* hak, hak_loc_t* list_loc, int* { if (!HAK_CNODE_IS_SYMBOL(lval) && !HAK_CNODE_IS_DSYMBOL_CLA(lval)) { - hak_setsynerrbfmt(hak, HAK_SYNERR_LVALUE, HAK_CNODE_GET_LOC(lval), HAK_CNODE_GET_TOK(lval), "bad lvalue - invalid identifier"); + /* for example, 1 := 20 */ + hak_setsynerrbfmt(hak, HAK_SYNERR_LVALUE, HAK_CNODE_GET_LOC(lval), HAK_NULL, + "bad lvalue - invalid identifier '%.*js'", + HAK_CNODE_GET_TOKLEN(lval), HAK_CNODE_GET_TOKPTR(lval)); goto oops; } #if defined(TRANSFORM_ALIST) @@ -840,7 +847,9 @@ static HAK_INLINE hak_cnode_t* leave_list (hak_t* hak, hak_loc_t* list_loc, int* rval = HAK_CNODE_CONS_CDR(rval); rval = HAK_CNODE_CONS_CAR(rval); - hak_setsynerrbfmt(hak, HAK_SYNERR_RVALUE, HAK_CNODE_GET_LOC(rval), HAK_CNODE_GET_TOK(rval), "too many rvalues after :="); + hak_setsynerrbfmt(hak, HAK_SYNERR_RVALUE, HAK_CNODE_GET_LOC(rval), HAK_NULL, + "too many rvalues after := around '%.*js'", + HAK_CNODE_GET_TOKLEN(rval), HAK_CNODE_GET_TOKPTR(rval)); goto oops; } @@ -1227,7 +1236,7 @@ static int chain_to_list (hak_t* hak, hak_cnode_t* obj, hak_loc_t* loc) * can only be triggered by a wrong qlist where a period is * allowed. so i can safely hard-code the error code to * HAK_SYNERR_RPAREN */ - hak_setsynerr(hak, HAK_SYNERR_RPAREN, TOKEN_LOC(hak), TOKEN_NAME(hak)); + hak_setsynerrbfmt(hak, HAK_SYNERR_RPAREN, TOKEN_LOC(hak), HAK_NULL, ") expected around '%.*js'", TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak)); return -1; } else if (flagv & DOTTED) @@ -1276,8 +1285,10 @@ static int chain_to_list (hak_t* hak, hak_cnode_t* obj, hak_loc_t* loc) if ((flagv & JSON) && rstl->count > 0 && !(flagv & (COMMAED | COLONED))) { /* there is no separator between array/dictionary elements - * for instance, [1 2] { 10 20 } */ - hak_setsynerr(hak, HAK_SYNERR_NOSEP, TOKEN_LOC(hak), HAK_NULL); + * for instance, #{10:20, 30:40 40:50} */ + hak_setsynerrbfmt(hak, HAK_SYNERR_NOSEP, TOKEN_LOC(hak), HAK_NULL, + "no separator between array/dictionary elements around '%.*js", + TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak)); return -1; } @@ -1387,7 +1398,7 @@ static int feed_begin_include (hak_t* hak) if (hak->c->cci_rdr(hak, HAK_IO_OPEN, arg) <= -1) { const hak_ooch_t* orgmsg = hak_backuperrmsg(hak); - hak_setsynerrbfmt(hak, HAK_SYNERR_INCLUDE, TOKEN_LOC(hak), TOKEN_NAME(hak), "unable to include %js - %js", io_name, orgmsg); + hak_setsynerrbfmt(hak, HAK_SYNERR_INCLUDE, TOKEN_LOC(hak), HAK_NULL, "unable to include %js - %js", io_name, orgmsg); goto oops; } diff --git a/pas/hak.pas b/pas/hak.pas index 2386e0e..d6b8be8 100644 --- a/pas/hak.pas +++ b/pas/hak.pas @@ -77,9 +77,9 @@ type destructor Destroy(); override; procedure Ignite(heapsize: System.SizeUint); procedure AddBuiltinPrims(); - procedure CompileFile(filename: PBchar); - procedure CompileText(text: PBchar); - procedure CompileText(text: PBchar; len: System.SizeUint); + procedure CompileFile(filename: System.PAnsiChar); + procedure CompileText(text: System.PAnsiChar); + procedure CompileText(text: System.PAnsiChar; len: System.SizeUint); procedure CompileText(text: PUchar); procedure CompileText(text: PUchar; len: System.SizeUint); {$if defined(HAK_WIDE_CHAR_SIZE_IS_4)} @@ -416,14 +416,14 @@ begin exit(0); end; -procedure Interp.CompileFile(filename: PBchar); +procedure Interp.CompileFile(filename: System.PAnsiChar); var f: System.THandle = -1; attached: boolean = false; feed_ongoing: boolean = false; errnum: System.Integer; errmsg: string; - buf: array[0..1023] of Bchar; + buf: array[0..1023] of System.AnsiChar; len: System.LongInt; label oops; @@ -482,12 +482,12 @@ oops: raise Exception.Create(errmsg); end; -procedure Interp.CompileText(text: PBchar); +procedure Interp.CompileText(text: System.PAnsiChar); begin self.CompileText(text, SysUtils.Strlen(text)); end; -procedure Interp.CompileText(text: PBchar; len: System.SizeUint); +procedure Interp.CompileText(text: System.PAnsiChar; len: System.SizeUint); var errnum: integer; errmsg: string;