ftp.nice.ch/pub/next/developer/languages/lisp/AKCL.1.599.s.tar.gz#/akcl-1-599/c/catch.c

This is catch.c in view mode; [Download] [Up]

/*
(c) Copyright Taiichi Yuasa and Masami Hagiya, 1984.  All rights reserved.
Copying of this file is authorized to users who have executed the true and
proper "License Agreement for Kyoto Common LISP" with SIGLISP.
*/

/*

	catch.c

	dynamic non-local exit
*/

#include "include.h"

Fcatch(args)
object args;
{
	object *top = vs_top;
	object tag;

	if (endp(args))
		FEtoo_few_argumentsF(args);
	eval(MMcar(args));
	vs_top = top;
	vs_push(vs_base[0]);
	frs_push(FRS_CATCH, vs_base[0]);
	if (nlj_active)
		nlj_active = FALSE;
	else
		Fprogn(MMcdr(args));
	frs_pop();
}

siLerror_set()
{
	object *old_base = vs_base;
	object *value_top;
	object *old_lex = lex_env;

	check_arg(1);
	vs_push(Cnil);
	frs_push(FRS_CATCHALL, Cnil);
	if (nlj_active) {
		nlj_active = FALSE;
		old_base[0] = nlj_tag;
		frs_pop();
		vs_base = old_base;
		vs_top = vs_base+1;
		lex_env = old_lex;
		return;
	} else {
		lex_env = vs_top;
		vs_push(Cnil);
		vs_push(Cnil);
		vs_push(Cnil);
		eval(vs_base[0]);
		old_base[0] = Cnil;
	}
	frs_pop();
	lex_env = old_lex;
	value_top = vs_top;
	vs_top = old_base + 1;
	while(vs_base<value_top) {
		vs_push(vs_base[0]);
		vs_base++;
	}
	vs_base = old_base;
}

Funwind_protect(args)
object args;
{
	object *top = vs_top;
	object *value_top;
	if (endp(args))
		FEtoo_few_argumentsF(args);
	frs_push(FRS_PROTECT, Cnil);
	if (nlj_active) {
		object tag = nlj_tag;
		frame_ptr fr = nlj_fr;
		object *base;

		value_top = vs_top;
		vs_top = top;
		while(vs_base<value_top) {
		 	vs_push(vs_base[0]);
			vs_base++;
		}
		value_top = vs_top;
		nlj_active = FALSE;
		frs_pop();
		Fprogn(MMcdr(args));
		vs_base = top;
		vs_top = value_top;
		if (vs_top == vs_base) vs_base[0] = Cnil;
		unwind(fr, tag);
		/* never reached */
	} else {
		eval(MMcar(args));
		frs_pop();
		value_top = vs_top;
		vs_top = top;
		while(vs_base<value_top) {
		 	vs_push(vs_base[0]);
			vs_base++;
		}
		value_top = vs_top;
		Fprogn(MMcdr(args));
		vs_base = top;
		vs_top = value_top;
		if (vs_top == vs_base) vs_base[0] = Cnil;
	}
}

Fthrow(args)
object args;
{
	object *top = vs_top;
	object tag;
	frame_ptr fr;
	if (endp(args) || endp(MMcdr(args)))
		FEtoo_few_argumentsF(args);
	if (!endp(MMcddr(args)))
		FEtoo_many_argumentsF(args);
	eval(MMcar(args));
	vs_top = top;
	tag = vs_base[0];
	vs_push(tag);
	fr = frs_sch_catch(tag);
	if (fr == NULL)
		FEerror("~S is an undefined tag.", 1, tag);
	eval(MMcadr(args));
	unwind(fr, tag);
	/* never reached */
}

init_catch()
{
	make_special_form("CATCH", Fcatch);
	make_si_function("ERROR-SET", siLerror_set);
	make_special_form("UNWIND-PROTECT", Funwind_protect);
	make_special_form("THROW", Fthrow);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.