/* =====> SERROR.C */ /* TIPC Scheme '84 Runtime Support - Error Processors (C) Copyright 1984,1985 by Texas Instruments Incorporated. All rights reserved. Author: John C. Jensen Installation: Texas Instruments Incorporated, Dallas, Texas Division: Central Research Laboratories Cost Center: Computer Science Laboratory Project: Computer Architecture Branch Date Written: 13 June 1984 Last Modification: (tc) 05 June 1986 - Set or Ref of Fluid variable which is not defined in fluid environment is now non- restartable from error processor or inspector. (rb) 21 Jan 1988 - getmem errors return to Scheme toplevel rather than aborting to DOS (tc) 16 Feb 1988 - added PRO_ERROR routine for protected mode */ #include "ctype.h" #include "scheme.h" #include "slist.h" static char digits[10]={'0','1','2','3','4','5','6','7','8','9'}; static char bdigits[10]={' ','1','2','3','4','5','6','7','8','9'}; /************************************************************************/ /* Wrong Number of Arguments to a Closure */ /************************************************************************/ #define NUM_ARGS 16 /* offset of operand count in a closure object */ wrong_args(args_passed, closure) int args_passed; /* number of arguments passed */ int closure[2]; /* pointer to called closure object */ { int args_expected; /* the number of arguments expected */ /*%%int i; /* our old friend the index variable */*/ int page,disp; /* page/displacement parts of closure pointer */ /*%%long *this_reg; /* pointer to a register during fixup */*/ /*%%long unbound; /* pointer to the symbol ***unbound*** */*/ static char *msg= "Invalid argument count: Function expected xx argument(s)\nbut was called with yy as follows:"; /* 11111111112222222222333333333344444444445555555 5556666666666777777777788888888889 012345678901234567890123456789012345678901234567890123456 7890123456789012345678901234567890 */ static int insert_offset = 77; /* offset in msg for arguments passed */ long make_ptr(); /* makes a Scheme pointer from page, disp */ ENTER(wrong_args); /* determine the number of arguments expected */ page = CORRPAGE(closure[C_PAGE]); disp = closure[C_DISP]; if (ptype[page] == CONTTYPE*2) { args_expected = 1; } else { args_expected = get_fix(SPECFIX, get_word(page, disp+NUM_ARGS)); if (args_expected < 0) args_expected = ~ args_expected; } /* Insert arguments expected into error message text */ msg[42] = bdigits[args_expected / 10]; msg[43] = digits[args_expected % 10]; /* set Scheme variables to reflect error condition */ arg_err(closure, args_passed, msg, insert_offset); /***** Argument "fixup" code turned off 25 July 1985 (JCJ) ***** /* if too few arguments, set undefined registers to "***unbound***" */ if (args_expected > args_passed) { unbound = make_ptr(UN_PAGE, UN_DISP); /* create ***unbound*** pointer */ this_reg = (®0)+args_expected; /* pointer to last undefined register */ while (args_expected > args_passed) { *this_reg = unbound; /* set register contents to ***unbound*** */ this_reg--; args_expected--; } /* end: while (args_expected > args_passed) */ } /* end: if (args_expected > args_passed) */ ***** Argument "fixup" code turned off 25 July 1985 (JCJ) *****/ } /* end of function: wrong_args(args_passed, closure) */ /************************************************************************/ /* Local Support-- Cons up "call" expression, output message text */ /************************************************************************/ arg_err(ftn, args_passed, msg, offset) int ftn[2]; /* function object */ int args_passed; /* the count of arguments passed */ char *msg; /* the error message text */ int offset; /* offset in "msg" for inserting argument count */ { int i; /* index variable */ long *this_reg; /* pointer to a register during "consing" */ /* insert count of arguments passed into the error message string */ msg[offset] = bdigits[args_passed / 10]; msg[offset+1] = digits[args_passed % 10]; /* cons up the function and arguments into a list */ this_reg = (®0)+args_passed; /* pointer to last argument register */ tmp_page = tmp_disp = 0; /* initialize end-of-list to nil */ for (i = 0; i < args_passed; i++, this_reg--) cons(tmp_reg, this_reg, tmp_reg); cons(tmp_reg, ftn, tmp_reg); /* put procedure object at front of list */ /* set up the error message text and irritant */ set_error(1, msg, tmp_reg); } /* end of function: arg_err(ftn, args_passed, msg, offset) */ /************************************************************************/ /* Error-- Attempted to call a non-procedural object */ /************************************************************************/ not_proc(non_ftn_obj, args_passed) int non_ftn_obj[2]; /* pointer to object in functional position */ int args_passed; /* the number of arguments in the call */ { static char *msg= "Attempt to call a non-procedural object with xx argument(s) as follows:"; /* 1111111111222222222233333333334444444444555555555566666666667 012345678901234567890123456789012345678901234567890123456 7890123456789 */ static int insert_offset = 45; /* offset in msg for argument count */ arg_err(non_ftn_obj, args_passed, msg, insert_offset); } /* end of function: not_proc(non_ftn_obj, args_passed) */ /************************************************************************/ /* Error-- Symbol Not Fluidly Bound */ /************************************************************************/ not_fluidly_bound(page,disp,source) int page; /* symbol's page number */ int disp; /* symbol's displacement */ int source[2]; /* register containing the value to be bound */ { /* create pointer to symbol and set up error parameters */ tmp_page = ADJPAGE(page); tmp_disp = disp; set_numeric_error(1, SET_FLUID_ERROR, tmp_reg); } /* end of function: not_fluidly_bound(page,disp,source) */ /************************************************************************/ /* Error-- Symbol Not Globally Bound */ /************************************************************************/ not_globally_bound(page,disp,source) int page; /* symbol's page number */ int disp; /* symbol's displacement */ int source[2]; /* register containing the value to be bound */ { /* create pointer to symbol and set up error parameters */ tmp_page = ADJPAGE(page); tmp_disp = disp; set_numeric_error(0, SET_GLOBAL_ERROR, tmp_reg); } /* end of function: not_globally_bound(page,disp,source) */ /************************************************************************/ /* Error-- Symbol Not Lexically Bound */ /************************************************************************/ not_lexically_bound(page, disp) int page; /* symbol's page number */ int disp; /* symbol's displacement */ { /* create pointer to symbol and set up error parameters */ tmp_page = ADJPAGE(page); tmp_disp = disp; set_numeric_error(0, SET_LEXICAL_ERROR, tmp_reg); } /* end of function: not_lexically_bound(page, disp) */ /************************************************************************/ /* Error-- Symbol Not Bound */ /************************************************************************/ sym_undefined(page,disp,env,dest) int page; /* symbol's page number */ int disp; /* symbol's displacement */ int env[2]; /* the environment supposed to contain said symbol */ int dest[2]; /* register into which the value was to be loaded */ { int error_number; /* numeric error code */ int error_restart; /* Can you resume from error? 0=yes,1=no */ error_restart = 0; /* Default to resumable */ if (env == GNV_reg) error_number = REF_GLOBAL_ERROR; else { if (env == FNV_reg) { error_number = REF_FLUID_ERROR; error_restart = 1; /* Can't continue from fluid error */ } else error_number = REF_LEXICAL_ERROR; } /* create pointer to undefined symbol and set message parameters */ tmp_page = ADJPAGE(page); tmp_disp = disp; set_numeric_error(error_restart, error_number, tmp_reg); } /* end of function: sym_undefined(page,disp,env,dest) */ /************************************************************************/ /* getmem error */ /************************************************************************/ getmem_error(routine) char *routine; { void rbrk(); void force_re(); printf("[VM INTERNAL ERROR] %s: getmem error\n", routine); printf("Press any key to return to Scheme toplevel.\n"); /*rb*/ getch(); rbrk(); /*rb*/ force_re(); /* we won't return */ /*rb*/ exit(); } /************************************************************************/ /* rlsmem error */ /************************************************************************/ rlsmem_error(routine) char *routine; { printf("[VM INTERNAL ERROR] %s: rlsmem error", routine); } /************************************************************************/ /* set error condition */ /************************************************************************/ set_error(code, message, irritant) int code; /* error condition code */ char *message; /* text of error condition */ int irritant[2]; /* object causing the error */ { /* bind error code to the symbol |*error-code*| */ C_push(tmp_reg); intern (tm2_reg, "*ERROR-CODE*", 12); tmp_page = SPECFIX*2; tmp_disp = code & 0x7fff; sym_bind(tm2_reg, tmp_reg, GNV_reg); /* bind error message text to the symbol |*error-message*| */ intern (tm2_reg, "*ERROR-MESSAGE*", 15); alloc_string(tmp_reg, message); sym_bind(tm2_reg, tmp_reg, GNV_reg); /* bind irritant to the symbol |*irritant*| */ C_pop(tmp_reg); intern (tm2_reg, "*IRRITANT*", 10); sym_bind(tm2_reg, irritant, GNV_reg); } /* end of function: set_error(code, message, irritant) */ /************************************************************************/ /* set numeric error condition */ /************************************************************************/ set_numeric_error(code, error_number, irritant) int code; /* error condition code */ int error_number; /* numeric error code for a given error condition */ int irritant[2]; /* object causing the error */ { int lcl_reg[2]; /* a temporary register for fixnum values */ /* bind error code to the symbol |*ERROR-CODE*| */ intern (tm2_reg, "*ERROR-CODE*", 12); lcl_reg[C_PAGE] = SPECFIX*2; lcl_reg[C_DISP] = code & 0x7fff; sym_bind(tm2_reg, lcl_reg, GNV_reg); /* bind error message text to the symbol |*ERROR-MESSAGE*| */ intern (tm2_reg, "*ERROR-MESSAGE*", 15); lcl_reg[C_DISP] = error_number; sym_bind(tm2_reg, lcl_reg, GNV_reg); /* bind irritant to the symbol |*IRRITANT*| */ intern (tm2_reg, "*IRRITANT*", 10); sym_bind(tm2_reg, irritant, GNV_reg); } /* end of function: set_numeric_error(code, error_number, irritant) */ /************************************************************************/ /* Process Invalid Source Operand Condition */ /************************************************************************/ set_src_err(op, args, arg1, arg2, arg3, arg4) char *op; /* name of instruction failing */ int args; /* number of arguments (operands) to instruction */ int arg1[2],arg2[2],arg3[2],arg4[2]; /* register argument(s) */ { int i; /* the usual index variable */ int *reg_ptr; /*%%int sym[2]; /* local "register" for symbol name */*/ mov_reg(tmp_reg, nil_reg); reg_ptr = (&arg1) + args - 1; for (i = 0; i < args; i++, reg_ptr--) cons(tmp_reg, *reg_ptr, tmp_reg); intern(tm2_reg, op, strlen(op)); cons(tmp_reg, tm2_reg, tmp_reg); set_numeric_error(1, INVALID_OPERAND_ERROR, tmp_reg); } /* end of function: set_src_err(op, args, arg1, arg2, arg3, arg4) */ #ifdef PROMEM /************************************************************************/ /* Process Protected Mode Error */ /************************************************************************/ pro_error(rtn,fnc,errnum) char *rtn,*fnc; int errnum; { char ch; printf("\nFatal Error during %s , performing %s - Error # %d", rtn,fnc,errnum); printf("\nPress any key for attempt to SCHEME-RESET"); ch = getch(); printf("\n[Returning to top level]\n"); force_reset(); } #endif