implemented defun as a shortcut to (set xxxx (lambda () ..))
This commit is contained in:
		| @ -759,29 +759,68 @@ static int compile_if (hcl_t* hcl, hcl_oop_t src) | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int compile_lambda (hcl_t* hcl, hcl_oop_t src) | static int compile_lambda (hcl_t* hcl, hcl_oop_t src, int defun) | ||||||
| { | { | ||||||
| 	hcl_oop_t obj, args; | 	hcl_oop_t obj, args; | ||||||
| 	hcl_oow_t nargs, ntmprs; | 	hcl_oow_t nargs, ntmprs; | ||||||
| 	hcl_ooi_t jump_inst_pos; | 	hcl_ooi_t jump_inst_pos; | ||||||
| 	hcl_oow_t saved_tv_count, tv_dup_start; | 	hcl_oow_t saved_tv_count, tv_dup_start; | ||||||
|  | 	hcl_oop_t defun_name; | ||||||
|  |  | ||||||
| 	HCL_ASSERT (hcl, HCL_IS_CONS(hcl, src)); | 	HCL_ASSERT (hcl, HCL_IS_CONS(hcl, src)); | ||||||
| 	HCL_ASSERT (hcl, HCL_CONS_CAR(src) == hcl->_lambda); |  | ||||||
|  |  | ||||||
| 	saved_tv_count = hcl->c->tv.size; | 	saved_tv_count = hcl->c->tv.size; | ||||||
| 	obj = HCL_CONS_CDR(src); | 	obj = HCL_CONS_CDR(src); | ||||||
|  |  | ||||||
|  | 	if (defun) | ||||||
|  | 	{ | ||||||
|  | 		HCL_ASSERT (hcl, HCL_CONS_CAR(src) == hcl->_defun); | ||||||
|  |  | ||||||
|  | 		if (HCL_IS_NIL(hcl, obj)) | ||||||
|  | 		{ | ||||||
|  | 			hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGNAMELIST, HCL_NULL, HCL_NULL, | ||||||
|  | 				"no defun name - %O", src); /* TODO: error location */ | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 		else if (!HCL_IS_CONS(hcl, obj)) | ||||||
|  | 		{ | ||||||
|  | 			hcl_setsynerrbfmt (hcl, HCL_SYNERR_DOTBANNED, HCL_NULL, HCL_NULL, | ||||||
|  | 				"redundant cdr in defun - %O", src); /* TODO: error location */ | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		defun_name = HCL_CONS_CAR(obj); | ||||||
|  | 		if (!HCL_IS_SYMBOL(hcl, defun_name)) | ||||||
|  | 		{ | ||||||
|  | 			hcl_setsynerrbfmt (hcl, HCL_SYNERR_VARNAME, HCL_NULL, HCL_NULL, | ||||||
|  | 				"defun name not a symbol - %O", defun_name); /* TODO: error location */ | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (HCL_OBJ_GET_FLAGS_SYNCODE(defun_name)) | ||||||
|  | 		{ | ||||||
|  | 			hcl_setsynerrbfmt (hcl, HCL_SYNERR_BANNEDVARNAME, HCL_NULL, HCL_NULL,  | ||||||
|  | 				"special symbol not to be used as a defun name - %O", defun_name); /* TOOD: error location */ | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		obj = HCL_CONS_CDR(obj); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		HCL_ASSERT (hcl, HCL_CONS_CAR(src) == hcl->_lambda); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (HCL_IS_NIL(hcl, obj)) | 	if (HCL_IS_NIL(hcl, obj)) | ||||||
| 	{ | 	{ | ||||||
| 		HCL_DEBUG1 (hcl, "Syntax error - no argument list in lambda - %O\n", src); | 		hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGNAMELIST, HCL_NULL, HCL_NULL, | ||||||
| 		hcl_setsynerr (hcl, HCL_SYNERR_ARGNAMELIST, HCL_NULL, HCL_NULL); /* TODO: error location */ | 			"no argument list in lambda - %O", src); /* TODO: error location */ | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 	else if (!HCL_IS_CONS(hcl, obj)) | 	else if (!HCL_IS_CONS(hcl, obj)) | ||||||
| 	{ | 	{ | ||||||
| 		HCL_DEBUG1 (hcl, "Syntax error - redundant cdr in lambda - %O\n", src); | 		hcl_setsynerrbfmt (hcl, HCL_SYNERR_DOTBANNED, HCL_NULL, HCL_NULL, | ||||||
| 		hcl_setsynerr (hcl, HCL_SYNERR_DOTBANNED, HCL_NULL, HCL_NULL); /* TODO: error location */ | 			"redundant cdr in lambda - %O", src); /* TODO: error location */ | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -797,8 +836,8 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src) | |||||||
|  |  | ||||||
| 		if (!HCL_IS_CONS(hcl, args)) | 		if (!HCL_IS_CONS(hcl, args)) | ||||||
| 		{ | 		{ | ||||||
| 			HCL_DEBUG1 (hcl, "Syntax error - not a lambda argument list - %O\n", args); | 			hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGNAMELIST, HCL_NULL, HCL_NULL,  | ||||||
| 			hcl_setsynerr (hcl, HCL_SYNERR_ARGNAMELIST, HCL_NULL, HCL_NULL); /* TODO: error location */ | 				"not a lambda argument list - %O", args); /* TODO: error location */ | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @ -930,6 +969,29 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src) | |||||||
| 	if (emit_single_param_instruction (hcl, HCL_CODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) return -1; | 	if (emit_single_param_instruction (hcl, HCL_CODE_JUMP_FORWARD_0, MAX_CODE_JUMP) <= -1) return -1; | ||||||
|  |  | ||||||
| 	SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT_LIST, obj); | 	SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT_LIST, obj); | ||||||
|  |  | ||||||
|  | 	if (defun) | ||||||
|  | 	{ | ||||||
|  | 		hcl_oow_t index; | ||||||
|  | 		hcl_cframe_t* cf; | ||||||
|  |  | ||||||
|  | 		if (find_temporary_variable_backward(hcl, defun_name, &index) <= -1) | ||||||
|  | 		{ | ||||||
|  | 			PUSH_SUBCFRAME (hcl, COP_EMIT_SET, defun_name); /* set doesn't evaluate the variable name */ | ||||||
|  | 			cf = GET_SUBCFRAME(hcl); | ||||||
|  | 			cf->u.set.var_type = VAR_NAMED; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			/* the check in compile_lambda() must ensure this condition */ | ||||||
|  | 			HCL_ASSERT (hcl, index <= HCL_SMOOI_MAX);  | ||||||
|  |  | ||||||
|  | 			PUSH_SUBCFRAME (hcl, COP_EMIT_SET, HCL_SMOOI_TO_OOP(index));  | ||||||
|  | 			cf = GET_SUBCFRAME(hcl); | ||||||
|  | 			cf->u.set.var_type = VAR_INDEXED; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	PUSH_SUBCFRAME (hcl, COP_EMIT_LAMBDA, HCL_SMOOI_TO_OOP(jump_inst_pos)); | 	PUSH_SUBCFRAME (hcl, COP_EMIT_LAMBDA, HCL_SMOOI_TO_OOP(jump_inst_pos)); | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -995,7 +1057,7 @@ static int compile_set (hcl_t* hcl, hcl_oop_t src) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var = HCL_CONS_CAR(obj); | 	var = HCL_CONS_CAR(obj); | ||||||
| 	if (HCL_BRANDOF(hcl, var) != HCL_BRAND_SYMBOL) | 	if (!HCL_IS_SYMBOL(hcl, var)) | ||||||
| 	{ | 	{ | ||||||
| 		hcl_setsynerrbfmt (hcl, HCL_SYNERR_VARNAME, HCL_NULL, HCL_NULL, "variable name not a symbol - %O", var); /* TODO: error location */ | 		hcl_setsynerrbfmt (hcl, HCL_SYNERR_VARNAME, HCL_NULL, HCL_NULL, "variable name not a symbol - %O", var); /* TODO: error location */ | ||||||
| 		return -1; | 		return -1; | ||||||
| @ -1207,8 +1269,7 @@ static int compile_cons_xlist_expression (hcl_t* hcl, hcl_oop_t obj) | |||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			case HCL_SYNCODE_DEFUN: | 			case HCL_SYNCODE_DEFUN: | ||||||
| HCL_DEBUG0 (hcl, "DEFUN NOT IMPLEMENTED...\n"); | 				if (compile_lambda(hcl, obj, 1) <= -1) return -1; | ||||||
| /* TODO: not implemented yet */ |  | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			case HCL_SYNCODE_DO: | 			case HCL_SYNCODE_DO: | ||||||
| @ -1230,7 +1291,7 @@ HCL_DEBUG0 (hcl, "DO NOT IMPLEMENTED...\n"); | |||||||
|  |  | ||||||
| 			case HCL_SYNCODE_LAMBDA: | 			case HCL_SYNCODE_LAMBDA: | ||||||
| 				/* (lambda (x y) (+ x y)) */ | 				/* (lambda (x y) (+ x y)) */ | ||||||
| 				if (compile_lambda(hcl, obj) <= -1) return -1; | 				if (compile_lambda(hcl, obj, 0) <= -1) return -1; | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			case HCL_SYNCODE_SET: | 			case HCL_SYNCODE_SET: | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user