All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			changed || to |& for bidirectional piping
		
			
				
	
	
		
			1642 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1642 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|     Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved.
 | |
| 
 | |
|     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.
 | |
|  */
 | |
| 
 | |
| #include "hawk-prv.h"
 | |
| 
 | |
| static const hawk_ooch_t* assop_str[] =
 | |
| {
 | |
| 	/* this table must match hawk_assop_type_t in run.h */
 | |
| 	HAWK_T("="),
 | |
| 	HAWK_T("+="),
 | |
| 	HAWK_T("-="),
 | |
| 	HAWK_T("*="),
 | |
| 	HAWK_T("/="),
 | |
| 	HAWK_T("\\="),
 | |
| 	HAWK_T("%="),
 | |
| 	HAWK_T("**="), /* exponentation, also ^= */
 | |
| 	HAWK_T("%%="),
 | |
| 	HAWK_T(">>="),
 | |
| 	HAWK_T("<<="),
 | |
| 	HAWK_T("&="),
 | |
| 	HAWK_T("^^="),
 | |
| 	HAWK_T("|=")
 | |
| };
 | |
| 
 | |
| static const hawk_ooch_t* binop_str[][2] =
 | |
| {
 | |
| 	{ HAWK_T("||"), HAWK_T("||") },
 | |
| 	{ HAWK_T("&&"), HAWK_T("&&") },
 | |
| 	{ HAWK_T("in"), HAWK_T("in") },
 | |
| 
 | |
| 	{ HAWK_T("|"),  HAWK_T("|") },
 | |
| 	{ HAWK_T("^^"), HAWK_T("^^") },
 | |
| 	{ HAWK_T("&"),  HAWK_T("&") },
 | |
| 
 | |
| 	{ HAWK_T("==="), HAWK_T("===") },
 | |
| 	{ HAWK_T("!=="), HAWK_T("!==") },
 | |
| 	{ HAWK_T("=="), HAWK_T("==") },
 | |
| 	{ HAWK_T("!="), HAWK_T("!=") },
 | |
| 	{ HAWK_T(">"),  HAWK_T(">") },
 | |
| 	{ HAWK_T(">="), HAWK_T(">=") },
 | |
| 	{ HAWK_T("<"),  HAWK_T("<") },
 | |
| 	{ HAWK_T("<="), HAWK_T("<=") },
 | |
| 
 | |
| 	{ HAWK_T("<<"), HAWK_T("<<") },
 | |
| 	{ HAWK_T(">>"), HAWK_T(">>") },
 | |
| 
 | |
| 	{ HAWK_T("+"),  HAWK_T("+") },
 | |
| 	{ HAWK_T("-"),  HAWK_T("-") },
 | |
| 	{ HAWK_T("*"),  HAWK_T("*") },
 | |
| 	{ HAWK_T("/"),  HAWK_T("/") },
 | |
| 	{ HAWK_T("\\"), HAWK_T("\\") },
 | |
| 	{ HAWK_T("%"),  HAWK_T("%") },
 | |
| 	{ HAWK_T("**"), HAWK_T("**") }, /* exponentation, also ^ */
 | |
| 
 | |
| 	{ HAWK_T(" "),  HAWK_T("%%") }, /* take note of this entry */
 | |
| 	{ HAWK_T("~"),  HAWK_T("~") },
 | |
| 	{ HAWK_T("!~"), HAWK_T("!~") }
 | |
| };
 | |
| 
 | |
| static const hawk_ooch_t* unrop_str[] =
 | |
| {
 | |
| 	HAWK_T("+"),
 | |
| 	HAWK_T("-"),
 | |
| 	HAWK_T("!"),
 | |
| 	HAWK_T("~")
 | |
| };
 | |
| 
 | |
| static const hawk_ooch_t* incop_str[] =
 | |
| {
 | |
| 	HAWK_T("++"),
 | |
| 	HAWK_T("--"),
 | |
| 	HAWK_T("++"),
 | |
| 	HAWK_T("--")
 | |
| };
 | |
| 
 | |
| static const hawk_ooch_t* getline_inop_str[] =
 | |
| {
 | |
| 	HAWK_T("|"),
 | |
| 	HAWK_T("|&"),
 | |
| 	HAWK_T("<"),
 | |
| 	HAWK_T("")
 | |
| };
 | |
| 
 | |
| static const hawk_ooch_t* print_outop_str[] =
 | |
| {
 | |
| 	HAWK_T("|"),
 | |
| 	HAWK_T("|&"),
 | |
| 	HAWK_T(">"),
 | |
| 	HAWK_T(">>"),
 | |
| 	HAWK_T("")
 | |
| };
 | |
| 
 | |
| #define PUT_SRCSTR(hawk,str) do { if (hawk_putsrcoocstr(hawk, str) == -1) return -1; } while(0)
 | |
| 
 | |
| #define PUT_NL(hawk) do { \
 | |
| 	if (hawk->opt.trait & HAWK_CRLF) PUT_SRCSTR(hawk, HAWK_T("\r")); \
 | |
| 	PUT_SRCSTR(hawk, HAWK_T("\n")); \
 | |
| } while(0)
 | |
| 
 | |
| #define PUT_SRCSTRN(hawk,str,len) do { \
 | |
| 	if (hawk_putsrcoochars(hawk, str, len) == -1) return -1; \
 | |
| } while(0)
 | |
| 
 | |
| #define PRINT_TABS(hawk,depth) do { \
 | |
| 	if (print_tabs(hawk,depth) == -1) return -1; \
 | |
| } while(0)
 | |
| 
 | |
| #define PRINT_EXPR(hawk,nde) do { \
 | |
| 	if (print_expr(hawk,nde) == -1) return -1; \
 | |
| } while(0)
 | |
| 
 | |
| #define PRINT_EXPR_LIST(hawk,nde) do { \
 | |
| 	if (print_expr_list(hawk,nde) == -1) return -1; \
 | |
| } while(0)
 | |
| 
 | |
| #define PRINT_EXPR_LIST_FOR_IDX(hawk,nde) do { \
 | |
| 	if (print_expr_list_for_idx(hawk,nde) == -1) return -1; \
 | |
| } while(0)
 | |
| 
 | |
| #define PRINT_STMTS(hawk,nde,depth) do { \
 | |
| 	if (print_stmts(hawk,nde,depth) == -1) return -1; \
 | |
| } while(0)
 | |
| 
 | |
| static int print_tabs (hawk_t* hawk, int depth);
 | |
| static int print_expr (hawk_t* hawk, hawk_nde_t* nde);
 | |
