#include #include #include "ss.h" #include "parse.h" /*** turning token values into function names and pointers ***/ Func *func[MAX_TOKEN]; void print_func( void) { int i; fprintf( out, "Functions: index, pointer, name, #retvals, #args, description\n"); for( i = 0; i < MAX_TOKEN; ++i) if( func[i]->type) fprintf( out, "%3d 0x%x %-8s %2d %2d %s\n", i, *(&func[i]->nargs+1), func[i]->name, func[i]->rcount, func[i]->nargs, func[i]->desc); /* *(&func[i]->nargs+1) should be func[i]->f, which can't be directly cast for printing without compile warning */ } struct flist { int val; Func F; /* rcound and nargs are ignored if < 0 */ }; #if 0 static struct flist hidden_fnames_list[] = /* these don't show up in the help display */ { { 0, { 0, 0, 0, 0, 0, 0 }} }; #endif static struct flist fnames_list[] = { /* operator functions, in decreasing order of precedence */ { '(', { "()", SS_OP, -1,-1, bad_func, "parentheses, (expr)" }}, /* "()" and UPLUS are here just for the help display, there are no run-time functions for them */ { X_PP, { "++", SS_OP, -1,-1, op_pp_mm, "postfix increment, x++" }}, { X_MM, { "--", SS_OP, -1,-1, op_pp_mm, "postfix decrement, x--" }}, { PP_X, { "++", SS_OP, -1,-1, op_pp_mm, "prefix increment, ++x" }}, { MM_X, { "--", SS_OP, -1,-1, op_pp_mm, "prefix decrement, --x" }}, { UMINUS, { "-", SS_OP, -1,-1, op_uminus, "unary minus"}}, { UPLUS, { "+", SS_OP, -1,-1, bad_func, "unary plus"}}, { '~', { "~", SS_OP, -1,-1, op_bit_not, "bitwise NOT" }}, { NOT_OP, { "!", SS_OP, -1,-1, op_not, "logical NOT" }}, { NOT, { "NOT", SS_OP|SS_WORD, -1,-1, op_not, "logical NOT" }}, { CAST_INT, { "(int)", SS_OP, -1,-1, op_cast_int, "cast" }}, { CAST_LONG, { "(long)", SS_OP, -1,-1, op_cast_long, "cast" }}, { CAST_DOUBLE, { "(double)", SS_OP, -1,-1, op_cast_double, "cast" }}, { POW_OP, { "**", SS_OP, -1,-1, op_pow, "exponentiation, x**y == pow(x,y)" }}, { '*', { "*", SS_OP, -1,-1, op_mul, "multiplication" }}, { '/', { "/", SS_OP, -1,-1, op_div, "division" }}, { '%', { "%", SS_OP, -1,-1, op_mod, "mod, x%y == fmod(x,y)" }}, { '+', { "+", SS_OP, -1,-1, op_add, "addition" }}, { '-', { "-", SS_OP, -1,-1, op_sub, "subtraction" }}, { SHL, { "<<", SS_OP, -1,-1, op_shl, "shift left, x<>", SS_OP, -1,-1, op_shr, "shift right, x>>y == x/2**y" }}, { LT, { "<", SS_OP, -1,-1, op_lt, "less than" }}, { LE, { "<=", SS_OP, -1,-1, op_le, "less than or equal" }}, { GT, { ">", SS_OP, -1,-1, op_gt, "greater than" }}, { GE, { ">=", SS_OP, -1,-1, op_ge, "greater than or equal" }}, { EQ, { "==", SS_OP, -1,-1, op_eq, "equal" }}, { NE, { "!=", SS_OP, -1,-1, op_ne, "not equal" }}, { '&', { "&", SS_OP, -1,-1, op_bit_and, "bitwise AND" }}, { '^', { "^", SS_OP, -1,-1, op_bit_xor, "bitwise XOR" }}, { '|', { "|", SS_OP, -1,-1, op_bit_or, "bitwise OR" }}, { AND_OP, { "&&", SS_OP, -1,-1, op_and, "logical AND" }}, { AND, { "AND", SS_OP|SS_WORD, -1,-1, op_and, "logical AND" }}, { XOR_OP, { "^^", SS_OP, -1,-1, op_xor, "logical XOR" }}, { XOR, { "XOR", SS_OP|SS_WORD, -1,-1, op_xor, "logical XOR" }}, { OR_OP, { "||", SS_OP, -1,-1, op_or, "logical OR" }}, { OR, { "OR", SS_OP|SS_WORD, -1,-1, op_or, "logical OR" }}, { '?', { "?:", SS_OP, -1,-1, op_cond, "conditional operator, e1 ? e2 : e3" }}, { '=', { "=", SS_OP, -1,-1, bad_func, "assignment" }}, /* '=' is here just for the help display, there is no run-time function for assignment */ { MUL_ASGN, { "*=", SS_ASGN|SS_OP, -1,-1, op_asgn, "multiplication assignment" }}, { DIV_ASGN, { "/=", SS_ASGN|SS_OP, -1,-1, op_asgn, "division assignment" }}, { MOD_ASGN, { "%=", SS_ASGN|SS_OP, -1,-1, op_asgn, "mod assignment" }}, { ADD_ASGN, { "+=", SS_ASGN|SS_OP, -1,-1, op_asgn, "addition assignment" }}, { SUB_ASGN, { "-=", SS_ASGN|SS_OP, -1,-1, op_asgn, "subtraction assignment" }}, { SHL_ASGN, { "<<=", SS_ASGN|SS_OP, -1,-1, op_asgn, "shift left assignment" }}, { SHR_ASGN, { ">>=", SS_ASGN|SS_OP, -1,-1, op_asgn, "shift right assignment" }}, { BIT_AND_ASGN, { "&=", SS_ASGN|SS_OP, -1,-1, op_asgn, "bitwise AND assignment" }}, { BIT_XOR_ASGN, { "^=", SS_ASGN|SS_OP, -1,-1, op_asgn, "bitwise XOR assignment" }}, { BIT_OR_ASGN, { "|=", SS_ASGN|SS_OP, -1,-1, op_asgn, "bitwise OR assignment" }}, { AND_ASGN, { "&&=", SS_ASGN|SS_OP, -1,-1, op_asgn, "logical AND assignment" }}, { XOR_ASGN, { "^^=", SS_ASGN|SS_OP, -1,-1, op_asgn, "logical XOR assignment" }}, { OR_ASGN, { "||=", SS_ASGN|SS_OP, -1,-1, op_asgn, "logical OR assignment" }}, { ',', { ",", SS_OP, -1,-1, op_comma, "comma operator" }}, /* numeric functions */ #include "tmp/nf_table" /* range functions */ #include "tmp/rf_table" { 0, { 0, 0, 0, 0, 0 }} }; /*** initialize list of function names and pointers ***/ static Func bad = { "unknown", 0, -1,-1, bad_func, "" }; void init_func( void) { int i, c; for( i = 0; i < MAX_TOKEN; ++i) func[i] = &bad; #if 0 for( i = 0; (c = hidden_fnames_list[i].val); ++i) func[c] = &hidden_fnames_list[i].F; #endif for( i = 0; (c = fnames_list[i].val); ++i) func[c] = &fnames_list[i].F; } static const char *commands[] = { "byrows|bycols - set default direction", "copy [byrows|bycols] dest_range src_range", "debug [on|off|level]", "eval [byrows|bycols] [range|symbols] [number_of_iterations]", "exit", "fill [byrows|bycols] range", "fill [byrows|bycols] range start_expr, increment_expr", "fill [byrows|bycols] range { expr_list }", "fill [byrows|bycols] range \"fmt\", \"start\", increments...", "format A0|RC|CR - formula printing format", "format [cell|row|col|range|symbols] \"fmt_string\"", "headers on|off", "help - print list of operators, functions, commands and constants", "help [\"what\"] - print help matching string", "output \"fname\" - redirect output to a file", "plot|plot2d|plot3d [\"fname\"] [byrows|bycols] [range]", "print [\"fname\"] [byrows|bycols] [range] [all|constants|...\n" "...|formats|formulas|functions|pointers|states|symbols|values]...", /* previous two lines are joined */ "quit", "reset [range|symbols] - set formulas to unevaluated state", "srand expr - initialize the pseudo-random number generator", 0 }; void func_help( const char *what) { int i; if( what) { for( i = 0; fnames_list[i].F.name ; ++i) { if( strstr( fnames_list[i].F.name, what) || strstr( fnames_list[i].F.desc, what) ) fprintf( out, " %s%s\t%s\n", fnames_list[i].F.name, strlen(fnames_list[i].F.name) < 6 ? "\t" : "", fnames_list[i].F.desc); } for( i = 0; commands[i]; ++i) { if( strstr( commands[i], what) ) fprintf( out, " %s\n", commands[i]); } return; } fprintf( out, "Operators:\n"); for( i = 0; fnames_list[i].F.type & SS_OP; ++i) fprintf( out, " %s%s\t%s\n", fnames_list[i].F.name, strlen(fnames_list[i].F.name) < 6 ? "\t" : "", fnames_list[i].F.desc); fprintf( out, "Numeric functions:\n"); for( ; fnames_list[i].F.type & SS_NF; ++i) fprintf( out, " %s%s\t%s\n", fnames_list[i].F.name, strlen(fnames_list[i].F.name) < 6 ? "\t" : "", fnames_list[i].F.desc); fprintf( out, "Range functions:\n"); for( ; fnames_list[i].F.type & SS_RF; ++i) fprintf( out, " %s%s\t%s\n", fnames_list[i].F.name, strlen(fnames_list[i].F.name) < 6 ? "\t" : "", fnames_list[i].F.desc); fprintf( out, "Commands:\n"); for( i = 0; commands[i]; ++i) fprintf( out, " %s\n", commands[i]); print_constants(); }