| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * $Id$ | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-02-07 14:13:13 +00:00
										 |  |  |     Copyright (c) 2016-2018 Chung, Hyung-Hwan. All rights reserved. | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |     modification, are permitted provided that the following conditions | 
					
						
							|  |  |  |     are met: | 
					
						
							|  |  |  |     1. Redistributions of source code must retain the above copyright | 
					
						
							|  |  |  |        notice, this list of conditions and the following disclaimer. | 
					
						
							|  |  |  |     2. Redistributions in binary form must reproduce the above copyright | 
					
						
							|  |  |  |        notice, this list of conditions and the following disclaimer in the | 
					
						
							|  |  |  |        documentation and/or other materials provided with the distribution. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | 
					
						
							|  |  |  |     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
					
						
							|  |  |  |     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 
					
						
							|  |  |  |     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 
					
						
							|  |  |  |     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
					
						
							|  |  |  |     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
					
						
							|  |  |  |     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
					
						
							|  |  |  |     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
					
						
							|  |  |  |     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
					
						
							|  |  |  |     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-07 23:01:17 +09:00
										 |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | #define _CRT_SECURE_NO_WARNINGS
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | #include <hak.h>
 | 
					
						
							|  |  |  | #include <hak-chr.h>
 | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | #include <hak-cmgr.h>
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | #include <hak-str.h>
 | 
					
						
							|  |  |  | #include <hak-utl.h>
 | 
					
						
							|  |  |  | #include <hak-opt.h>
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <limits.h>
 | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #include <locale.h>
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | #if defined(HAVE_ISOCLINE_H) && defined(HAVE_ISOCLINE_LIB)
 | 
					
						
							|  |  |  | #	include <isocline.h>
 | 
					
						
							|  |  |  | #	define USE_ISOCLINE
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | #	include <windows.h>
 | 
					
						
							|  |  |  | #	include <tchar.h>
 | 
					
						
							| 
									
										
										
										
											2018-03-31 07:10:43 +00:00
										 |  |  | #	include <io.h>
 | 
					
						
							|  |  |  | #	include <fcntl.h>
 | 
					
						
							|  |  |  | #	include <time.h>
 | 
					
						
							|  |  |  | #	include <signal.h>
 | 
					
						
							| 
									
										
										
										
											2018-11-03 15:57:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | #elif defined(__OS2__)
 | 
					
						
							|  |  |  | #	define INCL_DOSMODULEMGR
 | 
					
						
							|  |  |  | #	define INCL_DOSPROCESS
 | 
					
						
							|  |  |  | #	define INCL_DOSERRORS
 | 
					
						
							|  |  |  | #	include <os2.h>
 | 
					
						
							| 
									
										
										
										
											2021-03-28 03:44:27 +00:00
										 |  |  | #	include <signal.h>
 | 
					
						
							| 
									
										
										
										
											2018-11-03 15:57:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #elif defined(__DOS__)
 | 
					
						
							| 
									
										
										
										
											2016-10-06 17:49:47 +00:00
										 |  |  | #	include <dos.h>
 | 
					
						
							| 
									
										
										
										
											2016-10-25 13:44:38 +00:00
										 |  |  | #	include <time.h>
 | 
					
						
							| 
									
										
										
										
											2023-12-09 14:01:03 +09:00
										 |  |  | #	include <signal.h>
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | #elif defined(macintosh)
 | 
					
						
							| 
									
										
										
										
											2016-10-06 17:49:47 +00:00
										 |  |  | #	include <Timer.h>
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2018-02-09 01:13:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-03 15:57:14 +00:00
										 |  |  | #	include <sys/types.h>
 | 
					
						
							|  |  |  | #	include <errno.h>
 | 
					
						
							|  |  |  | #	include <unistd.h>
 | 
					
						
							|  |  |  | #	include <fcntl.h>
 | 
					
						
							| 
									
										
										
										
											2016-10-06 17:49:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #	if defined(HAVE_TIME_H)
 | 
					
						
							|  |  |  | #		include <time.h>
 | 
					
						
							|  |  |  | #	endif
 | 
					
						
							|  |  |  | #	if defined(HAVE_SYS_TIME_H)
 | 
					
						
							|  |  |  | #		include <sys/time.h>
 | 
					
						
							|  |  |  | #	endif
 | 
					
						
							|  |  |  | #	if defined(HAVE_SIGNAL_H)
 | 
					
						
							|  |  |  | #		include <signal.h>
 | 
					
						
							|  |  |  | #	endif
 | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | #if defined(__DOS__) || defined(_WIN32) || defined(__OS2__)
 | 
					
						
							|  |  |  | #define FOPEN_R_FLAGS "rb"
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define FOPEN_R_FLAGS "r"
 | 
					
						
							| 
									
										
										
										
											2018-02-09 03:48:30 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-10-06 17:49:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | typedef struct xtn_t xtn_t; | 
					
						
							|  |  |  | struct xtn_t | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-11-05 22:31:33 +09:00
										 |  |  | 	const char* cci_path; /* main source file */ | 
					
						
							| 
									
										
										
										
											2024-02-02 14:57:46 +09:00
										 |  |  | 	/*const char* udi_path; */ /* not implemented as of snow */ | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 	const char* udo_path; | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 14:40:56 +00:00
										 |  |  | 	int vm_running; | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		hak_bch_t* ptr; | 
					
						
							|  |  |  | 		hak_bch_t buf[1024]; /* not used if isocline is used */ | 
					
						
							|  |  |  | 		hak_oow_t len; | 
					
						
							|  |  |  | 		hak_oow_t pos; | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 		int eof; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		hak_oow_t ncompexprs; /* number of compiled expressions */ | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	} feed; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	/*hak_oop_t sym_errstr;*/ | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 11:29:47 +00:00
										 |  |  | /* ========================================================================= */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static hak_t* g_hak = HAK_NULL; | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ========================================================================= */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static int vm_startup (hak_t* hak) | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	xtn_t* xtn = (xtn_t*)hak_getxtn(hak); | 
					
						
							| 
									
										
										
										
											2018-02-08 14:40:56 +00:00
										 |  |  | 	xtn->vm_running = 1; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static void vm_cleanup (hak_t* hak) | 
					
						
							| 
									
										
										
										
											2018-02-08 14:40:56 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	xtn_t* xtn = (xtn_t*)hak_getxtn(hak); | 
					
						
							| 
									
										
										
										
											2018-11-02 14:15:28 +00:00
										 |  |  | 	xtn->vm_running = 0; | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(USE_ISOCLINE)
 | 
					
						
							|  |  |  | 	if (xtn->feed.ptr && xtn->feed.ptr != xtn->feed.buf) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ic_free (xtn->feed.ptr); | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		xtn->feed.ptr = HAK_NULL; | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-02-08 14:40:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-11 11:16:28 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static void vm_checkbc (hak_t* hak, hak_oob_t bcode) | 
					
						
							| 
									
										
										
										
											2018-03-11 11:16:28 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static void on_gc_hak (hak_t* hak) | 
					
						
							| 
									
										
										
										
											2018-03-08 14:18:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	/*xtn_t* xtn = (xtn_t*)hak_getxtn(hak);*/ | 
					
						
							|  |  |  | 	/*if (xtn->sym_errstr) xtn->sym_errstr = hak_moveoop(hak, xtn->sym_errstr);*/ | 
					
						
							| 
									
										
										
										
											2018-03-08 14:18:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | /* ========================================================================= */ | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static int handle_logopt (hak_t* hak, const hak_bch_t* logstr) | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	const hak_bch_t* cm, * flt; | 
					
						
							|  |  |  | 	hak_bitmask_t logmask; | 
					
						
							|  |  |  | 	hak_oow_t tlen, i; | 
					
						
							|  |  |  | 	hak_bcs_t fname; | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-19 19:23:18 +00:00
										 |  |  | 	static struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		const char* name; | 
					
						
							|  |  |  | 		int op; /* 0: bitwise-OR, 1: bitwise-AND */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		hak_bitmask_t mask; | 
					
						
							| 
									
										
										
										
											2021-07-19 19:23:18 +00:00
										 |  |  | 	} xtab[] = | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		{ "",           0, 0 }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		{ "app",        0, HAK_LOG_APP }, | 
					
						
							|  |  |  | 		{ "compiler",   0, HAK_LOG_COMPILER }, | 
					
						
							|  |  |  | 		{ "vm",         0, HAK_LOG_VM }, | 
					
						
							|  |  |  | 		{ "mnemonic",   0, HAK_LOG_MNEMONIC }, | 
					
						
							|  |  |  | 		{ "gc",         0, HAK_LOG_GC }, | 
					
						
							|  |  |  | 		{ "ic",         0, HAK_LOG_IC }, | 
					
						
							|  |  |  | 		{ "primitive",  0, HAK_LOG_PRIMITIVE }, | 
					
						
							| 
									
										
										
										
											2021-07-19 19:23:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 16:02:39 +00:00
										 |  |  | 		/* select a specific level */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		{ "fatal",      0, HAK_LOG_FATAL }, | 
					
						
							|  |  |  | 		{ "error",      0, HAK_LOG_ERROR }, | 
					
						
							|  |  |  | 		{ "warn",       0, HAK_LOG_WARN }, | 
					
						
							|  |  |  | 		{ "info",       0, HAK_LOG_INFO }, | 
					
						
							|  |  |  | 		{ "debug",      0, HAK_LOG_DEBUG }, | 
					
						
							| 
									
										
										
										
											2021-07-19 19:23:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 16:02:39 +00:00
										 |  |  | 		/* select a specific level or higher */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		{ "fatal+",     0, HAK_LOG_FATAL }, | 
					
						
							|  |  |  | 		{ "error+",     0, HAK_LOG_FATAL | HAK_LOG_ERROR }, | 
					
						
							|  |  |  | 		{ "warn+",      0, HAK_LOG_FATAL | HAK_LOG_ERROR | HAK_LOG_WARN }, | 
					
						
							|  |  |  | 		{ "info+",      0, HAK_LOG_FATAL | HAK_LOG_ERROR | HAK_LOG_WARN | HAK_LOG_INFO }, | 
					
						
							|  |  |  | 		{ "debug+",     0, HAK_LOG_FATAL | HAK_LOG_ERROR | HAK_LOG_WARN | HAK_LOG_INFO | HAK_LOG_DEBUG }, | 
					
						
							| 
									
										
										
										
											2021-07-19 19:23:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 16:02:39 +00:00
										 |  |  | 		/* select a specific level or lower */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		{ "fatal-",     0, HAK_LOG_FATAL | HAK_LOG_ERROR | HAK_LOG_WARN | HAK_LOG_INFO | HAK_LOG_DEBUG }, | 
					
						
							|  |  |  | 		{ "error-",     0, HAK_LOG_ERROR | HAK_LOG_WARN | HAK_LOG_INFO | HAK_LOG_DEBUG }, | 
					
						
							|  |  |  | 		{ "warn-",      0, HAK_LOG_WARN | HAK_LOG_INFO | HAK_LOG_DEBUG }, | 
					
						
							|  |  |  | 		{ "info-",      0, HAK_LOG_INFO | HAK_LOG_DEBUG }, | 
					
						
							|  |  |  | 		{ "debug-",     0, HAK_LOG_DEBUG }, | 
					
						
							| 
									
										
										
										
											2021-07-19 19:23:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 16:02:39 +00:00
										 |  |  | 		/* exclude a specific level */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		{ "-fatal",     1, ~(hak_bitmask_t)HAK_LOG_FATAL }, | 
					
						
							|  |  |  | 		{ "-error",     1, ~(hak_bitmask_t)HAK_LOG_ERROR }, | 
					
						
							|  |  |  | 		{ "-warn",      1, ~(hak_bitmask_t)HAK_LOG_WARN }, | 
					
						
							|  |  |  | 		{ "-info",      1, ~(hak_bitmask_t)HAK_LOG_INFO }, | 
					
						
							|  |  |  | 		{ "-debug",     1, ~(hak_bitmask_t)HAK_LOG_DEBUG }, | 
					
						
							| 
									
										
										
										
											2021-07-19 19:23:18 +00:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	cm = hak_find_bchar_in_bcstr(logstr, ','); | 
					
						
							| 
									
										
										
										
											2021-03-28 03:44:27 +00:00
										 |  |  | 	if (cm) | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2021-07-19 18:59:17 +00:00
										 |  |  | 		fname.len = cm - logstr; | 
					
						
							| 
									
										
										
										
											2019-04-16 15:46:00 +00:00
										 |  |  | 		logmask = 0; | 
					
						
							| 
									
										
										
										
											2021-07-19 18:59:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 		do | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			flt = cm + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			cm = hak_find_bchar_in_bcstr(flt, ','); | 
					
						
							|  |  |  | 			tlen = (cm)? (cm - flt): hak_count_bcstr(flt); | 
					
						
							| 
									
										
										
										
											2021-07-19 18:59:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			for (i = 0; i < HAK_COUNTOF(xtab); i++) | 
					
						
							| 
									
										
										
										
											2021-07-19 19:23:18 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 				if (hak_comp_bchars_bcstr(flt, tlen, xtab[i].name) == 0) | 
					
						
							| 
									
										
										
										
											2021-07-19 19:23:18 +00:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					if (xtab[i].op) logmask &= xtab[i].mask; | 
					
						
							|  |  |  | 					else logmask |= xtab[i].mask; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			if (i >= HAK_COUNTOF(xtab)) | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 				fprintf(stderr, "ERROR: unrecognized value  - [%.*s] - [%s]\n", (int)tlen, flt, logstr); | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		while (cm); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		if (!(logmask & HAK_LOG_ALL_TYPES)) logmask |= HAK_LOG_ALL_TYPES;  /* no types specified. force to all types */ | 
					
						
							|  |  |  | 		if (!(logmask & HAK_LOG_ALL_LEVELS)) logmask |= HAK_LOG_ALL_LEVELS;  /* no levels specified. force to all levels */ | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		logmask = HAK_LOG_ALL_LEVELS | HAK_LOG_ALL_TYPES; | 
					
						
							|  |  |  | 		fname.len = hak_count_bcstr(logstr); | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	fname.ptr = (hak_bch_t*)logstr; | 
					
						
							|  |  |  | 	hak_setoption (hak, HAK_LOG_TARGET_BCS, &fname); | 
					
						
							|  |  |  | 	hak_setoption (hak, HAK_LOG_MASK, &logmask); | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | #if defined(HAK_BUILD_DEBUG)
 | 
					
						
							|  |  |  | static int handle_dbgopt (hak_t* hak, const hak_bch_t* str) | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	/*xtn_t* xtn = (xtn_t*)hak_getxtn(hak);*/ | 
					
						
							|  |  |  | 	const hak_bch_t* cm, * flt; | 
					
						
							|  |  |  | 	hak_oow_t len; | 
					
						
							|  |  |  | 	hak_bitmask_t trait, dbgopt = 0; | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cm = str - 1; | 
					
						
							|  |  |  | 	do | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		flt = cm + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		cm = hak_find_bchar_in_bcstr(flt, ','); | 
					
						
							|  |  |  | 		len = cm? (cm - flt): hak_count_bcstr(flt); | 
					
						
							| 
									
										
										
										
											2024-03-08 00:23:52 +09:00
										 |  |  | 		if (len == 0) continue; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		else if (hak_comp_bchars_bcstr(flt, len, "gc") == 0) dbgopt |= HAK_TRAIT_DEBUG_GC; | 
					
						
							|  |  |  | 		else if (hak_comp_bchars_bcstr(flt, len, "bigint") == 0) dbgopt |= HAK_TRAIT_DEBUG_BIGINT; | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 			fprintf(stderr, "ERROR: unknown debug option value - %.*s\n", (int)len, flt); | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	while (cm); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 	hak_getoption(hak, HAK_TRAIT, &trait); | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	trait |= dbgopt; | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 	hak_setoption(hak, HAK_TRAIT, &trait); | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-10-06 17:49:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ========================================================================= */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-09 14:01:03 +09:00
										 |  |  | #if defined(_WIN32) || defined(__DOS__) || defined(__OS2__) || defined(macintosh)
 | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | typedef void(*signal_handler_t)(int); | 
					
						
							|  |  |  | #elif defined(macintosh)
 | 
					
						
							| 
									
										
										
										
											2018-03-31 07:10:43 +00:00
										 |  |  | typedef void(*signal_handler_t)(int); /* TODO: */ | 
					
						
							| 
									
										
										
										
											2018-10-14 10:28:28 +00:00
										 |  |  | #elif defined(SA_SIGINFO)
 | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | typedef void(*signal_handler_t)(int, siginfo_t*, void*); | 
					
						
							| 
									
										
										
										
											2018-10-14 10:28:28 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | typedef void(*signal_handler_t)(int); | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-09 14:01:03 +09:00
										 |  |  | #if defined(_WIN32) || defined(__DOS__) || defined(__OS2__)
 | 
					
						
							| 
									
										
										
										
											2018-03-31 07:10:43 +00:00
										 |  |  | static void handle_sigint (int sig) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (g_hak) hak_abort (g_hak); | 
					
						
							| 
									
										
										
										
											2018-03-31 07:10:43 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | #elif defined(macintosh)
 | 
					
						
							| 
									
										
										
										
											2018-03-31 07:10:43 +00:00
										 |  |  | /* TODO */ | 
					
						
							| 
									
										
										
										
											2018-10-14 10:28:28 +00:00
										 |  |  | #elif defined(SA_SIGINFO)
 | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | static void handle_sigint (int sig, siginfo_t* siginfo, void* ctx) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (g_hak) hak_abort (g_hak); | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-10-14 10:28:28 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | static void handle_sigint (int sig) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (g_hak) hak_abort (g_hak); | 
					
						
							| 
									
										
										
										
											2018-10-14 10:28:28 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void set_signal (int sig, signal_handler_t handler) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-12-09 14:01:03 +09:00
										 |  |  | #if defined(_WIN32) || defined(__DOS__) || defined(__OS2__)
 | 
					
						
							| 
									
										
										
										
											2018-03-31 07:10:43 +00:00
										 |  |  | 	signal (sig, handler); | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | #elif defined(macintosh)
 | 
					
						
							|  |  |  | 	/* TODO: implement this */ | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	struct sigaction sa; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memset (&sa, 0, sizeof(sa)); | 
					
						
							|  |  |  | 	/*sa.sa_handler = handler;*/ | 
					
						
							| 
									
										
										
										
											2018-10-14 10:28:28 +00:00
										 |  |  | #if defined(SA_SIGINFO)
 | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | 	sa.sa_flags = SA_SIGINFO; | 
					
						
							|  |  |  | 	sa.sa_sigaction = handler; | 
					
						
							| 
									
										
										
										
											2018-10-14 10:28:28 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	sa.sa_handler = handler; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | 	sigemptyset (&sa.sa_mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sigaction (sig, &sa, NULL); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void set_signal_to_default (int sig) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-12-09 14:01:03 +09:00
										 |  |  | #if defined(_WIN32) || defined(__DOS__) || defined(__OS2__)
 | 
					
						
							| 
									
										
										
										
											2018-03-31 07:10:43 +00:00
										 |  |  | 	signal (sig, SIG_DFL); | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | #elif defined(macintosh)
 | 
					
						
							|  |  |  | 	/* TODO: implement this */ | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2021-03-28 03:44:27 +00:00
										 |  |  | 	struct sigaction sa; | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	memset (&sa, 0, sizeof(sa)); | 
					
						
							|  |  |  | 	sa.sa_handler = SIG_DFL; | 
					
						
							|  |  |  | 	sa.sa_flags = 0; | 
					
						
							|  |  |  | 	sigemptyset (&sa.sa_mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sigaction (sig, &sa, NULL); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | /* ========================================================================= */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-08 00:51:07 +09:00
										 |  |  | static void print_info (void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | #if defined(HAK_CONFIGURE_CMD) && defined(HAK_CONFIGURE_ARGS)
 | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 	printf("Configured with: %s %s\n", HAK_CONFIGURE_CMD, HAK_CONFIGURE_ARGS); | 
					
						
							| 
									
										
										
										
											2023-12-07 23:01:17 +09:00
										 |  |  | #elif defined(_WIN32)
 | 
					
						
							|  |  |  | 	printf("Built for windows\n"); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* TODO: improve this part */ | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2023-10-08 00:51:07 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static void print_synerr (hak_t* hak) | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_synerr_t synerr; | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	xtn_t* xtn; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	xtn = (xtn_t*)hak_getxtn(hak); | 
					
						
							| 
									
										
										
										
											2025-10-11 01:49:08 +09:00
										 |  |  | 	hak_getsynerr(hak, &synerr); | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	hak_logbfmt(hak,HAK_LOG_STDERR, "ERROR: "); | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	if (synerr.loc.file) | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "%js", synerr.loc.file); | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "%hs", xtn->cci_path); | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	hak_logbfmt(hak, HAK_LOG_STDERR, "[%zu,%zu] %js", | 
					
						
							| 
									
										
										
										
											2018-02-07 13:55:22 +00:00
										 |  |  | 		synerr.loc.line, synerr.loc.colm, | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		(hak_geterrmsg(hak) != hak_geterrstr(hak)? hak_geterrmsg(hak): hak_geterrstr(hak)) | 
					
						
							| 
									
										
										
										
											2018-02-07 13:55:22 +00:00
										 |  |  | 	); | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	hak_logbfmt(hak, HAK_LOG_STDERR, "\n"); | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static void print_other_error (hak_t* hak) | 
					
						
							| 
									
										
										
										
											2024-04-05 01:26:02 +09:00
										 |  |  | { | 
					
						
							|  |  |  | 	xtn_t* xtn; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_loc_t loc; | 
					
						
							| 
									
										
										
										
											2024-04-05 01:26:02 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	xtn = (xtn_t*)hak_getxtn(hak); | 
					
						
							|  |  |  | 	hak_geterrloc(hak, &loc); | 
					
						
							| 
									
										
										
										
											2024-04-05 01:26:02 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	hak_logbfmt(hak,HAK_LOG_STDERR, "ERROR: "); | 
					
						
							| 
									
										
										
										
											2024-04-05 01:26:02 +09:00
										 |  |  | 	if (loc.file) | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "%js", loc.file); | 
					
						
							| 
									
										
										
										
											2024-04-05 01:26:02 +09:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "%hs", xtn->cci_path); | 
					
						
							| 
									
										
										
										
											2024-04-05 01:26:02 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	hak_logbfmt(hak, HAK_LOG_STDERR, "[%zu,%zu] %js", loc.line, loc.colm, hak_geterrmsg(hak)); | 
					
						
							| 
									
										
										
										
											2024-04-05 01:26:02 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	hak_logbfmt(hak, HAK_LOG_STDERR, "\n"); | 
					
						
							| 
									
										
										
										
											2024-04-05 01:26:02 +09:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2024-02-20 22:57:30 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static void print_error (hak_t* hak, const hak_bch_t* msghdr) | 
					
						
							| 
									
										
										
										
											2024-02-20 22:57:30 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 	if (HAK_ERRNUM(hak) == HAK_ESYNERR) print_synerr(hak); | 
					
						
							|  |  |  | 	else print_other_error(hak); | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	/*else hak_logbfmt(hak, HAK_LOG_STDERR, "ERROR: %hs - [%d] %js\n", msghdr, hak_geterrnum(hak), hak_geterrmsg(hak));*/ | 
					
						
							| 
									
										
										
										
											2024-02-20 22:57:30 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(USE_ISOCLINE)
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static void print_incomplete_expression_error (hak_t* hak) | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* 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; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_loc_t loc; | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	xtn = hak_getxtn(hak); | 
					
						
							|  |  |  | 	hak_getfeedloc (hak, &loc); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	hak_logbfmt(hak, HAK_LOG_STDERR, "ERROR: "); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	if (loc.file) | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "%js", loc.file); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "%hs", xtn->cci_path); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* 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 */ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	hak_logbfmt(hak, HAK_LOG_STDERR, "[%zu,%zu] incomplete expression\n", loc.line, loc.colm); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static void show_prompt (hak_t* hak, int level) | 
					
						
							| 
									
										
										
										
											2024-01-21 11:40:40 +09:00
										 |  |  | { | 
					
						
							|  |  |  | /* TODO: different prompt per level */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_resetfeedloc (hak); /* restore the line number to 1 in the interactive mode */ | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | #if !defined(USE_ISOCLINE)
 | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	hak_logbfmt(hak, HAK_LOG_STDOUT, "HAK> "); | 
					
						
							|  |  |  | 	hak_logbfmt(hak, HAK_LOG_STDOUT, HAK_NULL); /* flushing */ | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2024-01-21 11:40:40 +09:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-07-18 10:28:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static hak_oop_t execute_in_interactive_mode (hak_t* hak) | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_oop_t retv; | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_decode (hak, hak_getcode(hak), 0, hak_getbclen(hak)); | 
					
						
							|  |  |  | 	HAK_LOG0 (hak, HAK_LOG_MNEMONIC, "------------------------------------------\n"); | 
					
						
							|  |  |  | 	g_hak = hak; | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 	/*setup_tick ();*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	retv = hak_execute(hak); | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flush pending output data in the interactive mode(e.g. printf without a newline) */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_flushudio (hak); | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!retv) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 		print_error(hak, "execute"); | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* print the result in the interactive mode regardless 'verbose' */ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDOUT, "%O\n", retv); /* TODO: show this go to the output handler?? */ | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 		/*
 | 
					
						
							|  |  |  | 		 * print the value of ERRSTR. | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		hak_oop_cons_t cons = hak_getatsysdic(hak, xtn->sym_errstr); | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 		if (cons) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			HAK_ASSERT(hak, HAK_IS_CONS(hak, cons)); | 
					
						
							|  |  |  | 			HAK_ASSERT(hak, HAK_CONS_CAR(cons) == xtn->sym_errstr); | 
					
						
							|  |  |  | 			hak_print (hak, HAK_CONS_CDR(cons)); | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		*/ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/*cancel_tick();*/ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	g_hak = HAK_NULL; | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return retv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static hak_oop_t execute_in_batch_mode(hak_t* hak, int verbose) | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_oop_t retv; | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_decode(hak, hak_getcode(hak), 0, hak_getbclen(hak)); | 
					
						
							|  |  |  | 	HAK_LOG3(hak, HAK_LOG_MNEMONIC, "BYTECODES bclen=%zu lflen=%zu ngtmprs=%zu\n", hak_getbclen(hak), hak_getlflen(hak), hak_getngtmprs(hak)); | 
					
						
							|  |  |  | 	g_hak = hak; | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 	/*setup_tick ();*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-27 09:09:40 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* TESTING */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_code_t xcode; | 
					
						
							|  |  |  | 	hak_ptlc_t mem; | 
					
						
							| 
									
										
										
										
											2023-12-28 00:27:27 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 	memset(&xcode, 0, HAK_SIZEOF(xcode)); | 
					
						
							|  |  |  | 	memset(&mem, 0, HAK_SIZEOF(mem)); | 
					
						
							| 
									
										
										
										
											2023-12-28 00:27:27 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_marshalcodetomem(hak, &hak->code, &mem); | 
					
						
							|  |  |  | 	hak_unmarshalcodefrommem(hak, &xcode, (const hak_ptl_t*)&mem); | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	hak_freemem(hak, mem.ptr); | 
					
						
							| 
									
										
										
										
											2023-12-28 00:27:27 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_decode(hak, &xcode, 0, xcode.bc.len); | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 	hak_purgecode(hak, &xcode); | 
					
						
							| 
									
										
										
										
											2023-12-27 09:09:40 +09:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | /* END TESTING */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	retv = hak_execute(hak); | 
					
						
							|  |  |  | 	hak_flushudio (hak); | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 	if (!retv) print_error(hak, "execute"); | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	else if (verbose) hak_logbfmt(hak, HAK_LOG_STDERR, "EXECUTION OK - EXITED WITH %O\n", retv); | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/*cancel_tick();*/ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	g_hak = HAK_NULL; | 
					
						
							|  |  |  | 	/*hak_dumpsymtab (hak);*/ | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return retv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static int on_fed_cnode_in_interactive_mode (hak_t* hak, hak_cnode_t* obj) | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	xtn_t* xtn = (xtn_t*)hak_getxtn(hak); | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	int flags = 0; | 
					
						
							| 
									
										
										
										
											2024-02-20 22:57:30 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* in the interactive, the compile error must not break the input loop.
 | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	 * this function returns 0 to go on despite a compile-time error. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * if a single line or continued lines contain multiple expressions, | 
					
						
							|  |  |  | 	 * execution is delayed until the last expression is compiled. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-17 12:20:25 +09:00
										 |  |  | 	if (xtn->feed.ncompexprs <= 0) | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2024-02-25 13:55:03 +09:00
										 |  |  | 		/* the first expression in the current user input line.
 | 
					
						
							|  |  |  | 		 * arrange to clear byte-codes before compiling the expression. */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		flags = HAK_COMPILE_CLEAR_CODE | HAK_COMPILE_CLEAR_FUNBLK; | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-02-20 22:57:30 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (hak_compile(hak, obj, flags) <= -1) | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		/*print_error(hak, "compile"); */ | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 		xtn->feed.pos = xtn->feed.len; /* arrange to discard the rest of the line */ | 
					
						
							| 
									
										
										
										
											2024-05-16 19:40:43 +09:00
										 |  |  | 		return -1; /* this causes the feed function to fail and
 | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 		              the error handler to print the error message */ | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-01-21 11:40:40 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-16 19:40:43 +09:00
										 |  |  | 	xtn->feed.ncompexprs++; | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static int on_fed_cnode_in_batch_mode (hak_t* hak, hak_cnode_t* obj) | 
					
						
							| 
									
										
										
										
											2023-11-10 00:03:03 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	/*xtn_t* xtn = (xtn_t*)hak_getxtn(hak);*/ | 
					
						
							|  |  |  | 	return hak_compile(hak, obj, 0); | 
					
						
							| 
									
										
										
										
											2023-11-10 00:03:03 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | #if defined(USE_ISOCLINE)
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static int get_line (hak_t* hak, xtn_t* xtn, FILE* fp) | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 	char* inp; | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	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
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		ic_set_history (HAK_NULL, -1); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 		ic_enable_multiline (1); | 
					
						
							|  |  |  | 		ic_enable_multiline_indent (1); | 
					
						
							|  |  |  | 		ic_set_matching_braces ("()[]{}"); | 
					
						
							|  |  |  | 		ic_enable_brace_insertion (1); | 
					
						
							|  |  |  | 		ic_set_insertion_braces("()[]{}\"\"''"); | 
					
						
							|  |  |  | 		inited = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	if (xtn->feed.eof) return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xtn->feed.pos = 0; | 
					
						
							|  |  |  | 	xtn->feed.len = 0; | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	if (xtn->feed.ptr) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		HAK_ASSERT(hak, xtn->feed.ptr != xtn->feed.buf); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 		ic_free (xtn->feed.ptr); | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		xtn->feed.ptr = HAK_NULL; | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	inp = ic_readline("HAK"); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	if (inp == NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* TODO: check if it's an error or Eof */ | 
					
						
							|  |  |  | 		xtn->feed.eof = 1; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		HAK_ASSERT(hak, xtn->feed.pos == 0); | 
					
						
							|  |  |  | 		HAK_ASSERT(hak, xtn->feed.len == 0); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	xtn->feed.len = hak_count_bcstr(inp); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	xtn->feed.ptr = inp; | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static int get_line (hak_t* hak, xtn_t* xtn, FILE* fp) | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (xtn->feed.eof) return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	xtn->feed.pos = 0; | 
					
						
							|  |  |  | 	xtn->feed.len = 0; | 
					
						
							|  |  |  | 	xtn->feed.ptr = xtn->feed.buf; /* use the internal buffer */ | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		int ch = fgetc(fp); | 
					
						
							|  |  |  | 		if (ch == EOF) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (ferror(fp)) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 				hak_logbfmt(hak, HAK_LOG_STDERR, "ERROR: failed to read - %hs - %hs\n", xtn->cci_path, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 				return -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			xtn->feed.eof = 1; | 
					
						
							| 
									
										
										
										
											2024-04-17 12:20:25 +09:00
										 |  |  | 			if (xtn->feed.len <= 0) return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		xtn->feed.buf[xtn->feed.len++] = (hak_bch_t)(unsigned int)ch; | 
					
						
							|  |  |  | 		if (ch == '\n' || xtn->feed.len >= HAK_COUNTOF(xtn->feed.buf)) break; | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | static int feed_loop (hak_t* hak, xtn_t* xtn, int verbose) | 
					
						
							| 
									
										
										
										
											2022-07-18 10:28:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	FILE* fp = HAK_NULL; | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 	int is_tty; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-07 23:01:17 +09:00
										 |  |  | #if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__)
 | 
					
						
							| 
									
										
										
										
											2024-02-02 14:57:46 +09:00
										 |  |  | 	errno_t err = fopen_s(&fp, xtn->cci_path, FOPEN_R_FLAGS); | 
					
						
							| 
									
										
										
										
											2023-12-07 23:01:17 +09:00
										 |  |  | 	if (err != 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "ERROR: failed to open - %hs - %hs\n", xtn->cci_path, strerror(err)); | 
					
						
							| 
									
										
										
										
											2023-12-07 23:01:17 +09:00
										 |  |  | 		goto oops; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2023-11-05 22:31:33 +09:00
										 |  |  | 	fp = fopen(xtn->cci_path, FOPEN_R_FLAGS); | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 	if (!fp) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "ERROR: failed to open - %hs - %hs\n", xtn->cci_path, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 		goto oops; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-12-07 23:01:17 +09:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-07 23:01:17 +09:00
										 |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	is_tty = _isatty(_fileno(fp)); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 	is_tty = isatty(fileno(fp)); | 
					
						
							| 
									
										
										
										
											2023-12-07 23:01:17 +09:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 10:24:01 +09:00
										 |  |  | 	/* override the default cnode handler. the default one simply
 | 
					
						
							|  |  |  | 	 * compiles the expression node without execution */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	/*if (hak_beginfeed(hak, is_tty? on_fed_cnode_in_interactive_mode: HAK_NULL) <= -1)*/ | 
					
						
							|  |  |  | 	if (hak_beginfeed(hak, is_tty? on_fed_cnode_in_interactive_mode: on_fed_cnode_in_batch_mode) <= -1) | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "ERROR: cannot begin feed - [%d] %js\n", hak_geterrnum(hak), hak_geterrmsg(hak)); | 
					
						
							| 
									
										
										
										
											2023-05-18 10:24:01 +09:00
										 |  |  | 		goto oops; | 
					
						
							| 
									
										
										
										
											2022-07-29 11:39:13 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-07-22 08:02:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	if (is_tty) | 
					
						
							| 
									
										
										
										
											2022-07-18 10:28:36 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 		/* interactive mode */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		show_prompt (hak, 0); | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		while (1) | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 			int n; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			hak_oow_t pos; | 
					
						
							|  |  |  | 			hak_oow_t len; | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 		#if defined(USE_ISOCLINE)
 | 
					
						
							|  |  |  | 			int lf_injected = 0; | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-17 12:20:25 +09:00
										 |  |  | 			/* read a line regardless of the actual expression */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			n = get_line(hak, xtn, fp); | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 			if (n <= -1) goto oops; | 
					
						
							|  |  |  | 			if (n == 0) break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* feed the line */ | 
					
						
							| 
									
										
										
										
											2024-04-15 13:14:49 +09:00
										 |  |  | 			pos = xtn->feed.pos; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			/* update xtn->feed.pos before calling hak_feedbchars() so that the callback sees the updated value */ | 
					
						
							| 
									
										
										
										
											2024-04-15 13:14:49 +09:00
										 |  |  | 			xtn->feed.pos = xtn->feed.len; | 
					
						
							| 
									
										
										
										
											2024-04-17 02:00:28 +09:00
										 |  |  | 			len = xtn->feed.len - pos; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			n = hak_feedbchars(hak, &xtn->feed.ptr[pos], len); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 		#if defined(USE_ISOCLINE)
 | 
					
						
							|  |  |  | 		chars_fed: | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							|  |  |  | 			if (n <= -1) | 
					
						
							| 
									
										
										
										
											2024-04-15 13:14:49 +09:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 				print_error(hak, "feed"); /* syntax error or something - mostly compile error */ | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		#if defined(USE_ISOCLINE)
 | 
					
						
							|  |  |  | 			reset_on_feed_error: | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 				hak_resetfeed(hak); | 
					
						
							|  |  |  | 				hak_clearcode(hak); /* clear the compiled code but not executed yet in advance */ | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 				xtn->feed.ncompexprs = 0; /* next time, on_fed_cnode_in_interactive_mode() clears code and fnblks */ | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 				/*if (len > 0)*/ show_prompt(hak, 0); /* show prompt after error */ | 
					
						
							| 
									
										
										
										
											2024-04-15 13:14:49 +09:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-04-17 02:00:28 +09:00
										 |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 				if (!hak_feedpending(hak)) | 
					
						
							| 
									
										
										
										
											2024-04-17 02:00:28 +09:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 					if (xtn->feed.ncompexprs > 0) | 
					
						
							| 
									
										
										
										
											2024-04-17 12:20:25 +09:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 						if (hak_getbclen(hak) > 0) execute_in_interactive_mode (hak); | 
					
						
							| 
									
										
										
										
											2024-04-17 12:20:25 +09:00
										 |  |  | 						xtn->feed.ncompexprs = 0; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 					else | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						/* usually this part is reached if the input string is
 | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 						 * one or more whilespaces and/or comments only. | 
					
						
							|  |  |  | 						 * ------------------------------------------------------ | 
					
						
							|  |  |  | 						 * if the previous compiled code has not been cleared (e.g. | 
					
						
							|  |  |  | 						 * hcl_compile() ever called with HCL_COMPILE_CLEAR_CODE | 
					
						
							|  |  |  | 						 * or hcl_clearcode() explicitly called), hak_getbcllen(hak) | 
					
						
							|  |  |  | 						 * may still return a positive number greater than 0. */ | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 					show_prompt (hak, 0); /* show prompt after execution */ | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 				} | 
					
						
							|  |  |  | 		#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; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 					n = hak_feedbchars(hak, &lf, 1); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 					goto chars_fed; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 					print_incomplete_expression_error(hak); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 					goto reset_on_feed_error; | 
					
						
							| 
									
										
										
										
											2024-04-17 02:00:28 +09:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 		#endif
 | 
					
						
							| 
									
										
										
										
											2024-04-17 02:00:28 +09:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-05-15 22:59:34 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	#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 */ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDOUT, "\n"); | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	#endif
 | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 		/* non-interactive mode */ | 
					
						
							| 
									
										
										
										
											2024-02-22 01:21:11 +09:00
										 |  |  | 		while (1) | 
					
						
							| 
									
										
										
										
											2023-11-08 00:11:43 +09:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			hak_bch_t buf[1024]; | 
					
						
							|  |  |  | 			hak_oow_t xlen; | 
					
						
							| 
									
										
										
										
											2023-11-10 00:03:03 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			xlen = fread(buf, HAK_SIZEOF(buf[0]), HAK_COUNTOF(buf), fp); | 
					
						
							|  |  |  | 			if (xlen > 0 && hak_feedbchars(hak, buf, xlen) <= -1) goto endfeed_error; | 
					
						
							|  |  |  | 			if (xlen < HAK_COUNTOF(buf)) | 
					
						
							| 
									
										
										
										
											2023-11-08 00:11:43 +09:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2023-11-10 00:03:03 +09:00
										 |  |  | 				if (ferror(fp)) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 					hak_logbfmt(hak, HAK_LOG_STDERR, "ERROR: failed to read - %hs - %hs\n", xtn->cci_path, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2023-11-10 00:03:03 +09:00
										 |  |  | 					goto oops; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2023-11-08 00:11:43 +09:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-07-18 10:28:36 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (hak_endfeed(hak) <= -1) | 
					
						
							| 
									
										
										
										
											2022-07-23 06:57:01 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2024-10-27 19:17:07 +09:00
										 |  |  | 	endfeed_error: | 
					
						
							| 
									
										
										
										
											2025-09-21 11:03:34 +09:00
										 |  |  | 		print_error(hak, "endfeed"); | 
					
						
							| 
									
										
										
										
											2022-07-23 06:57:01 +00:00
										 |  |  | 		goto oops; /* TODO: proceed or just exit? */ | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 	fclose (fp); | 
					
						
							| 
									
										
										
										
											2022-07-23 06:57:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (!is_tty && hak_getbclen(hak) > 0) execute_in_batch_mode (hak, verbose); | 
					
						
							| 
									
										
										
										
											2022-07-18 10:28:36 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | oops: | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 	if (fp) fclose (fp); | 
					
						
							| 
									
										
										
										
											2022-07-18 10:28:36 +00:00
										 |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-21 11:40:40 +09:00
										 |  |  | /* #define DEFAULT_HEAPSIZE (512000ul) */ | 
					
						
							| 
									
										
										
										
											2024-01-14 09:48:57 +09:00
										 |  |  | #define DEFAULT_HEAPSIZE (0ul) /* don't use the pre-allocated heap */
 | 
					
						
							| 
									
										
										
										
											2021-03-28 03:44:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-13 10:20:33 +00:00
										 |  |  | int main (int argc, char* argv[]) | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_t* hak = HAK_NULL; | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	xtn_t* xtn; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_cb_t hakcb; | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 	hak_errinf_t errinf; | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_bci_t c; | 
					
						
							|  |  |  | 	static hak_bopt_lng_t lopt[] = | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | #if defined(HAK_BUILD_DEBUG)
 | 
					
						
							| 
									
										
										
										
											2021-01-01 07:34:21 +00:00
										 |  |  | 		{ ":debug",       '\0' }, | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-01-01 07:34:21 +00:00
										 |  |  | 		{ ":heapsize",    '\0' }, | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 		{ ":log",         'l'  }, | 
					
						
							| 
									
										
										
										
											2024-01-21 11:40:40 +09:00
										 |  |  | 		{ "info",         '\0' }, | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 		{ ":modlibdirs",  '\0' }, | 
					
						
							| 
									
										
										
										
											2021-01-01 07:34:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		{ HAK_NULL,       '\0' } | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	static hak_bopt_t opt = | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2024-08-12 02:27:07 +09:00
										 |  |  | 		"l:v", | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 		lopt | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	const char* logopt = HAK_NULL; | 
					
						
							|  |  |  | 	hak_oow_t heapsize = DEFAULT_HEAPSIZE; | 
					
						
							| 
									
										
										
										
											2019-04-16 09:35:56 +00:00
										 |  |  | 	int verbose = 0; | 
					
						
							| 
									
										
										
										
											2023-10-08 00:51:07 +09:00
										 |  |  | 	int show_info = 0; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	const char* modlibdirs = HAK_NULL; | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | #if defined(HAK_BUILD_DEBUG)
 | 
					
						
							|  |  |  | 	const char* dbgopt = HAK_NULL; | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	setlocale(LC_ALL, ""); | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if !defined(macintosh)
 | 
					
						
							|  |  |  | 	if (argc < 2) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	print_usage: | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		fprintf(stderr, "Usage: %s [options] script-filename [output-filename]\n", argv[0]); | 
					
						
							|  |  |  | 		fprintf(stderr, "Options are:\n"); | 
					
						
							|  |  |  | 		fprintf(stderr, " -v  show verbose messages\n"); | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	while ((c = hak_getbopt(argc, argv, &opt)) != HAK_BCI_EOF) | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		switch (c) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			case 'l': | 
					
						
							|  |  |  | 				logopt = opt.arg; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-16 09:35:56 +00:00
										 |  |  | 			case 'v': | 
					
						
							|  |  |  | 				verbose = 1; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 			case '\0': | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 				if (hak_comp_bcstr(opt.lngopt, "heapsize") == 0) | 
					
						
							| 
									
										
										
										
											2021-01-01 07:34:21 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 					heapsize = strtoul(opt.arg, HAK_NULL, 0); | 
					
						
							| 
									
										
										
										
											2021-01-01 07:34:21 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 			#if defined(HAK_BUILD_DEBUG)
 | 
					
						
							|  |  |  | 				else if (hak_comp_bcstr(opt.lngopt, "debug") == 0) | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					dbgopt = opt.arg; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			#endif
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 				else if (hak_comp_bcstr(opt.lngopt, "info") == 0) | 
					
						
							| 
									
										
										
										
											2023-10-08 00:51:07 +09:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					show_info = 1; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 				else if (hak_comp_bcstr(opt.lngopt, "modlibdirs") == 0) | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					modlibdirs = opt.arg; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				goto print_usage; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case ':': | 
					
						
							|  |  |  | 				if (opt.lngopt) | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 					fprintf(stderr, "bad argument for '%s'\n", opt.lngopt); | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 					fprintf(stderr, "bad argument for '%c'\n", opt.opt); | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				goto print_usage; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-16 08:39:33 +09:00
										 |  |  | 	if ((opt.ind + 1) != argc && (opt.ind + 2) != argc && !show_info) goto print_usage; | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 	hak = hak_openstd(HAK_SIZEOF(xtn_t), &errinf); | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (HAK_UNLIKELY(!hak)) | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 		const hak_bch_t* msg; | 
					
						
							|  |  |  | 	#if defined(HAK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 		hak_bch_t msgbuf[HAK_ERRMSG_CAPA]; | 
					
						
							|  |  |  | 		hak_oow_t msglen, wcslen; | 
					
						
							|  |  |  | 		msglen = HAK_COUNTOF(msgbuf); | 
					
						
							|  |  |  | 		hak_conv_ucstr_to_bcstr_with_cmgr(errinf.msg, &wcslen, msgbuf, &msglen, hak_get_cmgr_by_id(HAK_CMGR_UTF8)); | 
					
						
							|  |  |  | 		msg = msgbuf; | 
					
						
							|  |  |  | 	#else
 | 
					
						
							|  |  |  | 		msg = errinf.msg; | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		printf("ERROR: cannot open hak - %s\n", msg); | 
					
						
							| 
									
										
										
										
											2018-04-25 04:12:13 +00:00
										 |  |  | 		goto oops; | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	xtn = (xtn_t*)hak_getxtn(hak); | 
					
						
							| 
									
										
										
										
											2021-02-07 17:57:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		hak_oow_t tab_size; | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 		tab_size = 5000; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		hak_setoption (hak, HAK_SYMTAB_SIZE, &tab_size); | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 		tab_size = 5000; | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		hak_setoption (hak, HAK_SYSDIC_SIZE, &tab_size); | 
					
						
							| 
									
										
										
										
											2023-11-29 17:12:21 +09:00
										 |  |  | 		tab_size = 600; /* TODO: choose a better stack size or make this user specifiable */ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		hak_setoption (hak, HAK_PROCSTK_SIZE, &tab_size); | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		hak_bitmask_t trait = 0; | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		/*trait |= HAK_TRAIT_NOGC;*/ | 
					
						
							|  |  |  | 		trait |= HAK_TRAIT_AWAIT_PROCS; | 
					
						
							|  |  |  | 		trait |= HAK_TRAIT_LANG_ENABLE_EOL; | 
					
						
							|  |  |  | 		hak_setoption (hak, HAK_TRAIT, &trait); | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 	if (modlibdirs) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	#if defined(HAK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 		hak_ooch_t* tmp; | 
					
						
							|  |  |  | 		tmp = hak_dupbtoucstr(hak, modlibdirs, HAK_NULL); | 
					
						
							|  |  |  | 		if (HAK_UNLIKELY(!tmp)) | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 			hak_logbfmt(hak, HAK_LOG_STDERR,"ERROR: cannot duplicate modlibdirs - [%d] %js\n", hak_geterrnum(hak), hak_geterrmsg(hak)); | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 			goto oops; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		if (hak_setoption(hak, HAK_MOD_LIBDIRS, tmp) <= -1) | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 			hak_logbfmt(hak, HAK_LOG_STDERR,"ERROR: cannot set modlibdirs - [%d] %js\n", hak_geterrnum(hak), hak_geterrmsg(hak)); | 
					
						
							|  |  |  | 			hak_freemem(hak, tmp); | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 			goto oops; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_freemem(hak, tmp); | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 	#else
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 		if (hak_setoption(hak, HAK_MOD_LIBDIRS, modlibdirs) <= -1) | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 			hak_logbfmt(hak, HAK_LOG_STDERR,"ERROR: cannot set modlibdirs - [%d] %js\n", hak_geterrnum(hak), hak_geterrmsg(hak)); | 
					
						
							| 
									
										
										
										
											2024-01-05 15:01:59 +09:00
										 |  |  | 			goto oops; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	memset (&hakcb, 0, HAK_SIZEOF(hakcb)); | 
					
						
							|  |  |  | 	hakcb.on_gc = on_gc_hak; | 
					
						
							|  |  |  | 	hakcb.vm_startup = vm_startup; | 
					
						
							|  |  |  | 	hakcb.vm_cleanup = vm_cleanup; | 
					
						
							|  |  |  | 	/*hakcb.vm_checkbc = vm_checkbc;*/ | 
					
						
							|  |  |  | 	hak_regcb (hak, &hakcb); | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-18 01:09:04 +09:00
										 |  |  | 	if (logopt && handle_logopt(hak, logopt) <= -1) goto oops; | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | #if defined(HAK_BUILD_DEBUG)
 | 
					
						
							| 
									
										
										
										
											2025-09-18 01:09:04 +09:00
										 |  |  | 	if (dbgopt && handle_dbgopt(hak, dbgopt) <= -1) goto oops; | 
					
						
							| 
									
										
										
										
											2018-02-05 10:43:25 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-08 00:51:07 +09:00
										 |  |  | 	if (show_info) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 		print_info(); | 
					
						
							| 
									
										
										
										
											2023-10-08 00:51:07 +09:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (hak_ignite(hak, heapsize) <= -1) | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "cannot ignite hak - [%d] %js\n", hak_geterrnum(hak), hak_geterrmsg(hak)); | 
					
						
							| 
									
										
										
										
											2018-04-25 04:12:13 +00:00
										 |  |  | 		goto oops; | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (hak_addbuiltinprims(hak) <= -1) | 
					
						
							| 
									
										
										
										
											2016-10-06 17:49:47 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "cannot add builtin primitives - [%d] %js\n", hak_geterrnum(hak), hak_geterrmsg(hak)); | 
					
						
							| 
									
										
										
										
											2018-04-25 04:12:13 +00:00
										 |  |  | 		goto oops; | 
					
						
							| 
									
										
										
										
											2016-10-06 17:49:47 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-05 22:31:33 +09:00
										 |  |  | 	xtn->cci_path = argv[opt.ind++]; /* input source code file */ | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 	if (opt.ind < argc) xtn->udo_path = argv[opt.ind++]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (hak_attachcciostdwithbcstr(hak, xtn->cci_path) <= -1) | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "ERROR: cannot attach source input stream - [%d] %js\n", hak_geterrnum(hak), hak_geterrmsg(hak)); | 
					
						
							| 
									
										
										
										
											2023-11-05 16:58:45 +09:00
										 |  |  | 		goto oops; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (hak_attachudiostdwithbcstr(hak, "", xtn->udo_path) <= -1) /* TODO: add udi path */ | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 		hak_logbfmt(hak, HAK_LOG_STDERR, "ERROR: cannot attach user data streams - [%d] %js\n", hak_geterrnum(hak), hak_geterrmsg(hak)); | 
					
						
							| 
									
										
										
										
											2018-04-25 04:12:13 +00:00
										 |  |  | 		goto oops; | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-28 03:44:27 +00:00
										 |  |  | 	/* -- from this point onward, any failure leads to jumping to the oops label
 | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | 	 * -- instead of returning -1 immediately. --*/ | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	set_signal(SIGINT, handle_sigint); | 
					
						
							| 
									
										
										
										
											2018-03-10 17:53:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 12:57:05 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2020-10-08 09:25:54 +00:00
										 |  |  | // TODO: change the option name
 | 
					
						
							|  |  |  | // in the INTERACTIVE mode, the compiler generates MAKE_FUNCTION for lambda functions.
 | 
					
						
							| 
									
										
										
										
											2021-01-26 10:10:18 +00:00
										 |  |  | // in the non-INTERACTIVE mode, the compiler generates MAKE_BLOCK for lambda functions.
 | 
					
						
							| 
									
										
										
										
											2020-10-05 09:37:26 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	hak_bitmask_t trait; | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 	hak_getoption(hak, HAK_TRAIT, &trait); | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	trait |= HAK_TRAIT_INTERACTIVE; | 
					
						
							| 
									
										
										
										
											2025-10-06 00:59:20 +09:00
										 |  |  | 	hak_setoption(hak, HAK_TRAIT, &trait); | 
					
						
							| 
									
										
										
										
											2020-10-05 09:37:26 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-10-07 08:06:49 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-07-18 10:28:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-02 23:58:15 +09:00
										 |  |  | 	if (feed_loop(hak, xtn, verbose) <= -1) goto oops; | 
					
						
							| 
									
										
										
										
											2020-10-13 14:44:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	set_signal_to_default(SIGINT); | 
					
						
							|  |  |  | 	hak_close(hak); | 
					
						
							| 
									
										
										
										
											2018-04-25 04:12:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2018-02-09 17:15:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | oops: | 
					
						
							| 
									
										
										
										
											2025-09-05 01:16:24 +09:00
										 |  |  | 	set_signal_to_default(SIGINT); /* harmless to call multiple times without set_signal() */ | 
					
						
							|  |  |  | 	if (hak) hak_close(hak); | 
					
						
							| 
									
										
										
										
											2018-02-09 17:15:31 +00:00
										 |  |  | 	return -1; | 
					
						
							| 
									
										
										
										
											2016-09-28 14:40:37 +00:00
										 |  |  | } |