| static int print_expr_list (hawk_t* hawk, hawk_nde_t* tree);
 | |
| static int print_expr_list_for_idx (hawk_t* hawk, hawk_nde_t* tree);
 | |
| static int print_stmts (hawk_t* hawk, hawk_nde_t* tree, int depth);
 | |
| 
 | |
| static int print_tabs (hawk_t* hawk, int depth)
 | |
| {
 | |
| 	while (depth > 0)
 | |
| 	{
 | |
| 		PUT_SRCSTR(hawk, HAWK_T("\t"));
 | |
| 		depth--;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int print_printx (hawk_t* hawk, hawk_nde_print_t* px)
 | |
| {
 | |
| 	hawk_oocs_t kw;
 | |
| 
 | |
| 	if (px->type == HAWK_NDE_PRINT)
 | |
| 	{
 | |
| 		hawk_getkwname(hawk, HAWK_KWID_PRINT, &kw);
 | |
| 		PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		hawk_getkwname(hawk, HAWK_KWID_PRINTF, &kw);
 | |
| 		PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 	}
 | |
| 
 | |
| 	if (px->args != HAWK_NULL)
 | |
| 	{
 | |
| 		PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 		PRINT_EXPR_LIST(hawk, px->args);
 | |
| 	}
 | |
| 
 | |
| 	if (px->out != HAWK_NULL)
 | |
| 	{
 | |
| 		PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 		PUT_SRCSTR(hawk, print_outop_str[px->out_type]);
 | |
| 		PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 		PRINT_EXPR(hawk, px->out);
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int print_expr (hawk_t* hawk, hawk_nde_t* nde)
 | |
| {
 | |
| 	hawk_oocs_t kw;
 | |
| 
 | |
| 	switch (nde->type)
 | |
| 	{
 | |
| 		case HAWK_NDE_GRP:
 | |
| 		{
 | |
| 			hawk_nde_t* p = ((hawk_nde_grp_t*)nde)->body;
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			while (p != HAWK_NULL)
 | |
| 			{
 | |
| 				PRINT_EXPR(hawk, p);
 | |
| 				if (p->next != HAWK_NULL)
 | |
| 					PUT_SRCSTR(hawk, HAWK_T(","));
 | |
| 				p = p->next;
 | |
| 			}
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_ASS:
 | |
| 		{
 | |
| 			hawk_nde_ass_t* px = (hawk_nde_ass_t*)nde;
 | |
| 
 | |
| 			PRINT_EXPR(hawk, px->left);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 			PUT_SRCSTR(hawk, assop_str[px->opcode]);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 			PRINT_EXPR(hawk, px->right);
 | |
| 
 | |
| 			HAWK_ASSERT (px->right->next == HAWK_NULL);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_EXP_BIN:
 | |
| 		{
 | |
| 			hawk_nde_exp_t* px = (hawk_nde_exp_t*)nde;
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			PRINT_EXPR(hawk, px->left);
 | |
| 			HAWK_ASSERT (px->left->next == HAWK_NULL);
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 			PUT_SRCSTR(hawk, binop_str[px->opcode][(hawk->opt.trait & HAWK_BLANKCONCAT)? 0: 1]);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 
 | |
| 			if (px->right->type == HAWK_NDE_ASS)
 | |
| 				PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			PRINT_EXPR(hawk, px->right);
 | |
| 			if (px->right->type == HAWK_NDE_ASS)
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			HAWK_ASSERT (px->right->next == HAWK_NULL);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_EXP_UNR:
 | |
| 		{
 | |
| 			hawk_nde_exp_t* px = (hawk_nde_exp_t*)nde;
 | |
| 			HAWK_ASSERT (px->right == HAWK_NULL);
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			PUT_SRCSTR(hawk, unrop_str[px->opcode]);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			PRINT_EXPR(hawk, px->left);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_EXP_INCPRE:
 | |
| 		{
 | |
| 			hawk_nde_exp_t* px = (hawk_nde_exp_t*)nde;
 | |
| 			HAWK_ASSERT (px->right == HAWK_NULL);
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, incop_str[px->opcode]);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			PRINT_EXPR(hawk, px->left);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_EXP_INCPST:
 | |
| 		{
 | |
| 			hawk_nde_exp_t* px = (hawk_nde_exp_t*)nde;
 | |
| 			HAWK_ASSERT (px->right == HAWK_NULL);
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			PRINT_EXPR(hawk, px->left);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			PUT_SRCSTR(hawk, incop_str[px->opcode]);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_CND:
 | |
| 		{
 | |
| 			hawk_nde_cnd_t* px = (hawk_nde_cnd_t*)nde;
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			PRINT_EXPR(hawk, px->test);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")?"));
 | |
| 
 | |
| 			PRINT_EXPR(hawk, px->left);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(":"));
 | |
| 			PRINT_EXPR(hawk, px->right);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_CHAR:
 | |
| 		{
 | |
| 			hawk_ooch_t tmp = ((hawk_nde_char_t*)nde)->val;
 | |
| 			hawk_ooch_t buf[16];
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("\'"));
 | |
| 			if (tmp == '\0')
 | |
| 				PUT_SRCSTR(hawk, HAWK_T("\\0"));
 | |
| 			else if (tmp == '\'')
 | |
| 				PUT_SRCSTR(hawk, HAWK_T("\\'"));
 | |
| 			else if (hawk_is_ooch_print(tmp))
 | |
| 				PUT_SRCSTRN(hawk, &tmp, 1);
 | |
| 		#if defined(HAWK_OOCH_IS_UCH)
 | |
| 			else if (tmp <= 0xFFFF)
 | |
| 			{
 | |
| 				hawk_fmttooocstr(hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\u%04x"), (hawk_oochu_t)tmp);
 | |
| 				PUT_SRCSTR(hawk, buf);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				hawk_fmttooocstr(hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\U%08x"), (hawk_oochu_t)tmp);
 | |
| 				PUT_SRCSTR(hawk, buf);
 | |
| 			}
 | |
| 		#else
 | |
| 			else
 | |
| 			{
 | |
| 				hawk_fmttooocstr(hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\x%02x"), (hawk_oochu_t)tmp);
 | |
| 				PUT_SRCSTR(hawk, buf);
 | |
| 			}
 | |
| 		#endif
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("\'"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_BCHR:
 | |
| 		{
 | |
| 			hawk_bch_t tmp = ((hawk_nde_bchr_t*)nde)->val;
 | |
| 			hawk_ooch_t buf[16];
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("@b\'"));
 | |
| 			if (tmp == '\0')
 | |
| 				PUT_SRCSTR(hawk, HAWK_T("\\0"));
 | |
| 			else if (tmp == '\'')
 | |
| 				PUT_SRCSTR(hawk, HAWK_T("\\'"));
 | |
| 			else if (hawk_is_bch_print(tmp))
 | |
| 			{
 | |
| 				hawk_ooch_t oc = (hawk_bchu_t)tmp;
 | |
| 				PUT_SRCSTRN(hawk, &oc, 1);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				hawk_fmttooocstr(hawk, buf, HAWK_COUNTOF(buf), HAWK_T("\\x%02x"), (hawk_bchu_t)tmp);
 | |
| 				PUT_SRCSTR(hawk, buf);
 | |
| 			}
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("\'"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_INT:
 | |
| 		{
 | |
| 			if (((hawk_nde_int_t*)nde)->str)
 | |
| 			{
 | |
| 				PUT_SRCSTRN(hawk, ((hawk_nde_int_t*)nde)->str, ((hawk_nde_int_t*)nde)->len);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				/* Note that the array sizing fomula is not accurate
 | |
| 				 * but should be good enoug consiering the followings.
 | |
| 				 *
 | |
| 				 * size minval                               digits  sign
 | |
| 				 *   1  -128                                      3  1
 | |
| 				 *   2  -32768                                    5  1
 | |
| 				 *   4  -2147483648                              10  1
 | |
| 				 *   8  -9223372036854775808                     19  1
 | |
| 				 *  16  -170141183460469231731687303715884105728 39  1
 | |
| 				 */
 | |
| 				hawk_ooch_t buf[HAWK_SIZEOF(hawk_int_t) * 3 + 2];
 | |
| 
 | |
| 				hawk_fmt_intmax_to_oocstr (
 | |
| 					buf, HAWK_COUNTOF(buf),
 | |
| 					((hawk_nde_int_t*)nde)->val,
 | |
| 					10,
 | |
| 					-1,
 | |
| 					HAWK_T('\0'),
 | |
| 					HAWK_NULL
 | |
| 				);
 | |
| 				PUT_SRCSTR(hawk, buf);
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_FLT:
 | |
| 		{
 | |
| 			if (((hawk_nde_flt_t*)nde)->str)
 | |
| 			{
 | |
| 				PUT_SRCSTRN(hawk, ((hawk_nde_flt_t*)nde)->str, ((hawk_nde_flt_t*)nde)->len);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				hawk_ooch_t buf[96];
 | |
| 
 | |
| 			#if defined(HAWK_USE_FLTMAX)
 | |
| 				/*hawk_fmttooocstr(hawk, buf, HAWK_COUNTOF(buf), HAWK_T("%jf"), ((hawk_nde_flt_t*)nde)->val);*/
 | |
| 				hawk_fmttooocstr(hawk, buf, HAWK_COUNTOF(buf), HAWK_T("%jjf"), &((hawk_nde_flt_t*)nde)->val);
 | |
| 			#else
 | |
| 				hawk_fmttooocstr(hawk, buf, HAWK_COUNTOF(buf), HAWK_T("%zf"), ((hawk_nde_flt_t*)nde)->val);
 | |
| 			#endif
 | |
| 				PUT_SRCSTR(hawk, buf);
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_STR:
 | |
| 		{
 | |
| 			hawk_ooch_t* ptr;
 | |
| 			hawk_oow_t len, i;
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("\""));
 | |
| 
 | |
| 			ptr = ((hawk_nde_str_t*)nde)->ptr;
 | |
| 			len = ((hawk_nde_str_t*)nde)->len;
 | |
| 			for (i = 0; i < len; i++)
 | |
| 			{
 | |
| 				/* TODO: maybe more de-escaping?? */
 | |
| 				switch (ptr[i])
 | |
| 				{
 | |
| 					case HAWK_T('\n'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\n"));
 | |
| 						break;
 | |
| 					case HAWK_T('\r'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\r"));
 | |
| 						break;
 | |
| 					case HAWK_T('\t'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\t"));
 | |
| 						break;
 | |
| 					case HAWK_T('\f'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\f"));
 | |
| 						break;
 | |
| 					case HAWK_T('\b'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\b"));
 | |
| 						break;
 | |
| 					case HAWK_T('\v'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\v"));
 | |
| 						break;
 | |
| 					case HAWK_T('\a'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\a"));
 | |
| 						break;
 | |
| 					case HAWK_T('\0'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\0"));
 | |
| 						break;
 | |
| 					case HAWK_T('\"'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\\""));
 | |
| 						break;
 | |
| 					case HAWK_T('\\'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\\\"));
 | |
| 						break;
 | |
| 					default:
 | |
| 						PUT_SRCSTRN(hawk, &ptr[i], 1);
 | |
| 						break;
 | |
| 				}
 | |
| 			}
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("\""));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_MBS:
 | |
| 		{
 | |
| 			hawk_bch_t* ptr;
 | |
| 			hawk_oow_t len, i;
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("@b\""));
 | |
| 			ptr = ((hawk_nde_mbs_t*)nde)->ptr;
 | |
| 			len = ((hawk_nde_mbs_t*)nde)->len;
 | |
| 			for (i = 0; i < len; i++)
 | |
| 			{
 | |
| 				/* TODO: maybe more de-escaping?? */
 | |
| 				switch (ptr[i])
 | |
| 				{
 | |
| 					case HAWK_BT('\n'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\n"));
 | |
| 						break;
 | |
| 					case HAWK_BT('\r'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\r"));
 | |
| 						break;
 | |
| 					case HAWK_BT('\t'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\t"));
 | |
| 						break;
 | |
| 					case HAWK_BT('\f'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\f"));
 | |
| 						break;
 | |
| 					case HAWK_BT('\b'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\b"));
 | |
| 						break;
 | |
| 					case HAWK_BT('\v'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\v"));
 | |
| 						break;
 | |
| 					case HAWK_BT('\a'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\a"));
 | |
| 						break;
 | |
| 					case HAWK_BT('\0'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\0"));
 | |
| 						break;
 | |
| 					case HAWK_BT('\"'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\\""));
 | |
| 						break;
 | |
| 					case HAWK_BT('\\'):
 | |
| 						PUT_SRCSTR(hawk, HAWK_T("\\\\"));
 | |
| 						break;
 | |
| 					default:
 | |
| 					{
 | |
| 					#if defined(HAWK_OOCH_IS_BCH)
 | |
| 						PUT_SRCSTRN(hawk, &ptr[i], 1);
 | |
| 					#else
 | |
| 						hawk_ooch_t oc = (hawk_bchu_t)ptr[i];
 | |
| 						if (HAWK_BYTE_PRINTABLE(oc))
 | |
| 						{
 | |
| 							PUT_SRCSTRN(hawk, &oc, 1);
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							hawk_bch_t xbuf[3];
 | |
| 							hawk_byte_to_bcstr (oc, xbuf, HAWK_COUNTOF(xbuf), 16, '0');
 | |
| 							PUT_SRCSTR(hawk, HAWK_T("\\x"));
 | |
| 							oc = (hawk_bchu_t)xbuf[0]; PUT_SRCSTRN(hawk, &oc, 1);
 | |
| 							oc = (hawk_bchu_t)xbuf[1]; PUT_SRCSTRN(hawk, &oc, 1);
 | |
| 						}
 | |
| 					#endif
 | |
| 						break;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("\""));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_REX:
 | |
| 		{
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("/"));
 | |
| 			PUT_SRCSTRN(hawk,
 | |
| 				((hawk_nde_rex_t*)nde)->str.ptr,
 | |
| 				((hawk_nde_rex_t*)nde)->str.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("/"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_XNIL:
 | |
| 		{
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("@nil"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_XARGC:
 | |
| 		{
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("@argc"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_XARGV:
 | |
| 		{
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("@argv"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_XARGVIDX:
 | |
| 		{
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("@argv["));
 | |
| 			PRINT_EXPR(hawk, ((hawk_nde_xargvidx_t*)nde)->pos);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("]"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_FUN:
 | |
| 		{
 | |
| 			PUT_SRCSTRN(hawk,
 | |
| 				((hawk_nde_fun_t*)nde)->name.ptr,
 | |
| 				((hawk_nde_fun_t*)nde)->name.len);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_ARG:
 | |
| 		{
 | |
| 			hawk_ooch_t tmp[HAWK_SIZEOF(hawk_int_t)*8+2];
 | |
| 			hawk_oow_t n;
 | |
| 			hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
 | |
| 			HAWK_ASSERT (px->id.idxa != (hawk_oow_t)-1);
 | |
| 
 | |
| 			n = hawk_int_to_oocstr(px->id.idxa, 10, HAWK_NULL, tmp, HAWK_COUNTOF(tmp));
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("__p"));
 | |
| 			PUT_SRCSTRN(hawk, tmp, n);
 | |
| 
 | |
| 			HAWK_ASSERT (px->idx == HAWK_NULL);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_ARGIDX:
 | |
| 		{
 | |
| 			hawk_oow_t n;
 | |
| 			hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
 | |
| 			HAWK_ASSERT (px->id.idxa != (hawk_oow_t)-1);
 | |
| 			HAWK_ASSERT (px->idx != HAWK_NULL);
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("__p"));
 | |
| 			n = hawk_int_to_oocstr(px->id.idxa, 10, HAWK_NULL, hawk->tmp.fmt, HAWK_COUNTOF(hawk->tmp.fmt));
 | |
| 			PUT_SRCSTRN(hawk, hawk->tmp.fmt, n);
 | |
| 			PRINT_EXPR_LIST_FOR_IDX(hawk, px->idx);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_NAMED:
 | |
| 		{
 | |
| 			hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
 | |
| 			HAWK_ASSERT (px->id.idxa == (hawk_oow_t)-1);
 | |
| 			HAWK_ASSERT (px->idx == HAWK_NULL);
 | |
| 
 | |
| 			PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_NAMEDIDX:
 | |
| 		{
 | |
| 			hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
 | |
| 			HAWK_ASSERT (px->id.idxa == (hawk_oow_t)-1);
 | |
| 			HAWK_ASSERT (px->idx != HAWK_NULL);
 | |
| 
 | |
| 			PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
 | |
| 			PRINT_EXPR_LIST_FOR_IDX(hawk, px->idx);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_GBL:
 | |
| 		{
 | |
| 			hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
 | |
| 
 | |
| 			if (px->id.idxa != (hawk_oow_t)-1)
 | |
| 			{
 | |
| 				/* deparsing is global. so i can't honor hawk->parse.pragma.trait
 | |
| 				 * which can change in each input file. let me just check hawk->opt.trait */
 | |
| 				if (!(hawk->opt.trait & HAWK_IMPLICIT))
 | |
| 				{
 | |
| 					/* no implicit(named) variable is allowed.
 | |
| 					 * use the actual name */
 | |
| 					PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
 | |
| 				}
 | |
| 				else if (px->id.idxa < hawk->tree.ngbls_base)
 | |
| 				{
 | |
| 					/* static global variables */
 | |
| 					PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					hawk_ooch_t tmp[HAWK_SIZEOF(hawk_int_t)*8+2];
 | |
| 					hawk_oow_t n;
 | |
| 
 | |
| 					PUT_SRCSTR(hawk, HAWK_T("__g"));
 | |
| 					n = hawk_int_to_oocstr(px->id.idxa, 10, HAWK_NULL, tmp, HAWK_COUNTOF(tmp));
 | |
| 					PUT_SRCSTRN(hawk, tmp, n);
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
 | |
| 			}
 | |
| 			HAWK_ASSERT (px->idx == HAWK_NULL);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_GBLIDX:
 | |
| 		{
 | |
| 			hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
 | |
| 
 | |
| 			if (px->id.idxa != (hawk_oow_t)-1)
 | |
| 			{
 | |
| 				/* deparsing is global. so i can't honor hawk->parse.pragma.trait
 | |
| 				 * which can change in each input file. let me just check hawk->opt.trait */
 | |
| 				if (!(hawk->opt.trait & HAWK_IMPLICIT))
 | |
| 				{
 | |
| 					/* no implicit(named) variable is allowed.
 | |
| 					 * use the actual name */
 | |
| 					PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
 | |
| 				}
 | |
| 				else if (px->id.idxa < hawk->tree.ngbls_base)
 | |
| 				{
 | |
| 					/* static global variables */
 | |
| 					PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					hawk_ooch_t tmp[HAWK_SIZEOF(hawk_int_t)*8+2];
 | |
| 					hawk_oow_t n;
 | |
| 
 | |
| 					PUT_SRCSTR(hawk, HAWK_T("__g"));
 | |
| 					n = hawk_int_to_oocstr(px->id.idxa, 10, HAWK_NULL, tmp, HAWK_COUNTOF(tmp));
 | |
| 					PUT_SRCSTRN(hawk, tmp, n);
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
 | |
| 			}
 | |
| 			HAWK_ASSERT (px->idx != HAWK_NULL);
 | |
| 			PRINT_EXPR_LIST_FOR_IDX(hawk, px->idx);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		case HAWK_NDE_LCL:
 | |
| 		{
 | |
| 			hawk_oow_t n;
 | |
| 			hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
 | |
| 
 | |
| 			if (px->id.idxa != (hawk_oow_t)-1)
 | |
| 			{
 | |
| 				PUT_SRCSTR(hawk, HAWK_T("__l"));
 | |
| 				n = hawk_int_to_oocstr(px->id.idxa, 10, HAWK_NULL, hawk->tmp.fmt, HAWK_COUNTOF(hawk->tmp.fmt));
 | |
| 				PUT_SRCSTRN(hawk, hawk->tmp.fmt, n);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
 | |
| 			}
 | |
| 			HAWK_ASSERT (px->idx == HAWK_NULL);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_LCLIDX:
 | |
| 		{
 | |
| 			hawk_oow_t n;
 | |
| 			hawk_nde_var_t* px = (hawk_nde_var_t*)nde;
 | |
| 
 | |
| 			if (px->id.idxa != (hawk_oow_t)-1)
 | |
| 			{
 | |
| 				PUT_SRCSTR(hawk, HAWK_T("__l"));
 | |
| 				n = hawk_int_to_oocstr(px->id.idxa, 10, HAWK_NULL, hawk->tmp.fmt, HAWK_COUNTOF(hawk->tmp.fmt));
 | |
| 				PUT_SRCSTRN(hawk, hawk->tmp.fmt, n);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				PUT_SRCSTRN(hawk, px->id.name.ptr, px->id.name.len);
 | |
| 			}
 | |
| 			HAWK_ASSERT (px->idx != HAWK_NULL);
 | |
| 			PRINT_EXPR_LIST_FOR_IDX(hawk, px->idx);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_POS:
 | |
| 		{
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("$("));
 | |
| 			PRINT_EXPR(hawk, ((hawk_nde_pos_t*)nde)->val);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_FNCALL_FNC:
 | |
| 		{
 | |
| 			hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)nde;
 | |
| 			PUT_SRCSTRN(hawk, px->u.fnc.info.name.ptr, px->u.fnc.info.name.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			PRINT_EXPR_LIST(hawk, px->args);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_FNCALL_FUN:
 | |
| 		{
 | |
| 			hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)nde;
 | |
| 			PUT_SRCSTRN(hawk, px->u.fun.name.ptr, px->u.fun.name.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			PRINT_EXPR_LIST(hawk, px->args);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_FNCALL_VAR:
 | |
| 		{
 | |
| 			hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)nde;
 | |
| 			PRINT_EXPR(hawk, (hawk_nde_t*)px->u.var.var);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			PRINT_EXPR_LIST(hawk, px->args);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_GETLINE:
 | |
| 		{
 | |
| 			hawk_nde_getline_t* px = (hawk_nde_getline_t*)nde;
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 
 | |
| 			if (px->in && (px->in_type == HAWK_IN_PIPE || px->in_type == HAWK_IN_RWPIPE))
 | |
| 			{
 | |
| 				PRINT_EXPR(hawk, px->in);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 				PUT_SRCSTR(hawk, getline_inop_str[px->in_type]);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 			}
 | |
| 
 | |
| 			hawk_getkwname(hawk, (px->mbs? HAWK_KWID_GETBLINE: HAWK_KWID_GETLINE), &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			if (px->var)
 | |
| 			{
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 				PRINT_EXPR(hawk, px->var);
 | |
| 			}
 | |
| 
 | |
| 			if (px->in && px->in_type == HAWK_IN_FILE)
 | |
| 			{
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 				PUT_SRCSTR(hawk, getline_inop_str[px->in_type]);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 				PRINT_EXPR(hawk, px->in);
 | |
| 			}
 | |
| 
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_PRINT:
 | |
| 		case HAWK_NDE_PRINTF:
 | |
| 		{
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("("));
 | |
| 			if (print_printx(hawk, (hawk_nde_print_t*)nde) <= -1) return -1;
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		default:
 | |
| 		{
 | |
| 			hawk_seterrnum(hawk, HAWK_NULL, HAWK_EINTERN);
 | |
| 			return -1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int print_expr_list (hawk_t* hawk, hawk_nde_t* tree)
 | |
| {
 | |
| 	hawk_nde_t* p = tree;
 | |
| 
 | |
| 	while (p)
 | |
| 	{
 | |
| 		PRINT_EXPR(hawk, p);
 | |
| 		p = p->next;
 | |
| 		if (p) PUT_SRCSTR(hawk, HAWK_T(","));
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int print_expr_list_for_idx (hawk_t* hawk, hawk_nde_t* tree)
 | |
| {
 | |
| 	hawk_nde_t* p = tree;
 | |
| 
 | |
| 	PUT_SRCSTR(hawk, HAWK_T("["));
 | |
| 	while (p)
 | |
| 	{
 | |
| 		PRINT_EXPR(hawk, p);
 | |
| 		p = p->next;
 | |
| 		if (p)
 | |
| 		{
 | |
| 			if (p->type == HAWK_NDE_NULL)
 | |
| 			{
 | |
| 				/* the parser injects a HAWK_NDE_NULL node between the true multi-dimensional indices
 | |
| 				 * if the true multi-dimensional indices are enabled(i.e. HAWK_ENABLE_GC is defined)
 | |
| 				 * e.g. a[x][y][z]
 | |
| 				 * let me print this regardless of */
 | |
| 				PUT_SRCSTR(hawk, HAWK_T("]["));
 | |
| 				p = p->next;
 | |
| 			}
 | |
| 			else PUT_SRCSTR(hawk, HAWK_T(","));
 | |
| 		}
 | |
| 	}
 | |
| 	PUT_SRCSTR(hawk, HAWK_T("]"));
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int print_stmt (hawk_t* hawk, hawk_nde_t* p, int depth)
 | |
| {
 | |
| 	hawk_oow_t i;
 | |
| 	hawk_oocs_t kw;
 | |
| 
 | |
| 	switch (p->type)
 | |
| 	{
 | |
| 		case HAWK_NDE_NULL:
 | |
| 		{
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_BLK:
 | |
| 		{
 | |
| 			hawk_oow_t n;
 | |
| 			hawk_nde_blk_t* px = (hawk_nde_blk_t*)p;
 | |
| 
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("{"));
 | |
| 			PUT_NL(hawk);
 | |
| 
 | |
| 			if (px->org_nlcls > 0)
 | |
| 			{
 | |
| 				PRINT_TABS(hawk, depth + 1);
 | |
| 
 | |
| 				hawk_getkwname(hawk, HAWK_KWID_XLOCAL, &kw);
 | |
| 				PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 
 | |
| 				/* though the parser pushed up all local variables to the outer-most level,
 | |
| 				 * the code here restores the original declarations with org_nlcls and prv_nlcls */
 | |
| 				for (i = 0; i < px->org_nlcls - 1; i++)
 | |
| 				{
 | |
| 					PUT_SRCSTR(hawk, HAWK_T("__l"));
 | |
| 					n = hawk_int_to_oocstr(px->outer_nlcls + i, 10, HAWK_NULL, hawk->tmp.fmt, HAWK_COUNTOF(hawk->tmp.fmt));
 | |
| 					PUT_SRCSTRN(hawk, hawk->tmp.fmt, n);
 | |
| 					PUT_SRCSTR(hawk, HAWK_T(", "));
 | |
| 				}
 | |
| 
 | |
| 				PUT_SRCSTR(hawk, HAWK_T("__l"));
 | |
| 				n = hawk_int_to_oocstr(px->outer_nlcls + i, 10, HAWK_NULL, hawk->tmp.fmt, HAWK_COUNTOF(hawk->tmp.fmt));
 | |
| 				PUT_SRCSTRN(hawk, hawk->tmp.fmt, n);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 				PUT_NL(hawk);
 | |
| 			}
 | |
| 
 | |
| 			PRINT_STMTS(hawk, px->body, depth + 1);
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("}"));
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_IF:
 | |
| 		{
 | |
| 			hawk_nde_if_t* px = (hawk_nde_if_t*)p;
 | |
| 
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_IF, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" ("));
 | |
| 			PRINT_EXPR(hawk, px->test);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			PUT_NL(hawk);
 | |
| 
 | |
| 			HAWK_ASSERT (px->then_part != HAWK_NULL);
 | |
| 			if (px->then_part->type == HAWK_NDE_BLK)
 | |
| 				PRINT_STMTS(hawk, px->then_part, depth);
 | |
| 			else
 | |
| 				PRINT_STMTS(hawk, px->then_part, depth + 1);
 | |
| 
 | |
| 			if (px->else_part != HAWK_NULL)
 | |
| 			{
 | |
| 				PRINT_TABS(hawk, depth);
 | |
| 				hawk_getkwname(hawk, HAWK_KWID_ELSE, &kw);
 | |
| 				PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 				PUT_NL(hawk);
 | |
| 				if (px->else_part->type == HAWK_NDE_BLK)
 | |
| 					PRINT_STMTS(hawk, px->else_part, depth);
 | |
| 				else
 | |
| 					PRINT_STMTS(hawk, px->else_part, depth + 1);
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_SWITCH:
 | |
| 		{
 | |
| 			hawk_nde_switch_t* px = (hawk_nde_switch_t*)p;
 | |
| 
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_SWITCH, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" ("));
 | |
| 			PRINT_EXPR(hawk, px->test);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			PUT_NL(hawk);
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("{"));
 | |
| 			PUT_NL(hawk);
 | |
| 			if (px->case_part) PRINT_STMTS(hawk, px->case_part, depth);
 | |
| 			/* default_part is one of the case_parts. no explicit printing is needed */
 | |
| 			/*if (px->default_part) PRINT_STMTS(hawk, px->default_part, depth);*/
 | |
| 			PUT_NL(hawk);
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("}"));
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_CASE:
 | |
| 		{
 | |
| 			/* this is not a real statement and is subject to the owning switch statement. */
 | |
| 			hawk_nde_case_t* px = (hawk_nde_case_t*)p;
 | |
| 
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, (px->val? HAWK_KWID_CASE: HAWK_KWID_DEFAULT), &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			if (px->val)
 | |
| 			{
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 				PRINT_EXPR(hawk, px->val);
 | |
| 			}
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(":"));
 | |
| 			PUT_NL(hawk);
 | |
| 			if (px->action) PRINT_STMTS(hawk, px->action, depth + 1);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_WHILE:
 | |
| 		{
 | |
| 			hawk_nde_while_t* px = (hawk_nde_while_t*)p;
 | |
| 
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_WHILE, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" ("));
 | |
| 			PRINT_EXPR(hawk, px->test);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			PUT_NL(hawk);
 | |
| 			if (px->body->type == HAWK_NDE_BLK)
 | |
| 			{
 | |
| 				PRINT_STMTS(hawk, px->body, depth);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				PRINT_STMTS(hawk, px->body, depth + 1);
 | |
| 			}
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_DOWHILE:
 | |
| 		{
 | |
| 			hawk_nde_while_t* px = (hawk_nde_while_t*)p;
 | |
| 
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_DO, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_NL(hawk);
 | |
| 			if (px->body->type == HAWK_NDE_BLK)
 | |
| 			{
 | |
| 				PRINT_STMTS(hawk, px->body, depth);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				PRINT_STMTS(hawk, px->body, depth + 1);
 | |
| 			}
 | |
| 
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_WHILE, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" ("));
 | |
| 			PRINT_EXPR(hawk, px->test);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(");"));
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_FOR:
 | |
| 		{
 | |
| 			hawk_nde_for_t* px = (hawk_nde_for_t*)p;
 | |
| 
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_FOR, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" ("));
 | |
| 			if (px->init != HAWK_NULL)
 | |
| 			{
 | |
| 				PRINT_EXPR(hawk, px->init);
 | |
| 			}
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("; "));
 | |
| 			if (px->test != HAWK_NULL)
 | |
| 			{
 | |
| 				PRINT_EXPR(hawk, px->test);
 | |
| 			}
 | |
| 			PUT_SRCSTR(hawk, HAWK_T("; "));
 | |
| 			if (px->incr != HAWK_NULL)
 | |
| 			{
 | |
| 				PRINT_EXPR(hawk, px->incr);
 | |
| 			}
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(")"));
 | |
| 			PUT_NL(hawk);
 | |
| 
 | |
| 			if (px->body->type == HAWK_NDE_BLK)
 | |
| 			{
 | |
| 				PRINT_STMTS(hawk, px->body, depth);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				PRINT_STMTS(hawk, px->body, depth + 1);
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_FORIN:
 | |
| 		{
 | |
| 			hawk_nde_forin_t* px = (hawk_nde_forin_t*)p;
 | |
| 
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_FOR, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 			PRINT_EXPR(hawk, px->test);
 | |
| 			PUT_NL(hawk);
 | |
| 			if (px->body->type == HAWK_NDE_BLK)
 | |
| 			{
 | |
| 				PRINT_STMTS(hawk, px->body, depth);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				PRINT_STMTS(hawk, px->body, depth + 1);
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_BREAK:
 | |
| 		{
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_BREAK, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_CONTINUE:
 | |
| 		{
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_CONTINUE, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_RETURN:
 | |
| 		{
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			if (((hawk_nde_return_t*)p)->val == HAWK_NULL)
 | |
| 			{
 | |
| 				hawk_getkwname(hawk, HAWK_KWID_RETURN, &kw);
 | |
| 				PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 				PUT_NL(hawk);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				hawk_getkwname(hawk, HAWK_KWID_RETURN, &kw);
 | |
| 				PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 				HAWK_ASSERT (((hawk_nde_return_t*)p)->val->next == HAWK_NULL);
 | |
| 
 | |
| 				PRINT_EXPR(hawk, ((hawk_nde_return_t*)p)->val);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 				PUT_NL(hawk);
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_EXIT:
 | |
| 		{
 | |
| 			hawk_nde_exit_t* px = (hawk_nde_exit_t*)p;
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 
 | |
| 			if (px->val == HAWK_NULL)
 | |
| 			{
 | |
| 				hawk_getkwname(hawk, (px->abort? HAWK_KWID_XABORT: HAWK_KWID_EXIT), &kw);
 | |
| 				PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 				PUT_NL(hawk);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				hawk_getkwname(hawk, (px->abort? HAWK_KWID_XABORT: HAWK_KWID_EXIT), &kw);
 | |
| 				PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 				HAWK_ASSERT (px->val->next == HAWK_NULL);
 | |
| 				PRINT_EXPR(hawk, px->val);
 | |
| 				PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 				PUT_NL(hawk);
 | |
| 			}
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_NEXT:
 | |
| 		{
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_NEXT, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_NEXTFILE:
 | |
| 		{
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			if (((hawk_nde_nextfile_t*)p)->out)
 | |
| 			{
 | |
| 				hawk_getkwname(hawk, HAWK_KWID_NEXTOFILE, &kw);
 | |
| 				PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				hawk_getkwname(hawk, HAWK_KWID_NEXTFILE, &kw);
 | |
| 				PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			}
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_DELETE:
 | |
| 		{
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_DELETE, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 			hawk_prnpt(hawk, ((hawk_nde_delete_t*)p)->var);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_RESET:
 | |
| 		{
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			hawk_getkwname(hawk, HAWK_KWID_XRESET, &kw);
 | |
| 			PUT_SRCSTRN(hawk, kw.ptr, kw.len);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(" "));
 | |
| 			hawk_prnpt(hawk, ((hawk_nde_reset_t*)p)->var);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		case HAWK_NDE_PRINT:
 | |
| 		case HAWK_NDE_PRINTF:
 | |
| 		{
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			if (print_printx(hawk, (hawk_nde_print_t*)p) <= -1) return -1;
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		default:
 | |
| 		{
 | |
| 			PRINT_TABS(hawk, depth);
 | |
| 			PRINT_EXPR(hawk, p);
 | |
| 			PUT_SRCSTR(hawk, HAWK_T(";"));
 | |
| 			PUT_NL(hawk);
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int print_stmts (hawk_t* hawk, hawk_nde_t* tree, int depth)
 | |
| {
 | |
| 	hawk_nde_t* p = tree;
 | |
| 
 | |
| 	while (p)
 | |
| 	{
 | |
| 		if (print_stmt(hawk, p, depth) <= -1) return -1;
 | |
| 		p = p->next;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int hawk_prnpt (hawk_t* hawk, hawk_nde_t* tree)
 | |
| {
 | |
| 	return print_stmts(hawk, tree, 0);
 | |
| }
 | |
| 
 | |
| int hawk_prnnde (hawk_t* hawk, hawk_nde_t* tree)
 | |
| {
 | |
| 	return print_stmt(hawk, tree, 0);
 | |
| }
 | |
| 
 | |
| int hawk_prnptnpt (hawk_t* hawk, hawk_nde_t* tree)
 | |
| {
 | |
| 	hawk_nde_t* nde = tree;
 | |
| 
 | |
| 	while (nde)
 | |
| 	{
 | |
| 		if (print_expr(hawk, nde) <= -1) return -1;
 | |
| 		if (!nde->next) break;
 | |
| 
 | |
| 		PUT_SRCSTR(hawk, HAWK_T(","));
 | |
| 		nde = nde->next;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| void hawk_clrpt (hawk_t* hawk, hawk_nde_t* tree)
 | |
| {
 | |
| 	hawk_nde_t* p = tree;
 | |
| 	hawk_nde_t* next;
 | |
| 
 | |
| 	while (p)
 | |
| 	{
 | |
| 		next = p->next;
 | |
| 
 | |
| 		switch (p->type)
 | |
| 		{
 | |
| 			case HAWK_NDE_NULL:
 | |
| 			{
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_BLK:
 | |
| 			{
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_blk_t*)p)->body);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_IF:
 | |
| 			{
 | |
| 				hawk_nde_if_t* px = (hawk_nde_if_t*)p;
 | |
| 				hawk_clrpt(hawk, px->test);
 | |
| 				hawk_clrpt(hawk, px->then_part);
 | |
| 				if (px->else_part) hawk_clrpt(hawk, px->else_part);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_SWITCH:
 | |
| 			{
 | |
| 				hawk_nde_switch_t* px = (hawk_nde_switch_t*)p;
 | |
| 				hawk_clrpt(hawk, px->test);
 | |
| 				if (px->case_part) hawk_clrpt(hawk, px->case_part);
 | |
| 				/* px->default_part is one of the case parts. explicit clean up isn't required */
 | |
| 				/*if (px->default_part) hawk_clrpt(hawk, px->default_part);*/
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_CASE:
 | |
| 			{
 | |
| 				hawk_nde_case_t* px = (hawk_nde_case_t*)p;
 | |
| 				if (px->val) hawk_clrpt(hawk, px->val);
 | |
| 				if (px->action) hawk_clrpt(hawk, px->action);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_WHILE:
 | |
| 			case HAWK_NDE_DOWHILE:
 | |
| 			{
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_while_t*)p)->test);
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_while_t*)p)->body);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_FOR:
 | |
| 			{
 | |
| 				hawk_nde_for_t* px = (hawk_nde_for_t*)p;
 | |
| 				if (px->init) hawk_clrpt(hawk, px->init);
 | |
| 				if (px->test) hawk_clrpt(hawk, px->test);
 | |
| 				if (px->incr) hawk_clrpt(hawk, px->incr);
 | |
| 				hawk_clrpt(hawk, px->body);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_FORIN:
 | |
| 			{
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_forin_t*)p)->test);
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_forin_t*)p)->body);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_BREAK:
 | |
| 			{
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_CONTINUE:
 | |
| 			{
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_RETURN:
 | |
| 			{
 | |
| 				hawk_nde_return_t* px = (hawk_nde_return_t*)p;
 | |
| 				if (px->val) hawk_clrpt(hawk, px->val);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_EXIT:
 | |
| 			{
 | |
| 				if (((hawk_nde_exit_t*)p)->val != HAWK_NULL)
 | |
| 					hawk_clrpt(hawk, ((hawk_nde_exit_t*)p)->val);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_NEXT:
 | |
| 			case HAWK_NDE_NEXTFILE:
 | |
| 			{
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_DELETE:
 | |
| 			{
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_delete_t*)p)->var);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_RESET:
 | |
| 			{
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_reset_t*)p)->var);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_PRINT:
 | |
| 			case HAWK_NDE_PRINTF:
 | |
| 			{
 | |
| 				hawk_nde_print_t* px = (hawk_nde_print_t*)p;
 | |
| 				if (px->args) hawk_clrpt(hawk, px->args);
 | |
| 				if (px->out) hawk_clrpt(hawk, px->out);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_GRP:
 | |
| 			{
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_grp_t*)p)->body);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_ASS:
 | |
| 			{
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_ass_t*)p)->left);
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_ass_t*)p)->right);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_EXP_BIN:
 | |
| 			{
 | |
| 				hawk_nde_exp_t* px = (hawk_nde_exp_t*)p;
 | |
| 				HAWK_ASSERT (px->left->next == HAWK_NULL);
 | |
| 				HAWK_ASSERT (px->right->next == HAWK_NULL);
 | |
| 
 | |
| 				hawk_clrpt(hawk, px->left);
 | |
| 				hawk_clrpt(hawk, px->right);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_EXP_UNR:
 | |
| 			case HAWK_NDE_EXP_INCPRE:
 | |
| 			case HAWK_NDE_EXP_INCPST:
 | |
| 			{
 | |
| 				hawk_nde_exp_t* px = (hawk_nde_exp_t*)p;
 | |
| 				HAWK_ASSERT (px->right == HAWK_NULL);
 | |
| 				hawk_clrpt(hawk, px->left);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_CND:
 | |
| 			{
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_cnd_t*)p)->test);
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_cnd_t*)p)->left);
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_cnd_t*)p)->right);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_CHAR:
 | |
| 			case HAWK_NDE_BCHR:
 | |
| 			{
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_INT:
 | |
| 			{
 | |
| 				if (((hawk_nde_int_t*)p)->str)
 | |
| 					hawk_freemem(hawk, ((hawk_nde_int_t*)p)->str);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_FLT:
 | |
| 			{
 | |
| 				if (((hawk_nde_flt_t*)p)->str)
 | |
| 					hawk_freemem(hawk, ((hawk_nde_flt_t*)p)->str);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_STR:
 | |
| 			{
 | |
| 				hawk_freemem(hawk, ((hawk_nde_str_t*)p)->ptr);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_MBS:
 | |
| 			{
 | |
| 				hawk_freemem(hawk, ((hawk_nde_mbs_t*)p)->ptr);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_REX:
 | |
| 			{
 | |
| 				hawk_nde_rex_t* rex = (hawk_nde_rex_t*)p;
 | |
| 				hawk_freerex(hawk, rex->code[0], rex->code[1]);
 | |
| 				hawk_freemem(hawk, ((hawk_nde_rex_t*)p)->str.ptr);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_XNIL:
 | |
| 			{
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_XARGC:
 | |
| 			case HAWK_NDE_XARGV:
 | |
| 			{
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_XARGVIDX:
 | |
| 			{
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_xargvidx_t*)p)->pos);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_FUN:
 | |
| 			{
 | |
| 				hawk_freemem(hawk, ((hawk_nde_fun_t*)p)->name.ptr);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_NAMED:
 | |
| 			case HAWK_NDE_GBL:
 | |
| 			case HAWK_NDE_LCL:
 | |
| 			case HAWK_NDE_ARG:
 | |
| 			{
 | |
| 				hawk_nde_var_t* px = (hawk_nde_var_t*)p;
 | |
| 				HAWK_ASSERT (px->idx == HAWK_NULL);
 | |
| 				if (px->id.name.ptr) hawk_freemem(hawk, px->id.name.ptr);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_NAMEDIDX:
 | |
| 			case HAWK_NDE_GBLIDX:
 | |
| 			case HAWK_NDE_LCLIDX:
 | |
| 			case HAWK_NDE_ARGIDX:
 | |
| 			{
 | |
| 				hawk_nde_var_t* px = (hawk_nde_var_t*)p;
 | |
| 				HAWK_ASSERT (px->idx != HAWK_NULL);
 | |
| 				hawk_clrpt(hawk, px->idx);
 | |
| 				if (px->id.name.ptr) hawk_freemem(hawk, px->id.name.ptr);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_POS:
 | |
| 			{
 | |
| 				hawk_clrpt(hawk, ((hawk_nde_pos_t*)p)->val);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_FNCALL_FNC:
 | |
| 			{
 | |
| 				hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)p;
 | |
| 				/* hawk_freemem(hawk, px->u.fnc); */
 | |
| 				hawk_freemem(hawk, px->u.fnc.info.name.ptr);
 | |
| 				hawk_clrpt(hawk, px->args);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_FNCALL_FUN:
 | |
| 			{
 | |
| 				hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)p;
 | |
| 				hawk_freemem(hawk, px->u.fun.name.ptr);
 | |
| 				hawk_clrpt(hawk, px->args);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_FNCALL_VAR:
 | |
| 			{
 | |
| 				hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)p;
 | |
| 				hawk_clrpt(hawk, (hawk_nde_t*)px->u.var.var);
 | |
| 				hawk_clrpt(hawk, px->args);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			case HAWK_NDE_GETLINE:
 | |
| 			{
 | |
| 				hawk_nde_getline_t* px = (hawk_nde_getline_t*)p;
 | |
| 				if (px->var) hawk_clrpt(hawk, px->var);
 | |
| 				if (px->in) hawk_clrpt(hawk, px->in);
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			default:
 | |
| 			{
 | |
| 				HAWK_ASSERT (!"should never happen - invalid node type");
 | |
| 				hawk_freemem(hawk, p);
 | |
| 				break;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		p = next;
 | |
| 	}
 | |
| }
 |