/Classes/common-42s/core_globals.cc
C++ | 3488 lines | 3466 code | 6 blank | 16 comment | 0 complexity | f95c7bc6f32c9f486f19b1de23ead199 MD5 | raw file
Possible License(s): GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /*****************************************************************************
- * Free42 -- an HP-42S calculator simulator
- * Copyright (C) 2004-2011 Thomas Okken
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see http://www.gnu.org/licenses/.
- *****************************************************************************/
- #include <stdlib.h>
- #include "core_globals.h"
- #include "core_commands2.h"
- #include "core_commands4.h"
- #include "core_display.h"
- #include "core_helpers.h"
- #include "core_main.h"
- #include "core_math1.h"
- #include "core_tables.h"
- #include "core_variables.h"
- #include "undo.h"
- #include "shell.h"
- error_spec errors[] = {
- { /* NONE */ NULL, 0 },
- { /* ALPHA_DATA_IS_INVALID */ "Alpha Data Is Invalid", 21 },
- { /* INSUFFICIENT_MEMORY */ "Insufficient Memory", 19 },
- { /* NOT_YET_IMPLEMENTED */ "Not Yet Implemented", 19 },
- { /* OUT_OF_RANGE */ "Out of Range", 12 },
- { /* DIVIDE_BY_0 */ "Divide by 0", 11 },
- { /* INVALID_TYPE */ "Invalid Type", 12 },
- { /* INVALID_DATA */ "Invalid Data", 12 },
- { /* DIMENSION_ERROR */ "Dimension Error", 15 },
- { /* SIZE_ERROR */ "Size Error", 10 },
- { /* INTERNAL_ERROR */ "Internal Error", 14 },
- { /* NONEXISTENT */ "Nonexistent", 11 },
- { /* RESTRICTED_OPERATION */ "Restricted Operation", 20 },
- { /* YES */ "Yes", 3 },
- { /* NO */ "No", 2 },
- { /* STOP */ NULL, 0 },
- { /* LABEL_NOT_FOUND */ "Label Not Found", 15 },
- { /* NO_REAL_VARIABLES */ "No Real Variables", 17 },
- { /* NO_COMPLEX_VARIABLES */ "No Complex Variables", 20 },
- { /* NO_MATRIX_VARIABLES */ "No Matrix Variables", 19 },
- { /* NO_MENU_VARIABLES */ "No Menu Variables", 17 },
- { /* STAT_MATH_ERROR */ "Stat Math Error", 15 },
- { /* INVALID_FORECAST_MODEL */ "Invalid Forecast Model", 22 },
- { /* SOLVE_INTEG_RTN_LOST */ "Solve/Integ RTN Lost", 20 },
- { /* SINGULAR_MATRIX */ "Singular Matrix", 15 },
- { /* SOLVE_SOLVE */ "Solve(Solve)", 12 },
- { /* INTEG_INTEG */ "Integ(Integ)", 12 },
- { /* RUN */ NULL, 0 },
- { /* INTERRUPTED */ "Interrupted", 11 },
- { /* PRINTING_IS_DISABLED */ "Printing Is Disabled", 20 },
- { /* INTERRUPTIBLE */ NULL, 0 },
- { /* NO_VARIABLES */ "No Variables", 12 }
- };
- menu_spec menus[] = {
- { /* MENU_ALPHA1 */ MENU_NONE, MENU_ALPHA2, MENU_ALPHA2,
- { { MENU_ALPHA_ABCDE1, 5, "ABCDE" },
- { MENU_ALPHA_FGHI, 4, "FGHI" },
- { MENU_ALPHA_JKLM, 4, "JKLM" },
- { MENU_ALPHA_NOPQ1, 4, "NOPQ" },
- { MENU_ALPHA_RSTUV1, 5, "RSTUV" },
- { MENU_ALPHA_WXYZ, 4, "WXYZ" } } },
- { /* MENU_ALPHA2 */ MENU_NONE, MENU_ALPHA1, MENU_ALPHA1,
- { { MENU_ALPHA_PAREN, 5, "( [ {" },
- { MENU_ALPHA_ARROW, 3, "\020^\016" },
- { MENU_ALPHA_COMP, 5, "< = >" },
- { MENU_ALPHA_MATH, 4, "MATH" },
- { MENU_ALPHA_PUNC1, 4, "PUNC" },
- { MENU_ALPHA_MISC1, 4, "MISC" } } },
- { /* MENU_ALPHA_ABCDE1 */ MENU_ALPHA1, MENU_ALPHA_ABCDE2, MENU_ALPHA_ABCDE2,
- { { MENU_NONE, 1, "A" },
- { MENU_NONE, 1, "B" },
- { MENU_NONE, 1, "C" },
- { MENU_NONE, 1, "D" },
- { MENU_NONE, 1, "E" },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_ABCDE2 */ MENU_ALPHA1, MENU_ALPHA_ABCDE1, MENU_ALPHA_ABCDE1,
- { { MENU_NONE, 1, "\026" },
- { MENU_NONE, 1, "\024" },
- { MENU_NONE, 1, "\031" },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_FGHI */ MENU_ALPHA1, MENU_NONE, MENU_NONE,
- { { MENU_NONE, 1, "F" },
- { MENU_NONE, 1, "G" },
- { MENU_NONE, 1, "H" },
- { MENU_NONE, 1, "I" },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_JKLM */ MENU_ALPHA1, MENU_NONE, MENU_NONE,
- { { MENU_NONE, 1, "J" },
- { MENU_NONE, 1, "K" },
- { MENU_NONE, 1, "L" },
- { MENU_NONE, 1, "M" },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_NOPQ1 */ MENU_ALPHA1, MENU_ALPHA_NOPQ2, MENU_ALPHA_NOPQ2,
- { { MENU_NONE, 1, "N" },
- { MENU_NONE, 1, "O" },
- { MENU_NONE, 1, "P" },
- { MENU_NONE, 1, "Q" },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_NOPQ2 */ MENU_ALPHA1, MENU_ALPHA_NOPQ1, MENU_ALPHA_NOPQ1,
- { { MENU_NONE, 1, "\025" },
- { MENU_NONE, 1, "\034" },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_RSTUV1 */ MENU_ALPHA1, MENU_ALPHA_RSTUV2, MENU_ALPHA_RSTUV2,
- { { MENU_NONE, 1, "R" },
- { MENU_NONE, 1, "S" },
- { MENU_NONE, 1, "T" },
- { MENU_NONE, 1, "U" },
- { MENU_NONE, 1, "V" },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_RSTUV2 */ MENU_ALPHA1, MENU_ALPHA_RSTUV1, MENU_ALPHA_RSTUV1,
- { { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, "\035" },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_WXYZ */ MENU_ALPHA1, MENU_NONE, MENU_NONE,
- { { MENU_NONE, 1, "W" },
- { MENU_NONE, 1, "X" },
- { MENU_NONE, 1, "Y" },
- { MENU_NONE, 1, "Z" },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_PAREN */ MENU_ALPHA2, MENU_NONE, MENU_NONE,
- { { MENU_NONE, 1, "(" },
- { MENU_NONE, 1, ")" },
- { MENU_NONE, 1, "[" },
- { MENU_NONE, 1, "]" },
- { MENU_NONE, 1, "{" },
- { MENU_NONE, 1, "}" } } },
- { /* MENU_ALPHA_ARROW */ MENU_ALPHA2, MENU_NONE, MENU_NONE,
- { { MENU_NONE, 1, "\020" },
- { MENU_NONE, 1, "^" },
- { MENU_NONE, 1, "\016" },
- { MENU_NONE, 1, "\017" },
- { MENU_NONE, 1, " " },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_COMP */ MENU_ALPHA2, MENU_NONE, MENU_NONE,
- { { MENU_NONE, 1, "=" },
- { MENU_NONE, 1, "\014" },
- { MENU_NONE, 1, "<" },
- { MENU_NONE, 1, ">" },
- { MENU_NONE, 1, "\011" },
- { MENU_NONE, 1, "\013" } } },
- { /* MENU_ALPHA_MATH */ MENU_ALPHA2, MENU_NONE, MENU_NONE,
- { { MENU_NONE, 1, "\005" },
- { MENU_NONE, 1, "\003" },
- { MENU_NONE, 1, "\002" },
- { MENU_NONE, 1, "\027" },
- { MENU_NONE, 1, "\023" },
- { MENU_NONE, 1, "\021" } } },
- { /* MENU_ALPHA_PUNC1 */ MENU_ALPHA2, MENU_ALPHA_PUNC2, MENU_ALPHA_PUNC2,
- { { MENU_NONE, 1, "," },
- { MENU_NONE, 1, ";" },
- { MENU_NONE, 1, ":" },
- { MENU_NONE, 1, "!" },
- { MENU_NONE, 1, "?" },
- { MENU_NONE, 1, "\"" } } },
- { /* MENU_ALPHA_PUNC2 */ MENU_ALPHA2, MENU_ALPHA_PUNC1, MENU_ALPHA_PUNC1,
- { { MENU_NONE, 1, "\032" },
- { MENU_NONE, 1, "_" },
- { MENU_NONE, 1, "`" },
- { MENU_NONE, 1, "'" },
- { MENU_NONE, 1, "\010" },
- { MENU_NONE, 1, "\012" } } },
- { /* MENU_ALPHA_MISC1 */ MENU_ALPHA2, MENU_ALPHA_MISC2, MENU_ALPHA_MISC2,
- { { MENU_NONE, 1, "$" },
- { MENU_NONE, 1, "*" },
- { MENU_NONE, 1, "#" },
- { MENU_NONE, 1, "/" },
- { MENU_NONE, 1, "\037" },
- { MENU_NONE, 1, " " } } },
- { /* MENU_ALPHA_MISC2 */ MENU_ALPHA2, MENU_ALPHA_MISC1, MENU_ALPHA_MISC1,
- { { MENU_NONE, 1, "\022" },
- { MENU_NONE, 1, "&" },
- { MENU_NONE, 1, "@" },
- { MENU_NONE, 1, "\\" },
- { MENU_NONE, 1, "~" },
- { MENU_NONE, 1, "|" } } },
- { /* MENU_ST */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { MENU_NONE, 4, "ST L" },
- { MENU_NONE, 4, "ST X" },
- { MENU_NONE, 4, "ST Y" },
- { MENU_NONE, 4, "ST Z" },
- { MENU_NONE, 4, "ST T" },
- { MENU_NONE, 0, "" } } },
- { /* MENU_IND_ST */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { MENU_NONE, 3, "IND" },
- { MENU_NONE, 4, "ST L" },
- { MENU_NONE, 4, "ST X" },
- { MENU_NONE, 4, "ST Y" },
- { MENU_NONE, 4, "ST Z" },
- { MENU_NONE, 4, "ST T" } } },
- { /* MENU_IND */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { MENU_NONE, 3, "IND" },
- { MENU_NONE, 0, "" },
- { MENU_NONE, 0, "" },
- { MENU_NONE, 0, "" },
- { MENU_NONE, 0, "" },
- { MENU_NONE, 0, "" } } },
- { /* MENU_MODES1 */ MENU_NONE, MENU_MODES2, MENU_MODES2,
- { { 0x2000 + CMD_DEG, 0, "" },
- { 0x2000 + CMD_RAD, 0, "" },
- { 0x2000 + CMD_GRAD, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x2000 + CMD_RECT, 0, "" },
- { 0x2000 + CMD_POLAR, 0, "" } } },
- { /* MENU_MODES2 */ MENU_NONE, MENU_MODES1, MENU_MODES1,
- { { 0x1000 + CMD_SIZE, 0, "" },
- { 0x2000 + CMD_QUIET, 0, "" },
- { 0x2000 + CMD_CPXRES, 0, "" },
- { 0x2000 + CMD_REALRES, 0, "" },
- { 0x2000 + CMD_KEYASN, 0, "" },
- { 0x2000 + CMD_LCLBL, 0, "" } } },
- { /* MENU_DISP */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0x2000 + CMD_FIX, 0, "" },
- { 0x2000 + CMD_SCI, 0, "" },
- { 0x2000 + CMD_ENG, 0, "" },
- { 0x2000 + CMD_ALL, 0, "" },
- { 0x2000 + CMD_RDXDOT, 0, "" },
- { 0x2000 + CMD_RDXCOMMA, 0, "" } } },
- #ifdef BIGSTACK
- { /* MENU_CLEAR1 */ MENU_NONE, MENU_CLEAR2, MENU_CLEAR3,
- #else
- { /* MENU_CLEAR1 */ MENU_NONE, MENU_CLEAR2, MENU_CLEAR2,
- #endif
- { { 0x1000 + CMD_CLSIGMA, 0, "" },
- { 0x1000 + CMD_CLP, 0, "" },
- { 0x1000 + CMD_CLV, 0, "" },
- { 0x1000 + CMD_CLST, 0, "" },
- { 0x1000 + CMD_CLA, 0, "" },
- { 0x1000 + CMD_CLX, 0, "" } } },
- #ifdef BIGSTACK
- { /* MENU_CLEAR2 */ MENU_NONE, MENU_CLEAR3, MENU_CLEAR1,
- #else
- { /* MENU_CLEAR2 */ MENU_NONE, MENU_CLEAR1, MENU_CLEAR1,
- #endif
- { { 0x1000 + CMD_CLRG, 0, "" },
- { 0x1000 + CMD_DEL, 0, "" },
- { 0x1000 + CMD_CLKEYS, 0, "" },
- { 0x1000 + CMD_CLLCD, 0, "" },
- { 0x1000 + CMD_CLMENU, 0, "" },
- { 0x1000 + CMD_CLALLa, 0, "" } } },
-
- { /* MENU_CONVERT1 */ MENU_NONE, MENU_CONVERT2, MENU_CONVERT4,
- { { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" } } },
-
- { /* MENU_CONVERT2 */ MENU_NONE, MENU_CONVERT3, MENU_CONVERT1,
- { { 0 , 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" } } },
-
- { /* MENU_FLAGS */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_SF, 0, "" },
- { 0x1000 + CMD_CF, 0, "" },
- { 0x1000 + CMD_FS_T, 0, "" },
- { 0x1000 + CMD_FC_T, 0, "" },
- { 0x1000 + CMD_FSC_T, 0, "" },
- { 0x1000 + CMD_FCC_T, 0, "" } } },
- { /* MENU_PROB */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_COMB, 0, "" },
- { 0x1000 + CMD_PERM, 0, "" },
- { 0x1000 + CMD_FACT, 0, "" },
- { 0x1000 + CMD_GAMMA, 0, "" },
- { 0x1000 + CMD_RAN, 0, "" },
- { 0x1000 + CMD_SEED, 0, "" } } },
- { /* MENU_CUSTOM1 */ MENU_NONE, MENU_CUSTOM2, MENU_CUSTOM3,
- { { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" } } },
- { /* MENU_CUSTOM2 */ MENU_NONE, MENU_CUSTOM3, MENU_CUSTOM1,
- { { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" } } },
- { /* MENU_CUSTOM3 */ MENU_NONE, MENU_CUSTOM1, MENU_CUSTOM2,
- { { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" } } },
- { /* MENU_PGM_FCN1 */ MENU_NONE, MENU_PGM_FCN2, MENU_PGM_FCN4,
- { { 0x1000 + CMD_LBL, 0, "" },
- { 0x1000 + CMD_RTN, 0, "" },
- { 0x1000 + CMD_INPUT, 0, "" },
- { 0x1000 + CMD_VIEW, 0, "" },
- { 0x1000 + CMD_AVIEW, 0, "" },
- { 0x1000 + CMD_XEQ, 0, "" } } },
- { /* MENU_PGM_FCN2 */ MENU_NONE, MENU_PGM_FCN3, MENU_PGM_FCN1,
- { { MENU_PGM_XCOMP0, 3, "X?0" },
- { MENU_PGM_XCOMPY, 3, "X?Y" },
- { 0x1000 + CMD_PROMPT, 0, "" },
- { 0x1000 + CMD_PSE, 0, "" },
- { 0x1000 + CMD_ISG, 0, "" },
- { 0x1000 + CMD_DSE, 0, "" } } },
- { /* MENU_PGM_FCN3 */ MENU_NONE, MENU_PGM_FCN4, MENU_PGM_FCN2,
- { { 0x1000 + CMD_AIP, 0, "" },
- { 0x1000 + CMD_XTOA, 0, "" },
- { 0x1000 + CMD_AGRAPH, 0, "" },
- { 0x1000 + CMD_PIXEL, 0, "" },
- { 0x1000 + CMD_BEEP, 0, "" },
- { 0x1000 + CMD_TONE, 0, "" } } },
- { /* MENU_PGM_FCN4 */ MENU_NONE, MENU_PGM_FCN1, MENU_PGM_FCN3,
- { { 0x1000 + CMD_MVAR, 0, "" },
- { 0x1000 + CMD_VARMENU, 0, "" },
- { 0x1000 + CMD_GETKEY, 0, "" },
- { 0x1000 + CMD_MENU, 0, "" },
- { 0x1000 + CMD_KEYG, 0, "" },
- { 0x1000 + CMD_KEYX, 0, "" } } },
- { /* MENU_PGM_XCOMP0 */ MENU_PGM_FCN2, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_X_EQ_0, 0, "" },
- { 0x1000 + CMD_X_NE_0, 0, "" },
- { 0x1000 + CMD_X_LT_0, 0, "" },
- { 0x1000 + CMD_X_GT_0, 0, "" },
- { 0x1000 + CMD_X_LE_0, 0, "" },
- { 0x1000 + CMD_X_GE_0, 0, "" } } },
- { /* MENU_PGM_XCOMPY */ MENU_PGM_FCN2, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_X_EQ_Y, 0, "" },
- { 0x1000 + CMD_X_NE_Y, 0, "" },
- { 0x1000 + CMD_X_LT_Y, 0, "" },
- { 0x1000 + CMD_X_GT_Y, 0, "" },
- { 0x1000 + CMD_X_LE_Y, 0, "" },
- { 0x1000 + CMD_X_GE_Y, 0, "" } } },
- { /* MENU_PRINT1 */ MENU_NONE, MENU_PRINT2, MENU_PRINT3,
- { { 0x1000 + CMD_PRSIGMA, 0, "" },
- { 0x1000 + CMD_PRP, 0, "" },
- { 0x1000 + CMD_PRV, 0, "" },
- { 0x1000 + CMD_PRSTK, 0, "" },
- { 0x1000 + CMD_PRA, 0, "" },
- { 0x1000 + CMD_PRX, 0, "" } } },
- { /* MENU_PRINT2 */ MENU_NONE, MENU_PRINT3, MENU_PRINT1,
- { { 0x1000 + CMD_PRUSR, 0, "" },
- { 0x1000 + CMD_LIST, 0, "" },
- { 0x1000 + CMD_ADV, 0, "" },
- { 0x1000 + CMD_PRLCD, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_DELAY, 0, "" } } },
- { /* MENU_PRINT3 */ MENU_NONE, MENU_PRINT1, MENU_PRINT2,
- { { 0x2000 + CMD_PON, 0, "" },
- { 0x2000 + CMD_POFF, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x2000 + CMD_MAN, 0, "" },
- { 0x2000 + CMD_NORM, 0, "" },
- { 0x2000 + CMD_TRACE, 0, "" } } },
- { /* MENU_TOP_FCN */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_SIGMAADD, 0, "" },
- { 0x1000 + CMD_INV, 0, "" },
- { 0x1000 + CMD_SQRT, 0, "" },
- { 0x1000 + CMD_LOG, 0, "" },
- { 0x1000 + CMD_LN, 0, "" },
- { 0x1000 + CMD_XEQ, 0, "" } } },
- { /* MENU_CATALOG */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" } } },
- { /* MENU_BLANK */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" } } },
- { /* MENU_PROGRAMMABLE */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" } } },
- { /* MENU_VARMENU */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" } } },
- { /* MENU_STAT1 */ MENU_NONE, MENU_STAT2, MENU_STAT2,
- { { 0x1000 + CMD_SIGMAADD, 0, "" },
- { 0x1000 + CMD_SUM, 0, "" },
- { 0x1000 + CMD_MEAN, 0, "" },
- { 0x1000 + CMD_WMEAN, 0, "" },
- { 0x1000 + CMD_SDEV, 0, "" },
- { MENU_STAT_CFIT, 4, "CFIT" } } },
- { /* MENU_STAT2 */ MENU_NONE, MENU_STAT1, MENU_STAT1,
- { { 0x2000 + CMD_ALLSIGMA, 0, "" },
- { 0x2000 + CMD_LINSIGMA, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_SIGMAREG, 0, "" },
- { 0x1000 + CMD_SIGMAREG_T, 0, "" } } },
- { /* MENU_STAT_CFIT */ MENU_STAT1, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_FCSTX, 0, "" },
- { 0x1000 + CMD_FCSTY, 0, "" },
- { 0x1000 + CMD_SLOPE, 0, "" },
- { 0x1000 + CMD_YINT, 0, "" },
- { 0x1000 + CMD_CORR, 0, "" },
- { MENU_STAT_MODL, 4, "MODL" } } },
- { /* MENU_STAT_MODL */ MENU_STAT_CFIT, MENU_NONE, MENU_NONE,
- { { 0x2000 + CMD_LINF, 0, "" },
- { 0x2000 + CMD_LOGF, 0, "" },
- { 0x2000 + CMD_EXPF, 0, "" },
- { 0x2000 + CMD_PWRF, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_BEST, 0, "" } } },
- { /* MENU_MATRIX1 */ MENU_NONE, MENU_MATRIX2, MENU_MATRIX3,
- { { 0x1000 + CMD_NEWMAT, 0, "" },
- { 0x1000 + CMD_INVRT, 0, "" },
- { 0x1000 + CMD_DET, 0, "" },
- { 0x1000 + CMD_TRANS, 0, "" },
- { 0x1000 + CMD_SIMQ, 0, "" },
- { 0x1000 + CMD_EDIT, 0, "" } } },
- { /* MENU_MATRIX2 */ MENU_NONE, MENU_MATRIX3, MENU_MATRIX1,
- { { 0x1000 + CMD_DOT, 0, "" },
- { 0x1000 + CMD_CROSS, 0, "" },
- { 0x1000 + CMD_UVEC, 0, "" },
- { 0x1000 + CMD_DIM, 0, "" },
- { 0x1000 + CMD_INDEX, 0, "" },
- { 0x1000 + CMD_EDITN, 0, "" } } },
- { /* MENU_MATRIX3 */ MENU_NONE, MENU_MATRIX1, MENU_MATRIX2,
- { { 0x1000 + CMD_STOIJ, 0, "" },
- { 0x1000 + CMD_RCLIJ, 0, "" },
- { 0x1000 + CMD_STOEL, 0, "" },
- { 0x1000 + CMD_RCLEL, 0, "" },
- { 0x1000 + CMD_PUTM, 0, "" },
- { 0x1000 + CMD_GETM, 0, "" } } },
- { /* MENU_MATRIX_SIMQ */ MENU_MATRIX1, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_MATA, 0, "" },
- { 0x1000 + CMD_MATB, 0, "" },
- { 0x1000 + CMD_MATX, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" } } },
- { /* MENU_MATRIX_EDIT1 */ MENU_NONE, MENU_MATRIX_EDIT2, MENU_MATRIX_EDIT2,
- { { 0x1000 + CMD_LEFT, 0, "" },
- { 0x1000 + CMD_OLD, 0, "" },
- { 0x1000 + CMD_UP, 0, "" },
- { 0x1000 + CMD_DOWN, 0, "" },
- { 0x1000 + CMD_GOTOROW, 0, "" },
- { 0x1000 + CMD_RIGHT, 0, "" } } },
- { /* MENU_MATRIX_EDIT2 */ MENU_NONE, MENU_MATRIX_EDIT1, MENU_MATRIX_EDIT1,
- { { 0x1000 + CMD_INSR, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_DELR, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x2000 + CMD_WRAP, 0, "" },
- { 0x2000 + CMD_GROW, 0, "" } } },
- { /* MENU_BASE */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_A_THRU_F, 0, "" },
- { 0x2000 + CMD_HEXM, 0, "" },
- { 0x2000 + CMD_DECM, 0, "" },
- { 0x2000 + CMD_OCTM, 0, "" },
- { 0x2000 + CMD_BINM, 0, "" },
- { MENU_BASE_LOGIC, 5, "LOGIC" } } },
- { /* MENU_BASE_A_THRU_F */ MENU_BASE, MENU_NONE, MENU_NONE,
- { { 0x4000, 1, "A" },
- { 0x4000, 1, "B" },
- { 0x4000, 1, "C" },
- { 0x4000, 1, "D" },
- { 0x4000, 1, "E" },
- { 0x4000, 1, "F" } } },
- { /* MENU_BASE_LOGIC */ MENU_BASE, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_AND, 0, "" },
- { 0x1000 + CMD_OR, 0, "" },
- { 0x1000 + CMD_XOR, 0, "" },
- { 0x1000 + CMD_NOT, 0, "" },
- { 0x1000 + CMD_BIT_T, 0, "" },
- { 0x1000 + CMD_ROTXY, 0, "" } } },
- { /* MENU_SOLVE */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_MVAR, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_PGMSLV, 0, "" },
- { 0x1000 + CMD_SOLVE, 0, "" } } },
- { /* MENU_INTEG */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0x1000 + CMD_MVAR, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_PGMINT, 0, "" },
- { 0x1000 + CMD_INTEG, 0, "" } } },
- { /* MENU_INTEG_PARAMS */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0, 4, "LLIM" },
- { 0, 4, "ULIM" },
- { 0, 3, "ACC" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0, 1, "\003" } } },
- #ifdef BIGSTACK
- { /* MENU_CLEAR3 */ MENU_NONE, MENU_CLEAR1, MENU_CLEAR2,
- { { 0x1000 + CMD_DROP, 0, "" },
- { 0x1000 + CMD_UNDO, 0, "" },
- { 0x1000 + CMD_REDO, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" },
- { 0x1000 + CMD_NULL, 0, "" } } },
-
-
-
- { /* MENU_CONVERT3 */ MENU_NONE, MENU_CONVERT4, MENU_CONVERT2,
- { { 0x1000 + CMD_TO_DEG, 0, "" },
- { 0x1000 + CMD_TO_RAD, 0, "" },
- { 0x1000 + CMD_TO_HR, 0, "" },
- { 0x1000 + CMD_TO_HMS, 0, "" },
- { 0x1000 + CMD_TO_REC, 0, "" },
- { 0x1000 + CMD_TO_POL, 0, "" } } },
-
- { /* MENU_CONVERT4 */ MENU_NONE, MENU_CONVERT1, MENU_CONVERT3,
- { { 0x1000 + CMD_IP, 0, "" },
- { 0x1000 + CMD_FP, 0, "" },
- { 0x1000 + CMD_RND, 0, "" },
- { 0x1000 + CMD_ABS, 0, "" },
- { 0x1000 + CMD_SIGN, 0, "" },
- { 0x1000 + CMD_MOD, 0, "" } } },
-
- { /* MENU_UNITS */ MENU_NONE, MENU_NONE, MENU_NONE,
- { { 0 , 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" },
- { 0, 0, "" } } },
- #endif
- };
- /* By how much do the variables, programs, and labels
- * arrays grow when they are full
- */
- #define VARS_INCREMENT 25
- #define PRGMS_INCREMENT 10
- #define LABELS_INCREMENT 10
- /* Registers */
- vartype *reg_x = NULL;
- vartype *reg_y = NULL;
- vartype *reg_z = NULL;
- vartype *reg_t = NULL;
- vartype *reg_lastx = NULL;
- int reg_alpha_length = 0;
- char reg_alpha[44];
- /* Flags */
- flags_struct flags;
- /* Variables */
- int vars_capacity = 0;
- int vars_count = 0;
- var_struct *vars = NULL;
- /* Programs */
- int prgms_capacity = 0;
- int prgms_count = 0;
- prgm_struct *prgms = NULL;
- int labels_capacity = 0;
- int labels_count = 0;
- label_struct *labels = NULL;
- int current_prgm = -1;
- int4 pc;
- int prgm_highlight_row = 0;
- int varmenu_length;
- char varmenu[7];
- int varmenu_rows;
- int varmenu_row;
- int varmenu_labellength[6];
- char varmenu_labeltext[6][7];
- int varmenu_role;
- bool mode_clall;
- int (*mode_interruptible)(int) = NULL;
- bool mode_stoppable;
- bool mode_command_entry;
- bool mode_number_entry;
- bool mode_alpha_entry;
- bool mode_shift;
- int mode_appmenu;
- int mode_plainmenu;
- bool mode_plainmenu_sticky;
- int mode_transientmenu;
- int mode_alphamenu;
- int mode_commandmenu;
- bool mode_running;
- bool mode_getkey;
- bool mode_pause = false;
- bool mode_disable_stack_lift; /* transient */
- bool mode_varmenu;
- bool mode_updown;
- int4 mode_sigma_reg;
- int mode_goose;
- bool mode_time_clktd;
- bool mode_time_clk24;
- bool mode_time_dmy;
- #if BIGSTACK
- stack_item *bigstack_head = NULL;
- /* True if we are currently operating with the extended stack */
- bool mode_rpl_enter = false;
- int stacksize = 4; /* stack size is always at least 4 */
- int last_pending_command = CMD_NONE;
- /* Keep track of what the stack type was before solve or integration */
- int orig_stack_type_before_solve = 0;
- #endif
- bool cllcd_cmd = false;
- phloat entered_number;
- int entered_string_length;
- char entered_string[15];
- int pending_command;
- arg_struct pending_command_arg;
- int xeq_invisible;
- /* Multi-keystroke commands -- edit state */
- /* Relevant when mode_command_entry != 0 */
- int incomplete_command;
- int incomplete_ind;
- int incomplete_alpha;
- int incomplete_length;
- int incomplete_maxdigits;
- int incomplete_argtype;
- int incomplete_num;
- char incomplete_str[7];
- int4 incomplete_saved_pc;
- int4 incomplete_saved_highlight_row;
- /* Command line handling temporaries */
- char cmdline[100];
- int cmdline_length;
- int cmdline_row;
- /* Matrix editor / matrix indexing */
- int matedit_mode; /* 0=off, 1=index, 2=edit, 3=editn */
- char matedit_name[7];
- int matedit_length;
- vartype *matedit_x;
- int4 matedit_i;
- int4 matedit_j;
- int matedit_prev_appmenu;
- /* INPUT */
- char input_name[11];
- int input_length;
- arg_struct input_arg;
- /* BASE application */
- int baseapp = 0;
- /* Random number generator */
- phloat random_number;
- /* NORM & TRACE mode: number waiting to be printed */
- int deferred_print = 0;
- /* Keystroke buffer - holds keystrokes received while
- * there is a program running.
- */
- int keybuf_head = 0;
- int keybuf_tail = 0;
- int keybuf[16];
- int remove_program_catalog = 0;
- bool bin_dec_mode_switch;
- bool state_file_has_old_bcd;
- /*******************/
- /* Private globals */
- /*******************/
- static bool state_bool_is_int;
- #define MAX_RTNS 8
- static int rtn_sp = 0;
- static int rtn_prgm[MAX_RTNS];
- static int4 rtn_pc[MAX_RTNS];
- typedef struct {
- int type;
- int4 rows;
- int4 columns;
- } matrix_persister;
- static int array_count;
- static int array_list_capacity;
- static void **array_list;
- static bool read_int(int *n) GLOBALS_SECT;
- static bool write_int(int n) GLOBALS_SECT;
- static bool read_int4(int4 *n) GLOBALS_SECT;
- static bool write_int4(int4 n) GLOBALS_SECT;
- static bool read_bool(bool *n) GLOBALS_SECT;
- static bool write_bool(bool n) GLOBALS_SECT;
- static bool array_list_grow() GLOBALS_SECT;
- static int array_list_search(void *array) GLOBALS_SECT;
- static bool persist_vartype(vartype *v) GLOBALS_SECT;
- static bool unpersist_vartype(vartype **v) GLOBALS_SECT;
- static void update_label_table(int prgm, int4 pc, int inserted) GLOBALS_SECT;
- static void invalidate_lclbls(int prgm_index) GLOBALS_SECT;
- static int pc_line_convert(int4 loc, int loc_is_pc) GLOBALS_SECT;
- static bool convert_programs() GLOBALS_SECT;
- #ifdef IPHONE
- static void convert_bigstack_drop() GLOBALS_SECT;
- static bool persist_undo() GLOBALS_SECT;
- static bool unpersist_undo() GLOBALS_SECT;
- #endif
- static bool array_list_grow() {
- if (array_count < array_list_capacity)
- return true;
- array_list_capacity += 10;
- void **p = (void **) realloc(array_list,
- array_list_capacity * sizeof(void *));
- if (p == NULL)
- return false;
- array_list = p;
- return true;
- }
- static int array_list_search(void *array) {
- for (int i = 0; i < array_count; i++)
- if (array_list[i] == array)
- return i;
- return -1;
- }
- static bool persist_vartype(vartype *v) {
- if (v == NULL) {
- int type = TYPE_NULL;
- return shell_write_saved_state(&type, sizeof(int));
- }
- switch (v->type) {
- case TYPE_REAL:
- return shell_write_saved_state(v, sizeof(vartype_real));
- case TYPE_COMPLEX:
- return shell_write_saved_state(v, sizeof(vartype_complex));
- case TYPE_STRING:
- return shell_write_saved_state(v, sizeof(vartype_string));
- case TYPE_REALMATRIX: {
- matrix_persister mp;
- vartype_realmatrix *rm = (vartype_realmatrix *) v;
- mp.type = rm->type;
- mp.rows = rm->rows;
- mp.columns = rm->columns;
- int4 size = mp.rows * mp.columns;
- bool must_write = true;
- if (rm->array->refcount > 1) {
- int n = array_list_search(rm->array);
- if (n == -1) {
- // A negative row count signals a new shared matrix
- mp.rows = -mp.rows;
- if (!array_list_grow())
- return false;
- array_list[array_count++] = rm->array;
- } else {
- // A zero row count means this matrix shares its data
- // with a previously written matrix
- mp.rows = 0;
- mp.columns = n;
- must_write = false;
- }
- }
- if (!shell_write_saved_state(&mp, sizeof(matrix_persister)))
- return false;
- if (must_write) {
- if (!shell_write_saved_state(rm->array->data,
- size * sizeof(phloat)))
- return false;
- if (!shell_write_saved_state(rm->array->is_string, size))
- return false;
- }
- return true;
- }
- case TYPE_COMPLEXMATRIX: {
- matrix_persister mp;
- vartype_complexmatrix *cm = (vartype_complexmatrix *) v;
- mp.type = cm->type;
- mp.rows = cm->rows;
- mp.columns = cm->columns;
- int4 size = mp.rows * mp.columns;
- bool must_write = true;
- if (cm->array->refcount > 1) {
- int n = array_list_search(cm->array);
- if (n == -1) {
- // A negative row count signals a new shared matrix
- mp.rows = -mp.rows;
- if (!array_list_grow())
- return false;
- array_list[array_count++] = cm->array;
- } else {
- // A zero row count means this matrix shares its data
- // with a previously written matrix
- mp.rows = 0;
- mp.columns = n;
- must_write = false;
- }
- }
- if (!shell_write_saved_state(&mp, sizeof(matrix_persister)))
- return false;
- if (must_write) {
- if (!shell_write_saved_state(cm->array->data,
- 2 * size * sizeof(phloat)))
- return false;
- }
- return true;
- }
- default:
- /* Should not happen */
- return true;
- }
- }
- // A few declarations to help unpersist_vartype get the offsets right,
- // in the case it needs to convert the state file.
- struct fake_bcd {
- short d_[P+1];
- };
- struct bin_real {
- int type;
- double x;
- };
- struct bin_complex {
- int type;
- double re, im;
- };
- struct dec_real {
- int type;
- fake_bcd x;
- };
- struct dec_complex {
- int type;
- fake_bcd re, im;
- };
- static bool unpersist_vartype(vartype **v) {
- int type;
- if (shell_read_saved_state(&type, sizeof(int)) != sizeof(int))
- return false;
- switch (type) {
- case TYPE_NULL: {
- *v = NULL;
- return true;
- }
- case TYPE_REAL: {
- vartype_real *r = (vartype_real *) new_real(0);
- if (r == NULL)
- return false;
- if (bin_dec_mode_switch) {
- #ifdef BCD_MATH
- int n = sizeof(bin_real) - sizeof(int);
- bin_real br;
- if (shell_read_saved_state(&br.type + 1, n) != n) {
- free_vartype((vartype *) r);
- return false;
- }
- r->x = br.x;
- #else
- int n = sizeof(dec_real) - sizeof(int);
- dec_real dr;
- if (shell_read_saved_state(&dr.type + 1, n) != n) {
- free_vartype((vartype *) r);
- return false;
- }
- r->x = bcd2double(dr.x.d_, state_file_has_old_bcd);
- #endif
- } else {
- int n = sizeof(vartype_real) - sizeof(int);
- if (shell_read_saved_state(&r->type + 1, n) != n) {
- free_vartype((vartype *) r);
- return false;
- }
- #ifdef BCD_MATH
- if (state_file_has_old_bcd)
- bcdfloat_old2new(r->x.bcd.d_);
- #endif
- }
- *v = (vartype *) r;
- return true;
- }
- case TYPE_COMPLEX: {
- vartype_complex *c = (vartype_complex *) new_complex(0, 0);
- if (c == NULL)
- return false;
- if (bin_dec_mode_switch) {
- #ifdef BCD_MATH
- int n = sizeof(bin_complex) - sizeof(int);
- bin_complex bc;
- if (shell_read_saved_state(&bc.type + 1, n) != n) {
- free_vartype((vartype *) c);
- return false;
- }
- c->re = bc.re;
- c->im = bc.im;
- #else
- int n = sizeof(dec_complex) - sizeof(int);
- dec_complex dc;
- if (shell_read_saved_state(&dc.type + 1, n) != n) {
- free_vartype((vartype *) c);
- return false;
- }
- c->re = bcd2double(dc.re.d_, state_file_has_old_bcd);
- c->im = bcd2double(dc.im.d_, state_file_has_old_bcd);
- #endif
- } else {
- int n = sizeof(vartype_complex) - sizeof(int);
- if (shell_read_saved_state(&c->type + 1, n) != n) {
- free_vartype((vartype *) c);
- return false;
- }
- #ifdef BCD_MATH
- if (state_file_has_old_bcd) {
- bcdfloat_old2new(c->re.bcd.d_);
- bcdfloat_old2new(c->im.bcd.d_);
- }
- #endif
- }
- *v = (vartype *) c;
- return true;
- }
- case TYPE_STRING: {
- vartype_string *s = (vartype_string *) new_string("", 0);
- int n = sizeof(vartype_string) - sizeof(int);
- if (s == NULL)
- return false;
- if (shell_read_saved_state(&s->type + 1, n) != n) {
- free_vartype((vartype *) s);
- return false;
- } else {
- *v = (vartype *) s;
- return true;
- }
- }
- case TYPE_REALMATRIX: {
- matrix_persister mp;
- int n = sizeof(matrix_persister) - sizeof(int);
- if (shell_read_saved_state(&mp.type + 1, n) != n)
- return false;
- if (mp.rows == 0) {
- // Shared matrix
- vartype *m = new_matrix_alias((vartype *) array_list[mp.columns]);
- if (m == NULL)
- return false;
- else {
- *v = m;
- return true;
- }
- }
- bool shared = mp.rows < 0;
- if (shared)
- mp.rows = -mp.rows;
- vartype_realmatrix *rm = (vartype_realmatrix *) new_realmatrix(mp.rows, mp.columns);
- if (rm == NULL)
- return false;
- if (bin_dec_mode_switch) {
- int4 size = mp.rows * mp.columns;
- #ifdef BCD_MATH
- int phsz = sizeof(double);
- #else
- int phsz = sizeof(fake_bcd);
- #endif
- int4 tsz = size * phsz;
- char *temp = (char *) malloc(tsz);
- if (temp == NULL) {
- free_vartype((vartype *) rm);
- return false;
- }
- if (shell_read_saved_state(temp, tsz) != tsz) {
- free(temp);
- free_vartype((vartype *) rm);
- return false;
- }
- if (shell_read_saved_state(rm->array->is_string, size) != size) {
- free(temp);
- free_vartype((vartype *) rm);
- return false;
- }
- #ifdef BCD_MATH
- for (int4 i = 0; i < size; i++) {
- if (rm->array->is_string[i]) {
- char *src = temp + i * phsz;
- char *dst = (char *) (rm->array->data + i);
- for (int j = 0; j < 7; j++)
- *dst++ = *src++;
- } else {
- rm->array->data[i] = ((double *) temp)[i];
- }
- }
- #else
- for (int4 i = 0; i < size; i++) {
- if (rm->array->is_string[i]) {
- char *src = temp + i * phsz;
- char *dst = (char *) (rm->array->data + i);
- for (int j = 0; j < 7; j++)
- *dst++ = *src++;
- } else {
- rm->array->data[i] = bcd2double((short *) (temp + phsz * i), state_file_has_old_bcd);
- }
- }
- #endif
- free(temp);
- } else {
- int4 size = mp.rows * mp.columns * sizeof(phloat);
- if (shell_read_saved_state(rm->array->data, size) != size) {
- free_vartype((vartype *) rm);
- return false;
- }
- size = mp.rows * mp.columns;
- if (shell_read_saved_state(rm->array->is_string, size) != size) {
- free_vartype((vartype *) rm);
- return false;
- }
- #ifdef BCD_MATH
- if (state_file_has_old_bcd)
- for (int4 i = 0; i < size; i++)
- if (!rm->array->is_string[i])
- bcdfloat_old2new(rm->array->data[i].bcd.d_);
- #endif
- }
- if (shared) {
- if (!array_list_grow()) {
- free_vartype((vartype *) rm);
- return false;
- }
- array_list[array_count++] = rm;
- }
- *v = (vartype *) rm;
- return true;
- }
- case TYPE_COMPLEXMATRIX: {
- matrix_persister mp;
- int n = sizeof(matrix_persister) - sizeof(int);
- if (shell_read_saved_state(&mp.type + 1, n) != n)
- return false;
- if (mp.rows == 0) {
- // Shared matrix
- vartype *m = new_matrix_alias((vartype *) array_list[mp.columns]);
- if (m == NULL)
- return false;
- else {
- *v = m;
- return true;
- }
- }
- bool shared = mp.rows < 0;
- if (shared)
- mp.rows = -mp.rows;
- vartype_complexmatrix *cm = (vartype_complexmatrix *)
- new_complexmatrix(mp.rows, mp.columns);
- if (cm == NULL)
- return false;
- if (bin_dec_mode_switch) {
- int4 size = 2 * mp.rows * mp.columns;
- for (int4 i = 0; i < size; i++)
- if (!read_phloat(cm->array->data + i)) {
- free_vartype((vartype *) cm);
- return false;
- }
- } else {
- int4 size = 2 * mp.rows * mp.columns * sizeof(phloat);
- if (shell_read_saved_state(cm->array->data, size) != size) {
- free_vartype((vartype *) cm);
- return false;
- }
- #ifdef BCD_MATH
- if (state_file_has_old_bcd)
- for (int4 i = 0; i < size; i++)
- bcdfloat_old2new(cm->array->data[i].bcd.d_);
- #endif
- }
- if (shared) {
- if (!array_list_grow()) {
- free_vartype((vartype *) cm);
- return false;
- }
- array_list[array_count++] = cm;
- }
- *v = (vartype *) cm;
- return true;
- }
- default:
- return false;
- }
- }
- static bool persist_globals() GLOBALS_SECT;
- static bool persist_globals() {
- int i;
- array_count = 0;
- array_list_capacity = 0;
- array_list = NULL;
- bool ret = false;
- #if BIGSTACK
- stack_item *si = bigstack_head;
- #endif
- if (!persist_vartype(reg_x))
- goto done;
- if (!persist_vartype(reg_y))
- goto done;
- if (!persist_vartype(reg_z))
- goto done;
- if (!persist_vartype(reg_t))
- goto done;
- if (!persist_vartype(reg_lastx))
- goto done;
- #if BIGSTACK
- if (!write_bool(true)) /* Yes, big stack block exists */
- goto done;
-
- persist_undo();
-
- if (!write_int(stacksize))
- goto done;
- while (si != NULL) {
- if (!persist_vartype(si->var))
- goto done;
- si = si->next;
- }
- if (!write_bool(mode_rpl_enter))
- goto done;
- #else
- if (!write_bool(false)) /* No, big stack block does not exist */
- goto done;
- #endif
- if (!write_int(reg_alpha_length))
- goto done;
- if (!shell_write_saved_state(reg_alpha, 44))
- goto done;
- if (!write_int4(mode_sigma_reg))
- goto done;
- if (!write_int(mode_goose))
- goto done;
- if (!write_bool(mode_time_clktd))
- goto done;
- if (!write_bool(mode_time_clk24))
- goto done;
- if (!write_bool(mode_time_dmy))
- goto done;
- if (!shell_write_saved_state(&flags, sizeof(flags_struct)))
- goto done;
- if (!write_int(vars_count))
- goto done;
- if (!shell_write_saved_state(vars, vars_count * sizeof(var_struct)))
- goto done;
- for (i = 0; i < vars_count; i++)
- if (!persist_vartype(vars[i].value))
- goto done;
- if (!write_int(prgms_count))
- goto done;
- if (!shell_write_saved_state(prgms, prgms_count * sizeof(prgm_struct)))
- goto done;
- for (i = 0; i < prgms_count; i++)
- if (!shell_write_saved_state(prgms[i].text, prgms[i].size))
- goto done;
- if (!write_int(current_prgm))
- goto done;
- if (!write_int4(pc))
- goto done;
- if (!write_int(prgm_highlight_row))
- goto done;
- if (!write_int(varmenu_length))
- goto done;
- if (!shell_write_saved_state(varmenu, 7))
- goto done;
- if (!write_int(varmenu_rows))
- goto done;
- if (!write_int(varmenu_row))
- goto done;
- if (!shell_write_saved_state(varmenu_labellength, 6 * sizeof(int)))
- goto done;
- if (!shell_write_saved_state(varmenu_labeltext, 42))
- goto done;
- if (!write_int(varmenu_role))
- goto done;
- if (!write_int(rtn_sp))
- goto done;
- if (!shell_write_saved_state(&rtn_prgm, MAX_RTNS * sizeof(int)))
- goto done;
- if (!shell_write_saved_state(&rtn_pc, MAX_RTNS * sizeof(int4)))
- goto done;
- ret = true;
- done:
- free(array_list);
- return ret;
- }
- static bool unpersist_globals(int4 ver) GLOBALS_SECT;
- static bool unpersist_globals(int4 ver) {
- int4 n;
- int i;
- array_count = 0;
- array_list_capacity = 0;
- array_list = NULL;
- bool ret = false;
- bool bigstack = false;
- free_vartype(reg_x);
- if (!unpersist_vartype(®_x))
- goto done;
- free_vartype(reg_y);
- if (!unpersist_vartype(®_y))
- goto done;
- free_vartype(reg_z);
- if (!unpersist_vartype(®_z))
- goto done;
- free_vartype(reg_t);
- if (!unpersist_vartype(®_t))
- goto done;
- free_vartype(reg_lastx);
- if (!unpersist_vartype(®_lastx))
- goto done;
- if (ver >= 12) {
- /* we are on atleast version 12, so this block exists */
- if (!read_bool(&bigstack))
- goto done;
- }
-
- #ifdef BIGSTACK
- if (bigstack)
- {
-
- if (ver >= 17) {
- unpersist_undo();
- }
-
- stacksize = 20; /* backward compatible pre version 13 big stack */
-
- if (ver >= 13) {
- if (!read_int(&stacksize))
- goto done;
- while(bigstack_head != NULL)
- {
- shift_big_stack_down();
- free_vartype(reg_t);
- }
- }
- int i = stacksize - 4;
- stack_item *lastsi = NULL;
- while (i-- > 0) {
- vartype *v = NULL;
- if (!unpersist_vartype(&v))
- goto done;
- stack_item *si = new_stack_item(v);
- si->next = NULL;
- if (lastsi == NULL)
- bigstack_head = si;
- else
- lastsi->next = si;
- lastsi = si;
- }
- if (!read_bool(&mode_rpl_enter))
- goto done;
- }
- #endif
- if (!read_int(®_alpha_length)) {
- reg_alpha_length = 0;
- goto done;
- }
- if (shell_read_saved_state(reg_alpha, 44) != 44) {
- reg_alpha_length = 0;
- goto done;
- }
- if (!read_int4(&mode_sigma_reg)) {
- mode_sigma_reg = 11;
- goto done;
- }
- if (!read_int(&mode_goose)) {
- mode_goose = -1;
- goto done;
- }
- if (ver >= 16) {
- if (!read_bool(&mode_time_clktd)) {
- mode_time_clktd = false;
- goto done;
- }
- if (!read_bool(&mode_time_clk24)) {
- mode_time_clk24 = false;
- goto done;
- }
- if (!read_bool(&mode_time_dmy)) {
- mode_time_dmy = false;
- goto done;
- }
- }
- if (shell_read_saved_state(&flags, sizeof(flags_struct))
- != sizeof(flags_struct))
- goto done;
- vars_capacity = 0;
- if (vars != NULL) {
- free(vars);
- vars = NULL;
- }
- if (!read_int(&vars_count)) {
- vars_count = 0;
- goto done;
- }
- n = vars_count * sizeof(var_struct);
- vars = (var_struct *) malloc(n);
- if (vars == NULL) {
- vars_count = 0;
- goto done;
- }
- if (shell_read_saved_state(vars, n) != n) {
- free(vars);
- vars = NULL;
- vars_count = 0;
- goto done;
- }
- vars_capacity = vars_count;
- for (i = 0; i < vars_count; i++)
- vars[i].value = NULL;
- for (i = 0; i < vars_count; i++)
- if (!unpersist_vartype(&vars[i].value)) {
- purge_all_vars();
- goto done;
- }
- prgms_capacity = 0;
- if (prgms != NULL) {
- free(prgms);
- prgms = NULL;
- }
- if (!read_int(&prgms_count)) {
- prgms_count = 0;
- goto done;
- }
- n = prgms_count * sizeof(prgm_struct);
- prgms = (prgm_struct *) malloc(n);
- if (prgms == NULL) {
- prgms_count = 0;
- goto done;
- }
- if (shell_read_saved_state(prgms, n) != n) {
- free(prgms);
- prgms = NULL;
- prgms_count = 0;
- goto done;
- }
- prgms_capacity = prgms_count;
- for (i = 0; i < prgms_count; i++) {
- prgms[i].capacity = prgms[i].size;
- prgms[i].text = (unsigned char *) malloc(prgms[i].size);
- // TODO - handle memory allocation failure
- }
- for (i = 0; i < prgms_count; i++) {
- if (shell_read_saved_state(prgms[i].text, prgms[i].size)
- != prgms[i].size) {
- clear_all_prgms();
- goto done;
- }
- }
- if (!read_int(¤t_prgm)) {
- current_prgm = 0;
- goto done;
- }
- if (!read_int4(&pc)) {
- pc = -1;
- goto done;
- }
- if (!read_int(&prgm_highlight_row)) {
- prgm_highlight_row = 0;
- goto done;
- }
- if (!read_int(&varmenu_length)) {
- varmenu_length = 0;
- goto done;
- }
- if (shell_read_saved_state(varmenu, 7) != 7) {
- varmenu_length = 0;
- goto done;
- }
- if (!read_int(&varmenu_rows)) {
- varmenu_length = 0;
- goto done;
- }
- if (!read_int(&varmenu_row)) {
- varmenu_length = 0;
- goto done;
- }
- if (shell_read_saved_state(varmenu_labellength, 6 * sizeof(int))
- != 6 * sizeof(int))
- goto done;
- if (shell_read_saved_state(varmenu_labeltext, 42) != 42)
- goto done;
- if (!read_int(&varmenu_role))
- goto done;
- if (!read_int(&rtn_sp))
- goto done;
- if (shell_read_saved_state(rtn_prgm, MAX_RTNS * sizeof(int))
- != MAX_RTNS * sizeof(int))
- goto done;
- if (shell_read_saved_state(rtn_pc, MAX_RTNS * sizeof(int4))
- != MAX_RTNS * sizeof(int4))
- goto done;
- if (bin_dec_mode_switch)
- if (!convert_programs()) {
- clear_all_prgms();
- goto done;
- }
- #ifdef IPHONE
- if (ver == 12 || ver == 13) {
- // CMD_DROP redefined from 315 to 329, to resolve clash with
- // Underhill's COPAN extensions.
- convert_bigstack_drop();
- }
- #endif
- rebuild_label_table();
- ret = true;
- done:
- free(array_list);
- return ret;
- }
- void clear_all_prgms() {
- if (prgms != NULL) {
- int i;
- for (i = 0; i < prgms_count; i++)
- if (prgms[i].text != NULL)
- free(prgms[i].text);
- free(prgms);
- }
- prgms = NULL;
- prgms_capacity = 0;
- prgms_count = 0;
- if (labels != NULL)
- free(labels);
- labels = NULL;
- labels_capacity = 0;
- labels_count = 0;
- }
- int clear_prgm(const arg_struct *arg) {
- int prgm_index = NULL;
- int i, j;
- if (arg->type == ARGTYPE_LBLINDEX)
- prgm_index = labels[arg->val.num].prgm;
- else if (arg->type == ARGTYPE_STR) {
- if (arg->length == 0) {
- if (current_prgm < 0 || current_prgm >= prgms_count)
- return ERR_INTERNAL_ERROR;
- prgm_index = current_prgm;
- } else {
- int i;
- for (i = labels_count - 1; i >= 0; i--)
- if (string_equals(arg->val.text, arg->length,
- labels[i].name, labels[i].length))
- goto found;
- return ERR_LABEL_NOT_FOUND;
- found:
- prgm_index = labels[i].prgm;
- }
- }
- clear_all_rtns();
- if (prgm_index == current_prgm)
- pc = -1;
- else if (current_prgm > prgm_index)
- current_prgm--;
- free(prgms[prgm_index].text);
- for (i = prgm_index; i < prgms_count - 1; i++)
- prgms[i] = prgms[i + 1];
- prgms_count--;
- i = j = 0;
- while (j < labels_count) {
- if (j > i)
- labels[i] = labels[j];
- j++;
- if (labels[i].prgm > prgm_index) {
- labels[i].prgm--;
- i++;
- } else if (labels[i].prgm < prgm_index)
- i++;
- }
- labels_count = i;
- if (prgms_count == 0 || prgm_index == prgms_count) {
- int saved_prgm = current_prgm;
- int saved_pc = pc;
- goto_dot_dot();
- current_prgm = saved_prgm;
- pc = saved_pc;
- }
- update_catalog();
- return ERR_NONE;
- }
- void clear_prgm_lines(int4 count) {
- int4 frompc, deleted, i, j;
- if (pc == -1)
- pc = 0;
- frompc = pc;
- while (count > 0) {
- int command;
- arg_struct arg;
- get_next_command(&pc, &command, &arg, 0);
- if (command == CMD_END) {
- pc -= 2;
- break;
- }
- count--;
- }
- deleted = pc - frompc;
- for (i = pc; i < prgms[current_prgm].size; i++)
- prgms[current_prgm].text[i - deleted] = prgms[current_prgm].text[i];
- prgms[current_prgm].size -= deleted;
- pc = frompc;
- i = j = 0;
- while (j < labels_count) {
- if (j > i)
- labels[i] = labels[j];
- j++;
- if (labels[i].prgm == current_prgm) {
- if (labels[i].pc < frompc)
- i++;
- else if (labels[i].pc >= frompc + deleted) {
- labels[i].pc -= deleted;
- i++;
- }
- } else
- i++;
- }
- labels_count = i;
- invalidate_lclbls(current_prgm);
- clear_all_rtns();
- }
- void goto_dot_dot() {
- int command;
- arg_struct arg;
- if (prgms_count != 0) {
- /* Check if last program is empty */
- pc = 0;
- current_prgm = prgms_count - 1;
- get_next_command(&pc, &command, &arg, 0);
- if (command == CMD_END) {
- pc = -1;
- return;
- }
- }
- if (prgms_count == prgms_capacity) {
- prgm_struct *newprgms;
- int i;
- prgms_capacity += 10;
- newprgms = (prgm_struct *) malloc(prgms_capacity * sizeof(prgm_struct));
- // TODO - handle memory allocation failure
- for (i = 0; i < prgms_count; i++)
- newprgms[i] = prgms[i];
- if (prgms != NULL)
- free(prgms);
- prgms = newprgms;
- }
- current_prgm = prgms_count++;
- prgms[current_prgm].capacity = 0;
- prgms[current_prgm].size = 0;
- prgms[current_prgm].lclbl_invalid = 1;
- prgms[current_prgm].text = NULL;
- command = CMD_END;
- arg.type = ARGTYPE_NONE;
- store_command(0, command, &arg);
- pc = -1;
- }
- int mvar_prgms_exist() {
- int i;
- for (i = 0; i < labels_count; i++)
- if (label_has_mvar(i))
- return 1;
- return 0;
- }
- int label_has_mvar(int lblindex) {
- int saved_prgm;
- int4 pc;
- int command;
- arg_struct arg;
- if (labels[lblindex].length == 0)
- return 0;
- saved_prgm = current_prgm;
- current_prgm = labels[lblindex].prgm;
- pc = labels[lblindex].pc;
- pc += get_command_length(current_prgm, pc);
- get_next_command(&pc, &command, &arg, 0);
- current_prgm = saved_prgm;
- return command == CMD_MVAR;
- }
- int get_command_length(int prgm_index, int4 pc) {
- prgm_struct *prgm = prgms + prgm_index;
- int4 pc2 = pc;
- int command = prgm->text[pc2++];
- int argtype = prgm->text[pc2++];
- command |= (argtype & 240) << 4;
- argtype &= 15;
- if (command == CMD_CONVERT) pc2 += 2;
-
- if ((command == CMD_GTO || command == CMD_XEQ)
- && (argtype == ARGTYPE_NUM || argtype == ARGTYPE_LCLBL))
- pc2 += 4;
- switch (argtype) {
- case ARGTYPE_NUM:
- case ARGTYPE_NEG_NUM:
- case ARGTYPE_IND_NUM: {
- while ((prgm->text[pc2++] & 128) == 0);
- break;
- }
- case ARGTYPE_STK:
- case ARGTYPE_IND_STK:
- case ARGTYPE_COMMAND:
- case ARGTYPE_LCLBL:
- pc2++;
- break;
- case ARGTYPE_STR:
- case ARGTYPE_IND_STR: {
- pc2 += prgm->text[pc2] + 1;
- break;
- }
- case ARGTYPE_DOUBLE:
- pc2 += sizeof(phloat);
- break;
- }
- return pc2 - pc;
- }
- void get_next_command(int4 *pc, int *command, arg_struct *arg, int find_target){
- prgm_struct *prgm = prgms + current_prgm;
- int i;
- int4 target_pc;
- int4 orig_pc = *pc;
- *command = prgm->text[(*pc)++];
- arg->type = prgm->text[(*pc)++];
- *command |= (arg->type & 240) << 4;
- arg->type &= 15;
- if ((*command == CMD_GTO || *command == CMD_XEQ)
- && (arg->type == ARGTYPE_NUM
- || arg->type == ARGTYPE_LCLBL)) {
- if (find_target) {
- target_pc = 0;
- for (i = 0; i < 4; i++)
- target_pc = (target_pc << 8) | prgm->text[(*pc)++];
- if (target_pc != -1) {
- arg->target = target_pc;
- find_target = 0;
- }
- } else
- (*pc) += 4;
- } else {
- find_target = 0;
- arg->target = -1;
- }
-
- switch (arg->type) {
- case ARGTYPE_NUM:
- case ARGTYPE_NEG_NUM:
- case ARGTYPE_IND_NUM: {
- int4 num = 0;
- unsigned char c;
- do {
- c = prgm->text[(*pc)++];
- num = (num << 7) | (c & 127);
- } while ((c & 128) == 0);
- if (arg->type == ARGTYPE_NEG_NUM) {
- arg->type = ARGTYPE_NUM;
- num = -num;
- }
- arg->val.num = num;
- break;
- }
- case ARGTYPE_STK:
- case ARGTYPE_IND_STK:
- arg->val.stk = prgm->text[(*pc)++];
- break;
- case ARGTYPE_COMMAND:
- arg->val.cmd = prgm->text[(*pc)++];
- break;
- case ARGTYPE_LCLBL:
- arg->val.lclbl = prgm->text[(*pc)++];
- break;
- case ARGTYPE_STR:
- case ARGTYPE_IND_STR: {
- arg->length = prgm->text[(*pc)++];
- for (i = 0; i < arg->length; i++)
- arg->val.text[i] = prgm->text[(*pc)++];
- break;
- }
- case ARGTYPE_DOUBLE: {
- unsigned char *b = (unsigned char *) &arg->val_d;
- for (int i = 0; i < (int) sizeof(phloat); i++)
- *b++ = prgm->text[(*pc)++];
- break;
- }
- }
- if (*command == CMD_NUMBER && arg->type != ARGTYPE_DOUBLE) {
- /* argtype is ARGTYPE_NUM; convert to phloat */
- arg->val_d = arg->val.num;
- arg->type = ARGTYPE_DOUBLE;
- }
-
- if (find_target) {
- target_pc = find_local_label(arg);
- arg->target = target…
Large files files are truncated, but you can click here to view the full file