/****************************************************************************** UNSW Prolog (version 4) Written by Claude Sammut Department of Computer Science University of New South Wales (and St. Joseph's U., Philadelphia) Copyright (c) 1983 - Claude Sammut ******************************************************************************/ /* Predicated to modify Prolog's behaviour */ #include "pred.h" #include static p_abort PREDICATE { extern jmp_buf env3; longjmp(env3, 1); } static p_halt PREDICATE { exit(); } static p_prompt PREDICATE { extern pval termb; extern atom *read_prompt, *prompt_string; if (unify(arg[0], frame[0], read_prompt, 0)) { if (isatom(arg[1])) { prompt_string = read_prompt = (atom *) arg[1]; return(TRUE); } else if (arg[0] == arg[1]) return(TRUE); fail("Prompt - second argument must be atom") } return(FALSE); } static trace PREDICATE { if (isatom(arg[0])) { arg[0] -> a.traced = TRUE; return(TRUE); } else fail("Cannot trace non-atom!") } static untrace PREDICATE { if (isatom(arg[0])) { arg[0] -> a.traced = FALSE; return(TRUE); } else fail("Tried to untrace non-atom") } static char *ops[] = {"xfx", "xfy", "yfx", "fx", "fy", "xf", "yf"}; static optype atopt(buff) char *buff; { register i; for (i = XFX; i <= YF; i++) if (strcmp(ops[i], buff) == 0) return(i); return(-1); } static insert_op(a, precedence, type) atom *a; short precedence; char type; { extern atom* hashtable[]; register atom *p, **q; /* new define must appear BEFORE existing definition in */ /* hash bucket. NONOP's must be last in chain. */ for (q = &(hashtable[hash(NAME(a))]); *q != a; q = &((*q) -> link)); p = (atom *) new(ATOM); p -> link = a; *q = p; p -> name = a -> name; p -> pred = precedence; p -> op_t = type; } static define_op PREDICATE { extern integer *stack_int; optype dtype; pval p; if (! isatom(arg[2])) fail("defop: 3rd argument must be atom") if (arg[2] -> a.op_t != NONOP) { p = (pval) intern(ATOM, ops[arg[2] -> a.op_t], strlen(ops[arg[2] -> a.op_t])); return(unify(arg[0], frame[0], stack_int, arg[2] -> a.pred) && unify(arg[1], frame[1], p, 0)); } if (! isinteger(arg[0]) || ! isatom(arg[1])) return(FALSE); if ((dtype = atopt(NAME(arg[1]))) == -1) fail("Defop - bad operator type") p = arg[2]; if (((dtype == FX || dtype == FY) && prefix(&p)) || ((dtype == XFX || dtype == XFY || dtype == YFX) && infix(&p)) || ((dtype == XF || dtype == YF) && postfix(&p))) { p -> a.op_t = INT_VAL(0); return(TRUE); } else insert_op(p, INT_VAL(0), dtype); return(TRUE); } static statistics PREDICATE { trace_stack(); return(TRUE); } do_time PREDICATE { extern int do_timing; do_timing = ! do_timing; } static dump PREDICATE { dump_stack(); dump_env(); } atom_table p_behave = { SET_PRED(NONOP, 0, 3, "defop", define_op), SET_PRED(FX, 700, 1, "spy", trace), SET_PRED(FX, 700, 1, "unspy", untrace), SET_PRED(NONOP, 0, 2, "prompt", p_prompt), SET_PRED(NONOP, 0, 0, "abort", p_abort), SET_PRED(NONOP, 0, 0, "halt", p_halt), SET_PRED(NONOP, 0, 0, "time", do_time), SET_PRED(NONOP, 0, 0, "dump", dump), SET_PRED(NONOP, 0, 0, "statistics", statistics), END_MARK };