From 4c0f2691e9da8633791e6425951d69c3ff2ed59c Mon Sep 17 00:00:00 2001 From: Landon Curt Noll Date: Wed, 13 Oct 1999 09:48:01 -0700 Subject: [PATCH] Release calc version 2.11.0t7 --- CHANGES | 101 ++++++++++++++++++++++++++++++++++++++++- Makefile | 4 +- addop.c | 5 ++ calc.c | 118 ++++++++++++++++++++++++++---------------------- calc.h | 4 +- codegen.c | 49 ++++++++++++++++---- config.h | 4 +- func.c | 48 ++++++++++++++------ lib/Makefile | 2 +- lib/README | 7 +++ lib/qtime.cal | 60 ++++++++++++++++++++++++ lib/regress.cal | 6 ++- lib_calc.c | 14 ++++-- opcodes.c | 55 +++++++++++----------- opcodes.h | 7 +-- value.h | 1 - version.c | 4 +- 17 files changed, 364 insertions(+), 125 deletions(-) create mode 100644 lib/qtime.cal diff --git a/CHANGES b/CHANGES index f0f1f9e..6d41f4f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,103 @@ -Following is the change from calc version 2.11.0t1 to date: +Following is the change from calc version 2.11.0t7 to date: + + Calc has some new command line flags / command line meaning: + (Thanks goes to Ernest Bowen ) + + -i Go into interactive mode if possible. + + -c Continue reading command lines even after an execution + error has caused the abandonment of a line + + To understand the -i and -c effects, consider the following + file (call it myfile.cal) which has deliberate errors in it: + + print 1; + mat A[1] = {2,3}; + print 2; + epsilon(-1); + print 3; + + calc read myfile + + Reports an error on the 2nd line and exits; prints 1 only. + + calc -c read myfile + + Report errors on the 2nd and 4th lines and exits; prints 1,2 and 3. + + calc -i read myfile + + Report errors on the 2nd and gives you a prompt; prints 1 only. + + calc -i -c read myfile + + Report errors on the 2nd and 4th and gives you a prompt; + prints 1, 2 and 3. + + cat myfile | calc + + Reports an error on the 2nd line and exits; prints 1 only. + + cat myfile | calc -c + + Report errors on the 2nd and 4th lines and exits; prints 1,2 and 3. + + Note that continuation refers to command lines, not to statements. So: + + calc -c 'print "start"; mat A[1] = {2,3}; print "end";' + + since it contains no newline, the whole string is compiled, + but execution is abandoned when the error is encountered and + the string ``end'' is not printed. + + You can use your shell to supply newlines in your command line + arguments. For example in sh, ksh, bash: + + calc -c 'print "start"; + mat A[1] = {2,3}; + print "end";' + + will print both ``start'' and ``end''. C-shell users can do: + + calc -c 'print "start"; \ + mat A[1] = {2,3}; \ + print "end";' + + however sh, ksh, bash will not see ``end'' printed because their + shell will remove the internal newlines. + + Added display(n) builtin which does almost the same as config("display",n) + except that rather than causing an execution with an out-of-range or + bad-type argument type, it simply writes a message to stderr. This + also now happens to the errmax() builtin. + + Added qtime.cal to the standard calc library. + + Added another command line flag to calc: + + -d Disable display of the opening title and config("lib_debug",0) + + The command: + + calc 'read qtime; qtime(2)' + + will output something like: + + qtime(utc_hr_offset) defined + It's nearly ten past six. + + whereas: + + calc -d 'read qtime; qtime(2)' + + will just say: + + It's nearly ten past six. + + A call of errmax(-1) will prevent errcount from aborting calc. + + +Following is the change from calc version 2.11.0t1 to 2.11.0t6.3: Removed the makefile symbol MAIN. Now forcing all functions to correctly be declared main. To satisfy some old broken compilers, a return 0; diff --git a/Makefile b/Makefile index bd3c680..33106ba 100644 --- a/Makefile +++ b/Makefile @@ -2259,11 +2259,11 @@ bsdilist: ${DISTLIST} ${BUILD_H_SRC} calc.1 ## check: all ./lib/regress.cal ${REGRESS_CAL} - ${CALC_ENV} ./calc -i -q read regress + ${CALC_ENV} ./calc -d -q read regress chk: ./lib/regress.cal ${REGRESS_CAL} ${V} echo '=-=-=-=-= start of $@ rule =-=-=-=-=' - ${CALC_ENV} ./calc -i -q read regress 2>&1 | ${AWK} -f check.awk + ${CALC_ENV} ./calc -d -q read regress 2>&1 | ${AWK} -f check.awk ${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-=' ## diff --git a/addop.c b/addop.c index abec25c..935e235 100644 --- a/addop.c +++ b/addop.c @@ -449,6 +449,11 @@ addop(long op) case OP_GLOBALADDR: diff = 1 + PTR_SIZE; break; + case OP_UNDEF: + fp->f_opcodecount -= 1; + oldop = OP_NOP; + oldoldop = OP_NOP; + return; default: cut = FALSE; } diff --git a/calc.c b/calc.c index 471fd7b..79df6cf 100644 --- a/calc.c +++ b/calc.c @@ -49,6 +49,7 @@ extern int isatty(int tty); /* TRUE if fd is a tty */ extern int p_flag; /* TRUE => pipe mode */ extern int q_flag; /* TRUE => don't execute rc files */ extern int u_flag; /* TRUE => unbuffer stdin and stdout */ +extern int d_flag; /* TRUE => disable heading, lib_debug == 0 */ extern char *pager; /* $PAGER or default */ extern int stdin_tty; /* TRUE if stdin is a tty */ @@ -63,9 +64,12 @@ extern char *version(void); /* return version string */ * static definitions and functions */ static char *usage = "usage: %s [-C] [-e] [-h] [-i] [-m mode] [-n] [-p]\n" - "\t[-q] [-u] [[--] calc_cmd ...]\n"; + "\t[-q] [-u] [-c] [-d] [[--] calc_cmd ...]\n"; static void intint(int arg); /* interrupt routine */ +static int havecommands; +static int c_flag; /* To permit continuation after error */ +static int i_flag; /* To go interactive if permitted */ /* * Top level calculator routine. @@ -84,7 +88,7 @@ main(int argc, char **argv) * parse args */ program = argv[0]; - while ((c = getopt(argc, argv, "Cehim:npquv")) != -1) { + while ((c = getopt(argc, argv, "Cehim:npquvcd")) != -1) { switch (c) { case 'C': #if defined(CUSTOM) @@ -107,7 +111,7 @@ main(int argc, char **argv) want_defhelp = 1; break; case 'i': - ign_errmax = TRUE; + i_flag = TRUE; break; case 'm': if (optarg[1] == '\0' || *optarg<'0' || *optarg>'7') { @@ -136,6 +140,12 @@ main(int argc, char **argv) case 'u': u_flag = TRUE; break; + case 'c': + c_flag = TRUE; + break; + case 'd': + d_flag = TRUE; + break; case 'v': /* * we are too early in processing to call @@ -153,6 +163,7 @@ main(int argc, char **argv) } } interactive = (optind >= argc); + havecommands = !interactive; /* * look at the length of any trailing command args @@ -201,8 +212,7 @@ main(int argc, char **argv) * initialize */ libcalc_call_me_first(); - stdin_tty = TRUE; /* assume internactive default */ - conf->tab_ok = TRUE; /* assume internactive default */ + stdin_tty = isatty(0); /* assume stdin is on fd 0 */ if (want_defhelp) { givehelp(DEFAULTCALCHELP); libcalc_call_me_last(); @@ -212,22 +222,13 @@ main(int argc, char **argv) /* * if allowed or needed, print version and setup bindings */ - if (interactive) { - /* - * check for pipe mode and/or non-tty stdin - */ - if (!p_flag) { - stdin_tty = isatty(0); /* assume stdin is on fd 0 */ - } - - /* - * if tty, setup bindings - */ - if (stdin_tty) { + if (!havecommands && stdin_tty) { + if (!d_flag) { printf("%s (version %s)\n", CALC_TITLE, version()); printf("[%s]\n\n", "Type \"exit\" to exit, or \"help\" for help."); - switch (hist_init(calcbindings)) { + } + switch (hist_init(calcbindings)) { case HIST_NOFILE: fprintf(stderr, "%s: Cannot open bindings file \"%s\", " @@ -240,7 +241,6 @@ main(int argc, char **argv) "%s: Cannot set terminal modes, " "fancy editing disabled\n", program); break; - } } } @@ -252,53 +252,65 @@ main(int argc, char **argv) /* * reset/initialize the computing environment */ - if (post_init) { + if (post_init) initialize(); - } else { - /* initialize already done, jmpbuf is ready */ - post_init = TRUE; - } + post_init = TRUE; + } - /* - * if arg mode or non-tty mode, just do the work and be gone - */ - if (!interactive || !stdin_tty) { - if (q_flag == FALSE && allow_read) { - runrcfiles(); - q_flag = TRUE; - } - if (interactive) - (void) openterminal(); - else - (void) openstring(cmdbuf); - start_done = TRUE; + (void) signal(SIGINT, intint); + + if (start_done == 0) { + if (!q_flag && allow_read) { + start_done = 1; + runrcfiles(); + } + start_done = 2; + } + if (start_done == 1) { + fprintf(stderr, "Execution error in rcfiles\n"); + if (c_flag) + getcommands(FALSE); + start_done = 2; + } + if (start_done == 2) { + if (havecommands) { + start_done = 3; + (void) openstring(cmdbuf); getcommands(FALSE); - libcalc_call_me_last(); - exit(0); } + start_done = 4; } - /* if in arg mode, we should not get here */ - if (!interactive) { - libcalc_call_me_last(); - exit(1); + if (start_done == 3) { + fprintf(stderr, "Execution error in commands\n"); + if (c_flag) + getcommands(FALSE); + else + closeinput(); + start_done = 4; } - - /* - * process commands - */ - if (!start_done) { + if (start_done == 4) { + if (stdin_tty && ((havecommands && !i_flag) || p_flag)) + start_done = 6; + else + openterminal(); + } + else if (start_done == 5) { + if (!stdin_tty && !c_flag) { + start_done = 6; + } reinitialize(); } - (void) signal(SIGINT, intint); - start_done = TRUE; - getcommands(TRUE); + + if (start_done < 6) { + start_done = 5; + getcommands(TRUE); + } /* * all done */ libcalc_call_me_last(); - /* exit(0); */ - return 0; + return (start_done - 6) ? 1 : 0; } diff --git a/calc.h b/calc.h index 23c81dc..a7474be 100644 --- a/calc.h +++ b/calc.h @@ -58,6 +58,8 @@ #define ABORT_MATH 3 /* abort on any math operation */ #define ABORT_NOW 4 /* abort right away */ +#define ERRMAX 20 /* default errmax value */ + /* * File ids corresponding to standard in, out, error, and when not in use. */ @@ -163,7 +165,7 @@ extern char *shell; /* $SHELL or default */ extern char *program; /* our name (argv[0]) */ extern int no_env; /* TRUE (-e) => ignore env vars on startup */ -extern int ign_errmax; /* TRUE (-i) => ignore when errcount exceeds errmax */ +extern int errmax; /* if >= 0, error when errcount exceeds errmax */ extern int new_std; /* TRUE (-n) => use newstd configuration */ extern int allow_read; /* FALSE => may not open any files for reading */ diff --git a/codegen.c b/codegen.c index dc8a913..2aa52f1 100644 --- a/codegen.c +++ b/codegen.c @@ -261,6 +261,8 @@ getfunction(void) { char *name; /* parameter name */ int type; /* type of token read */ + LABEL label; + long index; (void) tokenmode(TM_DEFAULT); if (gettoken() != T_SYMBOL) { @@ -276,9 +278,11 @@ getfunction(void) beginfunc(name, FALSE); enterfuncscope(); if (gettoken() != T_LEFTPAREN) { - scanerror(T_SEMICOLON, "Left parenthesis expected for function"); + scanerror(T_SEMICOLON, + "Left parenthesis expected for function"); return; } + index = 0; for (;;) { type = gettoken(); if (type == T_RIGHTPAREN) @@ -292,12 +296,22 @@ getfunction(void) case SYM_UNDEFINED: case SYM_GLOBAL: case SYM_STATIC: - (void) addparam(name); + index = addparam(name); break; default: scanerror(T_NULL, "Parameter \"%s\" is already defined", name); } type = gettoken(); + if (type == T_ASSIGN) { + clearlabel(&label); + addopone(OP_PARAMADDR, index); + addoplabel(OP_JUMPNN, &label); + getopassignment(); + addop(OP_ASSIGNPOP); + setlabel(&label); + type = gettoken(); + } + if (type == T_RIGHTPAREN) break; if (type != T_COMMA) { @@ -598,25 +612,25 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d scanerror(T_SEMICOLON, "CONTINUE not within FOR, WHILE, or DO"); return; } - addoplabel(OP_JUMPNE, contlabel); + addoplabel(OP_JUMPNZ, contlabel); break; case T_BREAK: if (breaklabel == NULL_LABEL) { scanerror(T_SEMICOLON, "BREAK not within FOR, WHILE, or DO"); return; } - addoplabel(OP_JUMPNE, breaklabel); + addoplabel(OP_JUMPNZ, breaklabel); break; case T_GOTO: if (gettoken() != T_SYMBOL) { scanerror(T_SEMICOLON, "Missing label in goto"); return; } - addop(OP_JUMPNE); + addop(OP_JUMPNZ); addlabel(tokensymbol()); break; default: - addoplabel(OP_JUMPEQ, &label1); + addoplabel(OP_JUMPZ, &label1); rescantoken(); getstatement(contlabel, breaklabel, NULL_LABEL, NULL_LABEL); if (gettoken() != T_ELSE) { @@ -667,7 +681,7 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d contlabel = &label1; rescantoken(); (void) getexprlist(); - addoplabel(OP_JUMPNE, &label3); + addoplabel(OP_JUMPNZ, &label3); addoplabel(OP_JUMP, breaklabel); if (gettoken() != T_SEMICOLON) { (void) tokenmode(oldmode); @@ -708,7 +722,7 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d clearlabel(breaklabel); setlabel(contlabel); getcondition(); - addoplabel(OP_JUMPEQ, breaklabel); + addoplabel(OP_JUMPZ, breaklabel); getstatement(contlabel, breaklabel, NULL_LABEL, NULL_LABEL); addoplabel(OP_JUMP, contlabel); setlabel(breaklabel); @@ -731,7 +745,7 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d } setlabel(contlabel); getcondition(); - addoplabel(OP_JUMPNE, &label3); + addoplabel(OP_JUMPNZ, &label3); setlabel(breaklabel); (void) tokenmode(oldmode); return; @@ -1377,6 +1391,21 @@ getassignment (void) { int type; /* type of expression */ + switch(gettoken()) { + case T_COMMA: + case T_SEMICOLON: + case T_NEWLINE: + case T_RIGHTPAREN: + case T_RIGHTBRACKET: + case T_RIGHTBRACE: + case T_EOF: + addop(OP_UNDEF); + rescantoken(); + return EXPR_RVALUE; + } + + rescantoken(); + type = getaltcond(); switch (gettoken()) { @@ -1441,7 +1470,7 @@ getaltcond(void) } clearlabel(&donelab); clearlabel(&altlab); - addoplabel(OP_JUMPEQ, &altlab); + addoplabel(OP_JUMPZ, &altlab); type = getaltcond(); if (gettoken() != T_COLON) { scanerror(T_SEMICOLON, "Missing colon for conditional expression"); diff --git a/config.h b/config.h index 920e940..09270df 100644 --- a/config.h +++ b/config.h @@ -85,7 +85,7 @@ /* - * config defult symbols + * config default symbols */ #define DISPLAY_DEFAULT 20 /* default digits for float display */ #define EPSILON_DEFAULT "1e-20" /* allowed error for float calculations */ @@ -95,8 +95,6 @@ #define MAXPRINT_DEFAULT 16 /* default number of elements printed */ #define MAXSCANCOUNT 20 /* default max scan errors before an abort */ -#define ERRMAX 20 /* default errmax value */ - /* * configuration object diff --git a/func.c b/func.c index a7b8f5c..b309fac 100644 --- a/func.c +++ b/func.c @@ -209,6 +209,28 @@ f_prompt(VALUE *vp) } +static VALUE +f_display(int count, VALUE **vals) +{ + long oldvalue; + VALUE res; + + oldvalue = conf->outdigits; + + if (count > 0) { + if (vals[0]->v_type != V_NUM || qisfrac(vals[0]->v_num) || + qisneg(vals[0]->v_num) || zge31b(vals[0]->v_num->num)) + fprintf(stderr, + "Out-of-range arg for display ignored\n"); + else + conf->outdigits = qtoi(vals[0]->v_num); + } + res.v_type = V_NUM; + res.v_num = itoq(oldvalue); + return res; +} + + /*ARGSUSED*/ static VALUE f_null(int count, VALUE **vals) @@ -4392,11 +4414,7 @@ f_errno(int count, VALUE **vals) math_error("errno argument out of range"); /*NOTREACHED*/ } - newerr = z1tol(vp->v_num->num); - if (newerr >= 32768) { - math_error("errno argument out of range"); - /*NOTREACHED*/ - } + newerr = (int) ztoi(vp->v_num->num); } olderr = set_errno(newerr); @@ -4423,7 +4441,7 @@ f_errcount(int count, VALUE **vals) math_error("errcount argument out of range"); /*NOTREACHED*/ } - newcount = z1tol(vp->v_num->num); + newcount = (int) ztoi(vp->v_num->num); } oldcount = set_errcount(newcount); @@ -4436,23 +4454,21 @@ f_errcount(int count, VALUE **vals) static VALUE f_errmax(int count, VALUE **vals) { - int newmax, oldmax; + int oldmax; VALUE *vp; VALUE result; - newmax = -1; + oldmax = errmax; if (count > 0) { vp = vals[0]; - /* arg must be an integer */ if (vp->v_type != V_NUM || qisfrac(vp->v_num) || - qisneg(vp->v_num) || zge31b(vp->v_num->num)) { - math_error("errcount argument out of range"); - /*NOTREACHED*/ - } - newmax = z1tol(vp->v_num->num); + zge31b(vp->v_num->num)) + fprintf(stderr, + "Out-of-range arg for errmax ignored\n"); + else + errmax = (int) ztoi(vp->v_num->num); } - oldmax = set_errmax(newmax); result.v_type = V_NUM; result.v_num = itoq((long) oldmax); @@ -6806,6 +6822,8 @@ static CONST struct builtin builtins[] = { "digit at specified decimal place of number"}, {"digits", 1, 1, 0, OP_NOP, f_digits, 0, "number of digits in number"}, + {"display", 0, 1, 0, OP_NOP, 0, f_display, + "number of decimal digits for displaying numbers"}, {"dp", 2, 2, 0, OP_NOP, 0, f_dp, "dot product of two vectors"}, {"epsilon", 0, 1, 0, OP_SETEPSILON, 0, 0, diff --git a/lib/Makefile b/lib/Makefile index a71eda2..14a9f66 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -44,7 +44,7 @@ CALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.cal \ test2700.cal test3100.cal test3300.cal test3400.cal prompt.cal \ test3500.cal seedrandom.cal test4000.cal test4100.cal test4600.cal \ beer.cal hello.cal test5100.cal test5200.cal randombitrun.cal \ - randomrun.cal xx_print.cal natnumset.cal + randomrun.cal xx_print.cal natnumset.cal qtime.cal # These files are found (but not built) in the distribution # diff --git a/lib/README b/lib/README index 843a0d4..20e5e5a 100644 --- a/lib/README +++ b/lib/README @@ -311,6 +311,13 @@ psqrt.cal Calculate square roots modulo a prime +qtime.cal + + qtime(utc_hr_offset) + + Print the time as English sentence given the hours offset from UTC. + + quat.cal quat(a, b, c, d) diff --git a/lib/qtime.cal b/lib/qtime.cal new file mode 100644 index 0000000..676b4a0 --- /dev/null +++ b/lib/qtime.cal @@ -0,0 +1,60 @@ +/* + * qtime - Display time as English sentence + * + * usage: + * qtime(utc_hr_offset) + * + * utc_hr_offset Offset from UTC in hours. + * + * Written by: Klaus Alexander Seistrup + * With minor mods by: Landon Curt Noll + * + * See: + * http://www.magnetic-ink.dk/download/qtime.html + * + * for examples of qtime() written on other languages. + */ + +/* + * qtime - Display time as English sentence + */ +define qtime(utc_hr_offset) +{ + static mat hr[12] = { + "twelve", "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "ten", "eleven" + }; + static mat mn[7] = { + "", "five ", "ten ", "a quarter ", "twenty ", "twenty-five ", "half " + }; + static mat ny[5] = { + "nearly ", "almost ", "", "just after ", "after " + }; + static mat up[3] = { + "to ", "", "past " + }; + local adj_mins = (((time() + utc_hr_offset*3600) % 86400) + 30) // 60 + 27; + local hours = (adj_mins // 60) % 12; + local minutes = adj_mins % 60; + local almost = minutes % 5; + local divisions = (minutes // 5) - 5; + local to_past_idx = divisions > 0 ? 1 : 0; + + if (divisions < 0) { + divisions = -divisions; + to_past_idx = -1; + } + ++to_past_idx; + + /* + * Print the English sentence + * + * We avoid forward and back quotes just to show that the char() + * builtin function can be used in conjunction with a printf. + */ + printf("It%cs %s%s%s%s", + char(0x27), ny[almost], mn[divisions], up[to_past_idx], hr[hours]); + if (divisions == 0) + printf(" o%cclock", char(0x27)); + printf (".\n"); +} diff --git a/lib/regress.cal b/lib/regress.cal index 019fa9e..9c11ac7 100644 --- a/lib/regress.cal +++ b/lib/regress.cal @@ -22,7 +22,7 @@ prob = 0; /* clear problem counter */ global junk; /* throw away value */ junk = errcount(0); /* clear error count */ -junk = errmax(0x7fffffff); /* set maximum error very high */ +junk = errmax(-1); /* prevent errcount from abouting */ global ecnt; /* expected value of errcount() */ ecnt = 0; /* clear expected errcount() value */ @@ -7468,7 +7468,9 @@ read -once unitfrac; print '9826: read -once unitfrac'; read -once varargs; print '9827: read -once varargs'; -print '9828: Ending read of selected calc libs'; +read -once qtime; +print '9828: read -once qtime'; +print '9829: Ending read of selected calc libs'; /* diff --git a/lib_calc.c b/lib_calc.c index fe95d1a..afdba64 100644 --- a/lib_calc.c +++ b/lib_calc.c @@ -82,6 +82,7 @@ int allow_exec = TRUE; /* FALSE => may not execute any commands */ int p_flag = FALSE; /* TRUE => pipe mode */ int q_flag = FALSE; /* TRUE => don't execute rc files */ int u_flag = FALSE; /* TRUE => unbuffer stdin and stdout */ +int d_flag = FALSE; /* TRUE => disable heading, lib_debug == 0 */ /* @@ -98,7 +99,7 @@ int interactive = FALSE; /* TRUE if interactive session (no cmd args) */ int post_init = FALSE; /* TRUE setjmp for math_error is readready */ int no_env = FALSE; /* TRUE (-e) => ignore env vars on startup */ -int ign_errmax = FALSE; /* TRUE (-i) => ignore when errcount exceeds errmax */ +int errmax = ERRMAX; /* if >= 0, maximum value for errcount */ NUMBER *epsilon_default; /* default allowed error for float calcs */ @@ -155,6 +156,13 @@ libcalc_call_me_first(void) conf = config_copy(&oldstd); } + /* + * -d turns off lib_debug + */ + if (d_flag) { + conf->lib_debug = 0; + } + /* * initialize */ @@ -229,10 +237,6 @@ reinitialize(void) math_setfp(stdout); resetscopes(); resetinput(); - if (q_flag == FALSE && allow_read) { - q_flag = TRUE; - runrcfiles(); - } (void) openterminal(); } diff --git a/opcodes.c b/opcodes.c index bb79252..d6bc87e 100644 --- a/opcodes.c +++ b/opcodes.c @@ -32,7 +32,6 @@ static VALUE oldvalue; /* previous calculation value */ static BOOL saveval = TRUE; /* to enable or disable saving */ static int calc_errno; /* most recent error-number */ static int errcount; /* counts calls to error_value */ -static int errmax = ERRMAX; /* maximum for errcount without abort */ static BOOL go; /* @@ -2467,7 +2466,7 @@ o_return(void) /*ARGSUSED*/ static void -o_jumpeq(FUNC *fp, BOOL *dojump) +o_jumpz(FUNC *fp, BOOL *dojump) { VALUE *vp; int i; /* result of comparison */ @@ -2491,7 +2490,7 @@ o_jumpeq(FUNC *fp, BOOL *dojump) /*ARGSUSED*/ static void -o_jumpne(FUNC *fp, BOOL *dojump) +o_jumpnz(FUNC *fp, BOOL *dojump) { VALUE *vp; int i; /* result of comparison */ @@ -2513,6 +2512,20 @@ o_jumpne(FUNC *fp, BOOL *dojump) } +/* + * jumpnn invokes a jump if top value points to a null value + */ +/*ARGSUSED*/ +static void +o_jumpnn(FUNC *fp, BOOL *dojump) +{ + if (stack->v_addr->v_type) { + *dojump = TRUE; + stack--; + } +} + + /*ARGSUSED*/ static void o_condorjump(FUNC *fp, BOOL *dojump) @@ -3111,7 +3124,8 @@ o_quit(FUNC *fp, long index) s = findstring(index); cp = s->s_str; } - if ((fp->f_name[0] == '*') && (fp->f_name[1] == '\0')) { + if (inputisterminal() && (fp->f_name[0] == '*') + && (fp->f_name[1] == '\0')) { if (cp) printf("%s\n", cp); hist_term(); @@ -3126,6 +3140,8 @@ o_quit(FUNC *fp, long index) printf("%s\n", cp); else printf("Quit statement executed\n"); + if (!inputisterminal() && fp->f_name[0] == '*') + closeinput(); go = FALSE; } @@ -3243,7 +3259,7 @@ error_value(int e) calc_errno = e; if (e > 0) errcount++; - if (errcount > errmax && !ign_errmax) { + if (errmax >= 0 && errcount > errmax) { math_error("Error %d caused errcount to exceed errmax", e); /*NOTREACHED*/ } @@ -3281,21 +3297,6 @@ set_errcount(int e) } -/* - * set_errno - return and set errno - */ -int -set_errmax(int e) -{ - int res; - - res = errmax; - if (e >= 0) - errmax = e; - return res; -} - - /* * Fill a newly created matrix at v1 with copies of value at v2. */ @@ -3427,8 +3428,8 @@ static struct opcode opcodes[MAX_OPCODE+1] = { {o_duplicate, OPNUL, "DUPLICATE"}, /* duplicate top value */ {o_pop, OPNUL, "POP"}, /* pop top value */ {o_return, OPRET, "RETURN"}, /* return value of function */ - {o_jumpeq, OPJMP, "JUMPEQ"}, /* jump if value zero */ - {o_jumpne, OPJMP, "JUMPNE"}, /* jump if value nonzero */ + {o_jumpz, OPJMP, "JUMPZ"}, /* jump if value zero */ + {o_jumpnz, OPJMP, "JUMPNZ"}, /* jump if value nonzero */ {o_jump, OPJMP, "JUMP"}, /* jump unconditionally */ {o_usercall, OPTWO, "USERCALL"}, /* call a user function */ {o_getvalue, OPNUL, "GETVALUE"}, /* convert address to value */ @@ -3531,7 +3532,8 @@ static struct opcode opcodes[MAX_OPCODE+1] = { {o_hashop, OPNUL, "HASHOP"}, /* binary hash op */ {o_backslash, OPNUL, "BACKSLASH"}, /* unary backslash op */ {o_setminus, OPNUL, "SETMINUS"}, /* binary backslash op */ - {o_plus, OPNUL, "PLUS"} /* unary + op */ + {o_plus, OPNUL, "PLUS"}, /* unary + op */ + {o_jumpnn, OPJMP, "JUMPNN"} /* jump if non-null */ }; @@ -3695,7 +3697,8 @@ calculate(FUNC *fp, int argcount) freevalue(&locals[i]); if (locals != localtable) free(locals); - printf("\t\"%s\": line %ld\n", funcname, funcline); + if (conf->calc_debug & 2) + printf("\t\"%s\": line %ld\n", funcname, funcline); while (stack > beginstack) freevalue(stack--); funcname = oldname; @@ -3751,11 +3754,11 @@ dumpop(unsigned long *pc) case OP_INDEXADDR: printf(" %ld %ld\n", pc[0], pc[1]); return 3; - case OP_PRINT: case OP_JUMPEQ: case OP_JUMPNE: case OP_JUMP: + case OP_PRINT: case OP_JUMPZ: case OP_JUMPNZ: case OP_JUMP: case OP_CONDORJUMP: case OP_CONDANDJUMP: case OP_CASEJUMP: case OP_INITSTATIC: case OP_MATCREATE: case OP_OBJCREATE: case OP_SHOW: case OP_ELEMINIT: case OP_ELEMADDR: - case OP_ELEMVALUE: + case OP_ELEMVALUE: case OP_JUMPNN: printf(" %ld\n", *pc); return 2; case OP_NUMBER: case OP_IMAGINARY: diff --git a/opcodes.h b/opcodes.h index a0229dc..ddafcb9 100644 --- a/opcodes.h +++ b/opcodes.h @@ -38,8 +38,8 @@ #define OP_DUPLICATE 23L /* duplicate top value on stack */ #define OP_POP 24L /* pop top value from stack */ #define OP_RETURN 25L /* return value of function */ -#define OP_JUMPEQ 26L /* jump if top value is zero */ -#define OP_JUMPNE 27L /* jump if top value is nonzero */ +#define OP_JUMPZ 26L /* jump if top value is zero */ +#define OP_JUMPNZ 27L /* jump if top value is nonzero */ #define OP_JUMP 28L /* jump unconditionally */ #define OP_USERCALL 29L /* call a user-defined function */ #define OP_GETVALUE 30L /* convert address to value */ @@ -143,7 +143,8 @@ #define OP_BACKSLASH 128L /* unary backslash */ #define OP_SETMINUS 129L /* binary backslash */ #define OP_PLUS 130L /* unary + */ -#define MAX_OPCODE 130L /* highest legal opcode */ +#define OP_JUMPNN 131L /* jump if top value is non-null */ +#define MAX_OPCODE 131L /* highest legal opcode */ /* diff --git a/value.h b/value.h index a050a0d..8bbd7c0 100644 --- a/value.h +++ b/value.h @@ -213,7 +213,6 @@ extern BOOL precvalue(VALUE *v1, VALUE *v2); extern VALUE error_value(int e); extern int set_errno(int e); extern int set_errcount(int e); -extern int set_errmax(int e); extern long countlistitems(LIST *lp); extern void addlistitems(LIST *lp, VALUE *vres); extern void addlistinv(LIST *lp, VALUE *vres); diff --git a/version.c b/version.c index 8764827..2657d4a 100644 --- a/version.c +++ b/version.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 David I. Bell + * Copyright (c) 1999 David I. Bell * Permission is granted to use, distribute, or modify this source, * provided that this copyright notice remains intact. * @@ -12,7 +12,7 @@ #define MAJOR_VER 2 /* major version */ #define MINOR_VER 11 /* minor version */ #define MAJOR_PATCH 0 /* patch level or 0 if no patch */ -#define MINOR_PATCH "6.3" /* test number or empty string if no patch */ +#define MINOR_PATCH "7" /* test number or empty string if no patch */ /* * calc version constants