* fixed a problem of not printing the closing parenthesis if the last CDR is not nil in qse_scm_print().
* separated the syntax bit for a symbol from the type bits
This commit is contained in:
		| @ -458,13 +458,7 @@ qse_scm_ent_t* qse_scm_makesyntent ( | ||||
| 	v = qse_scm_makesyment (scm, name); | ||||
| 	if (v == QSE_NULL) return QSE_NULL; | ||||
|  | ||||
| 	/* We piggy-back the syntax code to a symbol name. | ||||
| 	 * The syntax entity is basically a symbol except that the | ||||
| 	 * code field of its label entity is set to non-zero.  | ||||
| 	 * Read the comment in qse_scm_makeprocent() for difference between | ||||
| 	 * the syntax entity and the procedure entity. | ||||
| 	 */ | ||||
| 	TYPE(v) |= QSE_SCM_ENT_SYNT;  | ||||
| 	SYNT(v) = 1; | ||||
| 	SYNT_CODE(v) = code;  | ||||
|  | ||||
| 	return v; | ||||
|  | ||||
| @ -114,7 +114,7 @@ static qse_size_t long_to_str ( | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static QSE_INLINE push (qse_scm_t* scm, qse_scm_ent_t* obj) | ||||
| static QSE_INLINE int push (qse_scm_t* scm, qse_scm_ent_t* obj) | ||||
| { | ||||
| 	qse_scm_ent_t* top; | ||||
|  | ||||
| @ -132,16 +132,25 @@ static QSE_INLINE qse_scm_ent_t* pop (qse_scm_t* scm) | ||||
| 	return PAIR_CAR(top); | ||||
| } | ||||
|  | ||||
| static int print_entity ( | ||||
| 	qse_scm_t* scm, const qse_scm_ent_t* obj, int prt_cons_par) | ||||
| static QSE_INLINE print_num (qse_scm_t* scm, qse_long_t nval) | ||||
| { | ||||
| 	qse_long_t nval; | ||||
| 	qse_char_t tmp[QSE_SIZEOF(qse_long_t)*8+2]; | ||||
| 	qse_size_t len; | ||||
|  | ||||
| retry: | ||||
| 	len = long_to_str (nval, 10, QSE_NULL, tmp, QSE_COUNTOF(tmp)); | ||||
| 	OUTPUT_STRX (scm, tmp, len); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int print_entity (qse_scm_t* scm, const qse_scm_ent_t* obj) | ||||
| { | ||||
| 	const qse_scm_ent_t* cur; | ||||
|  | ||||
| next: | ||||
| 	if (IS_SMALLINT(scm,obj)) | ||||
| 	{ | ||||
| 		nval = FROM_SMALLINT(scm,obj); | ||||
| 		goto printnum; | ||||
| 		if (print_num (scm, FROM_SMALLINT(scm,obj)) <= -1) return -1; | ||||
| 		goto done; | ||||
| 	} | ||||
|  | ||||
| 	switch (TYPE(obj))  | ||||
| @ -160,14 +169,7 @@ retry: | ||||
|  | ||||
| 		case QSE_SCM_ENT_NUM: | ||||
| 		{ | ||||
| 			qse_char_t tmp[QSE_SIZEOF(qse_long_t)*8+2]; | ||||
| 			qse_size_t len; | ||||
|  | ||||
| 			nval = NUM_VALUE(obj); | ||||
|  | ||||
| 		printnum: | ||||
| 			len = long_to_str (nval, 10, QSE_NULL, tmp, QSE_COUNTOF(tmp)); | ||||
|                OUTPUT_STRX (scm, tmp, len); | ||||
| 			if (print_num (scm, NUM_VALUE(obj)) <= -1) return -1; | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| @ -192,6 +194,9 @@ retry: | ||||
| #endif | ||||
|  | ||||
| 		case QSE_SCM_ENT_SYM: | ||||
| 			/* Any needs for special action if SYNT(obj) is true? | ||||
| 			 * I simply treat the syntax symbol as a normal symbol | ||||
| 			 * for printing currently. */ | ||||
| 			OUTPUT_STR (scm, LAB_PTR(SYM_NAME(obj))); | ||||
| 			break; | ||||
|  | ||||
| @ -204,55 +209,52 @@ retry: | ||||
|  | ||||
| 		case QSE_SCM_ENT_PAIR: | ||||
| 		{ | ||||
| 			const qse_scm_ent_t* p = obj; | ||||
| 			if (prt_cons_par) OUTPUT_STR (scm, QSE_T("(")); | ||||
| 			 | ||||
| 			OUTPUT_STR (scm, QSE_T("(")); | ||||
| 			cur = obj; | ||||
|  | ||||
| 			do | ||||
| 			{ | ||||
| 				if (push (scm, PAIR_CDR(p)) <= -1) return -1; | ||||
| 				obj = PAIR_CAR(p); | ||||
| 				goto retry; | ||||
| 				/* Push what to print next on to the stack  | ||||
| 				 * the variable p is */ | ||||
| 				if (push (scm, PAIR_CDR(cur)) <= -1) return -1; | ||||
|  | ||||
| 				obj = PAIR_CAR(cur); | ||||
| 				/* Jump to the 'next' label so that the entity  | ||||
| 				 * pointed to by 'obj' is printed. Once it  | ||||
| 				 * ends, a jump back to the 'resume' label | ||||
| 				 * is made at the at of this function. */ | ||||
| 				goto next;  | ||||
|  | ||||
| 			resume: | ||||
| 				p = pop (scm); | ||||
| 				if (!IS_NIL(scm,p)) | ||||
| 				cur = pop (scm); /* Get back the CDR pushed */ | ||||
| 				if (IS_NIL(scm,cur))  | ||||
| 				{ | ||||
| 					/* The CDR part points to a NIL entity, which | ||||
| 					 * indicates the end of a list. break the loop */ | ||||
| 					break; | ||||
| 				} | ||||
| 				if (IS_SMALLINT(scm,cur) || TYPE(cur) != QSE_SCM_ENT_PAIR)  | ||||
| 				{ | ||||
| 					/* The CDR part does not point to a pair. */ | ||||
| 					OUTPUT_STR (scm, QSE_T(" . ")); | ||||
| 						 | ||||
| 					/* Push NIL so that the IS_NIL(scm,p) test in  | ||||
| 					 * the 'if' statement above breaks the loop | ||||
| 					 * after the jump is maded back to the 'resume'  | ||||
| 					 * label. */ | ||||
| 					if (push (scm, scm->nil) <= -1) return -1; | ||||
|  | ||||
| 					/* Make a jump to 'next' to print the CDR part */ | ||||
| 					obj = cur; | ||||
| 					goto next; | ||||
| 				} | ||||
|  | ||||
| 				/* The CDR part points to a pair. proceed to it */ | ||||
| 				OUTPUT_STR (scm, QSE_T(" ")); | ||||
| 					if (IS_SMALLINT(scm,p) || TYPE(p) != QSE_SCM_ENT_PAIR)  | ||||
| 					{ | ||||
| 						OUTPUT_STR (scm, QSE_T(". ")); | ||||
| 						 | ||||
| 						// push resume location | ||||
| 						// push .... | ||||
| 						if (push (scm, 1) <= -1) return -1; | ||||
| 						obj = p; | ||||
| 						goto retry; | ||||
| 						//qse_scm_print (scm, p); | ||||
| 			} | ||||
| 				} | ||||
| 			} | ||||
| 			while (!IS_NIL(scm,p) && !IS_SMALLINT(scm,p) && TYPE(p) == QSE_SCM_ENT_PAIR); | ||||
| 			if (prt_cons_par) OUTPUT_STR (scm, QSE_T(")")); | ||||
|  | ||||
| #if 0 | ||||
| 			do  | ||||
| 			{ | ||||
| 				qse_scm_print (scm, PAIR_CAR(p)); | ||||
| 				p = PAIR_CDR(p); | ||||
| 				if (!IS_NIL(scm,p)) | ||||
| 				{ | ||||
| 					OUTPUT_STR (scm, QSE_T(" ")); | ||||
| 					if (TYPE(p) != QSE_SCM_ENT_PAIR)  | ||||
| 					{ | ||||
| 						OUTPUT_STR (scm, QSE_T(". ")); | ||||
| 						qse_scm_print (scm, p); | ||||
| 					} | ||||
| 				} | ||||
| 			}  | ||||
| 			while (p != scm->nil && TYPE(p) == QSE_SCM_ENT_PAIR); | ||||
| 			if (prt_cons_par) OUTPUT_STR (scm, QSE_T(")")); | ||||
| #endif | ||||
|  | ||||
| 			while (1); | ||||
| 			OUTPUT_STR (scm, QSE_T(")")); | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| @ -262,13 +264,16 @@ retry: | ||||
| 		#endif | ||||
|  | ||||
| 		default: | ||||
| 			QSE_ASSERT (!"should never happen - unknown entity type"); | ||||
| 			QSE_ASSERTX ( | ||||
| 				0, | ||||
| 				"Unknown entity type - buggy!!" | ||||
| 			); | ||||
| 			qse_scm_seterror (scm, QSE_SCM_EINTERN, QSE_NULL, QSE_NULL); | ||||
| 			return -1; | ||||
| 	} | ||||
|  | ||||
| 	 | ||||
| 	/* if the print stack is not empty, we still got more to print */ | ||||
| done: | ||||
| 	/* if the printing stack is not empty, we still got more to print */ | ||||
| 	if (!IS_NIL(scm,scm->p.s)) goto resume;  | ||||
|  | ||||
| 	return 0; | ||||
| @ -276,10 +281,23 @@ retry: | ||||
|  | ||||
| int qse_scm_print (qse_scm_t* scm, const qse_scm_ent_t* obj) | ||||
| { | ||||
| 	int n; | ||||
|  | ||||
| 	QSE_ASSERTX ( | ||||
| 		scm->io.fns.out != QSE_NULL,  | ||||
| 		"Specify output function before calling qse_scm_print()" | ||||
| 	);	 | ||||
|  | ||||
| 	return print_entity (scm, obj, 1); | ||||
| 	n = print_entity (scm, obj); | ||||
|  | ||||
| 	/* clear the printing stack if an error has occurred for GC not to keep | ||||
| 	 * the entities in the stack */ | ||||
| 	if (n <= -1) scm->p.s = scm->nil; | ||||
|  | ||||
| 	QSE_ASSERTX ( | ||||
| 		IS_NIL(scm,scm->p.s), | ||||
| 		"The printing stack is not empty after printing - buggy!!" | ||||
| 	); | ||||
| 		 | ||||
| 	return n; | ||||
| } | ||||
|  | ||||
| @ -107,7 +107,7 @@ static int read_char (qse_scm_t* scm) | ||||
| 		else scm->r.curloc.colm++; | ||||
| 	} | ||||
|  | ||||
| qse_printf (QSE_T("[%c]\n"), scm->r.curc); | ||||
| /*qse_printf (QSE_T("[%c]\n"), scm->r.curc);*/ | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -157,14 +157,14 @@ static qse_scm_t* qse_scm_init ( | ||||
| { | ||||
| 	static qse_scm_ent_t static_values[3] = | ||||
| 	{ | ||||
| 		/* dswcount, mark, atom, type */ | ||||
| 		/* dswcount, mark, atom, synt, type */ | ||||
|  | ||||
| 		/* nil */ | ||||
| 		{ 0, 1, 1, QSE_SCM_ENT_NIL }, | ||||
| 		{ 0, 1, 1, 0, QSE_SCM_ENT_NIL }, | ||||
| 		/* f */ | ||||
| 		{ 0, 1, 1, QSE_SCM_ENT_T | QSE_SCM_ENT_BOOL },  | ||||
| 		{ 0, 1, 1, 0, QSE_SCM_ENT_T },  | ||||
| 		/* t */ | ||||
| 		{ 0, 1, 1, QSE_SCM_ENT_F | QSE_SCM_ENT_BOOL } | ||||
| 		{ 0, 1, 1, 0, QSE_SCM_ENT_F } | ||||
| 	}; | ||||
|  | ||||
| 	if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL(); | ||||
| @ -188,8 +188,8 @@ static qse_scm_t* qse_scm_init ( | ||||
|  | ||||
| 	/* initialize common values */ | ||||
| 	scm->nil    = &static_values[0]; | ||||
| 	scm->f      = &static_values[1]; | ||||
| 	scm->t      = &static_values[2]; | ||||
| 	scm->t      = &static_values[1]; | ||||
| 	scm->f      = &static_values[2]; | ||||
| 	scm->lambda = scm->nil; | ||||
| 	scm->quote  = scm->nil; | ||||
|  | ||||
|  | ||||
| @ -29,24 +29,22 @@ | ||||
| /* Note that not all these values can be ORed with each other. | ||||
|  * each value represents its own type except the following combinations. | ||||
|  * | ||||
|  *   QSE_SCM_ENT_T | QSE_SCM_ENT_BOOL | ||||
|  *   QSE_SCM_ENT_F | QSE_SCM_ENT_BOOL | ||||
|  *   QSE_SCM_ENT_SYM | QSE_SCM_ENT_SYNT | ||||
|  *   QSE_SCM_ENT_T | ||||
|  *   QSE_SCM_ENT_F | ||||
|  *   QSE_SCM_ENT_SYM  | ||||
|  */ | ||||
| enum qse_scm_ent_type_t | ||||
| { | ||||
| 	QSE_SCM_ENT_NIL     = (1 << 0), | ||||
| 	QSE_SCM_ENT_T       = (1 << 1), | ||||
| 	QSE_SCM_ENT_F       = (1 << 2), | ||||
| 	QSE_SCM_ENT_BOOL    = (1 << 3), | ||||
| 	QSE_SCM_ENT_NUM     = (1 << 4), | ||||
| 	QSE_SCM_ENT_REAL    = (1 << 5), | ||||
| 	QSE_SCM_ENT_STR     = (1 << 6),  | ||||
| 	QSE_SCM_ENT_NAM     = (1 << 7), | ||||
| 	QSE_SCM_ENT_SYM     = (1 << 8), | ||||
| 	QSE_SCM_ENT_PAIR    = (1 << 9), | ||||
| 	QSE_SCM_ENT_PROC    = (1 << 10), | ||||
| 	QSE_SCM_ENT_SYNT    = (1 << 11) | ||||
| 	QSE_SCM_ENT_NUM     = (1 << 3), | ||||
| 	QSE_SCM_ENT_REAL    = (1 << 4), | ||||
| 	QSE_SCM_ENT_STR     = (1 << 5),  | ||||
| 	QSE_SCM_ENT_NAM     = (1 << 6), | ||||
| 	QSE_SCM_ENT_SYM     = (1 << 7), | ||||
| 	QSE_SCM_ENT_PAIR    = (1 << 8), | ||||
| 	QSE_SCM_ENT_PROC    = (1 << 9) | ||||
|  | ||||
| }; | ||||
|  | ||||
| @ -66,7 +64,8 @@ struct qse_scm_ent_t | ||||
| 	qse_uint32_t dswcount: 2; | ||||
| 	qse_uint32_t mark:     1; | ||||
| 	qse_uint32_t atom:     1; | ||||
| 	qse_uint32_t type:     28; | ||||
| 	qse_uint32_t synt:     1; | ||||
| 	qse_uint32_t type:     27; | ||||
|  | ||||
| 	union | ||||
| 	{ | ||||
| @ -108,8 +107,10 @@ struct qse_scm_ent_t | ||||
|  | ||||
| #define DSWCOUNT(v)       ((v)->dswcount) | ||||
| #define MARK(v)           ((v)->mark) | ||||
| #define TYPE(v)           ((v)->type) | ||||
| #define ATOM(v)           ((v)->atom) | ||||
| #define SYNT(v)           ((v)->synt) | ||||
| #define TYPE(v)           ((v)->type) | ||||
|  | ||||
| #define NUM_VALUE(v)      ((v)->u.num.val) | ||||
| #define REAL_VALUE(v)     ((v)->u.real.val) | ||||
| #define STR_PTR(v)        ((v)->u.str.ptr) | ||||
| @ -118,10 +119,10 @@ struct qse_scm_ent_t | ||||
| #define LAB_CODE(v)       ((v)->u.lab.code) | ||||
| #define SYM_NAME(v)       ((v)->u.ref.ent[0]) | ||||
| #define SYM_PROP(v)       ((v)->u.ref.ent[1]) | ||||
| #define SYNT_CODE(v)      LAB_CODE(SYM_NAME(v)) | ||||
| #define PAIR_CAR(v)       ((v)->u.ref.ent[0]) | ||||
| #define PAIR_CDR(v)       ((v)->u.ref.ent[1]) | ||||
| #define PROC_CODE(v)      ((v)->u.proc.code) | ||||
| #define SYNT_CODE(v)      LAB_CODE(SYM_NAME(v)) | ||||
|  | ||||
| /** | ||||
|  * The qse_scm_enb_t type defines a value block. A value block is allocated | ||||
|  | ||||
		Reference in New Issue
	
	Block a user