From 431840f77b3b45df5fbdfcf46151b9933997007c Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 27 Oct 2024 19:17:07 +0900 Subject: [PATCH] improved the interactive input handling if isocline is available --- Makefile.in | 3 +- bin/Makefile.am | 2 +- bin/Makefile.in | 6 +- bin/hcl.c | 185 ++++++++++++++++++++++++++++++++++++++--------- configure | 58 +++++++++++++++ configure.ac | 13 +++- lib/Makefile.in | 1 + lib/hcl-cfg.h.in | 6 ++ lib/hcl.c | 2 +- lib/hcl.h | 55 ++++++++------ lib/read.c | 13 ++++ mod/Makefile.in | 1 + pas/Makefile.in | 1 + src/System.hcl | 19 ++++- t/Makefile.in | 1 + t/feed-01.hcl | 13 ++++ 16 files changed, 311 insertions(+), 68 deletions(-) diff --git a/Makefile.in b/Makefile.in index 56e40ec..5d79f6e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -174,7 +174,7 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/ac/ar-lib \ $(top_srcdir)/ac/compile $(top_srcdir)/ac/config.guess \ $(top_srcdir)/ac/config.sub $(top_srcdir)/ac/install-sh \ $(top_srcdir)/ac/ltmain.sh $(top_srcdir)/ac/missing README.md \ - ac/ar-lib ac/compile ac/config.guess ac/config.sub \ + ac/ar-lib ac/compile ac/config.guess ac/config.sub ac/depcomp \ ac/install-sh ac/ltmain.sh ac/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) @@ -260,6 +260,7 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +ISOCLINE_LIBS = @ISOCLINE_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBM = @LIBM@ diff --git a/bin/Makefile.am b/bin/Makefile.am index 54a6ae9..82c2469 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -27,7 +27,7 @@ bin_PROGRAMS = hcl hcl_SOURCES = hcl.c hcl_CPPFLAGS = $(CPPFLAGS_COMMON) hcl_LDFLAGS = $(LDFLAGS_COMMON) -hcl_LDADD = ../lib/libhcl.la $(LIBADD_COMMON) +hcl_LDADD = ../lib/libhcl.la $(LIBADD_COMMON) $(ISOCLINE_LIBS) if ENABLE_HCLX diff --git a/bin/Makefile.in b/bin/Makefile.in index e7fb433..122e567 100644 --- a/bin/Makefile.in +++ b/bin/Makefile.in @@ -119,7 +119,8 @@ am__DEPENDENCIES_1 = @ENABLE_LIBLTDL_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) @ENABLE_LIBLTDL_FALSE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) am__DEPENDENCIES_4 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) -hcl_DEPENDENCIES = ../lib/libhcl.la $(am__DEPENDENCIES_4) +hcl_DEPENDENCIES = ../lib/libhcl.la $(am__DEPENDENCIES_4) \ + $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -236,6 +237,7 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +ISOCLINE_LIBS = @ISOCLINE_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBM = @LIBM@ @@ -351,7 +353,7 @@ LIBADD_COMMON = $(am__append_1) $(am__append_2) hcl_SOURCES = hcl.c hcl_CPPFLAGS = $(CPPFLAGS_COMMON) hcl_LDFLAGS = $(LDFLAGS_COMMON) -hcl_LDADD = ../lib/libhcl.la $(LIBADD_COMMON) +hcl_LDADD = ../lib/libhcl.la $(LIBADD_COMMON) $(ISOCLINE_LIBS) @ENABLE_HCLX_TRUE@hclx_SOURCES = hclx.c @ENABLE_HCLX_TRUE@hclx_CPPFLAGS = $(CPPFLAGS_COMMON) @ENABLE_HCLX_TRUE@hclx_LDFLAGS = $(LDFLAGS_COMMON) diff --git a/bin/hcl.c b/bin/hcl.c index 6088108..d94eeef 100644 --- a/bin/hcl.c +++ b/bin/hcl.c @@ -41,6 +41,11 @@ #include #include +#if defined(HAVE_ISOCLINE_H) && defined(HAVE_ISOCLINE_LIB) +# include +# define USE_ISOCLINE +#endif + #if defined(_WIN32) # include # include @@ -86,17 +91,6 @@ #define FOPEN_R_FLAGS "r" #endif -typedef struct bb_t bb_t; -struct bb_t -{ - char buf[1024]; - hcl_oow_t pos; - hcl_oow_t len; - - FILE* fp; - hcl_bch_t* fn; -}; - typedef struct xtn_t xtn_t; struct xtn_t { @@ -108,7 +102,8 @@ struct xtn_t struct { - hcl_bch_t buf[1024]; + hcl_bch_t* ptr; + hcl_bch_t buf[1024]; /* not used if isocline is used */ hcl_oow_t len; hcl_oow_t pos; int eof; @@ -134,6 +129,14 @@ static void vm_cleanup (hcl_t* hcl) { xtn_t* xtn = (xtn_t*)hcl_getxtn(hcl); xtn->vm_running = 0; + +#if defined(USE_ISOCLINE) + if (xtn->feed.ptr && xtn->feed.ptr != xtn->feed.buf) + { + ic_free (xtn->feed.ptr); + xtn->feed.ptr = HCL_NULL; + } +#endif } /* @@ -420,12 +423,40 @@ static void print_error (hcl_t* hcl, const hcl_bch_t* msghdr) /*else hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: %hs - [%d] %js\n", msghdr, hcl_geterrnum(hcl), hcl_geterrmsg(hcl));*/ } + +#if defined(USE_ISOCLINE) +static void print_incomplete_expression_error (hcl_t* hcl) +{ + /* isocline is supposed to return a full expression. + * if something is pending in the feed side, the input isn't complete yet */ + xtn_t* xtn; + hcl_loc_t loc; + + xtn = hcl_getxtn(hcl); + hcl_getfeedloc (hcl, &loc); + + hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: "); + if (loc.file) + hcl_logbfmt (hcl, HCL_LOG_STDERR, "%js", loc.file); + else + hcl_logbfmt (hcl, HCL_LOG_STDERR, "%hs", xtn->cci_path); + + /* if the input is like this + * a := 2; c := { + * the second expression is incompelete. however, the whole input is not executed. + * the number of compiled expressions so far is in xtn->feed.ncompexprs, however */ + hcl_logbfmt (hcl, HCL_LOG_STDERR, "[%zu,%zu] incomplete expression\n", loc.line, loc.colm); +} +#endif + static void show_prompt (hcl_t* hcl, int level) { /* TODO: different prompt per level */ - hcl_resetfeedloc (hcl); + hcl_resetfeedloc (hcl); /* restore the line number to 1 in the interactive mode */ +#if !defined(USE_ISOCLINE) hcl_logbfmt (hcl, HCL_LOG_STDOUT, "HCL> "); hcl_logbfmt (hcl, HCL_LOG_STDOUT, HCL_NULL); /* flushing */ +#endif } static hcl_oop_t execute_in_interactive_mode (hcl_t* hcl) @@ -444,7 +475,7 @@ static hcl_oop_t execute_in_interactive_mode (hcl_t* hcl) if (!retv) { - print_error (hcl, "cannot execute"); + print_error (hcl, "execute"); } else { @@ -499,14 +530,8 @@ static hcl_oop_t execute_in_batch_mode(hcl_t* hcl, int verbose) retv = hcl_execute(hcl); hcl_flushudio (hcl); - if (!retv) - { - print_error (hcl, "cannot execute"); - } - else if (verbose) - { - hcl_logbfmt (hcl, HCL_LOG_STDERR, "EXECUTION OK - EXITED WITH %O\n", retv); - } + if (!retv) print_error (hcl, "execute"); + else if (verbose) hcl_logbfmt (hcl, HCL_LOG_STDERR, "EXECUTION OK - EXITED WITH %O\n", retv); /*cancel_tick();*/ g_hcl = HCL_NULL; @@ -535,7 +560,7 @@ static int on_fed_cnode_in_interactive_mode (hcl_t* hcl, hcl_cnode_t* obj) if (hcl_compile(hcl, obj, flags) <= -1) { - /*print_error(hcl, "failed to compile"); */ + /*print_error(hcl, "compile"); */ xtn->feed.pos = xtn->feed.len; /* arrange to discard the rest of the line */ return -1; /* this causes the feed function to fail and the error hander for to print the error message */ @@ -551,12 +576,57 @@ static int on_fed_cnode_in_batch_mode (hcl_t* hcl, hcl_cnode_t* obj) return hcl_compile(hcl, obj, 0); } +#if defined(USE_ISOCLINE) +static int get_line (hcl_t* hcl, xtn_t* xtn, FILE* fp) +{ + char* inp, * p; + static int inited = 0; + + if (!inited) + { + ic_style_def("kbd","gray underline"); // you can define your own styles + ic_style_def("ic-prompt","ansi-maroon"); // or re-define system styles + ic_set_history (HCL_NULL, -1); + ic_enable_multiline (1); + ic_enable_multiline_indent (1); + ic_set_matching_braces ("()[]{}"); + ic_enable_brace_insertion (1); + ic_set_insertion_braces("()[]{}\"\"''"); + inited = 1; + } + + if (xtn->feed.eof) return 0; + + xtn->feed.pos = 0; + xtn->feed.len = 0; + if (xtn->feed.ptr) + { + HCL_ASSERT (hcl, xtn->feed.ptr != xtn->feed.buf); + ic_free (xtn->feed.ptr); + xtn->feed.ptr = HCL_NULL; + } + + inp = ic_readline("HCL"); + if (inp == NULL) + { + /* TODO: check if it's an error or Eof */ + xtn->feed.eof = 1; + if (xtn->feed.len <= 0) return 0; + return 0; + } + + xtn->feed.len = hcl_count_bcstr(inp); + xtn->feed.ptr = inp; + return 1; +} +#else static int get_line (hcl_t* hcl, xtn_t* xtn, FILE* fp) { if (xtn->feed.eof) return 0; xtn->feed.pos = 0; xtn->feed.len = 0; + xtn->feed.ptr = xtn->feed.buf; /* use the internal buffer */ while (1) { @@ -581,6 +651,7 @@ static int get_line (hcl_t* hcl, xtn_t* xtn, FILE* fp) return 1; } +#endif static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose) { @@ -620,6 +691,7 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose) if (is_tty) { + /* interactive mode */ show_prompt (hcl, 0); while (1) @@ -628,6 +700,10 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose) hcl_oow_t pos; hcl_oow_t len; + #if defined(USE_ISOCLINE) + int lf_injected = 0; + #endif + /* read a line regardless of the actual expression */ n = get_line(hcl, xtn, fp); if (n <= -1) goto oops; @@ -635,43 +711,80 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose) /* feed the line */ pos = xtn->feed.pos; - /* do this before calling hcl_feedbchars() so that the callback sees the updated value */ + /* update xtn->feed.pos before calling hcl_feedbchars() so that the callback sees the updated value */ xtn->feed.pos = xtn->feed.len; len = xtn->feed.len - pos; - if (hcl_feedbchars(hcl, &xtn->feed.buf[pos], len) <= -1) + n = hcl_feedbchars(hcl, &xtn->feed.ptr[pos], len); + #if defined(USE_ISOCLINE) + chars_fed: + #endif + if (n <= -1) { - print_error (hcl, "failed to feed"); - if (len > 0) show_prompt (hcl, 0); + print_error (hcl, "feed"); /* syntax error or something - mostly compile error */ - hcl_clearcode(hcl); /* clear the compiled code but not executed yet in advance */ - xtn->feed.ncompexprs = 0; /* next time, hcl_compile() is supposed to clear code and fnblks */ + #if defined(USE_ISOCLINE) + reset_on_feed_error: + #endif + hcl_resetfeed (hcl); + hcl_clearcode (hcl); /* clear the compiled code but not executed yet in advance */ + xtn->feed.ncompexprs = 0; /* next time, on_fed_cnode_in_interactive_mode() clears code and fnblks */ + /*if (len > 0)*/ show_prompt (hcl, 0); /* show prompt after error */ } else { - /* TODO: check if this works when HCL_TRAIT_LANG_ENABLE_EOL is not set */ if (!hcl_feedpending(hcl)) { - if (xtn->feed.ncompexprs > 0 && hcl_getbclen(hcl) > 0) + if (xtn->feed.ncompexprs > 0) { - execute_in_interactive_mode (hcl); + if (hcl_getbclen(hcl) > 0) execute_in_interactive_mode (hcl); xtn->feed.ncompexprs = 0; } - show_prompt (hcl, 0); + else + { + HCL_ASSERT (hcl, hcl_getbclen(hcl) == 0); + /* usually this part is reached if the input string is + * one or more whilespaces and/or comments only */ + } + show_prompt (hcl, 0); /* show prompt after execution */ } + #if defined(USE_ISOCLINE) + else if (!lf_injected) + { + /* in this mode, one input string must be composed of one or more + * complete expression. however, it doesn't isocline doesn't include + * the ending line-feed in the returned input string. inject one to the feed */ + static const char lf = '\n'; + lf_injected = 1; + n = hcl_feedbchars(hcl, &lf, 1); + goto chars_fed; + } + else + { + print_incomplete_expression_error (hcl); + goto reset_on_feed_error; + } + #endif } } + #if !defined(USE_ISOCLINE) + /* eof is given, usually with ctrl-D, no new line is output after the prompt. + * this results in the OS prompt on the same line as this program's prompt. + * however ISOCLINE prints a newline upon ctrl-D. print \n when ISOCLINE is + * not used */ hcl_logbfmt (hcl, HCL_LOG_STDOUT, "\n"); + #endif } else { + /* non-interactive mode */ while (1) { hcl_bch_t buf[1024]; hcl_oow_t xlen; xlen = fread(buf, HCL_SIZEOF(buf[0]), HCL_COUNTOF(buf), fp); - if (xlen > 0 && hcl_feedbchars(hcl, buf, xlen) <= -1) goto feed_error; + if (xlen > 0 && hcl_feedbchars(hcl, buf, xlen) <= -1) goto endfeed_error; if (xlen < HCL_COUNTOF(buf)) { if (ferror(fp)) @@ -686,8 +799,8 @@ static int feed_loop (hcl_t* hcl, xtn_t* xtn, int verbose) if (hcl_endfeed(hcl) <= -1) { - feed_error: - print_error (hcl, "failed to feed"); + endfeed_error: + print_error (hcl, "endfeed"); goto oops; /* TODO: proceed or just exit? */ } fclose (fp); diff --git a/configure b/configure index fa2911c..1910aff 100755 --- a/configure +++ b/configure @@ -689,6 +689,7 @@ PACKAGE_VERSION_MINOR PACKAGE_VERSION_MAJOR QUADMATH_LIBS UNICOWS_LIBS +ISOCLINE_LIBS UNWIND_LIBS LTDL_LIBS DL_LIBS @@ -15576,6 +15577,12 @@ if test "x$ac_cv_header_quadmath_h" = xyes then : printf "%s\n" "#define HAVE_QUADMATH_H 1" >>confdefs.h +fi +ac_fn_c_check_header_compile "$LINENO" "isocline.h" "ac_cv_header_isocline_h" "$ac_includes_default" +if test "x$ac_cv_header_isocline_h" = xyes +then : + printf "%s\n" "#define HAVE_ISOCLINE_H 1" >>confdefs.h + fi ac_fn_c_check_header_compile "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" @@ -15979,6 +15986,57 @@ printf "%s\n" "#define HAVE_UNWIND_LIB 1" >>confdefs.h +fi + + +fi + +if test "x${ac_cv_header_isocline_h}" = "xyes" +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ic_readline in -lisocline" >&5 +printf %s "checking for ic_readline in -lisocline... " >&6; } +if test ${ac_cv_lib_isocline_ic_readline+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lisocline $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char ic_readline (); +int +main (void) +{ +return ic_readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_isocline_ic_readline=yes +else $as_nop + ac_cv_lib_isocline_ic_readline=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_isocline_ic_readline" >&5 +printf "%s\n" "$ac_cv_lib_isocline_ic_readline" >&6; } +if test "x$ac_cv_lib_isocline_ic_readline" = xyes +then : + + ISOCLINE_LIBS="-lisocline" + +printf "%s\n" "#define HAVE_ISOCLINE_LIB 1" >>confdefs.h + + + fi diff --git a/configure.ac b/configure.ac index 944b401..898c0e1 100644 --- a/configure.ac +++ b/configure.ac @@ -111,7 +111,7 @@ AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h fcntl.h dirent.h]) AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h execinfo.h ucontext.h]) AC_CHECK_HEADERS([dlfcn.h ltdl.h sys/mman.h sys/uio.h]) AC_CHECK_HEADERS([sys/devpoll.h sys/epoll.h poll.h]) -AC_CHECK_HEADERS([libunwind.h quadmath.h]) +AC_CHECK_HEADERS([libunwind.h quadmath.h isocline.h]) AC_CHECK_HEADERS([sys/ioctl.h net/if.h]) dnl check data types @@ -165,6 +165,17 @@ then AC_SUBST(UNWIND_LIBS) fi +if test "x${ac_cv_header_isocline_h}" = "xyes" +then + AC_CHECK_LIB([isocline], [ic_readline], + [ + ISOCLINE_LIBS="-lisocline" + AC_DEFINE([HAVE_ISOCLINE_LIB], [1], [libisocline is available]) + ] + ) + AC_SUBST(ISOCLINE_LIBS) +fi + dnl check is the import library for unicows.dll exists dnl this check doesn't look for a particular symbol dnl but for the symbol 'main' since i want to check diff --git a/lib/Makefile.in b/lib/Makefile.in index f239ee1..c167900 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -312,6 +312,7 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +ISOCLINE_LIBS = @ISOCLINE_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBM = @LIBM@ diff --git a/lib/hcl-cfg.h.in b/lib/hcl-cfg.h.in index 000128f..93fb08d 100644 --- a/lib/hcl-cfg.h.in +++ b/lib/hcl-cfg.h.in @@ -90,6 +90,12 @@ /* Define to 1 if you have the `isatty' function. */ #undef HAVE_ISATTY +/* Define to 1 if you have the header file. */ +#undef HAVE_ISOCLINE_H + +/* libisocline is available */ +#undef HAVE_ISOCLINE_LIB + /* Define to 1 if you have the `kqueue' function. */ #undef HAVE_KQUEUE diff --git a/lib/hcl.c b/lib/hcl.c index 681d0fb..a45b99b 100644 --- a/lib/hcl.c +++ b/lib/hcl.c @@ -370,7 +370,7 @@ void hcl_fini (hcl_t* hcl) if (hcl->vmprim.dl_cleanup) hcl->vmprim.dl_cleanup (hcl); } -void hcl_reset (hcl_t* hcl) +void hcl_resetcode (hcl_t* hcl) { hcl_oop_t v; hcl_oow_t i; diff --git a/lib/hcl.h b/lib/hcl.h index bf9406e..5b89471 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -324,8 +324,8 @@ typedef enum hcl_obj_type_t hcl_obj_type_t; * terminating null in a variable-char object. internel * use only. * kernel: 0 - ordinary object. - * 1 - kernel object. can survive hcl_reset(). - * 2 - kernel object. can survive hcl_reset(). + * 1 - kernel object. can survive hcl_resetcode(). + * 2 - kernel object. can survive hcl_resetcode(). * a symbol object with 2 in the kernel bits cannot be assigned a * value with the 'set' special form. * moved: 0 or 1. used by GC. internal use only. @@ -2127,27 +2127,6 @@ HCL_EXPORT void hcl_fini ( hcl_t* hcl ); -/** - * The hcl_reset() function some internal states back to the initial state. - * The affected internal states include byte code buffer, literal frame, - * ordinary global variables. You should take extra precaution as it is - * a risky function. For instance, a global variable inserted manually - * with hcl_putatsysdic() gets deleted if the kernel bit is not set on - * the variable symbol. - */ -HCL_EXPORT void hcl_reset ( - hcl_t* hcl -); - -#define HCL_XTN(hcl) ((void*)((hcl_uint8_t*)hcl + ((hcl_t*)hcl)->_instsize)) -#define HCL_MMGR(hcl) (((hcl_t*)(hcl))->_mmgr) -#define HCL_CMGR(hcl) (((hcl_t*)(hcl))->_cmgr) -#define HCL_ERRNUM(hcl) (((hcl_t*)(hcl))->errnum) - -void* hcl_getxtn ( - hcl_t* hcl -); - HCL_EXPORT hcl_cmgr_t* hcl_getcmgr ( hcl_t* hcl ); @@ -2513,11 +2492,19 @@ HCL_EXPORT int hcl_feedpending ( hcl_t* hcl ); +HCL_EXPORT void hcl_resetfeed ( + hcl_t* hcl +); HCL_EXPORT void hcl_resetfeedloc ( hcl_t* hcl ); +HCL_EXPORT void hcl_getfeedloc ( + hcl_t* hcl, + hcl_loc_t* loc +); + HCL_EXPORT int hcl_endfeed ( hcl_t* hcl ); @@ -2567,10 +2554,32 @@ HCL_EXPORT int hcl_decode ( hcl_oow_t end ); +/** + * The hcl_resetcode() function some internal states back to the initial state. + * The affected internal states include byte code buffer, literal frame, + * ordinary global variables. You should take extra precaution as it is + * a risky function. For instance, a global variable inserted manually + * with hcl_putatsysdic() gets deleted if the kernel bit is not set on + * the variable symbol. + */ +HCL_EXPORT void hcl_resetcode ( + hcl_t* hcl +); + HCL_EXPORT void hcl_clearcode ( hcl_t* hcl ); +#define HCL_XTN(hcl) ((void*)((hcl_uint8_t*)hcl + ((hcl_t*)hcl)->_instsize)) +#define HCL_MMGR(hcl) (((hcl_t*)(hcl))->_mmgr) +#define HCL_CMGR(hcl) (((hcl_t*)(hcl))->_cmgr) +#define HCL_ERRNUM(hcl) (((hcl_t*)(hcl))->errnum) + +void* hcl_getxtn ( + hcl_t* hcl +); + + #if defined(HCL_HAVE_INLINE) static HCL_INLINE hcl_code_t* hcl_getcode (hcl_t* hcl) { return &hcl->code; } static HCL_INLINE hcl_oob_t* hcl_getbcptr (hcl_t* hcl) { return hcl->code.bc.ptr; } diff --git a/lib/read.c b/lib/read.c index 3427146..050c7cb 100644 --- a/lib/read.c +++ b/lib/read.c @@ -3645,6 +3645,11 @@ int hcl_feedpending (hcl_t* hcl) return !(hcl->c->r.st == HCL_NULL && FLX_STATE(hcl) == HCL_FLX_START); } +void hcl_getfeedloc (hcl_t* hcl, hcl_loc_t* loc) +{ + *loc = hcl->c->feed.lx.loc; +} + void hcl_resetfeedloc (hcl_t* hcl) { hcl->c->feed.lx.loc.line = 1; @@ -3652,6 +3657,14 @@ void hcl_resetfeedloc (hcl_t* hcl) hcl->c->feed.lx.loc.file = HCL_NULL; } +void hcl_resetfeed (hcl_t* hcl) +{ + feed_reset_reader_state (hcl); + feed_clean_up_reader_stack (hcl); + feed_continue (hcl, HCL_FLX_START); + hcl_resetfeedloc (hcl); +} + int hcl_feed (hcl_t* hcl, const hcl_ooch_t* data, hcl_oow_t len) { /* TODO: need to return the number of processed characters? diff --git a/mod/Makefile.in b/mod/Makefile.in index c2d2b9c..ec4ab79 100644 --- a/mod/Makefile.in +++ b/mod/Makefile.in @@ -269,6 +269,7 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +ISOCLINE_LIBS = @ISOCLINE_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBM = @LIBM@ diff --git a/pas/Makefile.in b/pas/Makefile.in index 057375d..97f4586 100644 --- a/pas/Makefile.in +++ b/pas/Makefile.in @@ -210,6 +210,7 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +ISOCLINE_LIBS = @ISOCLINE_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBM = @LIBM@ diff --git a/src/System.hcl b/src/System.hcl index ea00b46..2717968 100644 --- a/src/System.hcl +++ b/src/System.hcl @@ -28,7 +28,6 @@ class System: Apex { ## ## initialize class variables ## ## - var(#class) asyncsg ## async semaphore group var(#class) gcfin_sem ## gc finalization semaphore var(#class) gcfin_should_exit @@ -39,6 +38,20 @@ class System: Apex { shr := (OrderedCollection:new) asyncsg := (SemaphoreGroup:new) +SemaphoreGroup new +SemaphoreGroup new: 10 + +## for keyword message, it's easy to tell... +a addSemaphore: sem ## sending addSemaphore to 'a' +a #addSeamphore sem ## calling the function 'a' + +## for binary message, it's also easy to tell. +1 + 2 ##-- resolved at the reader level ++ 1 2 ##-- ++ is a function object. `+ a: 10`-> what must be the meaning of this? + send the a message to the function object '+' with argument 10. + + fun(#class) addAsyncSemaphore(sem) { return (self.asyncsg addSemaphore sem) } @@ -53,7 +66,7 @@ class System: Apex { ## fun(#class) installSignalHandler: block { ## return (self.shr addLast: block) -## } +## }` ## ## fun(#class) uninstallSignalHandler: block { ## self.shr remove: block. @@ -93,7 +106,7 @@ class System: Apex { ## self _setSig: 16rFF. ## ]. ## -## ^ret. +## return ret. ## } ## ## fun(#class) __gc_finalizer diff --git a/t/Makefile.in b/t/Makefile.in index 82a39a6..4b763de 100644 --- a/t/Makefile.in +++ b/t/Makefile.in @@ -372,6 +372,7 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +ISOCLINE_LIBS = @ISOCLINE_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBM = @LIBM@ diff --git a/t/feed-01.hcl b/t/feed-01.hcl index 03d668b..ddf6cd9 100644 --- a/t/feed-01.hcl +++ b/t/feed-01.hcl @@ -130,4 +130,17 @@ i := (- -16r123abcd128738279878172387123aabbea19849d8282882822332332 123) k := -1919784483373631008405784517212288102153752573650638404319957951405 if (== i k) { printf "OK: i is %d\n" i k } \ else { printf "ERROR: i is not equal to %d\n" k } + + +a := #{ + (if (> 10 20) true else false ): 10, + (if (< 10 20) true else false ): 20 +} +b := (dic.get a true) +c := (dic.get a false) +if (== b 20) { printf "OK: b is %d\n" b } \ +else { printf "ERROR: b is %d, not 20\n" b } +if (== c 10) { printf "OK: b is %d\n" b } \ +else { printf "ERROR: b is %d, not 10\n" b } + } ## END