diff --git a/singlesource/bracmat.c b/singlesource/bracmat.c deleted file mode 100644 index 45b690f..0000000 --- a/singlesource/bracmat.c +++ /dev/null @@ -1,27572 +0,0 @@ -/* - Do not edit this file. It is generated by running `one.bra'. - The `one.bra' script combines many smaller .c and .h files. -*/ -#define SINGLESOURCE -/* Begin of potu.c */ -/* - Bracmat. Programming language with pattern matching on tree structures. - Copyright (C) 2002 Bart Jongejan - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - 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, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -/* -email: bartj@hum.ku.dk -*/ - -#define DATUM "27 September 2023" -#define VERSION "6.19.2" -#define BUILD "290" -/* -COMPILATION ------------ -It is assumed that the hardware is litte-endian, (which has become the most -common these days). - -If you can compile successfully but cannot run the program succesfully, -try putting -DBIGENDIAN on the command line of the compiler. -This works of course only if the machine's hardware is big-endian. - -The program only utilizes standard libraries. - -Until 2012, the source code consisted of a single file, bracmat.c. -Because XML is becoming more popular, a separate source file, xml.c -implemented reading XML files. Another separate source file, json.c, -implemented reading JSON files. -Since autumn 2023, bracmat.c is again complete source code for bracmat, -but it is no longer meant to be edited by hand! bracmat.c is now -in the folder 'singlesource' and created from multiple source files that -are in the 'src' folder. The script doing this is called 'one.bra'. It is -of course also possible to compile the source code in 'src' without first -creating bracmat.c. - -On *N?X, just compile with - - gcc -std=c99 -pedantic -Wall -O3 -static -DNDEBUG -o bracmat bracmat.c -lm - -The options are not necessary to successfully compile the program just - - gcc *.c -lm - -also works and produces the executable a.out. - -Profiling: - - gcc -Wall -c -pg -DNDEBUG bracmat.c - gcc -Wall -pg bracmat.o -lm - ./a.out 'get$"valid.bra";!r' - gprof a.out - -Test coverage: -(see http://gcc.gnu.org/onlinedocs/gcc/Invoking-Gcov.html#Invoking-Gcov) - - gcc -fprofile-arcs -ftest-coverage -DNDEBUG bracmat.c -lm - ./a.out - gcov bracmat.c - -*/ -/* How to compile with a ANSI-C compiler or newer -(OBSOLETE, Norcroft compiler, Microsoft qcl, Borland C, Atari compiler are not C99 compatible) - -Archimedes ANSI-C release 3: -*up -*del. :0.$.c.clog -*spool :0.$.c.clog -*cc bracmat -*spool - -With RISC_OS functions: - -cc bracmat - -file cc (in directory c): - -| >cc -up -delete $.c.clog -spool $.c.clog -cc -c %0 -IRAM:$.RISC_OSLib -if Sys$ReturnCode = 0 then run c.li %0 else spool - -file li (in directory c): - -| >li -link -o %0 o.%0 RAM:$.RISC_OSLib.o.RISC_OSLib RAM:$.Clib.o.Stubs -||G -spool -if Sys$ReturnCode = 0 then squeeze %0 else echo |G - -Microsoft QUICKC (MS-DOS) (compact and large model both possible) -qcl /Ox /AC /F D000 bracmat.c -Microsoft optimizing compiler V5.1 -cl /Ox /AC /F D000 bracmat.c - -Borland TURBOC (MS-DOS) V2.0 -tcc -w -f- -r- -mc -K- bracmat - -Atari : define -DATARI because of BIGENDIAN and extern int _stksize = -1; - and -DW32 but only if (int)==(long) -*/ -/* -NOTES -===== - -2002.12.15 ----------- -This is the open source version of Bracmat. - -Originally, Bracmat was written in Basic for the Amstrad computer. Its sole -purpose was to derive a simple expression for the curvature of a model -space-time, starting from the components of the metric. The only operations -the program was capable to perform were multiplications, exponentiations, -logarithms, and partial derivatives. The expressions were a mix of numbers -and symbolic variables, like "a+2*b". Thus, "a+a" was simplified to "2*a". - -The second version of Bracmat, about 1988, was developed in Ansi C and run -on an Acorn Archimedes. Great care was taken to make the program portable to -other hardware, such as Atari, VAX and even the PC. The PC architecture, with -its limited memory, its 16 bit architecture and its limitation on the size of -the program stack, posed some severe limitations on the program. Therefore -great care was taken to limit the use of the stack to a minimum. This has -lead to some rather large functions (to save stack-consuming function calls). - -The C version became a true programnming language, with program variables, -logical operators and function calls. The syntax, however, was not changed. -For example, instead of using "if...then...else...", I decided to write -something like "...&...|...", using lazy evaluation of the infix binary -logical operators "&" (AND) and "|" (OR) for program control. - -The logical operators, of course, should test for operands being "true" or -"false". The main provider of interesting truth values became the pattern -matching operator ":", which tests whether the pattern (the rhs-operand) -matches the subject (the lhs-operand). The single outstanding feature of -Bracmat is, in fact, its pattern recognition, which works on tree structures, -not on strings of characters. - -Bracmat was also extended with a few operators that makes this programming -language interesting in the field of computational linguistics, namely the -blank " ", the comma "," and the full stop ".". (The interpunction symbols -"?", "!" and ";" were already 'taken' to serve other purposes.) -*/ - -/* Begin of defines01.h */ - -#define DEBUGBRACMAT 0 /* Implement dbg'(expression), see DBGSRC macro */ -#define REFCOUNTSTRESSTEST 0 -#define DOSUMCHECK 0 -#define CHECKALLOCBOUNDS 0 /* only if NDEBUG is false */ -#define PVNAME 0 /* Allocate strings of variable names separately from variable - structure. Does not give better results. */ -#define STRINGMATCH_CAN_BE_NEGATED 0 /* ~@(a:a) */ -#define CODEPAGE850 0 -#define MAXSTACK 0 /* 1: Show max stack depth (eval function only)*/ -#define CUTOFFSUGGEST 1 -#define READMARKUPFAMILY 1 /* Read SGML, HTML and XML files. - (include xml.c in your project!) */ -#define READJSON 1 /* Read JSON files. (Include json.c in your project!) */ -#define SHOWMEMBLOCKS 0 -#define DATAMATCHESITSELF 0 /* An experiment from August 2021. -The idea is to make matching a data structure with itself faster by just -checking whether they have the same address. Only structures with no prefixes -anywhere and only using the operators DOT COMMA WHITE PLUS TIMES EXP LOG can be -compared safely this way. For example, - - (a=x+y+x) & ('$a:'$a) - -and - - (a=(x.y),z) & !a:!a - -succeed, whereas - - (b=x ~%) & ('$b:'$b) - -fails. - -To make this work, an extra bit has to be reserved in each node. The overhead -of setting the bit turns out to outweigh the advantage: programs become a -little bit slower, not faster. -*/ - -#define INTSCMP 0 /* dangerous way of comparing strings */ -#define ICPY 0 /* copy word by word instead of byte by byte */ - -/* Optional #defines for debugging and adaptation to machine */ - -#define SHOWMAXALLOCATED 1 /* Show the maximum number of allocated nodes. */ -#define SHOWCURRENTLYALLOCATED 0 /* Same, plus current number of allocated nodes, in groups of - 4,8,12 and >12 bytes */ - -#define EXPAND 0 - -#if DOSUMCHECK -#define BMALLOC(x,y,z) Bmalloc(x,y,z) -#define bmalloc(n) BMALLOC(__FILE__,__LINE__,n) -#else -#define bmalloc(n) Bmalloc(n) -#endif -/* End of defines01.h */ - -/* Begin of platformdependentdefs.h */ - -/* There are no optional #defines below this line. */ -#if defined __BYTE_ORDER && defined __LITTLE_ENDIAN /* gcc on linux defines these */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define BIGENDIAN 0 -#else -#define BIGENDIAN 1 -#endif -#endif - -#ifndef BIGENDIAN - -#if defined mc68000 || defined MC68000 || defined mc68010 || defined mc68020 || defined mc68030 || defined ATARI || defined sparc || defined __hpux || defined __hpux__ -#define BIGENDIAN 1 -#endif - -#endif - -#ifndef BIGENDIAN -#define BIGENDIAN 0 -#endif - -#if defined BRACMATEMBEDDED -#define _BRACMATEMBEDDED 1 -#else -#define _BRACMATEMBEDDED 0 -#endif - -#if (defined _Windows || defined _MT /*multithreaded, VC6.0*/)&& (!defined _CONSOLE && !defined __CONSOLE__ || defined NOTCONSOLE || _BRACMATEMBEDDED) -/* _CONSOLE defined by Visual C++ and __CONSOLE__ seems always to be defined in C++Builder */ -#define MICROSOFT_WINDOWS_API 1 -#else -#define MICROSOFT_WINDOWS_API 0 -#endif - -#if MICROSOFT_WINDOWS_API && defined POLL /* Often no need for polling in multithreaded apps.*/ -#define JMP 1 /* 1: listen to WM_QUIT message. 0: Do not listen to WM_QUIT message. */ -#else -#define JMP 0 -#endif - -#if _BRACMATEMBEDDED -#include "bracmat.h" -#endif - -#if defined sun && !defined __GNUC__ -#include /* SEEK_SET, SEEK_CUR */ -#define ALERT 7 -#define strtoul(a,b,c) strtol(a,b,c) -#else -#include -#endif - -#include - -#ifndef ALERT -#define ALERT '\a' -#endif - -#include -#include -#include - -#if defined _WIN64 || defined _WIN32 -#ifdef __BORLANDC__ -typedef unsigned int UINT32_T; -typedef signed int INT32_T; -#else -typedef unsigned __int32 UINT32_T; /* pre VS2010 has no int32_t */ -typedef signed __int32 INT32_T; /* pre VS2010 has no int32_t */ -#define STRTOUL _strtoui64 -#define STRTOL _strtoi64 -#endif -#else -#if defined __EMSCRIPTEN__ /* This is set if compiling with __EMSCRIPTEN__. */ -#define STRTOUL strtoull -#define STRTOL strtoll -#endif -#endif - -#if defined _WIN64 - /*Microsoft*/ -#define WORD32 0 -#define _4 1 -#define _5_6 1 -#define LONG long long -#define ULONG unsigned long long -#define LONGU "%llu" -#define LONGD "%lld" -#define LONGnD "%*lld" -#define LONG0D "%0lld" -#define LONG0nD "%0*lld" -#define LONGX "%llX" -/* -#define STRTOUL _strtoui64 -#define STRTOL _strtoi64 -*/ -#define FSEEK _fseeki64 -#define FTELL _ftelli64 -#else -#if !defined NO_C_INTERFACE && !defined _WIN32 -#if UINT_MAX == 4294967295ul -typedef unsigned int UINT32_T; -#elif ULONG_MAX == 4294967295ul -typedef unsigned long UINT32_T; -#endif -#endif -#if !defined NO_LOW_LEVEL_FILE_HANDLING -#if UINT_MAX == 4294967295ul -typedef signed int INT32_T; -#elif ULONG_MAX == 4294967295ul -typedef signed long INT32_T; -#endif -#endif -#if LONG_MAX <= 2147483647L -#define WORD32 1 -#define _4 1 -#define _5_6 1 -#else -#define WORD32 0 -#define _4 1 -#define _5_6 1 -#endif -#define LONG long -#define ULONG unsigned long -#define LONGU "%lu" -#define LONGD "%ld" -#define LONGnD "%*ld" -#define LONG0D "%0ld" -#define LONG0nD "%0*ld" -#define LONGX "%lX" -#ifndef STRTOUL -#define STRTOUL strtoul -#define STRTOL strtol -#endif -#define FSEEK fseek -#define FTELL ftell -#endif - -#if BIGENDIAN -#define iobj lobj -#define O(a,b,c) (a*0x1000000L+b*0x10000L+c*0x100) -#define notO 0xFF -#else -#if !WORD32 -#define iobj lobj -#endif -#define O(a,b,c) (a+b*0x100+c*0x10000L) -#define notO 0xFF000000 -#endif - -#define not_built_in(pn) (((pn)->v.fl & IS_OPERATOR) || (((pn)->u.lobj) & (notO))) - -#if defined __TURBOC__ || defined __MSDOS__ || defined _WIN32 || defined __GNUC__ -#define DELAY_DUE_TO_INPUT -#endif - -#include -#ifndef CLOCKS_PER_SEC -#ifdef CLK_TCK /* pre-ANSI-C */ -#define CLOCKS_PER_SEC CLK_TCK -#else -#if defined sun -#define CLOCKS_PER_SEC 1000000 /* ??? */ -#endif -#endif -#endif - -/*#define ARM */ /* assume it isn't an Acorn */ - -#if (defined __TURBOC__ && !defined __WIN32__) || (defined ARM && !defined __SYMBIAN32__) -#define O_S 1 /* 1 = with operating system interface swi$ (RISC_OS or TURBO-C), 0 = without */ -#else -#define O_S 0 -#endif - -#if defined ARM -#if O_S -#if defined __GNUC__ && !defined sparc -#include "sys/os.h" -#else -#include "os.h" -#endif -#endif -#endif - -#ifdef __TURBOC__ -#if O_S -typedef struct - { - int r[10]; - } os_regset; -#endif -#endif - -#if WORD32 -#define RADIX 10000L -#define TEN_LOG_RADIX 4L -#define HEADROOM 20L -#else -#if defined _WIN64 -#define RADIX 100000000LL -#define HEADROOM 800LL -#else -#define RADIX 100000000L -#define HEADROOM 800L -#endif -#define TEN_LOG_RADIX 8L -#endif - -#if ICPY -#define MEMCPY(a,b,n) icpy((LONG*)(a),(LONG*)(b),n) -#else -#define MEMCPY(a,b,n) memcpy((char *)(a),(char *)(b),n) -#endif -#if defined EMSCRIPTEN -#ifndef __EMSCRIPTEN__ -#define __EMSCRIPTEN__ -#endif -#endif -#if defined __EMSCRIPTEN__ /* This is set if compiling with __EMSCRIPTEN__. */ -#define EMSCRIPTEN_HTML 1 /* set to 1 if using __EMSCRIPTEN__ to convert this file to HTML*/ -#define GLOBALARGPTR 0 - -#define NO_C_INTERFACE -#define NO_FILE_RENAME -#define NO_FILE_REMOVE -#define NO_SYSTEM_CALL -#define NO_LOW_LEVEL_FILE_HANDLING -#define NO_FOPEN -#define NO_EXIT_ON_NON_SEVERE_ERRORS - -#else -#define EMSCRIPTEN_HTML 0 /* Normally this should be 0 */ -#define GLOBALARGPTR 1 /* Normally this should be 1 */ -#endif - -#if EMSCRIPTEN_HTML -/* must be 0: compiling with emcc (__EMSCRIPTEN__ C to JavaScript compiler) */ -#else -#define GLOBALARGPTR 1 /* 0 if compiling with emcc (__EMSCRIPTEN__ C to JavaScript compiler) */ -#endif - -#if DEBUGBRACMAT -#define DBGSRC(code) if(debug){code} -#else -#define DBGSRC(code) -#endif - -#if INTSCMP -#define STRCMP(a,b) intscmp((LONG*)(a),(LONG*)(b)) -#else -#define STRCMP(a,b) strcmp((char *)(a),(char *)(b)) -#endif - -#if SHOWMAXALLOCATED -#define BEZ O('b','e','z') -#endif - -#if O_S -#define SWI O('s','w','i') -#endif - -#if !defined NO_C_INTERFACE -#define ALC O('a','l','c') -#define FRE O('f','r','e') -#define PEE O('p','e','e') -#define POK O('p','o','k') -#define FNC O('f','n','c') -#endif - -#if !defined NO_FILE_RENAME -#define REN O('r','e','n') /* rename a file */ -#endif - -#if !defined NO_FILE_REMOVE -#define RMV O('r','m','v') /* remove a file */ -#endif - -#if !defined NO_SYSTEM_CALL -#define SYS O('s','y','s') -#endif - -#if !defined NO_LOW_LEVEL_FILE_HANDLING -#define FIL O('f','i','l') -#define CHR O('C','H','R') -#define DEC O('D','E','C') -#define CUR O('C','U','R') -#define END O('E','N','D')/* SEEK_END: no guarantee that this works !!*/ -#define SET O('S','E','T') -#define STRt O('S','T','R') -#define TEL O('T','E','L') -#endif - -#define ARG O('a','r','g') /* arg$ returns next program argument*/ -#define APP O('A','P','P') -#define ASC O('a','s','c') -#define BIN O('B','I','N') -#define CLK O('c','l','k') -#define CON O('C','O','N') -#if DEBUGBRACMAT -#define DBG O('d','b','g') -#endif -#define DEN O('d','e','n') -#define DIV O('d','i','v') -#if CODEPAGE850 -#define DOS O('D','O','S') -#endif -#if _BRACMATEMBEDDED -#if defined PYTHONINTERFACE -#define NI O('N','i', 0 ) -#define NII O('N','i','!') -#endif -#endif - -#define Chr O('c','h','r') -#define Chu O('c','h','u') -#define D2X O('d','2','x') /* dec -> hex */ -#define ECH O('E','C','H') -/* err$foo redirects error messages to foo */ -#define ERR O('e','r','r') -#define EXT O('E','X','T') -#define FLG O('f','l','g') -#define GET O('g','e','t') -#define GLF O('g','l','f') /* The opposite of flg */ -#define HT O('H','T', 0 ) -#define IM O('i', 0 , 0 ) -#define JSN O('J','S','N') -#define LIN O('L','I','N') -#define LOW O('l','o','w') -#define LST O('l','s','t') -#define MAP O('m','a','p') -#define MEM O('M','E','M') -#define MINONE O('-','1',0) -#define ML O('M','L',0) -#define MMF O('m','e','m') -#define MOD O('m','o','d') -#define MOP O('m','o','p') -#define NEW O('N','E','W') -#define New O('n','e','w') -#define ONE O('1', 0 , 0 ) -#define PI O('p','i', 0 ) -#define PUT O('p','u','t') -#define PRV O('?', 0 , 0 ) -#define RAW O('R','A','W') -#define REV O('r','e','v') /* strrev */ -#define SIM O('s','i','m') -#define STG O('S','T','R') -#define STR O('s','t','r') -#define TBL O('t','b','l') -#define TRM O('T','R','M') -#define TWO O('2', 0 , 0 ) -#define TXT O('T','X','T') -#define UPP O('u','p','p') -#define UGC O('u','g','c') /* Unicode General Category, a two-letter string */ -#define UTF O('u','t','f') -#define VAP O('V','A','P') -#define Vap O('v','a','p') /* map for string instead of list */ -#define WHL O('w','h','l') -#define WYD O('W','Y','D') /* lst option for wider lines */ -#define X O('X', 0 , 0 ) -#define X2D O('x','2','d') /* hex -> dec */ -#define XX O('e', 0 , 0 ) - -#if GLOBALARGPTR -#define VOIDORARGPTR void -#else -#define VOIDORARGPTR va_list * pargptr -#endif - -#if !DEBUGBRACMAT -#define match(IND,SUB,PAT,SNIJAF,POS,LENGTH,OP) match(SUB,PAT,SNIJAF,POS,LENGTH,OP) -#if CUTOFFSUGGEST -#define stringmatch(IND,WH,SUB,SNIJAF,PAT,PKN,POS,LENGTH,SUGGESTEDCUTOFF,MAYMOVESTARTOFSUBJECT) stringmatch(SUB,SNIJAF,PAT,PKN,POS,LENGTH,SUGGESTEDCUTOFF,MAYMOVESTARTOFSUBJECT) -#else -#define stringmatch(IND,WH,SUB,SNIJAF,PAT,PKN,POS,LENGTH) stringmatch(SUB,SNIJAF,PAT,PKN,POS,LENGTH) -#endif -#endif - -#define NARROWLINELENGTH 80 -#define WIDELINELENGTH 120 -/* End of platformdependentdefs.h */ - -/* Begin of flags.h */ - -/* flags (prefixes) in node */ -#define NOT 1 /* ~ */ - /* Keep definition of NOT like this because of mixing of logical and bit - operators && || | ^ & */ -#define SUCCESS (1<< 1) -#define READY (1<< 2) -#define POSITION (1<< 3) /* [ */ -#define INDIRECT (1<< 4) /* ! */ -#define DOUBLY_INDIRECT (1<< 5) /* !! */ -#define FENCE (1<< 6) /* ` (within same byte as ATOM and NOT) */ -#define ATOM (1<< 7) /* @ */ -#define NONIDENT (1<< 8) /* % */ -#define GREATER_THAN (1<< 9) /* > */ -#define SMALLER_THAN (1<<10) /* < */ -#define NUMBER (1<<11) /* # */ -#define FRACTION (1<<12) /* / */ -#define UNIFY (1<<13) /* ? */ -#define IDENT (1<<14) -#define IMPLIEDFENCE (1<<15) /* 20070222 */ - /* 1<<16 test whether operator - 1<<17 operator - 1<<18 operator - 1<<19 operator - 1<<20 operator - 1<<21 latebind - */ -#if DATAMATCHESITSELF -#define SELFMATCHING (1<<23) /* 20210801 */ -#define BITWISE_OR_SELFMATCHING |SELFMATCHING -#else -#define BITWISE_OR_SELFMATCHING -#endif - -#if WORD32 -#else -#if DATAMATCHESITSELF -#define BUILT_IN (1<<24) /* 20210801 only used for objects (operator =) */ -#define CREATEDWITHNEW (1<<25) /* 20210801 only used for objects (operator =) */ -#else -#define BUILT_IN (1<<23) /* 20210801 only used for objects (operator =) */ -#define CREATEDWITHNEW (1<<24) /* 20210801 only used for objects (operator =) */ -#endif -#endif - -/* operator leaf optab comment -Flgs 0 NOT - 1 SUCCESS - 2 READY - 3 POSITION - 4 INDIRECT - 5 DOUBLY_INDIRECT - 6 FENCE - 7 ATOM - 8 NONIDENT - 9 GREATER_THAN - 10 SMALLER_THAN - 11 NUMBER - 12 FRACTION - 13 UNIFY - 14 IDENT - 15 IMPLIEDFENCE - 16 IS_OPERATOR SHL - 17 (operators 0-14) QNUMBER - 18 " MINUS - 19 " QNUL - 20 " QFRACTION - 21 LATEBIND NOOP - 22 SELFMATCHING Toggles with DATAMATCHESITSELF - 23 BUILT_IN ONLY for 64 bit platform - 24 CREATEDWITHNEW ONLY for 64 bit platform - 25 (reference count) NON_REF_COUNT_BITS 25 or 23 - 26 " - 27 " - 28 " - 29 " - 30 " - 31 " - -Reference count starts with 0, not 1 - -About reference counting. -In a 32-bit version of Bracmat, most nodes have no more than 7 bits for refcounting. -Copies must be (and are) made as needed. -Objects (nodes with = ('EQUALS') have refcounters that are at least word-size. -*/ - -#if DATAMATCHESITSELF -#if WORD32 -#define NON_REF_COUNT_BITS 24 /* prefixes, hidden flags, operator bits */ -#else -#define NON_REF_COUNT_BITS 26 /* prefixes, hidden flags, operator bits */ -#endif -#else -#if WORD32 -#define NON_REF_COUNT_BITS 23 /* prefixes, hidden flags, operator bits */ -#else -#define NON_REF_COUNT_BITS 25 /* prefixes, hidden flags, operator bits */ -#endif -#endif - -#if REFCOUNTSTRESSTEST -#define REF_COUNT_BITS 1 -#endif - -#if !defined REF_COUNT_BITS -#if WORD32 -#define REF_COUNT_BITS (32 - NON_REF_COUNT_BITS) -#else -#define REF_COUNT_BITS (64 - NON_REF_COUNT_BITS) -#endif -#endif - -#define SHL 16 -#define REF 23 -#define OPSH (SHL+1) -#define IS_OPERATOR (1 << SHL) -#define EQUALS (( 0<> NON_REF_COUNT_BITS) << NON_REF_COUNT_BITS) -#if WORD32 -#define COPYFILTER ~ALL_REFCOUNT_BITS_SET -#else -#define COPYFILTER ~(ALL_REFCOUNT_BITS_SET | BUILT_IN | CREATEDWITHNEW) -#endif - -#define VISIBLE_FLAGS_WEAK (INDIRECT|DOUBLY_INDIRECT|FENCE|UNIFY) -#define VISIBLE_FLAGS_NON_COMP (INDIRECT|DOUBLY_INDIRECT|ATOM|NONIDENT|NUMBER|FRACTION|UNIFY) /* allows < > ~< and ~> as flags on numbers */ -#define VISIBLE_FLAGS_POS0 (INDIRECT|DOUBLY_INDIRECT|NONIDENT|QFRACTION|QDOUBLE|UNIFY|QNUMBER) -#define VISIBLE_FLAGS_POS (INDIRECT|DOUBLY_INDIRECT|NONIDENT|QFRACTION|QDOUBLE|UNIFY|QNUMBER|NOT|GREATER_THAN|SMALLER_THAN) -#define VISIBLE_FLAGS (INDIRECT|DOUBLY_INDIRECT|ATOM|NONIDENT|NUMBER|FRACTION|UNIFY|NOT|GREATER_THAN|SMALLER_THAN|FENCE|POSITION) - -#define HAS_VISIBLE_FLAGS_OR_MINUS(psk) ((psk)->v.fl & (VISIBLE_FLAGS|MINUS)) -#define RATIONAL(psk) (((psk)->v.fl & (QNUMBER|IS_OPERATOR|VISIBLE_FLAGS)) == QNUMBER) -#define RATIONAL_COMP(psk) (((psk)->v.fl & (QNUMBER|QDOUBLE|IS_OPERATOR|VISIBLE_FLAGS_NON_COMP)) == QNUMBER) -#define RATIONAL_COMP_NOT_NUL(psk) (((psk)->v.fl & (QNUMBER|QNUL|IS_OPERATOR|VISIBLE_FLAGS_NON_COMP)) == QNUMBER) -#define RATIONAL_WEAK(psk) (((psk)->v.fl & (QNUMBER|IS_OPERATOR|INDIRECT|DOUBLY_INDIRECT|FENCE|UNIFY)) == QNUMBER)/* allows < > ~< and ~> as flags on numbers */ -#define LESS(psk) (((psk)->v.fl & (VISIBLE_FLAGS_POS)) == (QNUMBER|SMALLER_THAN)) -#define LESS_EQUAL(psk) (((psk)->v.fl & (VISIBLE_FLAGS_POS)) == (QNUMBER|NOT|GREATER_THAN)) -#define MORE_EQUAL(psk) (((psk)->v.fl & (VISIBLE_FLAGS_POS)) == (QNUMBER|NOT|SMALLER_THAN)) -#define MORE(psk) (((psk)->v.fl & (VISIBLE_FLAGS_POS)) == (QNUMBER|GREATER_THAN)) -#define UNEQUAL(psk) (((psk)->v.fl & (VISIBLE_FLAGS_POS)) == (QNUMBER|NOT)) -#define LESSORMORE(psk) (((psk)->v.fl & (VISIBLE_FLAGS_POS)) == (QNUMBER|SMALLER_THAN|GREATER_THAN)) -#define EQUAL(psk) (((psk)->v.fl & (VISIBLE_FLAGS_POS)) == QNUMBER) -#define NOTLESSORMORE(psk) (((psk)->v.fl & (VISIBLE_FLAGS_POS)) == (QNUMBER|NOT|SMALLER_THAN|GREATER_THAN)) - -#define NUMBERFLAGS (QNUMBER|QDOUBLE|NOT|SMALLER_THAN|GREATER_THAN) -#define FLESS(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|QDOUBLE|SMALLER_THAN)) -#define FLESS_EQUAL(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|QDOUBLE|NOT|GREATER_THAN)) -#define FMORE_EQUAL(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|QDOUBLE|NOT|SMALLER_THAN)) -#define FMORE(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|QDOUBLE|GREATER_THAN)) -#define FUNEQUAL(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|QDOUBLE|NOT)) -#define FLESSORMORE(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|QDOUBLE|SMALLER_THAN|GREATER_THAN)) -#define FEQUAL(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|QDOUBLE)) -#define FNOTLESSORMORE(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|QDOUBLE|NOT|SMALLER_THAN|GREATER_THAN)) - -#define ILESS(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|SMALLER_THAN)) -#define ILESS_EQUAL(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|NOT|GREATER_THAN)) -#define IMORE_EQUAL(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|NOT|SMALLER_THAN)) -#define IMORE(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|GREATER_THAN)) -#define IUNEQUAL(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|NOT)) -#define ILESSORMORE(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|SMALLER_THAN|GREATER_THAN)) -#define IEQUAL(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER)) -#define INOTLESSORMORE(psk) (((psk)->v.fl & (NUMBERFLAGS)) == (QNUMBER|NOT|SMALLER_THAN|GREATER_THAN)) - -#define INTEGER(pn) (((pn)->v.fl & (QNUMBER|QFRACTION|QDOUBLE|IS_OPERATOR|VISIBLE_FLAGS)) == QNUMBER) -#define INTEGER_COMP(pn) (((pn)->v.fl & (QNUMBER|QFRACTION|QDOUBLE|IS_OPERATOR|VISIBLE_FLAGS_NON_COMP)) == QNUMBER) - -#define INTEGER_NOT_NEG(pn) (((pn)->v.fl & (QNUMBER|MINUS|QFRACTION|QDOUBLE|IS_OPERATOR|VISIBLE_FLAGS)) == QNUMBER) -#define INTEGER_NOT_NEG_COMP(pn) (((pn)->v.fl & (QNUMBER|MINUS|QFRACTION|QDOUBLE|IS_OPERATOR|VISIBLE_FLAGS_NON_COMP)) == QNUMBER) - -#define INTEGER_POS(pn) (((pn)->v.fl & (QNUMBER|MINUS|QNUL|QFRACTION|QDOUBLE|IS_OPERATOR|VISIBLE_FLAGS)) == QNUMBER) -#define INTEGER_POS_COMP(pn) (((pn)->v.fl & (QNUMBER|MINUS|QNUL|QFRACTION|QDOUBLE|IS_OPERATOR|VISIBLE_FLAGS_NON_COMP)) == QNUMBER) - -#define INTEGER_NOT_NUL_COMP(pn) (((pn)->v.fl & (QNUMBER|QNUL|QFRACTION|QDOUBLE|IS_OPERATOR|VISIBLE_FLAGS_NON_COMP)) == QNUMBER) -#define HAS_MINUS_SIGN(pn) (((pn)->v.fl & (MINUS|IS_OPERATOR)) == MINUS) - -#define RAT_NUL(pn) (((pn)->v.fl & (QNUL|IS_OPERATOR|VISIBLE_FLAGS)) == QNUL) -#define RAT_NUL_COMP(pn) (((pn)->v.fl & (QNUL|IS_OPERATOR|VISIBLE_FLAGS_NON_COMP)) == QNUL) -#define RAT_NEG(pn) (((pn)->v.fl & (QNUMBER|MINUS|IS_OPERATOR|VISIBLE_FLAGS)) == (QNUMBER|MINUS)) -#define RAT_NEG_COMP(pn) (((pn)->v.fl & (QNUMBER|MINUS|IS_OPERATOR|VISIBLE_FLAGS_NON_COMP)) == (QNUMBER|MINUS)) - -#define RAT_RAT(pn) (((pn)->v.fl & (QNUMBER|QFRACTION|QDOUBLE|IS_OPERATOR|VISIBLE_FLAGS)) == (QNUMBER|QFRACTION)) - -#define RAT_RAT_COMP(pn) (((pn)->v.fl & (QNUMBER|QFRACTION|QDOUBLE|IS_OPERATOR|VISIBLE_FLAGS_NON_COMP)) == (QNUMBER|QFRACTION)) -#define IS_ONE(pn) ((pn)->u.lobj == ONE && !((pn)->v.fl & (MINUS | VISIBLE_FLAGS))) -#define IS_NIL(pn) ((pn)->u.lobj == 0 && !((pn)->v.fl & (MINUS | VISIBLE_FLAGS))) - -#define functionFail(x) ((x)->v.fl ^= SUCCESS,(x)) -#define functionOk(x) (x) -/* End of flags.h */ - -/* Begin of nodedefs.h */ - -/* Begin of nodestruct.h */ - -typedef union - { -#ifndef NDEBUG - struct - { - ULONG Not : 1; /* ~ */ - ULONG success : 1; - ULONG ready : 1; - ULONG position : 1; /* [ */ - - ULONG indirect : 1; /* ! */ - ULONG doubly_indirect : 1; /* !! */ - ULONG fence : 1; /* ` (within same byte as ATOM and NOT) */ - ULONG atom : 1; /* @ */ - - ULONG nonident : 1; /* % */ - ULONG greater_than : 1; /* > */ - ULONG smaller_than : 1; /* < */ - ULONG number : 1; /* # */ - - ULONG breuk : 1; /* / */ - ULONG unify : 1; /* ? */ - ULONG ident : 1; - ULONG impliedfence : 1; - - ULONG is_operator : 1; - ULONG binop : 4; /* only if operator node*/ - /* EQUALS DOT COMMA OR AND MATCH WHITE PLUS TIMES EXP LOG DIF FUU FUN UNDERSCORE */ - ULONG latebind : 1; -#if WORD32 -#else - ULONG built_in : 1; /* only used for objects (operator =) */ - ULONG createdWithNew : 1; /* only used for objects (operator =) */ -#endif - ULONG refcount : REF_COUNT_BITS; - } node; - struct - { - ULONG Not : 1; /* ~ */ - ULONG success : 1; - ULONG ready : 1; - ULONG position : 1; /* [ */ - - ULONG indirect : 1; /* ! */ - ULONG doubly_indirect : 1; /* !! */ - ULONG fence : 1; /* ` (within same byte as ATOM and NOT) */ - ULONG atom : 1; /* @ */ - - ULONG nonident : 1; /* % */ - ULONG greater_than : 1; /* > */ - ULONG smaller_than : 1; /* < */ - ULONG number : 1; /* # */ - - ULONG breuk : 1; /* / */ - ULONG unify : 1; /* ? */ - ULONG ident : 1; - ULONG impliedfence : 1; - - ULONG is_operator : 1; - ULONG qgetal : 1; /* only if leaf */ - ULONG minus : 1; /* only if leaf */ - ULONG qnul : 1; /* only if leaf */ - ULONG qbreuk : 1; /* only if leaf */ - - ULONG latebind : 1; -#if WORD32 -#else - ULONG built_in : 1; /* only used for objects (operator =) */ - ULONG createdWithNew : 1; /* only used for objects (operator =) */ -#endif - ULONG refcount : REF_COUNT_BITS; - } leaf; -#endif - ULONG fl; - } tFlags; - -typedef struct sk - { - tFlags v; - - union - { - struct - { - struct sk* left, * right; - } p; - LONG lobj; /* This part of the structure can be used for comparisons - with short strings that fit into one word in one machine - operation, like "\0\0\0\0" or "1\0\0\0" */ - unsigned char obj; - char sobj; - } u; - } sk; - -typedef sk* psk; -typedef psk* ppsk; - -typedef struct knode - { - tFlags v; - psk left, right; - } knode; - -typedef struct stringrefnode - { - tFlags v; - psk pnode; - char* str; - size_t length; - } stringrefnode; - -typedef psk function_return_type; - -/* End of nodestruct.h */ - -#define RIGHT u.p.right -#define LEFT u.p.left -#define OBJ(p) &((p).u.obj) -#define LOBJ(p) ((p).u.lobj) -#define POBJ(p) &((p)->u.obj) -#define SPOBJ(p) &((p)->u.sobj) -#define PLOBJ(p) ((p)->u.lobj) - -#define Qnumber psk - -#define QOBJ(p) &(p) -#define QPOBJ(p) p - -#define FILTERS (FRACTION | NUMBER | SMALLER_THAN | GREATER_THAN | ATOM | NONIDENT) -#define ATOMFILTERS (FRACTION | NUMBER | SMALLER_THAN | GREATER_THAN | ATOM | FENCE | IDENT) -#define SATOMFILTERS (/*ATOM | */FENCE | IDENT) - -#define FLGS (FILTERS | FENCE | DOUBLY_INDIRECT | INDIRECT | POSITION) - -#define NEGATION(Flgs,flag) ((Flgs & NOT ) && \ - (Flgs & FILTERS) >= (flag) && \ - (Flgs & FILTERS) < ((flag) << 1)) -#define ANYNEGATION(Flgs) ((Flgs & NOT ) && (Flgs & FILTERS)) -#define ASSERTIVE(Flgs,flag) ((Flgs & flag) && !NEGATION(Flgs,flag)) -#define FAIL (pat->v.fl & NOT) -#define NOTHING(p) (((p)->v.fl & NOT) && !((p)->v.fl & FILTERS)) -#define NOTHINGF(Flgs) ((Flgs & NOT) && !(Flgs & FILTERS)) -#define BEQUEST (FILTERS | FENCE | UNIFY) -#define UNOPS (UNIFY | FLGS | NOT | MINUS) -#define HAS_UNOPS(a) ((a)->v.fl & UNOPS) -#define HAS__UNOPS(a) (is_op(a) && (a)->v.fl & (UNIFY | FLGS | NOT)) -#define IS_VARIABLE(a) ((a)->v.fl & (UNIFY | INDIRECT | DOUBLY_INDIRECT)) -#define IS_BANG_VARIABLE(a) ((a)->v.fl & (INDIRECT | DOUBLY_INDIRECT)) - -#define OPERATOR ((0xF<v.fl & OPERATOR) -#define kopo(pn) ((pn).v.fl & OPERATOR) -#define is_op(pn) ((pn)->v.fl & IS_OPERATOR) -#define is_object(pn) (((pn)->v.fl & OPERATOR) == EQUALS) -#define klopcode(pn) (Op(pn) >> OPSH) - -#define nil(p) knil[klopcode(p)] - -#define shared(pn) ((pn)->v.fl & ALL_REFCOUNT_BITS_SET) -#define currRefCount(pn) (((pn)->v.fl & ALL_REFCOUNT_BITS_SET) >> NON_REF_COUNT_BITS) - -/* End of nodedefs.h */ - -/* Begin of nonnodetypes.h */ - -typedef int Boolean; - -#define TRUE 1 -#define FALSE 0 - -#define RADIX2 (RADIX * RADIX) - -#define READBIN "rb" /* BIN is default for get$, overrule with option TXT */ -#define READTXT "r" -#define WRITEBIN "wb" /* BIN is default for lst$, overrule with option TXT */ -#define APPENDBIN "ab" -#define WRITETXT "w" /* TXT is default for put$, overrule with option BIN */ -#define APPENDTXT "a" - -#define PRISTINE (1<<2) /* Used to initialise matchstate variables. */ -#define ONCE (1<<3) -#define POSITION_ONCE (1<<4) -#define POSITION_MAX_REACHED (1<<5) -#define SHIFT_LMR 8 -#define SHIFT_RMR 16 - -#ifndef UNREFERENCED_PARAMETER -#if defined _MSC_VER -#define UNREFERENCED_PARAMETER(P) (P) -#else -#define UNREFERENCED_PARAMETER(P) -#endif -#endif - -#define SHIFT_STR 0 -#define SHIFT_VAP 1 -#define SHIFT_MEM 2 -#define SHIFT_ECH 3 -#define SHIFT_ML 4 -#define SHIFT_TRM 5 -#define SHIFT_HT 6 -#define SHIFT_X 7 -#define SHIFT_JSN 8 -#define SHIFT_TXT 9 /* "r" "w" "a" */ -#define SHIFT_BIN 10 /* "rb" "wb" "ab" */ - -#define OPT_STR (1 << SHIFT_STR) -#define OPT_VAP (1 << SHIFT_VAP) -#define OPT_MEM (1 << SHIFT_MEM) -#define OPT_ECH (1 << SHIFT_ECH) -#define OPT_TXT (1 << SHIFT_TXT) -#define OPT_BIN (1 << SHIFT_BIN) - -/* FUNCTIONS */ - -#define isSUCCESS(x) ((x)->v.fl & SUCCESS) -#define isFENCE(x) (((x)->v.fl & (SUCCESS|FENCE)) == FENCE) -#define isSUCCESSorFENCE(x) ((x)->v.fl & (SUCCESS|FENCE)) -#define isFailed(x) (((x)->v.fl & (SUCCESS|FENCE)) == 0) -/* End of nonnodetypes.h */ - -/* Begin of typedobjectnode.h */ - -struct typedObjectnode; -typedef Boolean(*method_pnt)(struct typedObjectnode* This, ppsk arg); - -typedef struct method - { - char* name; - method_pnt func; - } method; - -#if WORD32 -typedef struct typedObjectnode /* createdWithNew == 1 */ - { - tFlags v; - psk left, right; /* left == nil, right == data (if vtab == NULL) - or name of object type, e.g. [set], [hash], [file], [float] (if vtab != NULL)*/ - union - { - struct - { - unsigned int refcount : 30; - unsigned int built_in : 1; - unsigned int createdWithNew : 1; - } s; - int Int : 32; - } u; - void* voiddata; - method* vtab; /* The last element n of the array must have vtab[n].name == NULL */ - } typedObjectnode; -#else -typedef struct typedObjectnode /* createdWithNew == 1 */ - { - tFlags v; - psk left, right; /* left == nil, right == data (if vtab == NULL) - or name of object type, e.g. [set], [hash], [file], [float] (if vtab != NULL)*/ - void* voiddata; - method* vtab; /* The last element n of the array must have vtab[n].name == NULL */ - } typedObjectnode; -#endif - -typedef struct - { - psk self; - psk object; - method_pnt theMethod; - } objectStuff; -/* End of typedobjectnode.h */ - -/* Begin of objectnode.h */ - -#if WORD32 -#define BUILTIN (1 << 30) -typedef struct objectnode /* createdWithNew == 0 */ - { - tFlags v; - psk left, right; - union - { - struct - { - unsigned int refcount : 30; - unsigned int built_in : 1; - unsigned int createdWithNew : 1; - } s; - int Int : 32; - } u; - } objectnode; -#else -typedef struct objectnode /* createdWithNew == 0 */ - { - tFlags v; - psk left, right; - } objectnode; -#endif - -#if WORD32 -#define INCREFCOUNT(a) { ((objectnode*)a)->u.s.refcount++;(a)->v.fl &= ((~ALL_REFCOUNT_BITS_SET)|ONEREF); } -#define DECREFCOUNT(a) { ((objectnode*)a)->u.s.refcount--;(a)->v.fl |= ALL_REFCOUNT_BITS_SET; } -#define REFCOUNTNONZERO(a) ((a)->u.s.refcount) -#define ISBUILTIN(a) ((a)->u.s.built_in) -#define ISCREATEDWITHNEW(a) ((a)->u.s.createdWithNew) -#define SETCREATEDWITHNEW(a) (a)->u.s.createdWithNew = 1 -#else -#define ISBUILTIN(a) ((a)->v.fl & BUILT_IN) -#define ISCREATEDWITHNEW(a) ((a)->v.fl & CREATEDWITHNEW) -#define SETCREATEDWITHNEW(a) (a)->v.fl |= CREATEDWITHNEW -#endif -/* End of objectnode.h */ - -/* Begin of nnumber.h */ - -typedef struct nnumber - { - ptrdiff_t length; - ptrdiff_t ilength; - void* alloc; - void* ialloc; - LONG* inumber; - char* number; - size_t allocated; - size_t iallocated; - int sign; /* 0: positive, QNUL: zero, MINUS: negative number */ - } nnumber; -/* End of nnumber.h */ - -/* Begin of hashtypes.h */ - -typedef struct classdef - { - char* name; - method* vtab; - } classdef; - -typedef struct pskRecord - { - psk entry; - struct pskRecord* next; - } pskRecord; - -typedef int(*cmpfuncTp)(const char* s, const char* p); -typedef LONG(*hashfuncTp)(const char* s); - -typedef struct Hash - { - pskRecord** hash_table; - ULONG hash_size; - ULONG elements; /* elements >= record_count */ - ULONG record_count; /* record_count >= size - unoccupied */ - ULONG unoccupied; - cmpfuncTp cmpfunc; - hashfuncTp hashfunc; - } Hash; -/* End of hashtypes.h */ - -/* Begin of unicaseconv.h */ -/* Uses the fields Uppercase Mapping and Lowercase Mapping in Unicodedata.txt to convert lower case to upper case and vice versa */ - -struct ccaseconv {unsigned int L:21;int range:11;unsigned int inc:2;int dif:20;}; - -#define toUpperUnicode(a) convertLetter(a,l2u) -#define toLowerUnicode(a) convertLetter(a,u2l) -/* End of unicaseconv.h */ - -/* Begin of matchstate.h */ - -typedef union matchstate - { -#ifndef NDEBUG - struct - { - unsigned int bsave : 8; - - unsigned int blmr_true : 1; - unsigned int blmr_success : 1; /* SUCCESS */ - unsigned int blmr_pristine : 1; - unsigned int blmr_once : 1; - unsigned int blmr_position_once : 1; - unsigned int blmr_position_max_reached : 1; - unsigned int blmr_fence : 1; /* FENCE */ - unsigned int blmr_unused_15 : 1; - - unsigned int brmr_true : 1; - unsigned int brmr_success : 1; /* SUCCESS */ - unsigned int brmr_pristine : 1; - unsigned int brmr_once : 1; - unsigned int brmr_position_once : 1; - unsigned int brmr_position_max_reached : 1; - unsigned int brmr_fence : 1; /* FENCE */ - unsigned int brmr_unused_23 : 1; - - unsigned int unused_24_26 : 3; - unsigned int bonce : 1; - unsigned int unused_28_31 : 4; - } b; -#endif - struct - { - char sav; - char lmr; - char rmr; - unsigned char once; - } c; - unsigned int i; - } matchstate; -/* End of matchstate.h */ - -/* Begin of charput.h */ - -#ifdef __SYMBIAN32__ -/* #define DEFAULT_INPUT_BUFFER_SIZE 0x100*/ /* If too high you get __chkstk error. Stack = 8K only! */ -/* #define DEFAULT_INPUT_BUFFER_SIZE 0x7F00*/ -#define DEFAULT_INPUT_BUFFER_SIZE 0x2000 -#else -#ifdef _MSC_VER -#define DEFAULT_INPUT_BUFFER_SIZE 0x7F00 /* Microsoft C allows 32k automatic data */ - -#else -#ifdef __BORLANDC__ -#if __BORLANDC__ >= 0x500 -#define DEFAULT_INPUT_BUFFER_SIZE 0x7000 -#else -#define DEFAULT_INPUT_BUFFER_SIZE 0x7FFC -#endif -#else -#define DEFAULT_INPUT_BUFFER_SIZE 0x7FFC -#endif -#endif -#endif - -typedef struct inputBuffer - { - unsigned char* buffer; - unsigned int cutoff : 8; /* Set to true if very long string does not fit in buffer of size DEFAULT_INPUT_BUFFER_SIZE */ - unsigned int mallocallocated : 8; /* True if allocated with malloc. Otherwise on stack (except EPOC). */ - } inputBuffer; - -void putOperatorChar(int c); -void putLeafChar(int c); -/* End of charput.h */ - -#if defined SINGLESOURCE -//#define NODESTRUCT_H -#define UNICASECONV_H -#define UNICHARTYPES_H -#define GLOBALS_H -#define FILEWRITE_H -#define NUMBERCHECK_H -#define MEMORY_H -#define COPY_H -#define HEAD_H -#define BUILTINMETHOD_H -#define QUOTE_H -#define RESULT_H -#define CHARPUT_H -#define ENCODING_H -#define JSON_H -#define XML_H -#define WRITEERR_H -#define INPUT_H -#define WIPECOPY_H -#define RATIONAL_H -#define REAL_H -#define EQUAL_H -#define OBJECT_H -#define NODEUTIL_H -#define LAMBDA_H -#define OPT_H -#define VARIABLES_H -#define MACRO_H -#define HASH_H -#define CALCULATION_H -#define BINDING_H -#define POSITION_H -#define STRINGMATCH_H -#define TREEMATCH_H -#define BRANCH_H -#define FILESTATUS_H -#define SIMIL_H -#define OBJECTDEF_H -#define FUNCTIONS_H -#define CANONIZATION_C -#define EVALUATE_H - -/* Begin of unicaseconv.c */ -/* Based on http://unicode.org/Public/UNIDATA/UnicodeData.txt 2022-08-03 17:00 , - structures created with UnicodeData.bra -*/ - -struct ccaseconv l2u[]={ -{0x61,25,1,-32}, -{0xB5,0,0,743}, -{0xE0,22,1,-32}, -{0xF8,6,1,-32}, -{0xFF,0,0,121}, -{0x101,46,2,-1}, -{0x131,0,0,-232}, -{0x133,4,2,-1}, -{0x13A,14,2,-1}, -{0x14B,44,2,-1}, -{0x17A,4,2,-1}, -{0x17F,0,0,-300}, -{0x180,0,0,195}, -{0x183,2,2,-1}, -{0x188,0,0,-1}, -{0x18C,0,0,-1}, -{0x192,0,0,-1}, -{0x195,0,0,97}, -{0x199,0,0,-1}, -{0x19A,0,0,163}, -{0x19E,0,0,130}, -{0x1A1,4,2,-1}, -{0x1A8,0,0,-1}, -{0x1AD,0,0,-1}, -{0x1B0,0,0,-1}, -{0x1B4,2,2,-1}, -{0x1B9,0,0,-1}, -{0x1BD,0,0,-1}, -{0x1BF,0,0,56}, -{0x1C5,0,0,-1}, -{0x1C6,0,0,-2}, -{0x1C8,0,0,-1}, -{0x1C9,0,0,-2}, -{0x1CB,0,0,-1}, -{0x1CC,0,0,-2}, -{0x1CE,14,2,-1}, -{0x1DD,0,0,-79}, -{0x1DF,16,2,-1}, -{0x1F2,0,0,-1}, -{0x1F3,0,0,-2}, -{0x1F5,0,0,-1}, -{0x1F9,38,2,-1}, -{0x223,16,2,-1}, -{0x23C,0,0,-1}, -{0x23F,1,1,10815}, -{0x242,0,0,-1}, -{0x247,8,2,-1}, -{0x250,0,0,10783}, -{0x251,0,0,10780}, -{0x252,0,0,10782}, -{0x253,0,0,-210}, -{0x254,0,0,-206}, -{0x256,1,1,-205}, -{0x259,0,0,-202}, -{0x25B,0,0,-203}, -{0x25C,0,0,42319}, -{0x260,0,0,-205}, -{0x261,0,0,42315}, -{0x263,0,0,-207}, -{0x265,0,0,42280}, -{0x266,0,0,42308}, -{0x268,0,0,-209}, -{0x269,0,0,-211}, -{0x26A,0,0,42308}, -{0x26B,0,0,10743}, -{0x26C,0,0,42305}, -{0x26F,0,0,-211}, -{0x271,0,0,10749}, -{0x272,0,0,-213}, -{0x275,0,0,-214}, -{0x27D,0,0,10727}, -{0x280,0,0,-218}, -{0x282,0,0,42307}, -{0x283,0,0,-218}, -{0x287,0,0,42282}, -{0x288,0,0,-218}, -{0x289,0,0,-69}, -{0x28A,1,1,-217}, -{0x28C,0,0,-71}, -{0x292,0,0,-219}, -{0x29D,0,0,42261}, -{0x29E,0,0,42258}, -{0x345,0,0,84}, -{0x371,2,2,-1}, -{0x377,0,0,-1}, -{0x37B,2,1,130}, -{0x3AC,0,0,-38}, -{0x3AD,2,1,-37}, -{0x3B1,16,1,-32}, -{0x3C2,0,0,-31}, -{0x3C3,8,1,-32}, -{0x3CC,0,0,-64}, -{0x3CD,1,1,-63}, -{0x3D0,0,0,-62}, -{0x3D1,0,0,-57}, -{0x3D5,0,0,-47}, -{0x3D6,0,0,-54}, -{0x3D7,0,0,-8}, -{0x3D9,22,2,-1}, -{0x3F0,0,0,-86}, -{0x3F1,0,0,-80}, -{0x3F2,0,0,7}, -{0x3F3,0,0,-116}, -{0x3F5,0,0,-96}, -{0x3F8,0,0,-1}, -{0x3FB,0,0,-1}, -{0x430,31,1,-32}, -{0x450,15,1,-80}, -{0x461,32,2,-1}, -{0x48B,52,2,-1}, -{0x4C2,12,2,-1}, -{0x4CF,0,0,-15}, -{0x4D1,94,2,-1}, -{0x561,37,1,-48}, -{0x10D0,42,1,3008}, -{0x10FD,2,1,3008}, -{0x13F8,5,1,-8}, -{0x1C80,0,0,-6254}, -{0x1C81,0,0,-6253}, -{0x1C82,0,0,-6244}, -{0x1C83,1,1,-6242}, -{0x1C85,0,0,-6243}, -{0x1C86,0,0,-6236}, -{0x1C87,0,0,-6181}, -{0x1C88,0,0,35266}, -{0x1D79,0,0,35332}, -{0x1D7D,0,0,3814}, -{0x1D8E,0,0,35384}, -{0x1E01,148,2,-1}, -{0x1E9B,0,0,-59}, -{0x1EA1,94,2,-1}, -{0x1F00,7,1,8}, -{0x1F10,5,1,8}, -{0x1F20,7,1,8}, -{0x1F30,7,1,8}, -{0x1F40,5,1,8}, -{0x1F51,6,2,8}, -{0x1F60,7,1,8}, -{0x1F70,1,1,74}, -{0x1F72,3,1,86}, -{0x1F76,1,1,100}, -{0x1F78,1,1,128}, -{0x1F7A,1,1,112}, -{0x1F7C,1,1,126}, -{0x1F80,7,1,8}, -{0x1F90,7,1,8}, -{0x1FA0,7,1,8}, -{0x1FB0,1,1,8}, -{0x1FB3,0,0,9}, -{0x1FBE,0,0,-7205}, -{0x1FC3,0,0,9}, -{0x1FD0,1,1,8}, -{0x1FE0,1,1,8}, -{0x1FE5,0,0,7}, -{0x1FF3,0,0,9}, -{0x214E,0,0,-28}, -{0x2170,15,1,-16}, -{0x2184,0,0,-1}, -{0x24D0,25,1,-26}, -{0x2C30,47,1,-48}, -{0x2C61,0,0,-1}, -{0x2C65,0,0,-10795}, -{0x2C66,0,0,-10792}, -{0x2C68,4,2,-1}, -{0x2C73,0,0,-1}, -{0x2C76,0,0,-1}, -{0x2C81,98,2,-1}, -{0x2CEC,2,2,-1}, -{0x2CF3,0,0,-1}, -{0x2D00,36,1,-7264}, -{0x2D25,2,2,-7264}, -{0x2D2D,0,0,-7264}, -{0xA641,44,2,-1}, -{0xA681,26,2,-1}, -{0xA723,12,2,-1}, -{0xA733,60,2,-1}, -{0xA77A,2,2,-1}, -{0xA77F,8,2,-1}, -{0xA78C,0,0,-1}, -{0xA791,2,2,-1}, -{0xA794,0,0,48}, -{0xA797,18,2,-1}, -{0xA7B5,14,2,-1}, -{0xA7C8,2,2,-1}, -{0xA7D1,0,0,-1}, -{0xA7D7,2,2,-1}, -{0xA7F6,0,0,-1}, -{0xAB53,0,0,-928}, -{0xAB70,79,1,-38864}, -{0xFF41,25,1,-32}, -{0x10428,39,1,-40}, -{0x104D8,35,1,-40}, -{0x10597,10,1,-39}, -{0x105A3,14,1,-39}, -{0x105B3,6,1,-39}, -{0x105BB,1,1,-39}, -{0x10CC0,50,1,-64}, -{0x118C0,31,1,-32}, -{0x16E60,31,1,-32}, -{0x1E922,33,1,-34}, -{0x1FFFFF,0,0,0}}; - -struct ccaseconv u2l[]={ -{0x41,25,1,32}, -{0xC0,22,1,32}, -{0xD8,6,1,32}, -{0x100,46,2,1}, -{0x130,0,0,-199}, -{0x132,4,2,1}, -{0x139,14,2,1}, -{0x14A,44,2,1}, -{0x178,0,0,-121}, -{0x179,4,2,1}, -{0x181,0,0,210}, -{0x182,2,2,1}, -{0x186,0,0,206}, -{0x187,0,0,1}, -{0x189,1,1,205}, -{0x18B,0,0,1}, -{0x18E,0,0,79}, -{0x18F,0,0,202}, -{0x190,0,0,203}, -{0x191,0,0,1}, -{0x193,0,0,205}, -{0x194,0,0,207}, -{0x196,0,0,211}, -{0x197,0,0,209}, -{0x198,0,0,1}, -{0x19C,0,0,211}, -{0x19D,0,0,213}, -{0x19F,0,0,214}, -{0x1A0,4,2,1}, -{0x1A6,0,0,218}, -{0x1A7,0,0,1}, -{0x1A9,0,0,218}, -{0x1AC,0,0,1}, -{0x1AE,0,0,218}, -{0x1AF,0,0,1}, -{0x1B1,1,1,217}, -{0x1B3,2,2,1}, -{0x1B7,0,0,219}, -{0x1B8,0,0,1}, -{0x1BC,0,0,1}, -{0x1C4,0,0,2}, -{0x1C5,0,0,1}, -{0x1C7,0,0,2}, -{0x1C8,0,0,1}, -{0x1CA,0,0,2}, -{0x1CB,16,2,1}, -{0x1DE,16,2,1}, -{0x1F1,0,0,2}, -{0x1F2,2,2,1}, -{0x1F6,0,0,-97}, -{0x1F7,0,0,-56}, -{0x1F8,38,2,1}, -{0x220,0,0,-130}, -{0x222,16,2,1}, -{0x23A,0,0,10795}, -{0x23B,0,0,1}, -{0x23D,0,0,-163}, -{0x23E,0,0,10792}, -{0x241,0,0,1}, -{0x243,0,0,-195}, -{0x244,0,0,69}, -{0x245,0,0,71}, -{0x246,8,2,1}, -{0x370,2,2,1}, -{0x376,0,0,1}, -{0x37F,0,0,116}, -{0x386,0,0,38}, -{0x388,2,1,37}, -{0x38C,0,0,64}, -{0x38E,1,1,63}, -{0x391,16,1,32}, -{0x3A3,8,1,32}, -{0x3CF,0,0,8}, -{0x3D8,22,2,1}, -{0x3F4,0,0,-60}, -{0x3F7,0,0,1}, -{0x3F9,0,0,-7}, -{0x3FA,0,0,1}, -{0x3FD,2,1,-130}, -{0x400,15,1,80}, -{0x410,31,1,32}, -{0x460,32,2,1}, -{0x48A,52,2,1}, -{0x4C0,0,0,15}, -{0x4C1,12,2,1}, -{0x4D0,94,2,1}, -{0x531,37,1,48}, -{0x10A0,36,1,7264}, -{0x10C5,2,2,7264}, -{0x10CD,0,0,7264}, -{0x13A0,79,1,38864}, -{0x13F0,5,1,8}, -{0x1C90,42,1,-3008}, -{0x1CBD,2,1,-3008}, -{0x1E00,148,2,1}, -{0x1E9E,0,0,-7615}, -{0x1EA0,94,2,1}, -{0x1F08,7,1,-8}, -{0x1F18,5,1,-8}, -{0x1F28,7,1,-8}, -{0x1F38,7,1,-8}, -{0x1F48,5,1,-8}, -{0x1F59,6,2,-8}, -{0x1F68,7,1,-8}, -{0x1F88,7,1,-8}, -{0x1F98,7,1,-8}, -{0x1FA8,7,1,-8}, -{0x1FB8,1,1,-8}, -{0x1FBA,1,1,-74}, -{0x1FBC,0,0,-9}, -{0x1FC8,3,1,-86}, -{0x1FCC,0,0,-9}, -{0x1FD8,1,1,-8}, -{0x1FDA,1,1,-100}, -{0x1FE8,1,1,-8}, -{0x1FEA,1,1,-112}, -{0x1FEC,0,0,-7}, -{0x1FF8,1,1,-128}, -{0x1FFA,1,1,-126}, -{0x1FFC,0,0,-9}, -{0x2126,0,0,-7517}, -{0x212A,0,0,-8383}, -{0x212B,0,0,-8262}, -{0x2132,0,0,28}, -{0x2160,15,1,16}, -{0x2183,0,0,1}, -{0x24B6,25,1,26}, -{0x2C00,47,1,48}, -{0x2C60,0,0,1}, -{0x2C62,0,0,-10743}, -{0x2C63,0,0,-3814}, -{0x2C64,0,0,-10727}, -{0x2C67,4,2,1}, -{0x2C6D,0,0,-10780}, -{0x2C6E,0,0,-10749}, -{0x2C6F,0,0,-10783}, -{0x2C70,0,0,-10782}, -{0x2C72,0,0,1}, -{0x2C75,0,0,1}, -{0x2C7E,1,1,-10815}, -{0x2C80,98,2,1}, -{0x2CEB,2,2,1}, -{0x2CF2,0,0,1}, -{0xA640,44,2,1}, -{0xA680,26,2,1}, -{0xA722,12,2,1}, -{0xA732,60,2,1}, -{0xA779,2,2,1}, -{0xA77D,0,0,-35332}, -{0xA77E,8,2,1}, -{0xA78B,0,0,1}, -{0xA78D,0,0,-42280}, -{0xA790,2,2,1}, -{0xA796,18,2,1}, -{0xA7AA,0,0,-42308}, -{0xA7AB,0,0,-42319}, -{0xA7AC,0,0,-42315}, -{0xA7AD,0,0,-42305}, -{0xA7AE,0,0,-42308}, -{0xA7B0,0,0,-42258}, -{0xA7B1,0,0,-42282}, -{0xA7B2,0,0,-42261}, -{0xA7B3,0,0,928}, -{0xA7B4,14,2,1}, -{0xA7C4,0,0,-48}, -{0xA7C5,0,0,-42307}, -{0xA7C6,0,0,-35384}, -{0xA7C7,2,2,1}, -{0xA7D0,0,0,1}, -{0xA7D6,2,2,1}, -{0xA7F5,0,0,1}, -{0xFF21,25,1,32}, -{0x10400,39,1,40}, -{0x104B0,35,1,40}, -{0x10570,10,1,39}, -{0x1057C,14,1,39}, -{0x1058C,6,1,39}, -{0x10594,1,1,39}, -{0x10C80,50,1,64}, -{0x118A0,31,1,32}, -{0x16E40,31,1,32}, -{0x1E900,33,1,34}, -{0x1FFFFF,0,0,0}}; - -static int convertLetter(int a, struct ccaseconv * T) - { - int i; - if (a > 0x10FFFF) - return a; - for (i = 0;; ++i) - { - if ((unsigned int)a < T[i].L) - { - if (i == 0) - return a; - --i; - if ( (unsigned int)a <= (unsigned int)(T[i].L + T[i].range) - && ( T[i].inc < 2 - || !((a - T[i].L) & 1) - ) - ) - { - return a + T[i].dif; - } - else - { - break; - } - } - } - return a; - } - -/* End of unicaseconv.c */ - -/* Begin of unichartypes.c */ -/* -Based on UnicodeData.txt (2022-08-03 17:00) -Structures created with UnicodeData.bra -*/ - -/* Begin of unichartypes.h */ -/* -Uses the field 'General Category'. Values returned by gencat(int) are: - -Lu Uppercase_Letter an uppercase letter -Ll Lowercase_Letter a lowercase letter -Lt Titlecase_Letter a digraphic character, with first part uppercase -LC Cased_Letter Lu | Ll | Lt -Lm Modifier_Letter a modifier letter -Lo Other_Letter other letters, including syllables and ideographs -L Letter Lu | Ll | Lt | Lm | Lo -Mn Nonspacing_Mark a nonspacing combining mark (zero advance width) -Mc Spacing_Mark a spacing combining mark (positive advance width) -Me Enclosing_Mark an enclosing combining mark -M Mark Mn | Mc | Me -Nd Decimal_Number a decimal digit -Nl Letter_Number a letterlike numeric character -No Other_Number a numeric character of other type -N Number Nd | Nl | No -Pc Connector_Punctuation a connecting punctuation mark, like a tie -Pd Dash_Punctuation a dash or hyphen punctuation mark -Ps Open_Punctuation an opening punctuation mark (of a pair) -Pe Close_Punctuation a closing punctuation mark (of a pair) -Pi Initial_Punctuation an initial quotation mark -Pf Final_Punctuation a final quotation mark -Po Other_Punctuation a punctuation mark of other type -P Punctuation Pc | Pd | Ps | Pe | Pi | Pf | Po -Sm Math_Symbol a symbol of mathematical use -Sc Currency_Symbol a currency sign -Sk Modifier_Symbol a non-letterlike modifier symbol -So Other_Symbol a symbol of other type -S Symbol Sm | Sc | Sk | So -Zs Space_Separator a space character (of various non-zero widths) -Zl Line_Separator U+2028 LINE SEPARATOR only -Zp Paragraph_Separator U+2029 PARAGRAPH SEPARATOR only -Z Separator Zs | Zl | Zp -Cc Control a C0 or C1 control code -Cf Format a format control character -Cs Surrogate a surrogate code point -Co Private_Use a private-use character -Cn Unassigned a reserved unassigned code point or a noncharacter -C Other Cc | Cf | Cs | Co | Cn -*/ - -#ifdef __cplusplus -"C" const char * gencat(int a); -#endif -/* End of unichartypes.h */ - -#include - -typedef enum {e1L,e1M,e1N,e1P,e1S,e1Z,e1C,e1} mark1; -typedef enum {e2C,e2c,e2d,e2e,e2f,e2i,e2k,e2l,e2m,e2n,e2o,e2p,e2s,e2t,e2u,e2} mark2; -typedef struct tmark {unsigned char m1:4; unsigned char m2:4;} tmark; -typedef struct cletter {unsigned short int L;unsigned short int range;} cletter; -typedef struct cletter2 {unsigned int L;unsigned int range;} cletter2; - -static const char * firstMark = "LMNPSZC"; -static const char * secondMark = "Ccdefiklmnopstu"; - -static tmark Mark[] = {{e1C,e2c},{e1Z,e2s},{e1P,e2o},{e1S,e2c},{e1P,e2o},{e1P,e2s},{e1P,e2e},{e1P,e2o}, -{e1S,e2m},{e1P,e2o},{e1P,e2d},{e1P,e2o},{e1N,e2d},{e1P,e2o},{e1S,e2m},{e1P,e2o},{e1L,e2u},{e1P,e2s}, -{e1P,e2o},{e1P,e2e},{e1S,e2k},{e1P,e2c},{e1S,e2k},{e1P,e2s},{e1S,e2m},{e1P,e2e},{e1S,e2m},{e1C,e2c}, -{e1Z,e2s},{e1P,e2o},{e1S,e2c},{e1S,e2o},{e1P,e2o},{e1S,e2k},{e1S,e2o},{e1L,e2o},{e1P,e2i},{e1S,e2m}, -{e1C,e2f},{e1S,e2o},{e1S,e2k},{e1S,e2o},{e1S,e2m},{e1N,e2o},{e1S,e2k},{e1P,e2o},{e1S,e2k},{e1N,e2o}, -{e1L,e2o},{e1P,e2f},{e1N,e2o},{e1P,e2o},{e1L,e2u},{e1S,e2m},{e1L,e2u},{e1S,e2m},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2o},{e1L,e2u}, -{e1L,e2o},{e1L,e2u},{e1L,e2t},{e1L,e2u},{e1L,e2t},{e1L,e2u},{e1L,e2t},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2t},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2o},{e1L,e2m},{e1S,e2k},{e1L,e2m},{e1S,e2k}, -{e1L,e2m},{e1S,e2k},{e1L,e2m},{e1S,e2k},{e1L,e2m},{e1S,e2k},{e1M,e2n},{e1L,e2u},{e1L,e2u},{e1L,e2m}, -{e1S,e2k},{e1L,e2u},{e1L,e2m},{e1P,e2o},{e1L,e2u},{e1S,e2k},{e1L,e2u},{e1P,e2o},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1S,e2m},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1S,e2o},{e1M,e2n},{e1M,e2e},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2m},{e1P,e2o},{e1P,e2o},{e1P,e2d},{e1S,e2o},{e1S,e2c},{e1M,e2n},{e1P,e2d}, -{e1M,e2n},{e1P,e2o},{e1M,e2n},{e1P,e2o},{e1M,e2n},{e1P,e2o},{e1M,e2n},{e1L,e2o},{e1P,e2o},{e1C,e2f}, -{e1S,e2m},{e1P,e2o},{e1S,e2c},{e1P,e2o},{e1S,e2o},{e1M,e2n},{e1P,e2o},{e1C,e2f},{e1P,e2o},{e1L,e2o}, -{e1L,e2m},{e1L,e2o},{e1M,e2n},{e1N,e2d},{e1P,e2o},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1P,e2o},{e1L,e2o}, -{e1M,e2n},{e1C,e2f},{e1S,e2o},{e1M,e2n},{e1L,e2m},{e1M,e2n},{e1S,e2o},{e1M,e2n},{e1L,e2o},{e1N,e2d}, -{e1L,e2o},{e1S,e2o},{e1L,e2o},{e1P,e2o},{e1C,e2f},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1L,e2o}, -{e1M,e2n},{e1L,e2o},{e1N,e2d},{e1L,e2o},{e1M,e2n},{e1L,e2m},{e1S,e2o},{e1P,e2o},{e1L,e2m},{e1M,e2n}, -{e1S,e2c},{e1L,e2o},{e1M,e2n},{e1L,e2m},{e1M,e2n},{e1L,e2m},{e1M,e2n},{e1L,e2m},{e1M,e2n},{e1P,e2o}, -{e1L,e2o},{e1M,e2n},{e1P,e2o},{e1L,e2o},{e1S,e2k},{e1L,e2o},{e1C,e2f},{e1M,e2n},{e1L,e2o},{e1L,e2m}, -{e1M,e2n},{e1C,e2f},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1L,e2o},{e1M,e2c}, -{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1P,e2o},{e1N,e2d}, -{e1P,e2o},{e1L,e2m},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2c},{e1M,e2n}, -{e1M,e2c},{e1M,e2n},{e1L,e2o},{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1N,e2d},{e1L,e2o},{e1S,e2c},{e1N,e2o}, -{e1S,e2o},{e1S,e2c},{e1L,e2o},{e1P,e2o},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1M,e2n}, -{e1L,e2o},{e1N,e2d},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1P,e2o},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n}, -{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1N,e2d},{e1P,e2o},{e1S,e2c}, -{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n}, -{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1N,e2d},{e1S,e2o},{e1L,e2o},{e1N,e2o},{e1M,e2n}, -{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1L,e2o},{e1M,e2c},{e1N,e2d},{e1N,e2o},{e1S,e2o}, -{e1S,e2c},{e1S,e2o},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1M,e2c}, -{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1N,e2d},{e1P,e2o},{e1N,e2o},{e1S,e2o},{e1L,e2o},{e1M,e2n},{e1M,e2c}, -{e1P,e2o},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n}, -{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1N,e2d},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n}, -{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1L,e2o},{e1S,e2o},{e1L,e2o},{e1M,e2c},{e1N,e2o}, -{e1L,e2o},{e1M,e2n},{e1N,e2d},{e1N,e2o},{e1S,e2o},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n}, -{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1N,e2d},{e1M,e2c},{e1P,e2o},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n}, -{e1S,e2c},{e1L,e2o},{e1L,e2m},{e1M,e2n},{e1P,e2o},{e1N,e2d},{e1P,e2o},{e1L,e2o},{e1M,e2n},{e1L,e2o}, -{e1M,e2n},{e1L,e2o},{e1L,e2m},{e1M,e2n},{e1N,e2d},{e1L,e2o},{e1S,e2o},{e1P,e2o},{e1S,e2o},{e1P,e2o}, -{e1S,e2o},{e1M,e2n},{e1S,e2o},{e1N,e2d},{e1N,e2o},{e1S,e2o},{e1M,e2n},{e1S,e2o},{e1M,e2n},{e1S,e2o}, -{e1M,e2n},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1M,e2n}, -{e1P,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1S,e2o},{e1M,e2n},{e1S,e2o},{e1P,e2o},{e1S,e2o},{e1P,e2o}, -{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1L,e2o}, -{e1N,e2d},{e1P,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2c},{e1L,e2o}, -{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1L,e2o}, -{e1M,e2c},{e1N,e2d},{e1M,e2c},{e1M,e2n},{e1S,e2o},{e1L,e2u},{e1P,e2o},{e1L,e2m},{e1L,e2o},{e1M,e2n}, -{e1P,e2o},{e1N,e2o},{e1L,e2o},{e1S,e2o},{e1L,e2u},{e1P,e2d},{e1L,e2o},{e1S,e2o},{e1P,e2o},{e1L,e2o}, -{e1Z,e2s},{e1L,e2o},{e1P,e2s},{e1P,e2e},{e1L,e2o},{e1P,e2o},{e1N,e2l},{e1L,e2o},{e1M,e2n},{e1M,e2c}, -{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1P,e2o},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n}, -{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1P,e2o},{e1L,e2m},{e1P,e2o},{e1S,e2c}, -{e1L,e2o},{e1M,e2n},{e1N,e2d},{e1N,e2o},{e1P,e2o},{e1P,e2d},{e1P,e2o},{e1M,e2n},{e1C,e2f},{e1M,e2n}, -{e1N,e2d},{e1L,e2o},{e1L,e2m},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1M,e2c}, -{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1S,e2o},{e1P,e2o},{e1N,e2d},{e1L,e2o},{e1N,e2d}, -{e1N,e2o},{e1S,e2o},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1P,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2n}, -{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1N,e2d},{e1P,e2o}, -{e1L,e2m},{e1P,e2o},{e1M,e2n},{e1M,e2e},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1M,e2n}, -{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1N,e2d},{e1P,e2o},{e1S,e2o},{e1M,e2n}, -{e1S,e2o},{e1P,e2o},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c}, -{e1M,e2n},{e1L,e2o},{e1N,e2d},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c}, -{e1M,e2n},{e1M,e2c},{e1P,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1P,e2o},{e1N,e2d}, -{e1L,e2o},{e1N,e2d},{e1L,e2o},{e1L,e2m},{e1P,e2o},{e1L,e2u},{e1P,e2o},{e1M,e2n},{e1P,e2o},{e1M,e2n}, -{e1M,e2c},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1L,e2o}, -{e1L,e2m},{e1L,e2m},{e1L,e2m},{e1M,e2n},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2t},{e1L,e2t},{e1L,e2t},{e1L,e2u},{e1L,e2t}, -{e1S,e2k},{e1S,e2k},{e1L,e2u},{e1L,e2t},{e1S,e2k},{e1L,e2u},{e1S,e2k},{e1L,e2u},{e1S,e2k},{e1L,e2u}, -{e1L,e2t},{e1S,e2k},{e1Z,e2s},{e1C,e2f},{e1P,e2d},{e1P,e2o},{e1P,e2i},{e1P,e2f},{e1P,e2s},{e1P,e2i}, -{e1P,e2f},{e1P,e2s},{e1P,e2i},{e1P,e2o},{e1Z,e2l},{e1Z,e2p},{e1C,e2f},{e1Z,e2s},{e1P,e2o},{e1P,e2i}, -{e1P,e2f},{e1P,e2o},{e1P,e2c},{e1P,e2o},{e1S,e2m},{e1P,e2s},{e1P,e2e},{e1P,e2o},{e1S,e2m},{e1P,e2o}, -{e1P,e2c},{e1P,e2o},{e1Z,e2s},{e1C,e2f},{e1N,e2o},{e1L,e2m},{e1N,e2o},{e1S,e2m},{e1P,e2s},{e1P,e2e}, -{e1L,e2m},{e1N,e2o},{e1S,e2m},{e1P,e2s},{e1P,e2e},{e1L,e2m},{e1S,e2c},{e1M,e2n},{e1M,e2e},{e1M,e2n}, -{e1M,e2e},{e1M,e2n},{e1S,e2o},{e1L,e2u},{e1S,e2o},{e1L,e2u},{e1S,e2o},{e1L,e2u},{e1L,e2u},{e1S,e2o}, -{e1L,e2u},{e1S,e2o},{e1S,e2m},{e1L,e2u},{e1S,e2o},{e1L,e2u},{e1S,e2o},{e1L,e2u},{e1S,e2o},{e1L,e2u}, -{e1S,e2o},{e1L,e2u},{e1S,e2o},{e1L,e2u},{e1L,e2o},{e1S,e2o},{e1L,e2u},{e1S,e2m},{e1L,e2u},{e1S,e2o}, -{e1S,e2m},{e1S,e2o},{e1S,e2o},{e1N,e2o},{e1N,e2l},{e1L,e2u},{e1N,e2l},{e1N,e2o},{e1S,e2o},{e1S,e2m}, -{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m}, -{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1P,e2s}, -{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1P,e2s},{e1P,e2e},{e1S,e2o},{e1S,e2m}, -{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1N,e2o},{e1S,e2o},{e1N,e2o},{e1S,e2o},{e1S,e2m}, -{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1P,e2s},{e1P,e2e},{e1P,e2s}, -{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s}, -{e1P,e2e},{e1N,e2o},{e1S,e2o},{e1S,e2m},{e1P,e2s},{e1P,e2e},{e1S,e2m},{e1P,e2s},{e1P,e2e},{e1P,e2s}, -{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1S,e2m},{e1S,e2o},{e1S,e2m}, -{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e}, -{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e}, -{e1P,e2s},{e1P,e2e},{e1S,e2m},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1S,e2m},{e1P,e2s},{e1P,e2e}, -{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1S,e2m},{e1S,e2o},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2m},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1S,e2o},{e1L,e2u},{e1L,e2u},{e1M,e2n}, -{e1L,e2u},{e1P,e2o},{e1N,e2o},{e1P,e2o},{e1L,e2o},{e1L,e2m},{e1P,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n}, -{e1P,e2o},{e1P,e2i},{e1P,e2f},{e1P,e2i},{e1P,e2f},{e1P,e2o},{e1P,e2i},{e1P,e2f},{e1P,e2o},{e1P,e2i}, -{e1P,e2f},{e1P,e2o},{e1P,e2d},{e1P,e2o},{e1P,e2d},{e1P,e2o},{e1P,e2i},{e1P,e2f},{e1P,e2o},{e1P,e2i}, -{e1P,e2f},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2o}, -{e1L,e2m},{e1P,e2o},{e1P,e2d},{e1P,e2o},{e1P,e2d},{e1P,e2o},{e1P,e2s},{e1P,e2o},{e1S,e2o},{e1P,e2o}, -{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2d},{e1S,e2o}, -{e1Z,e2s},{e1P,e2o},{e1S,e2o},{e1L,e2m},{e1L,e2o},{e1N,e2l},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e}, -{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1S,e2o},{e1P,e2s},{e1P,e2e},{e1P,e2s}, -{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2d},{e1P,e2s},{e1P,e2e},{e1S,e2o},{e1N,e2l}, -{e1M,e2n},{e1M,e2c},{e1P,e2d},{e1L,e2m},{e1S,e2o},{e1N,e2l},{e1L,e2m},{e1L,e2o},{e1P,e2o},{e1S,e2o}, -{e1L,e2o},{e1M,e2n},{e1S,e2k},{e1L,e2m},{e1L,e2o},{e1P,e2d},{e1L,e2o},{e1P,e2o},{e1L,e2m},{e1L,e2o}, -{e1S,e2o},{e1N,e2o},{e1S,e2o},{e1L,e2o},{e1S,e2o},{e1L,e2o},{e1S,e2o},{e1N,e2o},{e1S,e2o},{e1N,e2o}, -{e1S,e2o},{e1N,e2o},{e1S,e2o},{e1N,e2o},{e1S,e2o},{e1N,e2o},{e1S,e2o},{e1L,e2o},{e1S,e2o},{e1L,e2o}, -{e1L,e2m},{e1L,e2o},{e1S,e2o},{e1L,e2o},{e1L,e2m},{e1P,e2o},{e1L,e2o},{e1L,e2m},{e1P,e2o},{e1L,e2o}, -{e1N,e2d},{e1L,e2o},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2o},{e1M,e2n},{e1M,e2e},{e1P,e2o},{e1M,e2n}, -{e1P,e2o},{e1L,e2m},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2m},{e1M,e2n},{e1L,e2o},{e1N,e2l}, -{e1M,e2n},{e1P,e2o},{e1S,e2k},{e1L,e2m},{e1S,e2k},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2m},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2m},{e1S,e2k},{e1L,e2u},{e1L,e2u},{e1L,e2o},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u},{e1L,e2u}, -{e1L,e2u},{e1L,e2u},{e1L,e2m},{e1L,e2u},{e1L,e2o},{e1L,e2m},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n}, -{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1S,e2o},{e1M,e2n},{e1N,e2o},{e1S,e2o}, -{e1S,e2c},{e1S,e2o},{e1L,e2o},{e1P,e2o},{e1M,e2c},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1P,e2o},{e1N,e2d}, -{e1M,e2n},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1M,e2n},{e1N,e2d},{e1L,e2o},{e1M,e2n}, -{e1P,e2o},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1P,e2o},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n}, -{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1P,e2o},{e1L,e2m},{e1N,e2d},{e1P,e2o},{e1L,e2o}, -{e1M,e2n},{e1L,e2m},{e1L,e2o},{e1N,e2d},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n}, -{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1M,e2c},{e1N,e2d},{e1P,e2o},{e1L,e2o},{e1L,e2m},{e1L,e2o}, -{e1S,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1L,e2o}, -{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1L,e2m},{e1P,e2o},{e1L,e2o},{e1M,e2c}, -{e1M,e2n},{e1M,e2c},{e1P,e2o},{e1L,e2o},{e1L,e2m},{e1M,e2c},{e1M,e2n},{e1L,e2o},{e1S,e2k},{e1L,e2m}, -{e1L,e2m},{e1S,e2k},{e1L,e2o},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1M,e2n},{e1M,e2c},{e1P,e2o},{e1M,e2c}, -{e1M,e2n},{e1N,e2d},{e1L,e2o},{e1C,e2s},{e1C,e2o},{e1L,e2o},{e1L,e2o},{e1M,e2n},{e1L,e2o},{e1S,e2m}, -{e1L,e2o},{e1S,e2k},{e1L,e2o},{e1P,e2e},{e1P,e2s},{e1S,e2o},{e1L,e2o},{e1S,e2o},{e1L,e2o},{e1S,e2c}, -{e1S,e2o},{e1M,e2n},{e1P,e2o},{e1P,e2s},{e1P,e2e},{e1P,e2o},{e1M,e2n},{e1P,e2o},{e1P,e2d},{e1P,e2c}, -{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e}, -{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2o},{e1P,e2s},{e1P,e2e},{e1P,e2o}, -{e1P,e2c},{e1P,e2o},{e1P,e2d},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2s},{e1P,e2e},{e1P,e2o}, -{e1S,e2m},{e1P,e2d},{e1S,e2m},{e1P,e2o},{e1S,e2c},{e1P,e2o},{e1L,e2o},{e1C,e2f},{e1P,e2o},{e1S,e2c}, -{e1P,e2o},{e1P,e2s},{e1P,e2e},{e1P,e2o},{e1S,e2m},{e1P,e2o},{e1P,e2d},{e1P,e2o},{e1N,e2d},{e1P,e2o}, -{e1S,e2m},{e1P,e2o},{e1L,e2u},{e1P,e2s},{e1P,e2o},{e1P,e2e},{e1S,e2k},{e1P,e2c},{e1S,e2k},{e1P,e2s}, -{e1S,e2m},{e1P,e2e},{e1S,e2m},{e1P,e2s},{e1P,e2e},{e1P,e2o},{e1P,e2s},{e1P,e2e},{e1P,e2o},{e1L,e2o}, -{e1L,e2m},{e1L,e2o},{e1L,e2m},{e1L,e2o},{e1S,e2c},{e1S,e2m},{e1S,e2k},{e1S,e2o},{e1S,e2c},{e1S,e2o}, -{e1S,e2m},{e1S,e2o},{e1C,e2f},{e1S,e2o},{e1L,e2o},{e1P,e2o},{e1N,e2o},{e1S,e2o},{e1N,e2l},{e1N,e2o}, -{e1S,e2o},{e1N,e2o},{e1S,e2o},{e1L,e2o},{e1N,e2o},{e1L,e2o},{e1N,e2o},{e1L,e2o},{e1N,e2l},{e1L,e2o}, -{e1N,e2l},{e1L,e2o},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1P,e2o},{e1N,e2l},{e1L,e2u},{e1L,e2l},{e1L,e2o}, -{e1N,e2d},{e1L,e2u},{e1L,e2l},{e1L,e2o},{e1P,e2o},{e1L,e2u},{e1L,e2l},{e1L,e2o},{e1L,e2m},{e1L,e2o}, -{e1P,e2o},{e1N,e2o},{e1L,e2o},{e1S,e2o},{e1N,e2o},{e1L,e2o},{e1N,e2o},{e1L,e2o},{e1N,e2o},{e1L,e2o}, -{e1N,e2o},{e1P,e2o},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1N,e2o},{e1L,e2o},{e1N,e2o},{e1L,e2o},{e1L,e2o}, -{e1N,e2o},{e1P,e2o},{e1L,e2o},{e1N,e2o},{e1P,e2o},{e1L,e2o},{e1N,e2o},{e1L,e2o},{e1S,e2o},{e1L,e2o}, -{e1N,e2o},{e1P,e2o},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1N,e2o},{e1L,e2o},{e1N,e2o},{e1L,e2o},{e1P,e2o}, -{e1N,e2o},{e1L,e2o},{e1L,e2u},{e1L,e2l},{e1N,e2o},{e1L,e2o},{e1N,e2d},{e1N,e2o},{e1L,e2o},{e1P,e2d}, -{e1L,e2o},{e1L,e2o},{e1N,e2o},{e1L,e2o},{e1N,e2o},{e1P,e2o},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1N,e2o}, -{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1P,e2o},{e1N,e2o},{e1N,e2d},{e1L,e2o},{e1L,e2o},{e1M,e2c}, -{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1P,e2o},{e1C,e2f},{e1P,e2o},{e1C,e2f},{e1L,e2o},{e1N,e2d},{e1L,e2o}, -{e1M,e2c},{e1N,e2d},{e1P,e2o},{e1L,e2o},{e1M,e2c},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1M,e2c},{e1L,e2o}, -{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1P,e2o},{e1P,e2o},{e1M,e2c},{e1N,e2d},{e1L,e2o},{e1P,e2o},{e1L,e2o}, -{e1P,e2o},{e1N,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1M,e2c},{e1P,e2o},{e1L,e2o},{e1L,e2o},{e1P,e2o}, -{e1L,e2o},{e1M,e2c},{e1N,e2d},{e1M,e2c},{e1L,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1M,e2c}, -{e1L,e2o},{e1M,e2c},{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1P,e2o},{e1N,e2d},{e1P,e2o}, -{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1N,e2d},{e1L,e2o}, -{e1M,e2c},{e1M,e2c},{e1M,e2c},{e1P,e2o},{e1L,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1M,e2c},{e1P,e2o}, -{e1L,e2o},{e1N,e2d},{e1P,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1P,e2o},{e1N,e2d}, -{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1N,e2d},{e1N,e2o},{e1P,e2o},{e1S,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2c}, -{e1P,e2o},{e1L,e2u},{e1L,e2l},{e1N,e2d},{e1N,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1M,e2c}, -{e1L,e2o},{e1M,e2c},{e1P,e2o},{e1N,e2d},{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1P,e2o},{e1L,e2o}, -{e1M,e2c},{e1L,e2o},{e1L,e2o},{e1M,e2c},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1M,e2c},{e1L,e2o},{e1M,e2c}, -{e1P,e2o},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1P,e2o}, -{e1N,e2d},{e1N,e2o},{e1P,e2o},{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1L,e2o},{e1N,e2d}, -{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1M,e2c},{e1L,e2o},{e1N,e2d},{e1L,e2o},{e1M,e2c},{e1P,e2o},{e1L,e2o}, -{e1M,e2c},{e1L,e2o},{e1M,e2c},{e1M,e2c},{e1M,e2c},{e1P,e2o},{e1N,e2d},{e1L,e2o},{e1N,e2o},{e1S,e2o}, -{e1S,e2c},{e1S,e2o},{e1P,e2o},{e1L,e2o},{e1N,e2l},{e1P,e2o},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1C,e2f}, -{e1L,e2o},{e1L,e2o},{e1N,e2d},{e1P,e2o},{e1L,e2o},{e1N,e2d},{e1L,e2o},{e1P,e2o},{e1L,e2o},{e1P,e2o}, -{e1S,e2o},{e1L,e2m},{e1P,e2o},{e1S,e2o},{e1N,e2d},{e1N,e2o},{e1L,e2o},{e1L,e2u},{e1L,e2l},{e1N,e2o}, -{e1P,e2o},{e1L,e2o},{e1L,e2o},{e1M,e2c},{e1L,e2m},{e1P,e2o},{e1L,e2m},{e1M,e2c},{e1L,e2o},{e1L,e2m}, -{e1L,e2o},{e1S,e2o},{e1P,e2o},{e1C,e2f},{e1S,e2o},{e1M,e2c},{e1S,e2o},{e1M,e2c},{e1C,e2f},{e1S,e2o}, -{e1S,e2o},{e1S,e2o},{e1S,e2o},{e1N,e2o},{e1S,e2o},{e1N,e2o},{e1L,e2u},{e1L,e2l},{e1L,e2u},{e1L,e2l}, -{e1L,e2u},{e1L,e2l},{e1L,e2u},{e1L,e2l},{e1L,e2u},{e1L,e2l},{e1L,e2u},{e1L,e2l},{e1L,e2u},{e1L,e2l}, -{e1L,e2u},{e1L,e2l},{e1L,e2u},{e1L,e2l},{e1L,e2u},{e1L,e2l},{e1L,e2u},{e1L,e2l},{e1L,e2u},{e1L,e2l}, -{e1L,e2u},{e1L,e2l},{e1L,e2u},{e1S,e2m},{e1L,e2l},{e1S,e2m},{e1L,e2l},{e1L,e2u},{e1S,e2m},{e1L,e2l}, -{e1S,e2m},{e1L,e2l},{e1L,e2u},{e1S,e2m},{e1L,e2l},{e1S,e2m},{e1L,e2l},{e1L,e2u},{e1S,e2m},{e1L,e2l}, -{e1S,e2m},{e1L,e2l},{e1L,e2u},{e1S,e2m},{e1L,e2l},{e1S,e2m},{e1L,e2l},{e1L,e2u},{e1L,e2l},{e1N,e2d}, -{e1S,e2o},{e1S,e2o},{e1S,e2o},{e1S,e2o},{e1S,e2o},{e1P,e2o},{e1L,e2l},{e1L,e2o},{e1L,e2l},{e1L,e2m}, -{e1L,e2o},{e1L,e2m},{e1N,e2d},{e1L,e2o},{e1S,e2o},{e1L,e2o},{e1L,e2o},{e1N,e2d},{e1S,e2c},{e1L,e2o}, -{e1L,e2m},{e1N,e2d},{e1L,e2o},{e1N,e2o},{e1L,e2u},{e1L,e2l},{e1L,e2m},{e1N,e2d},{e1P,e2o},{e1N,e2o}, -{e1S,e2o},{e1N,e2o},{e1S,e2c},{e1N,e2o},{e1S,e2o},{e1N,e2o},{e1L,e2o},{e1S,e2m},{e1S,e2o},{e1N,e2o}, -{e1S,e2o},{e1S,e2k},{e1S,e2o},{e1N,e2d},{e1L,e2o},{e1C,e2f},{e1M,e2n},{e1C,e2o},{e1,e2}}; - -static cletter Cletters0[]={{0x0,31},{0x20,0},{0x21,2},{0x24,0},{0x25,2},{0x28,0},{0x29,0},{0x2A,0}, -{0x2B,0},{0x2C,0},{0x2D,0},{0x2E,1},{0x30,9},{0x3A,1},{0x3C,2},{0x3F,1},{0x41,25},{0x5B,0}, -{0x5C,0},{0x5D,0},{0x5E,0},{0x5F,0},{0x60,0},{0x7B,0},{0x7C,0},{0x7D,0},{0x7E,0},{0x7F,32}, -{0xA0,0},{0xA1,0},{0xA2,3},{0xA6,0},{0xA7,0},{0xA8,0},{0xA9,0},{0xAA,0},{0xAB,0},{0xAC,0}, -{0xAD,0},{0xAE,0},{0xAF,0},{0xB0,0},{0xB1,0},{0xB2,1},{0xB4,0},{0xB6,1},{0xB8,0},{0xB9,0}, -{0xBA,0},{0xBB,0},{0xBC,2},{0xBF,0},{0xC0,22},{0xD7,0},{0xD8,6},{0xF7,0},{0x100,0},{0x102,0}, -{0x104,0},{0x106,0},{0x108,0},{0x10A,0},{0x10C,0},{0x10E,0},{0x110,0},{0x112,0},{0x114,0},{0x116,0}, -{0x118,0},{0x11A,0},{0x11C,0},{0x11E,0},{0x120,0},{0x122,0},{0x124,0},{0x126,0},{0x128,0},{0x12A,0}, -{0x12C,0},{0x12E,0},{0x130,0},{0x132,0},{0x134,0},{0x136,0},{0x139,0},{0x13B,0},{0x13D,0},{0x13F,0}, -{0x141,0},{0x143,0},{0x145,0},{0x147,0},{0x14A,0},{0x14C,0},{0x14E,0},{0x150,0},{0x152,0},{0x154,0}, -{0x156,0},{0x158,0},{0x15A,0},{0x15C,0},{0x15E,0},{0x160,0},{0x162,0},{0x164,0},{0x166,0},{0x168,0}, -{0x16A,0},{0x16C,0},{0x16E,0},{0x170,0},{0x172,0},{0x174,0},{0x176,0},{0x178,1},{0x17B,0},{0x17D,0}, -{0x181,1},{0x184,0},{0x186,1},{0x189,2},{0x18E,3},{0x193,1},{0x196,2},{0x19C,1},{0x19F,1},{0x1A2,0}, -{0x1A4,0},{0x1A6,1},{0x1A9,0},{0x1AC,0},{0x1AE,1},{0x1B1,2},{0x1B5,0},{0x1B7,1},{0x1BB,0},{0x1BC,0}, -{0x1C0,3},{0x1C4,0},{0x1C5,0},{0x1C7,0},{0x1C8,0},{0x1CA,0},{0x1CB,0},{0x1CD,0},{0x1CF,0},{0x1D1,0}, -{0x1D3,0},{0x1D5,0},{0x1D7,0},{0x1D9,0},{0x1DB,0},{0x1DE,0},{0x1E0,0},{0x1E2,0},{0x1E4,0},{0x1E6,0}, -{0x1E8,0},{0x1EA,0},{0x1EC,0},{0x1EE,0},{0x1F1,0},{0x1F2,0},{0x1F4,0},{0x1F6,2},{0x1FA,0},{0x1FC,0}, -{0x1FE,0},{0x200,0},{0x202,0},{0x204,0},{0x206,0},{0x208,0},{0x20A,0},{0x20C,0},{0x20E,0},{0x210,0}, -{0x212,0},{0x214,0},{0x216,0},{0x218,0},{0x21A,0},{0x21C,0},{0x21E,0},{0x220,0},{0x222,0},{0x224,0}, -{0x226,0},{0x228,0},{0x22A,0},{0x22C,0},{0x22E,0},{0x230,0},{0x232,0},{0x23A,1},{0x23D,1},{0x241,0}, -{0x243,3},{0x248,0},{0x24A,0},{0x24C,0},{0x24E,0},{0x294,0},{0x2B0,17},{0x2C2,3},{0x2C6,11},{0x2D2,13}, -{0x2E0,4},{0x2E5,6},{0x2EC,0},{0x2ED,0},{0x2EE,0},{0x2EF,16},{0x300,111},{0x370,0},{0x372,0},{0x374,0}, -{0x375,0},{0x376,0},{0x37A,0},{0x37E,0},{0x37F,0},{0x384,1},{0x386,0},{0x387,0},{0x388,7},{0x391,26}, -{0x3CF,0},{0x3D2,2},{0x3D8,0},{0x3DA,0},{0x3DC,0},{0x3DE,0},{0x3E0,0},{0x3E2,0},{0x3E4,0},{0x3E6,0}, -{0x3E8,0},{0x3EA,0},{0x3EC,0},{0x3EE,0},{0x3F4,0},{0x3F6,0},{0x3F7,0},{0x3F9,1},{0x3FD,50},{0x460,0}, -{0x462,0},{0x464,0},{0x466,0},{0x468,0},{0x46A,0},{0x46C,0},{0x46E,0},{0x470,0},{0x472,0},{0x474,0}, -{0x476,0},{0x478,0},{0x47A,0},{0x47C,0},{0x47E,0},{0x480,0},{0x482,0},{0x483,4},{0x488,1},{0x48A,0}, -{0x48C,0},{0x48E,0},{0x490,0},{0x492,0},{0x494,0},{0x496,0},{0x498,0},{0x49A,0},{0x49C,0},{0x49E,0}, -{0x4A0,0},{0x4A2,0},{0x4A4,0},{0x4A6,0},{0x4A8,0},{0x4AA,0},{0x4AC,0},{0x4AE,0},{0x4B0,0},{0x4B2,0}, -{0x4B4,0},{0x4B6,0},{0x4B8,0},{0x4BA,0},{0x4BC,0},{0x4BE,0},{0x4C0,1},{0x4C3,0},{0x4C5,0},{0x4C7,0}, -{0x4C9,0},{0x4CB,0},{0x4CD,0},{0x4D0,0},{0x4D2,0},{0x4D4,0},{0x4D6,0},{0x4D8,0},{0x4DA,0},{0x4DC,0}, -{0x4DE,0},{0x4E0,0},{0x4E2,0},{0x4E4,0},{0x4E6,0},{0x4E8,0},{0x4EA,0},{0x4EC,0},{0x4EE,0},{0x4F0,0}, -{0x4F2,0},{0x4F4,0},{0x4F6,0},{0x4F8,0},{0x4FA,0},{0x4FC,0},{0x4FE,0},{0x500,0},{0x502,0},{0x504,0}, -{0x506,0},{0x508,0},{0x50A,0},{0x50C,0},{0x50E,0},{0x510,0},{0x512,0},{0x514,0},{0x516,0},{0x518,0}, -{0x51A,0},{0x51C,0},{0x51E,0},{0x520,0},{0x522,0},{0x524,0},{0x526,0},{0x528,0},{0x52A,0},{0x52C,0}, -{0x52E,0},{0x531,37},{0x559,0},{0x55A,5},{0x589,0},{0x58A,0},{0x58D,1},{0x58F,0},{0x591,44},{0x5BE,0}, -{0x5BF,0},{0x5C0,0},{0x5C1,1},{0x5C3,0},{0x5C4,1},{0x5C6,0},{0x5C7,0},{0x5D0,34},{0x5F3,1},{0x600,5}, -{0x606,2},{0x609,1},{0x60B,0},{0x60C,1},{0x60E,1},{0x610,10},{0x61B,0},{0x61C,0},{0x61D,2},{0x620,31}, -{0x640,0},{0x641,9},{0x64B,20},{0x660,9},{0x66A,3},{0x66E,1},{0x670,0},{0x671,98},{0x6D4,0},{0x6D5,0}, -{0x6D6,6},{0x6DD,0},{0x6DE,0},{0x6DF,5},{0x6E5,1},{0x6E7,1},{0x6E9,0},{0x6EA,3},{0x6EE,1},{0x6F0,9}, -{0x6FA,2},{0x6FD,1},{0x6FF,0},{0x700,13},{0x70F,0},{0x710,0},{0x711,0},{0x712,29},{0x730,26},{0x74D,88}, -{0x7A6,10},{0x7B1,0},{0x7C0,9},{0x7CA,32},{0x7EB,8},{0x7F4,1},{0x7F6,0},{0x7F7,2},{0x7FA,0},{0x7FD,0}, -{0x7FE,1},{0x800,21},{0x816,3},{0x81A,0},{0x81B,8},{0x824,0},{0x825,2},{0x828,0},{0x829,4},{0x830,14}, -{0x840,24},{0x859,2},{0x85E,0},{0x860,39},{0x888,0},{0x889,5},{0x890,1},{0x898,7},{0x8A0,40},{0x8C9,0}, -{0x8CA,23},{0x8E2,0},{0x8E3,31},{0x903,0},{0x904,53},{0x93A,0},{0x93B,0},{0x93C,0},{0x93D,0},{0x93E,2}, -{0x941,7},{0x949,3},{0x94D,0},{0x94E,1},{0x950,0},{0x951,6},{0x958,9},{0x962,1},{0x964,1},{0x966,9}, -{0x970,0},{0x971,0},{0x972,14},{0x981,0},{0x982,1},{0x985,52},{0x9BC,0},{0x9BD,0},{0x9BE,2},{0x9C1,3}, -{0x9C7,5},{0x9CD,0},{0x9CE,0},{0x9D7,0},{0x9DC,5},{0x9E2,1},{0x9E6,9},{0x9F0,1},{0x9F2,1},{0x9F4,5}, -{0x9FA,0},{0x9FB,0},{0x9FC,0},{0x9FD,0},{0x9FE,4},{0xA03,0},{0xA05,52},{0xA3C,0},{0xA3E,2},{0xA41,16}, -{0xA59,5},{0xA66,9},{0xA70,1},{0xA72,2},{0xA75,0},{0xA76,0},{0xA81,1},{0xA83,0},{0xA85,52},{0xABC,0}, -{0xABD,0},{0xABE,2},{0xAC1,7},{0xAC9,3},{0xACD,0},{0xAD0,17},{0xAE2,1},{0xAE6,9},{0xAF0,0},{0xAF1,0}, -{0xAF9,0},{0xAFA,7},{0xB02,1},{0xB05,52},{0xB3C,0},{0xB3D,0},{0xB3E,0},{0xB3F,0},{0xB40,0},{0xB41,3}, -{0xB47,5},{0xB4D,9},{0xB57,0},{0xB5C,5},{0xB62,1},{0xB66,9},{0xB70,0},{0xB71,0},{0xB72,5},{0xB82,0}, -{0xB83,54},{0xBBE,1},{0xBC0,0},{0xBC1,11},{0xBCD,0},{0xBD0,0},{0xBD7,0},{0xBE6,9},{0xBF0,2},{0xBF3,5}, -{0xBF9,0},{0xBFA,0},{0xC00,0},{0xC01,2},{0xC04,0},{0xC05,52},{0xC3C,0},{0xC3D,0},{0xC3E,2},{0xC41,3}, -{0xC46,16},{0xC58,9},{0xC62,1},{0xC66,9},{0xC77,0},{0xC78,6},{0xC7F,0},{0xC80,0},{0xC81,0},{0xC82,1}, -{0xC84,0},{0xC85,52},{0xCBC,0},{0xCBD,0},{0xCBE,0},{0xCBF,0},{0xCC0,4},{0xCC6,0},{0xCC7,4},{0xCCC,1}, -{0xCD5,1},{0xCDD,4},{0xCE2,1},{0xCE6,9},{0xCF1,1},{0xCF3,0},{0xD00,1},{0xD02,1},{0xD04,54},{0xD3B,1}, -{0xD3D,0},{0xD3E,2},{0xD41,3},{0xD46,6},{0xD4D,0},{0xD4E,0},{0xD4F,0},{0xD54,2},{0xD57,0},{0xD58,6}, -{0xD5F,2},{0xD62,1},{0xD66,9},{0xD70,8},{0xD79,0},{0xD7A,5},{0xD81,0},{0xD82,1},{0xD85,65},{0xDCA,0}, -{0xDCF,2},{0xDD2,4},{0xDD8,7},{0xDE6,9},{0xDF2,1},{0xDF4,0},{0xE01,47},{0xE31,0},{0xE32,1},{0xE34,6}, -{0xE3F,0},{0xE40,5},{0xE46,0},{0xE47,7},{0xE4F,0},{0xE50,9},{0xE5A,1},{0xE81,47},{0xEB1,0},{0xEB2,1}, -{0xEB4,8},{0xEBD,7},{0xEC6,0},{0xEC8,6},{0xED0,9},{0xEDC,36},{0xF01,2},{0xF04,14},{0xF13,0},{0xF14,0}, -{0xF15,2},{0xF18,1},{0xF1A,5},{0xF20,9},{0xF2A,9},{0xF34,0},{0xF35,0},{0xF36,0},{0xF37,0},{0xF38,0}, -{0xF39,0},{0xF3A,0},{0xF3B,0},{0xF3C,0},{0xF3D,0},{0xF3E,1},{0xF40,44},{0xF71,13},{0xF7F,0},{0xF80,4}, -{0xF85,0},{0xF86,1},{0xF88,4},{0xF8D,47},{0xFBE,7},{0xFC6,0},{0xFC7,8},{0xFD0,4},{0xFD5,3},{0xFD9,1}, -{0x1000,42},{0x102B,1},{0x102D,3},{0x1031,0},{0x1032,5},{0x1038,0},{0x1039,1},{0x103B,1},{0x103D,1},{0x103F,0}, -{0x1040,9},{0x104A,5},{0x1050,5},{0x1056,1},{0x1058,1},{0x105A,3},{0x105E,2},{0x1061,0},{0x1062,2},{0x1065,1}, -{0x1067,6},{0x106E,2},{0x1071,3},{0x1075,12},{0x1082,0},{0x1083,1},{0x1085,1},{0x1087,5},{0x108D,0},{0x108E,0}, -{0x108F,0},{0x1090,9},{0x109A,2},{0x109D,0},{0x109E,1},{0x10A0,45},{0x10FB,0},{0x10FC,0},{0x1100,602},{0x135D,2}, -{0x1360,8},{0x1369,19},{0x1380,15},{0x1390,9},{0x13A0,85},{0x1400,0},{0x1401,619},{0x166D,0},{0x166E,0},{0x166F,16}, -{0x1680,0},{0x1681,25},{0x169B,0},{0x169C,0},{0x16A0,74},{0x16EB,2},{0x16EE,2},{0x16F1,32},{0x1712,2},{0x1715,0}, -{0x171F,18},{0x1732,1},{0x1734,0},{0x1735,1},{0x1740,17},{0x1752,1},{0x1760,16},{0x1772,1},{0x1780,51},{0x17B4,1}, -{0x17B6,0},{0x17B7,6},{0x17BE,7},{0x17C6,0},{0x17C7,1},{0x17C9,10},{0x17D4,2},{0x17D7,0},{0x17D8,2},{0x17DB,0}, -{0x17DC,0},{0x17DD,0},{0x17E0,9},{0x17F0,9},{0x1800,5},{0x1806,0},{0x1807,3},{0x180B,2},{0x180E,0},{0x180F,0}, -{0x1810,9},{0x1820,34},{0x1843,0},{0x1844,64},{0x1885,1},{0x1887,33},{0x18A9,0},{0x18AA,116},{0x1920,2},{0x1923,3}, -{0x1927,1},{0x1929,8},{0x1932,0},{0x1933,5},{0x1939,2},{0x1940,0},{0x1944,1},{0x1946,9},{0x1950,121},{0x19D0,9}, -{0x19DA,0},{0x19DE,33},{0x1A00,22},{0x1A17,1},{0x1A19,1},{0x1A1B,0},{0x1A1E,1},{0x1A20,52},{0x1A55,0},{0x1A56,0}, -{0x1A57,0},{0x1A58,8},{0x1A61,0},{0x1A62,0},{0x1A63,1},{0x1A65,7},{0x1A6D,5},{0x1A73,12},{0x1A80,25},{0x1AA0,6}, -{0x1AA7,0},{0x1AA8,5},{0x1AB0,13},{0x1ABE,0},{0x1ABF,68},{0x1B04,0},{0x1B05,46},{0x1B34,0},{0x1B35,0},{0x1B36,4}, -{0x1B3B,0},{0x1B3C,0},{0x1B3D,4},{0x1B42,0},{0x1B43,1},{0x1B45,7},{0x1B50,9},{0x1B5A,6},{0x1B61,9},{0x1B6B,8}, -{0x1B74,8},{0x1B7D,1},{0x1B80,1},{0x1B82,0},{0x1B83,29},{0x1BA1,0},{0x1BA2,3},{0x1BA6,1},{0x1BA8,1},{0x1BAA,0}, -{0x1BAB,2},{0x1BAE,1},{0x1BB0,9},{0x1BBA,43},{0x1BE6,0},{0x1BE7,0},{0x1BE8,1},{0x1BEA,2},{0x1BED,0},{0x1BEE,0}, -{0x1BEF,2},{0x1BF2,1},{0x1BFC,3},{0x1C00,35},{0x1C24,7},{0x1C2C,7},{0x1C34,1},{0x1C36,1},{0x1C3B,4},{0x1C40,9}, -{0x1C4D,2},{0x1C50,9},{0x1C5A,29},{0x1C78,5},{0x1C7E,1},{0x1C90,47},{0x1CC0,7},{0x1CD0,2},{0x1CD3,0},{0x1CD4,12}, -{0x1CE1,0},{0x1CE2,6},{0x1CE9,3},{0x1CED,0},{0x1CEE,5},{0x1CF4,0},{0x1CF5,1},{0x1CF7,0},{0x1CF8,1},{0x1CFA,0}, -{0x1D2C,62},{0x1D78,0},{0x1D9B,36},{0x1DC0,63},{0x1E00,0},{0x1E02,0},{0x1E04,0},{0x1E06,0},{0x1E08,0},{0x1E0A,0}, -{0x1E0C,0},{0x1E0E,0},{0x1E10,0},{0x1E12,0},{0x1E14,0},{0x1E16,0},{0x1E18,0},{0x1E1A,0},{0x1E1C,0},{0x1E1E,0}, -{0x1E20,0},{0x1E22,0},{0x1E24,0},{0x1E26,0},{0x1E28,0},{0x1E2A,0},{0x1E2C,0},{0x1E2E,0},{0x1E30,0},{0x1E32,0}, -{0x1E34,0},{0x1E36,0},{0x1E38,0},{0x1E3A,0},{0x1E3C,0},{0x1E3E,0},{0x1E40,0},{0x1E42,0},{0x1E44,0},{0x1E46,0}, -{0x1E48,0},{0x1E4A,0},{0x1E4C,0},{0x1E4E,0},{0x1E50,0},{0x1E52,0},{0x1E54,0},{0x1E56,0},{0x1E58,0},{0x1E5A,0}, -{0x1E5C,0},{0x1E5E,0},{0x1E60,0},{0x1E62,0},{0x1E64,0},{0x1E66,0},{0x1E68,0},{0x1E6A,0},{0x1E6C,0},{0x1E6E,0}, -{0x1E70,0},{0x1E72,0},{0x1E74,0},{0x1E76,0},{0x1E78,0},{0x1E7A,0},{0x1E7C,0},{0x1E7E,0},{0x1E80,0},{0x1E82,0}, -{0x1E84,0},{0x1E86,0},{0x1E88,0},{0x1E8A,0},{0x1E8C,0},{0x1E8E,0},{0x1E90,0},{0x1E92,0},{0x1E94,0},{0x1E9E,0}, -{0x1EA0,0},{0x1EA2,0},{0x1EA4,0},{0x1EA6,0},{0x1EA8,0},{0x1EAA,0},{0x1EAC,0},{0x1EAE,0},{0x1EB0,0},{0x1EB2,0}, -{0x1EB4,0},{0x1EB6,0},{0x1EB8,0},{0x1EBA,0},{0x1EBC,0},{0x1EBE,0},{0x1EC0,0},{0x1EC2,0},{0x1EC4,0},{0x1EC6,0}, -{0x1EC8,0},{0x1ECA,0},{0x1ECC,0},{0x1ECE,0},{0x1ED0,0},{0x1ED2,0},{0x1ED4,0},{0x1ED6,0},{0x1ED8,0},{0x1EDA,0}, -{0x1EDC,0},{0x1EDE,0},{0x1EE0,0},{0x1EE2,0},{0x1EE4,0},{0x1EE6,0},{0x1EE8,0},{0x1EEA,0},{0x1EEC,0},{0x1EEE,0}, -{0x1EF0,0},{0x1EF2,0},{0x1EF4,0},{0x1EF6,0},{0x1EF8,0},{0x1EFA,0},{0x1EFC,0},{0x1EFE,0},{0x1F08,7},{0x1F18,5}, -{0x1F28,7},{0x1F38,7},{0x1F48,5},{0x1F59,6},{0x1F68,7},{0x1F88,7},{0x1F98,7},{0x1FA8,7},{0x1FB8,3},{0x1FBC,0}, -{0x1FBD,0},{0x1FBF,2},{0x1FC8,3},{0x1FCC,0},{0x1FCD,2},{0x1FD8,3},{0x1FDD,2},{0x1FE8,4},{0x1FED,2},{0x1FF8,3}, -{0x1FFC,0},{0x1FFD,1},{0x2000,10},{0x200B,4},{0x2010,5},{0x2016,1},{0x2018,0},{0x2019,0},{0x201A,0},{0x201B,1}, -{0x201D,0},{0x201E,0},{0x201F,0},{0x2020,7},{0x2028,0},{0x2029,0},{0x202A,4},{0x202F,0},{0x2030,8},{0x2039,0}, -{0x203A,0},{0x203B,3},{0x203F,1},{0x2041,2},{0x2044,0},{0x2045,0},{0x2046,0},{0x2047,10},{0x2052,0},{0x2053,0}, -{0x2054,0},{0x2055,9},{0x205F,0},{0x2060,15},{0x2070,0},{0x2071,0},{0x2074,5},{0x207A,2},{0x207D,0},{0x207E,0}, -{0x207F,0},{0x2080,9},{0x208A,2},{0x208D,0},{0x208E,0},{0x2090,12},{0x20A0,32},{0x20D0,12},{0x20DD,3},{0x20E1,0}, -{0x20E2,2},{0x20E5,11},{0x2100,1},{0x2102,0},{0x2103,3},{0x2107,0},{0x2108,1},{0x210B,2},{0x2110,2},{0x2114,0}, -{0x2115,0},{0x2116,1},{0x2118,0},{0x2119,4},{0x211E,5},{0x2124,0},{0x2125,0},{0x2126,0},{0x2127,0},{0x2128,0}, -{0x2129,0},{0x212A,3},{0x212E,0},{0x2130,3},{0x2135,3},{0x213A,1},{0x213E,1},{0x2140,4},{0x2145,0},{0x214A,0}, -{0x214B,0},{0x214C,1},{0x214F,0},{0x2150,15},{0x2160,34},{0x2183,0},{0x2185,3},{0x2189,0},{0x218A,1},{0x2190,4}, -{0x2195,4},{0x219A,1},{0x219C,3},{0x21A0,0},{0x21A1,1},{0x21A3,0},{0x21A4,1},{0x21A6,0},{0x21A7,6},{0x21AE,0}, -{0x21AF,30},{0x21CE,1},{0x21D0,1},{0x21D2,0},{0x21D3,0},{0x21D4,0},{0x21D5,30},{0x21F4,267},{0x2300,7},{0x2308,0}, -{0x2309,0},{0x230A,0},{0x230B,0},{0x230C,19},{0x2320,1},{0x2322,6},{0x2329,0},{0x232A,0},{0x232B,80},{0x237C,0}, -{0x237D,29},{0x239B,24},{0x23B4,39},{0x23DC,5},{0x23E2,104},{0x2460,59},{0x249C,77},{0x24EA,21},{0x2500,182},{0x25B7,0}, -{0x25B8,8},{0x25C1,0},{0x25C2,53},{0x25F8,7},{0x2600,110},{0x266F,0},{0x2670,247},{0x2768,0},{0x2769,0},{0x276A,0}, -{0x276B,0},{0x276C,0},{0x276D,0},{0x276E,0},{0x276F,0},{0x2770,0},{0x2771,0},{0x2772,0},{0x2773,0},{0x2774,0}, -{0x2775,0},{0x2776,29},{0x2794,43},{0x27C0,4},{0x27C5,0},{0x27C6,0},{0x27C7,30},{0x27E6,0},{0x27E7,0},{0x27E8,0}, -{0x27E9,0},{0x27EA,0},{0x27EB,0},{0x27EC,0},{0x27ED,0},{0x27EE,0},{0x27EF,0},{0x27F0,15},{0x2800,255},{0x2900,130}, -{0x2983,0},{0x2984,0},{0x2985,0},{0x2986,0},{0x2987,0},{0x2988,0},{0x2989,0},{0x298A,0},{0x298B,0},{0x298C,0}, -{0x298D,0},{0x298E,0},{0x298F,0},{0x2990,0},{0x2991,0},{0x2992,0},{0x2993,0},{0x2994,0},{0x2995,0},{0x2996,0}, -{0x2997,0},{0x2998,0},{0x2999,62},{0x29D8,0},{0x29D9,0},{0x29DA,0},{0x29DB,0},{0x29DC,31},{0x29FC,0},{0x29FD,0}, -{0x29FE,257},{0x2B00,47},{0x2B30,20},{0x2B45,1},{0x2B47,5},{0x2B4D,178},{0x2C00,47},{0x2C60,0},{0x2C62,2},{0x2C67,0}, -{0x2C69,0},{0x2C6B,0},{0x2C6D,3},{0x2C72,0},{0x2C75,0},{0x2C7C,1},{0x2C7E,2},{0x2C82,0},{0x2C84,0},{0x2C86,0}, -{0x2C88,0},{0x2C8A,0},{0x2C8C,0},{0x2C8E,0},{0x2C90,0},{0x2C92,0},{0x2C94,0},{0x2C96,0},{0x2C98,0},{0x2C9A,0}, -{0x2C9C,0},{0x2C9E,0},{0x2CA0,0},{0x2CA2,0},{0x2CA4,0},{0x2CA6,0},{0x2CA8,0},{0x2CAA,0},{0x2CAC,0},{0x2CAE,0}, -{0x2CB0,0},{0x2CB2,0},{0x2CB4,0},{0x2CB6,0},{0x2CB8,0},{0x2CBA,0},{0x2CBC,0},{0x2CBE,0},{0x2CC0,0},{0x2CC2,0}, -{0x2CC4,0},{0x2CC6,0},{0x2CC8,0},{0x2CCA,0},{0x2CCC,0},{0x2CCE,0},{0x2CD0,0},{0x2CD2,0},{0x2CD4,0},{0x2CD6,0}, -{0x2CD8,0},{0x2CDA,0},{0x2CDC,0},{0x2CDE,0},{0x2CE0,0},{0x2CE2,0},{0x2CE5,5},{0x2CEB,0},{0x2CED,0},{0x2CEF,2}, -{0x2CF2,0},{0x2CF9,3},{0x2CFD,0},{0x2CFE,1},{0x2D30,55},{0x2D6F,0},{0x2D70,0},{0x2D7F,0},{0x2D80,94},{0x2DE0,31}, -{0x2E00,1},{0x2E02,0},{0x2E03,0},{0x2E04,0},{0x2E05,0},{0x2E06,2},{0x2E09,0},{0x2E0A,0},{0x2E0B,0},{0x2E0C,0}, -{0x2E0D,0},{0x2E0E,8},{0x2E17,0},{0x2E18,1},{0x2E1A,0},{0x2E1B,0},{0x2E1C,0},{0x2E1D,0},{0x2E1E,1},{0x2E20,0}, -{0x2E21,0},{0x2E22,0},{0x2E23,0},{0x2E24,0},{0x2E25,0},{0x2E26,0},{0x2E27,0},{0x2E28,0},{0x2E29,0},{0x2E2A,4}, -{0x2E2F,0},{0x2E30,9},{0x2E3A,1},{0x2E3C,3},{0x2E40,0},{0x2E41,0},{0x2E42,0},{0x2E43,12},{0x2E50,1},{0x2E52,2}, -{0x2E55,0},{0x2E56,0},{0x2E57,0},{0x2E58,0},{0x2E59,0},{0x2E5A,0},{0x2E5B,0},{0x2E5C,0},{0x2E5D,0},{0x2E80,379}, -{0x3000,0},{0x3001,2},{0x3004,0},{0x3005,0},{0x3006,0},{0x3007,0},{0x3008,0},{0x3009,0},{0x300A,0},{0x300B,0}, -{0x300C,0},{0x300D,0},{0x300E,0},{0x300F,0},{0x3010,0},{0x3011,0},{0x3012,1},{0x3014,0},{0x3015,0},{0x3016,0}, -{0x3017,0},{0x3018,0},{0x3019,0},{0x301A,0},{0x301B,0},{0x301C,0},{0x301D,0},{0x301E,1},{0x3020,0},{0x3021,8}, -{0x302A,3},{0x302E,1},{0x3030,0},{0x3031,4},{0x3036,1},{0x3038,2},{0x303B,0},{0x303C,0},{0x303D,0},{0x303E,1}, -{0x3041,85},{0x3099,1},{0x309B,1},{0x309D,1},{0x309F,0},{0x30A0,0},{0x30A1,89},{0x30FB,0},{0x30FC,2},{0x30FF,143}, -{0x3190,1},{0x3192,3},{0x3196,9},{0x31A0,31},{0x31C0,35},{0x31F0,15},{0x3200,30},{0x3220,9},{0x322A,29},{0x3248,7}, -{0x3250,0},{0x3251,14},{0x3260,31},{0x3280,9},{0x328A,38},{0x32B1,14},{0x32C0,319},{0x3400,6591},{0x4DC0,63},{0x4E00,21012}, -{0xA015,0},{0xA016,1142},{0xA490,54},{0xA4D0,39},{0xA4F8,5},{0xA4FE,1},{0xA500,267},{0xA60C,0},{0xA60D,2},{0xA610,15}, -{0xA620,9},{0xA62A,1},{0xA640,0},{0xA642,0},{0xA644,0},{0xA646,0},{0xA648,0},{0xA64A,0},{0xA64C,0},{0xA64E,0}, -{0xA650,0},{0xA652,0},{0xA654,0},{0xA656,0},{0xA658,0},{0xA65A,0},{0xA65C,0},{0xA65E,0},{0xA660,0},{0xA662,0}, -{0xA664,0},{0xA666,0},{0xA668,0},{0xA66A,0},{0xA66C,0},{0xA66E,0},{0xA66F,0},{0xA670,2},{0xA673,0},{0xA674,9}, -{0xA67E,0},{0xA67F,0},{0xA680,0},{0xA682,0},{0xA684,0},{0xA686,0},{0xA688,0},{0xA68A,0},{0xA68C,0},{0xA68E,0}, -{0xA690,0},{0xA692,0},{0xA694,0},{0xA696,0},{0xA698,0},{0xA69A,0},{0xA69C,1},{0xA69E,1},{0xA6A0,69},{0xA6E6,9}, -{0xA6F0,1},{0xA6F2,5},{0xA700,22},{0xA717,8},{0xA720,1},{0xA722,0},{0xA724,0},{0xA726,0},{0xA728,0},{0xA72A,0}, -{0xA72C,0},{0xA72E,0},{0xA732,0},{0xA734,0},{0xA736,0},{0xA738,0},{0xA73A,0},{0xA73C,0},{0xA73E,0},{0xA740,0}, -{0xA742,0},{0xA744,0},{0xA746,0},{0xA748,0},{0xA74A,0},{0xA74C,0},{0xA74E,0},{0xA750,0},{0xA752,0},{0xA754,0}, -{0xA756,0},{0xA758,0},{0xA75A,0},{0xA75C,0},{0xA75E,0},{0xA760,0},{0xA762,0},{0xA764,0},{0xA766,0},{0xA768,0}, -{0xA76A,0},{0xA76C,0},{0xA76E,0},{0xA770,0},{0xA779,0},{0xA77B,0},{0xA77D,1},{0xA780,0},{0xA782,0},{0xA784,0}, -{0xA786,0},{0xA788,0},{0xA789,1},{0xA78B,0},{0xA78D,0},{0xA78F,0},{0xA790,0},{0xA792,0},{0xA796,0},{0xA798,0}, -{0xA79A,0},{0xA79C,0},{0xA79E,0},{0xA7A0,0},{0xA7A2,0},{0xA7A4,0},{0xA7A6,0},{0xA7A8,0},{0xA7AA,4},{0xA7B0,4}, -{0xA7B6,0},{0xA7B8,0},{0xA7BA,0},{0xA7BC,0},{0xA7BE,0},{0xA7C0,0},{0xA7C2,0},{0xA7C4,3},{0xA7C9,0},{0xA7D0,0}, -{0xA7D6,0},{0xA7D8,0},{0xA7F2,2},{0xA7F5,0},{0xA7F7,0},{0xA7F8,1},{0xA7FB,6},{0xA802,0},{0xA803,2},{0xA806,0}, -{0xA807,3},{0xA80B,0},{0xA80C,22},{0xA823,1},{0xA825,1},{0xA827,0},{0xA828,3},{0xA82C,0},{0xA830,5},{0xA836,1}, -{0xA838,0},{0xA839,0},{0xA840,51},{0xA874,3},{0xA880,1},{0xA882,49},{0xA8B4,15},{0xA8C4,1},{0xA8CE,1},{0xA8D0,9}, -{0xA8E0,17},{0xA8F2,5},{0xA8F8,2},{0xA8FB,0},{0xA8FC,0},{0xA8FD,1},{0xA8FF,0},{0xA900,9},{0xA90A,27},{0xA926,7}, -{0xA92E,1},{0xA930,22},{0xA947,10},{0xA952,1},{0xA95F,0},{0xA960,28},{0xA980,2},{0xA983,0},{0xA984,46},{0xA9B3,0}, -{0xA9B4,1},{0xA9B6,3},{0xA9BA,1},{0xA9BC,1},{0xA9BE,2},{0xA9C1,12},{0xA9CF,0},{0xA9D0,9},{0xA9DE,1},{0xA9E0,4}, -{0xA9E5,0},{0xA9E6,0},{0xA9E7,8},{0xA9F0,9},{0xA9FA,46},{0xAA29,5},{0xAA2F,1},{0xAA31,1},{0xAA33,1},{0xAA35,1}, -{0xAA40,2},{0xAA43,0},{0xAA44,7},{0xAA4C,0},{0xAA4D,0},{0xAA50,9},{0xAA5C,3},{0xAA60,15},{0xAA70,0},{0xAA71,5}, -{0xAA77,2},{0xAA7A,0},{0xAA7B,0},{0xAA7C,0},{0xAA7D,0},{0xAA7E,49},{0xAAB0,0},{0xAAB1,0},{0xAAB2,2},{0xAAB5,1}, -{0xAAB7,1},{0xAAB9,4},{0xAABE,1},{0xAAC0,0},{0xAAC1,0},{0xAAC2,26},{0xAADD,0},{0xAADE,1},{0xAAE0,10},{0xAAEB,0}, -{0xAAEC,1},{0xAAEE,1},{0xAAF0,1},{0xAAF2,0},{0xAAF3,1},{0xAAF5,0},{0xAAF6,0},{0xAB01,45},{0xAB5B,0},{0xAB5C,3}, -{0xAB69,0},{0xAB6A,1},{0xABC0,34},{0xABE3,1},{0xABE5,0},{0xABE6,1},{0xABE8,0},{0xABE9,1},{0xABEB,0},{0xABEC,0}, -{0xABED,0},{0xABF0,9},{0xAC00,11259},{0xD800,2047},{0xE000,6399},{0xF900,473},{0xFB1D,0},{0xFB1E,0},{0xFB1F,9},{0xFB29,0}, -{0xFB2A,135},{0xFBB2,16},{0xFBD3,362},{0xFD3E,0},{0xFD3F,0},{0xFD40,15},{0xFD50,119},{0xFDCF,0},{0xFDF0,11},{0xFDFC,0}, -{0xFDFD,2},{0xFE00,15},{0xFE10,6},{0xFE17,0},{0xFE18,0},{0xFE19,0},{0xFE20,15},{0xFE30,0},{0xFE31,1},{0xFE33,1}, -{0xFE35,0},{0xFE36,0},{0xFE37,0},{0xFE38,0},{0xFE39,0},{0xFE3A,0},{0xFE3B,0},{0xFE3C,0},{0xFE3D,0},{0xFE3E,0}, -{0xFE3F,0},{0xFE40,0},{0xFE41,0},{0xFE42,0},{0xFE43,0},{0xFE44,0},{0xFE45,1},{0xFE47,0},{0xFE48,0},{0xFE49,3}, -{0xFE4D,2},{0xFE50,7},{0xFE58,0},{0xFE59,0},{0xFE5A,0},{0xFE5B,0},{0xFE5C,0},{0xFE5D,0},{0xFE5E,0},{0xFE5F,2}, -{0xFE62,0},{0xFE63,0},{0xFE64,2},{0xFE68,0},{0xFE69,0},{0xFE6A,1},{0xFE70,140},{0xFEFF,0},{0xFF01,2},{0xFF04,0}, -{0xFF05,2},{0xFF08,0},{0xFF09,0},{0xFF0A,0},{0xFF0B,0},{0xFF0C,0},{0xFF0D,0},{0xFF0E,1},{0xFF10,9},{0xFF1A,1}, -{0xFF1C,2},{0xFF1F,1},{0xFF21,25},{0xFF3B,0},{0xFF3C,0},{0xFF3D,0},{0xFF3E,0},{0xFF3F,0},{0xFF40,0},{0xFF5B,0}, -{0xFF5C,0},{0xFF5D,0},{0xFF5E,0},{0xFF5F,0},{0xFF60,0},{0xFF61,0},{0xFF62,0},{0xFF63,0},{0xFF64,1},{0xFF66,9}, -{0xFF70,0},{0xFF71,44},{0xFF9E,1},{0xFFA0,60},{0xFFE0,1},{0xFFE2,0},{0xFFE3,0},{0xFFE4,0},{0xFFE5,1},{0xFFE8,0}, -{0xFFE9,3},{0xFFED,1},{0xFFF9,2},{0xFFFC,1},{0xFFFF,0}}; - -static cletter Cletters1[]={{0x0000,250},{0x0100,2},{0x0107,44},{0x0137,8},{0x0140,52},{0x0175,3},{0x0179,16},{0x018A,1}, -{0x018C,112},{0x0280,80},{0x02E1,26},{0x0300,31},{0x0320,3},{0x032D,19},{0x0341,0},{0x0342,7},{0x034A,0},{0x0350,37}, -{0x0380,29},{0x039F,0},{0x03A0,47},{0x03D0,0},{0x03D1,4},{0x0400,39},{0x0428,39},{0x0450,77},{0x04A0,9},{0x04B0,35}, -{0x04D8,35},{0x0500,99},{0x056F,0},{0x0570,37},{0x0597,37},{0x0600,359},{0x0780,58},{0x0800,85},{0x0857,0},{0x0858,7}, -{0x0860,22},{0x0877,1},{0x0879,6},{0x0880,30},{0x08A7,8},{0x08E0,21},{0x08FB,4},{0x0900,21},{0x0916,5},{0x091F,0}, -{0x0920,25},{0x093F,0},{0x0980,55},{0x09BC,1},{0x09BE,1},{0x09C0,63},{0x0A00,0},{0x0A10,37},{0x0A40,8},{0x0A50,8}, -{0x0A60,28},{0x0A7D,1},{0x0A7F,0},{0x0A80,28},{0x0A9D,2},{0x0AC0,7},{0x0AC8,0},{0x0AC9,27},{0x0AEB,4},{0x0AF0,6}, -{0x0B00,53},{0x0B39,6},{0x0B40,21},{0x0B58,7},{0x0B60,18},{0x0B78,7},{0x0B80,17},{0x0B99,3},{0x0BA9,6},{0x0C00,72}, -{0x0C80,50},{0x0CC0,50},{0x0CFA,5},{0x0D00,35},{0x0D30,9},{0x0E60,30},{0x0E80,41},{0x0EAD,0},{0x0EB0,1},{0x0F00,28}, -{0x0F1D,9},{0x0F27,30},{0x0F51,3},{0x0F55,4},{0x0F70,17},{0x0F86,3},{0x0FB0,20},{0x0FC5,6},{0x0FE0,22},{0x1000,0}, -{0x1002,0},{0x1003,52},{0x1047,6},{0x1052,19},{0x1066,9},{0x1071,1},{0x1075,0},{0x1082,0},{0x1083,44},{0x10B0,2}, -{0x10B7,1},{0x10BB,1},{0x10BD,0},{0x10BE,3},{0x10CD,0},{0x10D0,24},{0x10F0,9},{0x1103,35},{0x112C,0},{0x1136,9}, -{0x1140,3},{0x1144,0},{0x1145,1},{0x1147,43},{0x1174,1},{0x1176,0},{0x1182,0},{0x1183,47},{0x11B3,2},{0x11BF,1}, -{0x11C1,3},{0x11C5,3},{0x11CD,0},{0x11CE,0},{0x11D0,9},{0x11DA,0},{0x11DB,0},{0x11DC,0},{0x11DD,2},{0x11E1,19}, -{0x1200,43},{0x122C,2},{0x1232,1},{0x1235,0},{0x1238,5},{0x123F,1},{0x1280,40},{0x12A9,0},{0x12B0,46},{0x12E0,2}, -{0x12F0,9},{0x1302,1},{0x1305,52},{0x133D,0},{0x133E,1},{0x1341,12},{0x1350,0},{0x1357,0},{0x135D,4},{0x1362,1}, -{0x1400,52},{0x1435,2},{0x1440,1},{0x1445,0},{0x1447,3},{0x144B,4},{0x1450,9},{0x145A,3},{0x145F,80},{0x14B0,2}, -{0x14B9,0},{0x14BB,3},{0x14C1,0},{0x14C4,1},{0x14C6,0},{0x14C7,0},{0x14D0,9},{0x1580,46},{0x15AF,2},{0x15B8,3}, -{0x15BE,0},{0x15C1,22},{0x15D8,3},{0x1600,47},{0x1630,2},{0x163B,1},{0x163E,0},{0x1641,2},{0x1644,0},{0x1650,9}, -{0x1660,12},{0x1680,42},{0x16AC,0},{0x16AE,1},{0x16B6,0},{0x16B8,0},{0x16B9,0},{0x16C0,9},{0x1700,26},{0x1720,1}, -{0x1726,0},{0x1730,9},{0x173A,1},{0x173C,2},{0x173F,0},{0x1740,235},{0x182C,2},{0x1838,0},{0x183B,0},{0x18A0,31}, -{0x18C0,31},{0x18E0,9},{0x18EA,8},{0x18FF,48},{0x1930,8},{0x193D,0},{0x193F,0},{0x1940,0},{0x1941,0},{0x1942,0}, -{0x1944,2},{0x1950,9},{0x19A0,48},{0x19D1,2},{0x19DC,3},{0x19E1,0},{0x19E2,0},{0x19E3,0},{0x19E4,0},{0x1A00,0}, -{0x1A0B,39},{0x1A39,0},{0x1A3A,0},{0x1A3F,7},{0x1A50,0},{0x1A57,1},{0x1A5C,45},{0x1A97,0},{0x1A9A,2},{0x1A9D,0}, -{0x1A9E,4},{0x1AB0,72},{0x1B00,9},{0x1C00,46},{0x1C2F,0},{0x1C3E,0},{0x1C40,0},{0x1C41,4},{0x1C50,9},{0x1C5A,18}, -{0x1C70,1},{0x1C72,29},{0x1CA9,0},{0x1CB1,0},{0x1CB4,0},{0x1D00,48},{0x1D46,0},{0x1D50,9},{0x1D60,41},{0x1D8A,4}, -{0x1D93,1},{0x1D96,0},{0x1D98,0},{0x1DA0,9},{0x1EE0,18},{0x1EF5,1},{0x1EF7,1},{0x1F02,0},{0x1F03,0},{0x1F04,47}, -{0x1F34,1},{0x1F3E,1},{0x1F41,0},{0x1F43,12},{0x1F50,9},{0x1FB0,0},{0x1FC0,20},{0x1FD5,7},{0x1FDD,3},{0x1FE1,16}, -{0x1FFF,0},{0x2000,921},{0x2400,110},{0x2470,4},{0x2480,2928},{0x2FF1,1},{0x3000,1071},{0x3430,15},{0x3441,5},{0x4400,9822}, -{0x6A60,9},{0x6A6E,1},{0x6A70,78},{0x6AC0,9},{0x6AD0,29},{0x6AF5,0},{0x6B00,47},{0x6B37,4},{0x6B3C,3},{0x6B40,3}, -{0x6B44,0},{0x6B45,0},{0x6B50,9},{0x6B5B,6},{0x6B63,44},{0x6E40,31},{0x6E60,31},{0x6E80,22},{0x6E97,3},{0x6F00,74}, -{0x6F50,0},{0x6F51,54},{0x6F93,78},{0x6FE2,0},{0x6FE3,0},{0x6FF0,1},{0x7000,7432},{0xAFF0,14},{0xB000,3225},{0xBC9C,0}, -{0xBC9F,0},{0xBCA0,3},{0xCF50,532},{0xD165,1},{0xD16A,2},{0xD16D,5},{0xD173,7},{0xD183,1},{0xD18C,29},{0xD1AE,147}, -{0xD245,0},{0xD2C0,51},{0xD300,86},{0xD360,24},{0xD400,25},{0xD41A,25},{0xD434,25},{0xD44E,25},{0xD468,25},{0xD482,25}, -{0xD49C,25},{0xD4B6,25},{0xD4D0,25},{0xD4EA,25},{0xD504,24},{0xD51E,25},{0xD538,24},{0xD552,25},{0xD56C,25},{0xD586,25}, -{0xD5A0,25},{0xD5BA,25},{0xD5D4,25},{0xD5EE,25},{0xD608,25},{0xD622,25},{0xD63C,25},{0xD656,25},{0xD670,25},{0xD68A,27}, -{0xD6A8,24},{0xD6C1,0},{0xD6C2,24},{0xD6DB,0},{0xD6DC,5},{0xD6E2,24},{0xD6FB,0},{0xD6FC,24},{0xD715,0},{0xD716,5}, -{0xD71C,24},{0xD735,0},{0xD736,24},{0xD74F,0},{0xD750,5},{0xD756,24},{0xD76F,0},{0xD770,24},{0xD789,0},{0xD78A,5}, -{0xD790,24},{0xD7A9,0},{0xD7AA,24},{0xD7C3,0},{0xD7C4,5},{0xD7CA,0},{0xD7CB,0},{0xD7CE,49},{0xD800,511},{0xDA37,3}, -{0xDA6D,7},{0xDA76,13},{0xDA85,1},{0xDA87,4},{0xDF00,9},{0xDF0A,0},{0xDF0B,31},{0xE030,61},{0xE100,44},{0xE137,6}, -{0xE140,9},{0xE14E,0},{0xE14F,0},{0xE290,29},{0xE2C0,43},{0xE2F0,9},{0xE2FF,0},{0xE4D0,26},{0xE4EB,0},{0xE4F0,9}, -{0xE7E0,228},{0xE8C7,8},{0xE900,33},{0xE922,33},{0xE94B,0},{0xE950,9},{0xE95E,1},{0xEC71,58},{0xECAC,0},{0xECAD,2}, -{0xECB0,0},{0xECB1,124},{0xED2E,0},{0xED2F,14},{0xEE00,187},{0xEEF0,1},{0xF000,245},{0xF100,12},{0xF10D,749},{0xF3FB,4}, -{0xF400,1994},{0xFBF0,9},{0xFFFF,0}}; - -static cletter2 Cletters2[]={{0x20000,74671},{0xE0001,126},{0xE0100,239},{0xF0000,131069},{0xFFFFF,0}}; - -static const char * gencat(int a) - { - unsigned int pivot; - unsigned int lo; - unsigned int hi; - unsigned int offset; - cletter *Cletters; - const char *def; - static char returnVal[3] = { '\0','\0','\0' }; - - if(a <= 0) - return 0; - lo = 0; - offset = 0; - Cletters = 0; - if(a < 0x10000) - { - pivot = 8; - hi = 1782; /* Range starting at lastindex does not consists of letters, so pivot must always stay less than lastindex. */ - assert(pivot < 1782); - Cletters = Cletters0; - def = "Ll"; - } - else if(a >= 0x20000) - { - int i; - for(i = 0;i < 4;++i) - { - if(Cletters2[i].L <= (unsigned int)a && (unsigned int)a <= Cletters2[i].L + Cletters2[i].range) - { - tmark mrk = Mark[i + 1782 + 430]; - returnVal[0] = firstMark[mrk.m1]; - returnVal[1] = secondMark[mrk.m2]; - returnVal[2] = '\0'; - break; - } - } - return returnVal; - } - else - { - a &= 0xFFFF; - pivot = 430 >> 1; - hi = 430; - Cletters = Cletters1; - def = "Mn"; - offset = 1782; - } - while(1) - { - assert(pivot < hi); - if((unsigned short)a < Cletters[pivot].L) - { - if(pivot == lo) - return def; - else - { - hi = pivot; - pivot = (pivot + lo) / 2; - } - } - else if((unsigned short)a <= Cletters[pivot].L + Cletters[pivot].range) - { - tmark mrk = Mark[pivot + offset]; - returnVal[0] = firstMark[mrk.m1]; - returnVal[1] = secondMark[mrk.m2]; - returnVal[2] = '\0'; - return returnVal; - } - else if(pivot + 1 == hi) - return def; - else - { - lo = pivot + 1; - pivot = (hi + pivot) / 2; - } - } - } - -/* End of unichartypes.c */ - -/* Begin of globals.c */ -/* Begin of globals.h */ - -#include -#include - -/* End of globals.h */ - -#if DEBUGBRACMAT -static int debug = 0; -#endif -#if CHECKALLOCBOUNDS -static int POINT = 0; -#endif - -#if CODEPAGE850 -static const unsigned char lowerEquivalent[256] = - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', - '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\', ']', '^', '_', - '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 215, 248, 249, 250, 251, 252, 253, 254, 223 /*ringel s*/, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 - }; - -static const unsigned char upperEquivalent[256] = - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', - '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', - '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 247, 216, 217, 218, 219, 220, 221, 222, 255 /* ij */ - }; -#endif - -static int dummy_op = WHITE; -static psk addr[7]; -static sk zeroNode, oneNode, minusOneNode, -nilNode, nilNodeNotNeutral, -zeroNodeNotNeutral, -oneNodeNotNeutral, -argNode, selfNode, SelfNode, twoNode, fourNode, sjtNode; - -static FILE* global_fpi; -static FILE* global_fpo; -static int optab[256]; - -#if GLOBALARGPTR -static va_list argptr; -#endif - -#if !defined NO_FOPEN -static char* errorFileName = NULL; -#endif -static FILE* errorStream = NULL; - -static int hum = 1; -static int listWithName = 1; -static int beNice = TRUE; -static psk global_anchor; -static size_t telling = 0; -static unsigned char* source; - -static const psk knil[16] = - { NULL,NULL,NULL,NULL,NULL,NULL,&nilNode,&zeroNode, - &oneNode,NULL,NULL,NULL,NULL,NULL,NULL,NULL }; - -#if !defined NO_FOPEN -static char* targetPath = NULL; /* Path that can be prepended to filenames. */ -#endif - -static int ARGC = 0; -static char** ARGV = NULL; - -static psk m0 = NULL, m1 = NULL, f0 = NULL, f1 = NULL, f4 = NULL, f5 = NULL; - -/* End of globals.c */ - -/* Begin of filewrite.c */ -/* Begin of filewrite.h */ - -#if _BRACMATEMBEDDED && !defined _MT - -#else -#define Printf printf -#endif - -int errorprintf(const char* fmt, ...); - -/* End of filewrite.h */ - -#include - -#if _BRACMATEMBEDDED - -static int(*WinIn)(void) = NULL; -static void(*WinOut)(int c) = NULL; -static void(*WinFlush)(void) = NULL; -#if defined PYTHONINTERFACE -static void(*Ni)(const char*) = NULL; -static const char* (*Nii)(const char*) = NULL; -#endif -static int mygetc(FILE* fpi) - { - if(WinIn && fpi == stdin) - { - return WinIn(); - } - else - return fgetc(fpi); - } - -static void myputc(int c) - { - if(WinOut && (global_fpo == stdout || global_fpo == stderr)) - { - WinOut(c); - } - else - fputc(c, global_fpo); - } -#else -static void myputc(int c) - { -#ifdef __EMSCRIPTEN__ - fputc(c, stdout); -#else - fputc(c, global_fpo); -#endif - } - -static int mygetc(FILE* fpi) - { -#ifdef __SYMBIAN32__ - if(fpi == stdin) - { - static unsigned char inputbuffer[256] = { 0 }; - static unsigned char* out = inputbuffer; - if(!*out) - { - static unsigned char* in = inputbuffer; - static int kar; - while(in < inputbuffer + sizeof(inputbuffer) - 2 - && (kar = fgetc(fpi)) != '\n' - ) - { - switch(kar) - { - case '\r': - break; - case 8: - if(in > inputbuffer) - { - --in; - putchar(' '); - putchar(8); - } - break; - default: - *in++ = kar; - } - } - *in = kar; - *++in = '\0'; - out = in = inputbuffer; - } - return *out++; - } -#endif - return fgetc(fpi); - } -#endif - -static void(*process)(int c) = myputc; - -static void myprintf(const char* strng, ...) - { - const char* i, * j; - va_list ap; - va_start(ap, strng); - i = strng; - while(i) - { - for(j = i; *j; j++) - (*process)(*j); - i = va_arg(ap, char*); - } - va_end(ap); - } - -#if _BRACMATEMBEDDED && !defined _MT -static int Printf(const char* fmt, ...) - { - char buffer[1000]; - int ret; - va_list ap; - va_start(ap, fmt); - ret = vsprintf(buffer, fmt, ap); - myprintf(buffer, NULL); - va_end(ap); - return ret; - } -#else -#define Printf printf -#endif - -int errorprintf(const char* fmt, ...) - { - char buffer[1000]; - int ret; - FILE* save = global_fpo; - va_list ap; - va_start(ap, fmt); - ret = vsprintf(buffer, fmt, ap); - global_fpo = errorStream; -#if !defined NO_FOPEN - if(global_fpo == NULL && errorFileName != NULL) - global_fpo = fopen(errorFileName, APPENDTXT); -#endif - if(global_fpo) - myprintf(buffer, NULL); - else - ret = 0; -#if !defined NO_FOPEN - if(errorStream == NULL && global_fpo != NULL) - fclose(global_fpo); -#endif - global_fpo = save; - va_end(ap); - return ret; - } - -static int lineTooLong(unsigned char* strng) - { - if(hum - && strlen((const char*)strng) > 10 /*LineLength*/ - /* very short strings are allowed to keep \n and \t */ - ) - return TRUE; - return FALSE; - } - -/* End of filewrite.c */ - -/* Begin of numbercheck.c */ - -/*strspn()*/ - -static int numbercheck(const char* begin) - { - int op_or_0, check; - int needNonZeroDigit = FALSE; - int signseen = FALSE; - char* endptr; - const char* savebegin = begin; - if(!*begin) - return 0; - op_or_0 = strspn(begin, "0123456789.-+/aAbBcCdDeEfFpPxX"); - if(begin[op_or_0]) - return DEFINITELYNONUMBER; - check = QNUMBER; - op_or_0 = *begin; - - if(op_or_0 == '-' || op_or_0 == '+') - { - op_or_0 = *++begin; - signseen = TRUE; - } - if(op_or_0 >= '0' && op_or_0 <= '9') - { - if(op_or_0 == '0') - { - if(*(begin + 1) == 'x' || *(begin + 1) == 'X' || *(begin + 1) == '.') - { - /* hexadecimal number, must be in domain of strtod */ - double testdouble = strtod(begin, &endptr); - if(*endptr) - return DEFINITELYNONUMBER; /* format error */ - if(testdouble == 0.0) - check |= QNUL; - /* Since doubles can be serialised to hex strings without - losing bits, hex numbers are treated like doubles, not like - integer or fractional numbers. - Format as the printf() "%a" format specifier. The 'p' - (exponent) specification is optional. */ - return check; - } - else - check |= QNUL; - } - if(optab[op_or_0 = *++begin] != -1) - { - if(signseen) - check = DEFINITELYNONUMBER; /*sign must not be inside quotes*/ - else - { - while((check != DEFINITELYNONUMBER) && (optab[op_or_0 = *begin++] != -1)) - { - if(op_or_0 == '/') - { - /* check &= ~QNUL;*/ - if(check & QFRACTION) - { - check = DEFINITELYNONUMBER; - break; - } - else - { - needNonZeroDigit = TRUE; - check |= QFRACTION; - } - } - else if(op_or_0 < '0' || op_or_0 > '9') - { - check = DEFINITELYNONUMBER; - break; - } - else - { - /* initial zero followed by - 0 <= k <= 9 makes no number */ - if((check & (QNUL | QFRACTION)) == QNUL) - { - return DEFINITELYNONUMBER; - } - else if(op_or_0 != '0') - { - needNonZeroDigit = FALSE; - /*check &= ~QNUL;*/ - } - else if(needNonZeroDigit) /* '/' followed by '0' */ - { - return DEFINITELYNONUMBER; - } - } - } - } - } - if(check == DEFINITELYNONUMBER) - { - double testdouble = strtod(savebegin, &endptr); - if(*endptr) - return check; /* format error */ - check = QNUMBER|QDOUBLE; - if(testdouble == 0.0) - check |= QNUL; - /* Since doubles can be serialised to hex strings without - losing bits, hex numbers are treated like doubles, not like - integer or fractional numbers. - Format as the printf() "%a" format specifier. The 'p' - (exponent) specification is optional. */ - return check; - } - /* Trailing closing parentheses were accepted on equal footing with '\0' bytes. */ - if(op_or_0 == ')') /* "2)"+3 @("-23/4)))))":-23/4) */ - { - check = DEFINITELYNONUMBER; - } - } - else - { - check = DEFINITELYNONUMBER; - } - if(check && needNonZeroDigit) - { - check = 0; - } - return check; - } - -static int fullnumbercheck(const char* begin) - { - if(*begin == '-') - { - int ret = numbercheck(begin + 1); - if(ret & ~DEFINITELYNONUMBER) - return ret | MINUS; - else - return ret; - } - else - return numbercheck(begin); - } - -static int sfullnumbercheck(char* begin, char* cutoff) - { - unsigned char sav = *cutoff; - int ret; - *cutoff = '\0'; - ret = fullnumbercheck(begin); - *cutoff = sav; - return ret; - } -/* End of numbercheck.c */ - -/* Begin of memory.c */ - -/* Begin of eval.h */ - -static psk eval(psk Pnode); -#define evaluate(x) \ -( ( ((x) = eval(x))->v.fl \ - & SUCCESS\ - ) \ - ? TRUE\ - : ((x)->v.fl & FENCE)\ -) -/* End of eval.h */ - -/* Begin of wipecopy.h */ - -static void wipe(psk top); - -/* End of wipecopy.h */ - -/* -After running valid.bra on 32 bit platform -1 8 32 -2 16384 131072 -3 32696 392352 -4 1024 16384 -5 256 5120 -6 2048 49152 - ------+ -total bytes = 594112 -*/ -#if WORD32 -#define MEM1SIZE 8 -#define MEM2SIZE 16384 -#define MEM3SIZE 32696 -#define MEM4SIZE 1024 -#define MEM5SIZE 256 -#define MEM6SIZE 2048 -#else -/* -After running valid.bra on 64 bit platform -1 8 64 -2 16384 262144 -3 32768 786432 -4 1024 32768 -5 2048 81920 -6 64 3072 - -------+ -total bytes = 1166400 -*/ -#define MEM1SIZE 8 -#define MEM2SIZE 16384 -#define MEM3SIZE 32768 -#define MEM4SIZE 1024 -#define MEM5SIZE 2048 -#define MEM6SIZE 64 -#endif - -#if SHOWMAXALLOCATED -static size_t globalloc = 0, maxgloballoc = 0; -#endif - -#if SHOWCURRENTLYALLOCATED -static size_t cnts[256], alloc_cnt = 0, totcnt = 0; -#endif - -struct memblock - { - struct memoryElement* lowestAddress; - struct memoryElement* highestAddress; - struct memoryElement* firstFreeElementBetweenAddresses; /* if NULL : no more free elements */ - struct memblock* previousOfSameLength; /* address of older ands smaller block with same sized elements */ - size_t sizeOfElement; -#if SHOWMAXALLOCATED - size_t numberOfFreeElementsBetweenAddresses; /* optional field. */ - size_t numberOfElementsBetweenAddresses; /* optional field. */ - size_t minimumNumberOfFreeElementsBetweenAddresses; -#endif - }; - -struct allocation - { - size_t elementSize; - int numberOfElements; - struct memblock* memoryBlock; - }; - -static struct allocation* global_allocations; -static int global_nallocations = 0; - -struct memoryElement - { - struct memoryElement* next; - }; -/* -struct pointerStruct - { - struct pointerStruct * lp; - } *global_p, *global_ep; -*/ -static struct memblock** pMemBlocks = 0; /* list of memblock, sorted - according to memory address */ -static int NumberOfMemBlocks = 0; -#if SHOWMAXALLOCATED -static int malloced = 0; -#endif - -#if DOSUMCHECK - -static int LineNo; -static const char* FileName; -static int globN; - -static int getchecksum(void) - { - int i; - int sum = 0; - for(i = 0; i < NumberOfMemBlocks; ++i) - { - struct memoryElement* me; - struct memblock* mb = pMemBlocks[i]; - me = mb->firstFreeElementBetweenAddresses; - while(me) - { - sum += (LONG)me; - me = me->next; - } - } - return sum; - } - -static int Checksum = 0; - -static void setChecksum(const char* file,int lineno, int n) - { - if(lineno) - { - LineNo = lineno; - FileName = file; - globN = n; - } - Checksum = getchecksum(); - } - -static void checksum(const char* file, int line) - { - static int nChecksum = 0; - nChecksum = getchecksum(); - if(Checksum && Checksum != nChecksum) - { - Printf("File %s, Line %d: Illegal write after bmalloc(%d) on line %d", file, line, globN, LineNo); - getchar(); - exit(1); - } - } -#else -#define setChecksum(a,b,c) -#define checksum(a,b) -#endif - -static struct memblock* initializeMemBlock(size_t elementSize, size_t numberOfElements) - { - size_t nlongpointers; - size_t stepSize; - struct memblock* mb; - struct memoryElement* mEa, * mEz; - mb = (struct memblock*)malloc(sizeof(struct memblock)); - if(mb) - { - mb->sizeOfElement = elementSize; - mb->previousOfSameLength = 0; - stepSize = elementSize / sizeof(struct memoryElement); - nlongpointers = stepSize * numberOfElements; - mb->firstFreeElementBetweenAddresses = mb->lowestAddress = (struct memoryElement*)malloc(elementSize * numberOfElements); - if(mb->lowestAddress == 0) - { -#if _BRACMATEMBEDDED - return 0; -#else - exit(-1); -#endif - } - else - { - mEa = mb->lowestAddress; - mb->highestAddress = mEa + nlongpointers; -#if SHOWMAXALLOCATED - mb->numberOfFreeElementsBetweenAddresses = numberOfElements; - mb->numberOfElementsBetweenAddresses = numberOfElements; - mb->minimumNumberOfFreeElementsBetweenAddresses = numberOfElements; -#endif - mEz = mb->highestAddress - stepSize; - for(; mEa < mEz; ) - { - mEa->next = mEa + stepSize; - assert(((LONG)(mEa->next) & 1) == 0); - mEa = mEa->next; - } - assert(mEa == mEz); - mEa->next = 0; - return mb; - } - } - else -#if _BRACMATEMBEDDED - return 0; -#else - exit(-1); -#endif - } - -/* The newMemBlocks function is introduced because the same code, -if in-line in bmalloc, and if compiled with -O3, doesn't run. */ -static struct memblock* newMemBlocks(size_t n) - { - struct memblock* mb; - int i, j = 0; - struct memblock** npMemBlocks; - mb = initializeMemBlock(global_allocations[n].elementSize, global_allocations[n].numberOfElements); - if(!mb) - return 0; - global_allocations[n].numberOfElements *= 2; - mb->previousOfSameLength = global_allocations[n].memoryBlock; - global_allocations[n].memoryBlock = mb; - - ++NumberOfMemBlocks; - npMemBlocks = (struct memblock**)malloc((NumberOfMemBlocks) * sizeof(struct memblock*)); - if(npMemBlocks) - { - for(i = 0; i < NumberOfMemBlocks - 1; ++i) - { - if(mb < pMemBlocks[i]) - { - npMemBlocks[j++] = mb; - for(; i < NumberOfMemBlocks - 1; ++i) - { - npMemBlocks[j++] = pMemBlocks[i]; - } - free(pMemBlocks); - pMemBlocks = npMemBlocks; -#if SHOWMEMBLOCKS - showMemBlocks(); -#endif - return mb; - } - npMemBlocks[j++] = pMemBlocks[i]; - } - npMemBlocks[j] = mb; - free(pMemBlocks); - pMemBlocks = npMemBlocks; -#if SHOWMEMBLOCKS - showMemBlocks(); -#endif - return mb; - } - else - { -#if _BRACMATEMBEDDED - return 0; -#else - exit(-1); -#endif - } - - } - -#if SHOWCURRENTLYALLOCATED -static void bezetting(void) - { - struct memblock* mb = 0; - size_t words = 0; - int i; - Printf("\nfree\n"); - for(i = 0; i < NumberOfMemBlocks; ++i) - { - mb = pMemBlocks[i]; -#if WORD32 || defined __VMS - Printf("%zd words per node : %lu of %lu\n", mb->sizeOfElement / sizeof(struct memoryElement), mb->numberOfFreeElementsBetweenAddresses, mb->numberOfElementsBetweenAddresses); -#else - Printf("%zd words per node : %zu of %lu\n", mb->sizeOfElement / sizeof(struct memoryElement), mb->numberOfFreeElementsBetweenAddresses, mb->numberOfElementsBetweenAddresses); -#endif - } - Printf("\nmin free\n"); - for(i = 0; i < NumberOfMemBlocks; ++i) - { - mb = pMemBlocks[i]; -#if WORD32 || defined __VMS - Printf("%zd words per node : %lu of %lu\n", mb->sizeOfElement / sizeof(struct memoryElement), mb->minimumNumberOfFreeElementsBetweenAddresses, mb->numberOfElementsBetweenAddresses); -#else - Printf("%zd words per node : %zu of %lu\n", mb->sizeOfElement / sizeof(struct memoryElement), mb->minimumNumberOfFreeElementsBetweenAddresses, mb->numberOfElementsBetweenAddresses); -#endif - } - Printf("more than %zd words per node : %u\n", words, malloced); - } -#endif - -#if DOSUMCHECK -static void* Bmalloc(const char* file, int lineno, size_t n) -#else -void* Bmalloc(size_t n) -#endif - { - void* ret; -#if DOSUMCHECK - size_t nn = n; -#endif -#if SHOWCURRENTLYALLOCATED - int tel; - alloc_cnt++; - if(n < 256) - cnts[n]++; - totcnt += n; -#endif -#if SHOWMAXALLOCATED - globalloc++; - if(maxgloballoc < globalloc) - maxgloballoc = globalloc; -#endif -#if CHECKALLOCBOUNDS - n += 3 * sizeof(LONG); -#endif - checksum(__FILE__, __LINE__); - n = (n - 1) / sizeof(struct memoryElement); - if(n < -#if _5_6 - 6 -#elif _4 - 4 -#else - 3 -#endif - ) - { - struct memblock* mb = global_allocations[n].memoryBlock; - ret = mb->firstFreeElementBetweenAddresses; - while(ret == 0) - { - mb = mb->previousOfSameLength; - if(!mb) - mb = newMemBlocks(n); - if(!mb) - break; - ret = mb->firstFreeElementBetweenAddresses; - } - if(ret != 0) - { -#if SHOWMAXALLOCATED - --(mb->numberOfFreeElementsBetweenAddresses); - if(mb->numberOfFreeElementsBetweenAddresses < mb->minimumNumberOfFreeElementsBetweenAddresses) - mb->minimumNumberOfFreeElementsBetweenAddresses = mb->numberOfFreeElementsBetweenAddresses; -#endif - mb->firstFreeElementBetweenAddresses = ((struct memoryElement*)mb->firstFreeElementBetweenAddresses)->next; - /** / - memset(ret,0,(n+1) * sizeof(struct pointerStruct)); - / **/ - ((LONG*)ret)[n] = 0; - ((LONG*)ret)[0] = 0; - setChecksum(file,lineno, nn); -#if CHECKALLOCBOUNDS - ((LONG*)ret)[n - 1] = 0; - ((LONG*)ret)[2] = 0; - ((LONG*)ret)[1] = n; - ((LONG*)ret)[n] = ('t' << 24) + ('e' << 16) + ('n' << 8) + ('d'); - ((LONG*)ret)[0] = ('s' << 24) + ('t' << 16) + ('a' << 8) + ('r'); - return (void*)(((LONG*)ret) + 2); -#else - return ret; -#endif - } - } - ret = malloc((n + 1) * sizeof(struct memoryElement)); - - if(!ret) - { -#if SHOWCURRENTLYALLOCATED - errorprintf( - "MEMORY FULL AFTER %lu ALLOCATIONS WITH MEAN LENGTH %lu\n", - globalloc, totcnt / alloc_cnt); - for(tel = 0; tel < 16; tel++) - { - int tel1; - for(tel1 = 0; tel1 < 256; tel1 += 16) - errorprintf("%lu ", (cnts[tel + tel1] * 1000UL + 500UL) / alloc_cnt); - errorprintf("\n"); - } - bezetting(); -#endif - errorprintf( - "memory full (requested block of %d bytes could not be allocated)", - (n << 2) + 4); - - exit(1); - } - -#if SHOWMAXALLOCATED - ++malloced; -#endif - ((LONG*)ret)[n] = 0; - ((LONG*)ret)[0] = 0; - setChecksum(file,lineno, n); -#if CHECKALLOCBOUNDS - ((LONG*)ret)[n - 1] = 0; - ((LONG*)ret)[2] = 0; - ((LONG*)ret)[1] = n; - ((LONG*)ret)[n] = ('t' << 24) + ('e' << 16) + ('n' << 8) + ('d'); - ((LONG*)ret)[0] = ('s' << 24) + ('t' << 16) + ('a' << 8) + ('r'); - return (void*)(((LONG*)ret) + 2); -#else - return ret; -#endif - } - -#if CHECKALLOCBOUNDS -static int isFree(void* p) - { - LONG* q; - int i; - struct memoryElement* I; - q = (LONG*)p - 2; - I = (struct memoryElement*)q; - for(i = 0; i < NumberOfMemBlocks; ++i) - { - struct memoryElement* me; - struct memblock* mb = pMemBlocks[i]; - me = (struct memoryElement*)mb->firstFreeElementBetweenAddresses; - while(me) - { - if(I == me) - return 1; - me = (struct memoryElement*)me->next; - } - } - return 0; - } - -static void result(psk Root); -static int rfree(psk p) - { - int r = 0; - if(isFree(p)) - { - printf(" ["); - result(p); - printf("] "); - r = 1; - } - if(is_op(p)) - { - r |= rfree(p->LEFT); - r |= rfree(p->RIGHT); - } - return r; - } - -static int areFree(char* t, psk p) - { - if(rfree(p)) - { - POINT = 1; - printf("%s:areFree(", t); - result(p); - POINT = 0; - printf("\n"); - return 1; - } - return 0; - } - -static void checkMem(void* p) - { - LONG* q; - q = (LONG*)p - 2; - if(q[0] == ('s' << 24) + ('t' << 16) + ('a' << 8) + ('r') - && q[q[1]] == ('t' << 24) + ('e' << 16) + ('n' << 8) + ('d') - ) - { - ; - } - else - { - char* s = (char*)q; - printf("s:["); - for(; s < (char*)(q + q[1] + 1); ++s) - { - if((((LONG)s) % 4) == 0) - printf("|"); - if(' ' <= *s && *s <= 127) - printf(" %c", *s); - else - printf("%.2x", (int)((unsigned char)*s)); - } - printf("] %p\n", p); - } - assert(q[0] == ('s' << 24) + ('t' << 16) + ('a' << 8) + ('r')); - assert(q[q[1]] == ('t' << 24) + ('e' << 16) + ('n' << 8) + ('d')); - } - -static void checkBounds(void* p) - { - struct memblock** q; - LONG* lp = (LONG*)p; - assert(p != 0); - checkMem(p); - lp = lp - 2; - p = lp; - assert(lp[0] == ('s' << 24) + ('t' << 16) + ('a' << 8) + ('r')); - assert(lp[lp[1]] == ('t' << 24) + ('e' << 16) + ('n' << 8) + ('d')); - for(q = pMemBlocks + NumberOfMemBlocks; --q >= pMemBlocks;) - { -#ifndef NDEBUG - size_t stepSize = (*q)->sizeOfElement / sizeof(struct memoryElement); -#endif // !NDEBUG - if((*q)->lowestAddress <= (struct memoryElement*)p && (struct memoryElement*)p < (*q)->highestAddress) - { - assert(lp[stepSize - 1] == ('t' << 24) + ('e' << 16) + ('n' << 8) + ('d')); - return; - } - } - } - -static void checkAllBounds(void) - { - struct memblock** q; - for(q = pMemBlocks + NumberOfMemBlocks; --q >= pMemBlocks;) - { - size_t stepSize = (*q)->sizeOfElement / sizeof(struct memoryElement); - - struct memoryElement* p = (struct memoryElement*)(*q)->lowestAddress; - struct memoryElement* e = (struct memoryElement*)(*q)->highestAddress; - size_t L = (*q)->sizeOfElement - 1; - struct memoryElement* x; - for(x = p; x < e; x += stepSize) - { - struct memoryElement* a = ((struct memoryElement*)x)->next; - if(a == 0 || (p <= a && a < e)) - ; - else - { - if((((LONG*)x)[0] == ('s' << 24) + ('t' << 16) + ('a' << 8) + ('r')) - && (((LONG*)x)[stepSize - 1] == ('t' << 24) + ('e' << 16) + ('n' << 8) + ('d'))) - ; - else - { - char* s = (char*)x; - printf("s:["); - for(; s <= (char*)x + L; ++s) - if(' ' <= *s && *s <= 127) - printf("%c", *s); - else if(*s == 0) - printf("NIL"); - else - printf("-%c", *s); - printf("] %p\n", x); - } - assert(((LONG*)x)[0] == ('s' << 24) + ('t' << 16) + ('a' << 8) + ('r')); - assert(((LONG*)x)[stepSize - 1] == ('t' << 24) + ('e' << 16) + ('n' << 8) + ('d')); - } - } - } - } -#endif - -static void bfree(void* p) - { - assert(p != (void*)&zeroNode); - assert(p != (void*)&oneNode); - assert(p != (void*)&minusOneNode); - assert(p != (void*)&nilNode); - assert(p != (void*)&nilNodeNotNeutral); - assert(p != (void*)&zeroNodeNotNeutral); - assert(p != (void*)&oneNodeNotNeutral); - assert(p != (void*)&argNode); - assert(p != (void*)&selfNode); - assert(p != (void*)&SelfNode); - assert(p != (void*)&twoNode); - assert(p != (void*)&fourNode); - assert(p != (void*)&sjtNode); - struct memblock** q; -#if CHECKALLOCBOUNDS - LONG* lp = (LONG*)p; -#endif - assert(p != 0); - checksum(__FILE__, __LINE__); -#if CHECKALLOCBOUNDS - checkBounds(p); - lp = lp - 2; - p = lp; -#endif -#if SHOWMAXALLOCATED - globalloc--; -#endif - for(q = pMemBlocks + NumberOfMemBlocks; --q >= pMemBlocks;) - { - if((*q)->lowestAddress <= (struct memoryElement*)p && (struct memoryElement*)p < (*q)->highestAddress) - { -#if SHOWMAXALLOCATED - ++((*q)->numberOfFreeElementsBetweenAddresses); -#endif - ((struct memoryElement*)p)->next = (*q)->firstFreeElementBetweenAddresses; - (*q)->firstFreeElementBetweenAddresses = (struct memoryElement*)p; - setChecksum(FileName,LineNo, globN); - return; - } - } - free(p); -#if SHOWMAXALLOCATED - --malloced; -#endif - setChecksum(FileName, LineNo, globN); - } - -#if SHOWMEMBLOCKS -static void showMemBlocks() - { - int totalbytes; - int i; - for(i = 0; i < NumberOfMemBlocks; ++i) - { -#if defined __VMS - printf("%p %d %p <= %p <= %p [%p] %lu\n" -#else - printf("%p %d %p <= %p <= %p [%p] %zu\n" -#endif - , pMemBlocks[i] - , i - , pMemBlocks[i]->lowestAddress - , pMemBlocks[i]->firstFreeElementBetweenAddresses - , pMemBlocks[i]->highestAddress - , pMemBlocks[i]->previousOfSameLength - , pMemBlocks[i]->sizeOfElement - ); - } - totalbytes = 0; - for(i = 0; i < global_nallocations; ++i) - { -#if defined __VMS - printf("%d %d %lu\n" -#else - printf("%d %d %zu\n" -#endif - , i + 1 - , global_allocations[i].numberOfElements - , global_allocations[i].numberOfElements * (i + 1) * sizeof(struct memoryElement) - ); - totalbytes += global_allocations[i].numberOfElements * (i + 1) * sizeof(struct memoryElement); - } - printf("total bytes = %d\n", totalbytes); - } -#endif - -static int addAllocation(size_t size, int number, int nallocations, struct allocation* allocations) - { - int i; - for(i = 0; i < nallocations; ++i) - { - if(allocations[i].elementSize == size) - { - allocations[i].numberOfElements += number; - return nallocations; - } - } - allocations[nallocations].elementSize = size; - allocations[nallocations].numberOfElements = number; - return nallocations + 1; - } - -static int memblocksort(const void* a, const void* b) - { - struct memblock* A = *(struct memblock**)a; - struct memblock* B = *(struct memblock**)b; - if(A->lowestAddress < B->lowestAddress) - return -1; - return 1; - } - -static int init_memoryspace(void) - { - int i; - global_allocations = (struct allocation*)malloc(sizeof(struct allocation) - * -#if _5_6 - 6 -#elif _4 - 4 -#else - 3 -#endif - ); - global_nallocations = addAllocation(1 * sizeof(struct memoryElement), MEM1SIZE, 0, global_allocations); - global_nallocations = addAllocation(2 * sizeof(struct memoryElement), MEM2SIZE, global_nallocations, global_allocations); - global_nallocations = addAllocation(3 * sizeof(struct memoryElement), MEM3SIZE, global_nallocations, global_allocations); -#if _4 - global_nallocations = addAllocation(4 * sizeof(struct memoryElement), MEM4SIZE, global_nallocations, global_allocations); -#endif -#if _5_6 - global_nallocations = addAllocation(5 * sizeof(struct memoryElement), MEM5SIZE, global_nallocations, global_allocations); - global_nallocations = addAllocation(6 * sizeof(struct memoryElement), MEM6SIZE, global_nallocations, global_allocations); -#endif - NumberOfMemBlocks = global_nallocations; - pMemBlocks = (struct memblock**)malloc(NumberOfMemBlocks * sizeof(struct memblock*)); - - if(pMemBlocks) - { - for(i = 0; i < NumberOfMemBlocks; ++i) - { - pMemBlocks[i] = global_allocations[i].memoryBlock = initializeMemBlock(global_allocations[i].elementSize, global_allocations[i].numberOfElements); - } - qsort(pMemBlocks, NumberOfMemBlocks, sizeof(struct memblock*), memblocksort); - /* - for(i = 0;i < NumberOfMemBlocks;++i) - { - printf ("%p %d %p %p %p %p %lu\n" - ,pMemBlocks[i] - ,i - ,pMemBlocks[i]->lowestAddress - ,pMemBlocks[i]->firstFreeElementBetweenAddresses - ,pMemBlocks[i]->highestAddress - ,pMemBlocks[i]->previousOfSameLength - ,pMemBlocks[i]->sizeOfElement - ); - } - */ - return 1; - } - else - return 0; - } - -static void pskfree(psk p) - { - bfree(p); - } - -static int all_refcount_bits_set(psk pnode) - { - return (shared(pnode) == ALL_REFCOUNT_BITS_SET) && !is_object(pnode); - } - -static void dec_refcount(psk pnode) - { - assert(pnode->v.fl & ALL_REFCOUNT_BITS_SET); - pnode->v.fl -= ONEREF; -#if WORD32 - if((pnode->v.fl & (OPERATOR | ALL_REFCOUNT_BITS_SET)) == EQUALS) - { - if(REFCOUNTNONZERO((objectnode*)pnode)) - { - DECREFCOUNT(pnode); - } - } -#endif - } - -#if SHOWMAXALLOCATED -#if SHOWCURRENTLYALLOCATED -static void initcnts(void) - { - for(ULONG tel = 0; tel < sizeof(cnts) / sizeof(cnts[0]); ++tel) - cnts[tel] = 0; - } -#endif - -static void Bez(char draft[22]) - { -#if MAXSTACK -#if defined _WIN32 || defined __VMS - sprintf(draft, "%lu.%lu.%d", (unsigned long)globalloc, (unsigned long)maxgloballoc, maxstack); -#else - sprintf(draft, "%zu.%zu.%d", globalloc, maxgloballoc, maxstack); -#endif -#else -#if defined _WIN32 || defined __VMS - sprintf(draft, "%lu.%lu", (unsigned long)globalloc, (unsigned long)maxgloballoc); -#else - sprintf(draft, "%zu.%zu", globalloc, maxgloballoc); -#endif -#endif - } -#endif -/* End of memory.c */ - -/* Begin of copy.c */ - -static psk iCopyOf(psk pnode) - { - /* REQUIREMENTS : After the string delimiting 0 all remaining bytes in the - current computer word must be 0 as well. - Argument must start on a word boundary. */ - psk ret; - size_t len; - len = sizeof(ULONG) + strlen((char*)POBJ(pnode)); - ret = (psk)bmalloc(len + 1); -#if ICPY - MEMCPY(ret, pnode, (len >> LOGWORDLENGTH) + 1); -#else - MEMCPY(ret, pnode, ((len / sizeof(LONG)) + 1) * sizeof(LONG)); -#endif - ret->v.fl &= COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - return ret; - } - -static psk copyof(psk pnode) - { - psk res; - res = iCopyOf(pnode); - res->v.fl &= ~IDENT; - return res; - } - -static psk new_operator_like(psk pnode) - { - if(Op(pnode) == EQUALS) - { - objectnode* goal; - assert(!ISBUILTIN((objectnode*)pnode)); - goal = (objectnode*)bmalloc(sizeof(objectnode)); -#if WORD32 - goal->u.Int = 0; -#else - goal->v.fl &= ~(BUILT_IN | CREATEDWITHNEW); -#endif - return (psk)goal; - } - else - return (psk)bmalloc(sizeof(knode)); - } - -static psk scopy(const char* str) - { - int nr = fullnumbercheck(str) & ~DEFINITELYNONUMBER; - psk pnode; - if(nr & MINUS) - { /* bracmat out$arg$() -123 */ - pnode = (psk)bmalloc(sizeof(ULONG) + strlen((const char*)str)); - strcpy((char*)(pnode)+sizeof(ULONG), str + 1); - } - else - { - pnode = (psk)bmalloc(sizeof(ULONG) + 1 + strlen((const char*)str)); - strcpy((char*)(pnode)+sizeof(ULONG), str); - } - pnode->v.fl = READY | SUCCESS | nr; - return pnode; - } - -static psk subtreecopy(psk src); - -static psk same_as_w(psk pnode) - { - if(shared(pnode) != ALL_REFCOUNT_BITS_SET) - { - (pnode)->v.fl += ONEREF; - return pnode; - } -#if WORD32 - else if(is_object(pnode)) - { - INCREFCOUNT(pnode); - return pnode; - } -#endif - else - { - return subtreecopy(pnode); - } - } - -static psk same_as_w_2(ppsk PPnode) - { - psk pnode = *PPnode; - if(shared(pnode) != ALL_REFCOUNT_BITS_SET) - { - pnode->v.fl += ONEREF; - return pnode; - } -#if WORD32 - else if(is_object(pnode)) - { - INCREFCOUNT(pnode); - return pnode; - } -#endif - else - { - /* - 0:?n&:?L&whl'(!n+1:?n:<10000&out$!n&XXX !L:?L) - 0:?n&:?L&whl'(!n+1:?n:<10000&out$!n&!L XXX:?L) This is not improved! - */ - *PPnode = subtreecopy(pnode); - return pnode; - } - } - -static psk _copyop(psk Pnode) - { - psk apnode; - apnode = new_operator_like(Pnode); - apnode->v.fl = Pnode->v.fl & COPYFILTER;/* (ALL_REFCOUNT_BITS_SET | CREATEDWITHNEW);*/ - apnode->LEFT = same_as_w_2(&Pnode->LEFT); - apnode->RIGHT = same_as_w(Pnode->RIGHT); - return apnode; - } - -static psk subtreecopy(psk src) - { - if(is_op(src)) - return _copyop(src); - else - return iCopyOf(src); - } - -static psk isolated(psk Pnode) - { - if(shared(Pnode)) - { - dec_refcount(Pnode); - return subtreecopy(Pnode); - } - return Pnode; - } - -static psk setflgs(psk pokn, ULONG Flgs) - { - if((Flgs & BEQUEST) || !(Flgs & SUCCESS)) - { - pokn = isolated(pokn); - pokn->v.fl ^= ((Flgs & SUCCESS) ^ SUCCESS); - pokn->v.fl |= (Flgs & BEQUEST); - if(ANYNEGATION(Flgs)) - pokn->v.fl |= NOT; - } - return pokn; - } - -#if ICPY -static void icpy(LONG* d, LONG* b, int words) - { - while(words--) - *d++ = *b++; - } -#endif - -static psk copyop(psk Pnode) - { - dec_refcount(Pnode); - return _copyop(Pnode); - } - -static psk charcopy(const char* strt, const char* until) - { - int nr = 0; - psk pnode; - if('0' <= *strt && *strt <= '9') - { - nr = QNUMBER BITWISE_OR_SELFMATCHING; - if(*strt == '0') - nr |= QNUL; - } - pnode = (psk)bmalloc(sizeof(ULONG) + 1 + (until - strt)); - strncpy((char*)(pnode)+sizeof(ULONG), strt, until - strt); - pnode->v.fl = READY | SUCCESS | nr; - return pnode; - } - -/* End of copy.c */ - -/* Begin of head.c */ - -static void copyToCutoff(psk* ppnode, psk pnode, psk cutoff) - { - for(;;) - { - if(is_op(pnode)) - { - if(pnode->RIGHT == cutoff) - { - *ppnode = same_as_w(pnode->LEFT); - break; - } - else - { - psk p = new_operator_like(pnode); - p->v.fl = pnode->v.fl & COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - p->LEFT = same_as_w(pnode->LEFT); - *ppnode = p; - ppnode = &(p->RIGHT); - pnode = pnode->RIGHT; - } - } - else - { - *ppnode = iCopyOf(pnode); - break; - } - } - } - -static psk Head(psk pnode) - { - if(pnode->v.fl & LATEBIND) - { - assert(!shared(pnode)); - if(is_op(pnode)) - { - psk root = pnode; - copyToCutoff(&pnode, root->LEFT, root->RIGHT); - wipe(root); - } - else - { - stringrefnode* ps = (stringrefnode*)pnode; - pnode = (psk)bmalloc(sizeof(ULONG) + 1 + ps->length); - pnode->v.fl = (ps->v.fl & COPYFILTER /*~ALL_REFCOUNT_BITS_SET*/ & ~LATEBIND); - strncpy((char*)(pnode)+sizeof(ULONG), (char*)ps->str, ps->length); - wipe(ps->pnode); - bfree(ps); - } - } - return pnode; - } -/* End of head.c */ - -/* Begin of builtinmethod.c */ - -static method_pnt findBuiltInMethodByName(typedObjectnode* object, const char* name) - { - method* methods = object->vtab; - if(methods) - { - for(; methods->name && strcmp(methods->name, name); ++methods) - ; - return methods->func; - } - return NULL; - } - -static method_pnt findBuiltInMethod(typedObjectnode* object, psk methodName) - { - if(!is_op(methodName)) - { - return findBuiltInMethodByName(object, (const char*)POBJ(methodName)); - } - return NULL; - } -/* End of builtinmethod.c */ - -/* Begin of quote.c */ - -static const char needsquotes[256] = { - /* - 1 : needsquotes if first character; - 3 : needsquotes always - 4 : needsquotes if \t and \n must be expanded - */ - 0,0,0,0,0,0,0,0,0,4,4,0,0,0,3,3, /* \L \D */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 3,1,0,1,3,1,3,3,3,3,3,3,3,1,3,1, /* SP ! # $ % & ' ( ) * + , - . / */ - 0,0,0,0,0,0,0,0,0,0,3,3,1,3,1,1, /* : < = > ? */ - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* @ */ - 0,0,0,0,0,0,0,0,0,0,0,1,3,1,3,3, /* [ \ ] ^ _ */ - 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ` */ - 0,0,0,0,0,0,0,0,0,0,0,3,3,3,1,0 };/* { | } ~ */ - -static int quote(unsigned char* strng) - { - unsigned char* pstring; - if(needsquotes[*strng] & 1) - return TRUE; - for(pstring = strng; *pstring; pstring++) - if(needsquotes[*pstring] & 2) - return TRUE; - else if((needsquotes[*pstring] & 4) - && lineTooLong(strng) - ) - return TRUE; - return FALSE; - } -/* End of quote.c */ - -/* Begin of result.c */ - -static const char opchar[16] = - { '=','.',',','|','&',':',' ','+','*','^','\016','\017','\'','$','_','?' }; - -static void parenthesised_result(psk Root, int level, int ind, int space); -#if DEBUGBRACMAT -static void hreslts(psk Root, int level, int ind, int space, psk cutoff); -#endif - -#define COMPLEX_MAX 80 -int LineLength = NARROWLINELENGTH; - -static size_t complexity(psk Root, size_t max) - { - static int Parent, Child; - while(is_op(Root)) - { - max += 2; /* Each time reslt is called, level is incremented by 1. - indent() calls complexity with twice that increment. - So to predict what complexity says at each level, we have - to add 2 in each iteration while descending the tree. */ - switch(Op(Root)) - { - case OR: - case AND: - max += COMPLEX_MAX / 5; - break; - case EQUALS: - case MATCH: - max += COMPLEX_MAX / 10; - break; - case DOT: - case COMMA: - case WHITE: - switch(Op(Root->LEFT)) - { - case DOT: - case COMMA: - case WHITE: - max += COMPLEX_MAX / 10; - break; - default: - max += COMPLEX_MAX / LineLength; - } - break; - default: - max += COMPLEX_MAX / LineLength; - } - Parent = Op(Root); - Child = Op(Root->LEFT); - if(HAS__UNOPS(Root->LEFT) || Parent >= Child) - max += (2 * COMPLEX_MAX) / LineLength; /* 2 parentheses */ - - Child = Op(Root->RIGHT); - if(HAS__UNOPS(Root->RIGHT) || Parent > Child || (Parent == Child && Parent > TIMES)) - max += (2 * COMPLEX_MAX) / LineLength; /* 2 parentheses */ - - if(max > COMPLEX_MAX) - return max; - max = complexity(Root->LEFT, max); - Root = Root->RIGHT; - } - if(!is_op(Root)) - max += (COMPLEX_MAX * strlen((char*)POBJ(Root))) / LineLength; - return max; - } - -static int indtel = 0, extraSpc = 0, number_of_flags_on_node = 0; - -static int indent(psk Root, int level, int ind) - { - if(hum) - { - if(ind > 0 || (ind == 0 && complexity(Root, 2 * level) > COMPLEX_MAX)) - { /* blanks that start a line */ - int p; - (*process)('\n'); - for(p = 2 * level + number_of_flags_on_node; p; p--) - (*process)(' '); - ind = TRUE; - } - else - { /* blanks after an operator or parenthesis */ - for(indtel = extraSpc + 2 * indtel; indtel; indtel--) - (*process)(' '); - ind = FALSE; - } - extraSpc = 0; - } - return ind; - } - -static int needIndent(psk Root, int ind, int level) - { - return hum && !ind && complexity(Root, 2 * level) > COMPLEX_MAX; - } - -static void do_something(int c) - { - if(c == 016 || c == 017) - { - (*process)('\\'); - (*process)(c == 016 ? 'L' : 'D'); - } - else - (*process)(c); - } - -static int printflags(psk Root) - { - int count = 0; - ULONG Flgs = Root->v.fl; - if(Flgs & FENCE) - { - (*process)('`'); - ++count; - } - if(Flgs & POSITION) - { - (*process)('['); - ++count; - } - if(Flgs & NOT) - { - (*process)('~'); - ++count; - } - if(Flgs & FRACTION) - { - (*process)('/'); - ++count; - } - if(Flgs & NUMBER) - { - (*process)('#'); - ++count; - } - if(Flgs & SMALLER_THAN) - { - (*process)('<'); - ++count; - } - if(Flgs & GREATER_THAN) - { - (*process)('>'); - ++count; - } - if(Flgs & NONIDENT) - { - (*process)('%'); - ++count; - } - if(Flgs & ATOM) - { - (*process)('@'); - ++count; - } - if(Flgs & UNIFY) - { - (*process)('?'); - ++count; - } - if(Flgs & INDIRECT) - { - (*process)('!'); - ++count; - } - if(Flgs & DOUBLY_INDIRECT) - { - (*process)('!'); - ++count; - } - return count; - } - -#define LHS 1 -#define RHS 2 - -#if DATAMATCHESITSELF -//#define SM(Root) {if((Root)->v.fl & SELFMATCHING) (*process)(';');} -#define SM(Root) -#else -#define SM(Root) -#endif - -static void endnode(psk Root, int space) - { - unsigned char* pstring; - int q, ikar; -#if CHECKALLOCBOUNDS - if(POINT) - printf("\n[%p %lld]", Root, (Root->v.fl & ALL_REFCOUNT_BITS_SET) / ONEREF); -#endif - SM(Root) - - if(!Root->u.obj - && !HAS_UNOPS(Root) - && space) - { - (*process)('('); - (*process)(')'); - return; - } - printflags(Root); - if(Root->v.fl & MINUS) - (*process)('-'); - if(beNice) - { - for(pstring = POBJ(Root); *pstring; pstring++) - do_something(*pstring); - } - else - { - Boolean longline = FALSE; - if((q = quote(POBJ(Root))) == TRUE) - (*process)('"'); - for(pstring = POBJ(Root); (ikar = *pstring) != 0; pstring++) - { - switch(ikar) - { - case '\n': - if(longline || lineTooLong(POBJ(Root))) - /* We need to call this, even though quote returned TRUE, - because quote may have returned before reaching this character. - */ - { - longline = TRUE; - (*process)('\n'); - continue; - } - ikar = 'n'; - break; - case '\f': - ikar = 'f'; - break; - case '\r': - ikar = 'r'; - break; - case '\b': - ikar = 'b'; - break; - case ALERT: - ikar = 'a'; - break; - case '\v': - ikar = 'v'; - break; - case '\t': - if(longline || lineTooLong(POBJ(Root))) - /* We need to call this, even though quote returned TRUE, - because quote may have returned before reaching this character. - */ - { - longline = TRUE; - (*process)('\t'); - continue; - } - ikar = 't'; - break; - case '"': - case '\\': - break; - case 016: - ikar = 'L'; - break; - case 017: - ikar = 'D'; - break; - default: - (*process)(ikar); - continue; - } - (*process)('\\'); - (*process)(ikar); - } - if(q) - (*process)('"'); - } - } - -#define RSP (Parent == WHITE ? RHS : 0) -#define LSP (Parent == WHITE ? LHS : 0) - -#ifndef reslt -static void reslt(psk Root, int level, int ind, int space) - { - static int Parent, Child, newind; - while(is_op(Root)) - { - if(Op(Root) == EQUALS) - Root->RIGHT = Head(Root->RIGHT); - Parent = Op(Root); - Child = Op(Root->LEFT); - if(needIndent(Root, ind, level)) - indtel++; - if(HAS__UNOPS(Root->LEFT) || Parent >= Child) - parenthesised_result(Root->LEFT, level + 1, FALSE, (space & LHS) | RSP); - else - reslt(Root->LEFT, level + 1, FALSE, (space & LHS) | RSP); - newind = indent(Root, level, ind); - if(newind) - extraSpc = 1; -#if CHECKALLOCBOUNDS - if(POINT) - printf("\n[%p %lld]", Root, (Root->v.fl & ALL_REFCOUNT_BITS_SET) / ONEREF); -#endif - SM(Root) - do_something(opchar[klopcode(Root)]); - Parent = Op(Root); - Child = Op(Root->RIGHT); - if(HAS__UNOPS(Root->RIGHT) || Parent > Child || (Parent == Child && Parent > TIMES)) - { - parenthesised_result(Root->RIGHT, level + 1, FALSE, LSP | (space & RHS)); - return; - } - else if(Parent < Child) - { - reslt(Root->RIGHT, level + 1, FALSE, LSP | (space & RHS)); - return; - } - else if(newind != ind || ((LSP | (space & RHS)) != space)) - { - reslt(Root->RIGHT, level, newind, LSP | (space & RHS)); - return; - } - Root = Root->RIGHT; - } - indent(Root, level, -1); - endnode(Root, space); - } - -#if DEBUGBRACMAT - -static void reslts(psk Root, int level, int ind, int space, psk cutoff) - { - static int Parent, Child, newind; - if(is_op(Root)) - { - if(Op(Root) == EQUALS) - Root->RIGHT = Head(Root->RIGHT); - - do - { - if(cutoff && Root->RIGHT == cutoff) - { - reslt(Root->LEFT, level, ind, space); - return; - } - Parent = Op(Root); - Child = Op(Root->LEFT); - if(needIndent(Root, ind, level)) - indtel++; - if(HAS__UNOPS(Root->LEFT) || Parent >= Child) - parenthesised_result(Root->LEFT, level + 1, FALSE, (space & LHS) | RSP); - else - reslt(Root->LEFT, level + 1, FALSE, (space & LHS) | RSP); - newind = indent(Root, level, ind); - if(newind) - extraSpc = 1; - SM(Root) - do_something(opchar[klopcode(Root)]); - Parent = Op(Root); - Child = Op(Root->RIGHT); - if(HAS__UNOPS(Root->RIGHT) || Parent > Child || (Parent == Child && Parent > TIMES)) - hreslts(Root->RIGHT, level + 1, FALSE, LSP | (space & RHS), cutoff); - else if(Parent < Child) - { - reslts(Root->RIGHT, level + 1, FALSE, LSP | (space & RHS), cutoff); - return; - } - else if(newind != ind || ((LSP | (space & RHS)) != space)) - { - reslts(Root->RIGHT, level, newind, LSP | (space & RHS), cutoff); - return; - } - Root = Root->RIGHT; - } while(is_op(Root)); - } - else - { - indent(Root, level, -1); - endnode(Root, space); - } - } -#endif /* DEBUGBRACMAT */ -#endif - -static void parenthesised_result(psk Root, int level, int ind, int space) - { - static int Parent, Child; - if(is_op(Root)) - { - int number_of_flags; - if(Op(Root) == EQUALS) - Root->RIGHT = Head(Root->RIGHT); - indent(Root, level, -1); - number_of_flags = printflags(Root); - number_of_flags_on_node += number_of_flags; - (*process)('('); - indtel = 0; - if(needIndent(Root, ind, level)) - extraSpc = 1; - Parent = Op(Root); - Child = Op(Root->LEFT); - if(HAS__UNOPS(Root->LEFT) || Parent >= Child) - parenthesised_result(Root->LEFT, level + 1, FALSE, RSP); - else - reslt(Root->LEFT, level + 1, FALSE, RSP); - ind = indent(Root, level, ind); - if(ind) - extraSpc = 1; -#if CHECKALLOCBOUNDS - if(POINT) - printf("\n[%p %lld]", Root, (Root->v.fl & ALL_REFCOUNT_BITS_SET) / ONEREF); -#endif - SM(Root) - do_something(opchar[klopcode(Root)]); - Parent = Op(Root); - - Child = Op(Root->RIGHT); - if(HAS__UNOPS(Root->RIGHT) || Parent > Child || (Parent == Child && Parent > TIMES)) - parenthesised_result(Root->RIGHT, level + 1, FALSE, LSP); - else if(Parent < Child) - reslt(Root->RIGHT, level + 1, FALSE, LSP); - else - reslt(Root->RIGHT, level, ind, LSP); - indent(Root, level, FALSE); - (*process)(')'); - number_of_flags_on_node -= number_of_flags; - } - else - { - indent(Root, level, -1); - endnode(Root, space); - } - } - -#if DEBUGBRACMAT -static void hreslts(psk Root, int level, int ind, int space, psk cutoff) - { - static int Parent, Child; - if(is_op(Root)) - { - int number_of_flags; - if(Op(Root) == EQUALS) - Root->RIGHT = Head(Root->RIGHT); - if(cutoff && Root->RIGHT == cutoff) - { - parenthesised_result(Root->LEFT, level, ind, space); - return; - } - indent(Root, level, -1); - number_of_flags = printflags(Root); - number_of_flags_on_node += number_of_flags; - (*process)('('); - indtel = 0; - if(needIndent(Root, ind, level)) - extraSpc = 1; - Parent = Op(Root); - Child = Op(Root->LEFT); - if(HAS__UNOPS(Root->LEFT) || Parent >= Child) - parenthesised_result(Root->LEFT, level + 1, FALSE, RSP); - else - reslt(Root->LEFT, level + 1, FALSE, RSP); - ind = indent(Root, level, ind); - if(ind) - extraSpc = 1; - SM(Root) - do_something(opchar[klopcode(Root)]); - Parent = Op(Root); - Child = Op(Root->RIGHT); - if(HAS__UNOPS(Root->RIGHT) || Parent > Child || (Parent == Child && Parent > TIMES)) - hreslts(Root->RIGHT, level + 1, FALSE, LSP, cutoff); - else if(Parent < Child) - reslts(Root->RIGHT, level + 1, FALSE, LSP, cutoff); - else - reslts(Root->RIGHT, level, ind, LSP, cutoff); - indent(Root, level, FALSE); - (*process)(')'); - number_of_flags_on_node -= number_of_flags; - } - else - { - indent(Root, level, -1); - endnode(Root, space); - } - } - -static void results(psk Root, psk cutoff) - { - if(HAS__UNOPS(Root)) - { - hreslts(Root, 0, FALSE, 0, cutoff); - } - else - reslts(Root, 0, FALSE, 0, cutoff); - } -#endif - -static void result(psk Root) - { - if(Root) - { - if(HAS__UNOPS(Root)) - { - parenthesised_result(Root, 0, FALSE, 0); - } - else - reslt(Root, 0, FALSE, 0); - } - } -/* End of result.c */ - -/* Begin of charput.c */ - -/* Begin of xml.h */ - -/*void XMLtext(FILE * fpi, char * source, int trim, int html, int xml);*/ - -/* End of xml.h */ - -static inputBuffer* InputArray; -static unsigned char* inputBufferPointer; -static unsigned char* maxInputBufferPointer; /* inputBufferPointer <= maxInputBufferPointer, - if inputBufferPointer == maxInputBufferPointer, don't assign to *inputBufferPointer */ - -static void lput(int c) - { - if(inputBufferPointer >= maxInputBufferPointer) - { - inputBuffer* newInputArray; - unsigned char* input_buffer; - unsigned char* dest; - int len; - size_t L; - - for(len = 0; InputArray[++len].buffer;) - ; - /* len = index of last element in InputArray array */ - - input_buffer = InputArray[len - 1].buffer; - /* The last string (probably on the stack, not on the heap) */ - - while(inputBufferPointer > input_buffer && optab[*--inputBufferPointer] == NOOP) - ; - /* inputBufferPointer points at last operator (where string can be split) or at - the start of the string. */ - - newInputArray = (inputBuffer*)bmalloc((2 + len) * sizeof(inputBuffer)); - /* allocate new array one element bigger than the previous. */ - - newInputArray[len + 1].buffer = NULL; - newInputArray[len + 1].cutoff = FALSE; - newInputArray[len + 1].mallocallocated = FALSE; - newInputArray[len].buffer = input_buffer; - /*The buffer pointers with lower index are copied further down.*/ - - /*Printf("input_buffer %p\n",input_buffer);*/ - - newInputArray[len].cutoff = FALSE; - newInputArray[len].mallocallocated = FALSE; - /*The active buffer is still the one declared in input(), - so on the stack (except under EPOC).*/ - --len; /* point at the second last element, the one that got filled up. */ - if(inputBufferPointer == input_buffer) - { - /* copy the full content of input_buffer to the second last element */ - dest = newInputArray[len].buffer = (unsigned char*)bmalloc(DEFAULT_INPUT_BUFFER_SIZE); - strncpy((char*)dest, (char*)input_buffer, DEFAULT_INPUT_BUFFER_SIZE - 1); - dest[DEFAULT_INPUT_BUFFER_SIZE - 1] = '\0'; - /* Make a notice that the element's string is cut-off */ - newInputArray[len].cutoff = TRUE; - newInputArray[len].mallocallocated = TRUE; - } - else - { - ++inputBufferPointer; /* inputBufferPointer points at first character after the operator */ - /* maxInputBufferPointer - inputBufferPointer >= 0 */ - L = (size_t)(inputBufferPointer - input_buffer); - dest = newInputArray[len].buffer = (unsigned char*)bmalloc(L + 1); - strncpy((char*)dest, (char*)input_buffer, L); - dest[L] = '\0'; - newInputArray[len].cutoff = FALSE; - newInputArray[len].mallocallocated = TRUE; - - /* Now remove the substring up to inputBufferPointer from input_buffer */ - L = (size_t)(maxInputBufferPointer - inputBufferPointer); - strncpy((char*)input_buffer, (char*)inputBufferPointer, L); - input_buffer[L] = '\0'; - inputBufferPointer = input_buffer + L; - } - - /* Copy previous element's fields */ - while(len) - { - --len; - newInputArray[len].buffer = InputArray[len].buffer; - newInputArray[len].cutoff = InputArray[len].cutoff; - newInputArray[len].mallocallocated = InputArray[len].mallocallocated; - } - bfree(InputArray); - InputArray = newInputArray; - } - assert(inputBufferPointer <= maxInputBufferPointer); - *inputBufferPointer++ = (unsigned char)c; - } - -/* referenced from xml.c json.c */ -void putOperatorChar(int c) -/* c == parenthesis, operator of flag */ - { - lput(c); - } - -/* referenced from xml.c json.c */ -void putLeafChar(int c) -/* c == any character that should end as part of an atom (string) */ - { - if(c & 0x80) - lput(0x7F); - lput(c | 0x80); - } - -/* End of charput.c */ - -/* Begin of encoding.c */ -/* Begin of encoding.h */ - -unsigned char* putCodePoint(ULONG val, unsigned char* s); -int getCodePoint(const char** ps); - -int getCodePoint2(const char** ps, int* isutf); - -/* End of encoding.h */ - -#if CODEPAGE850 -static unsigned char ISO8859toCodePage850(unsigned char kar) - - { - static unsigned char translationTable[] = - { - 0xBA,0xCD,0xC9,0xBB,0xC8,0xBC,0xCC,0xB9,0xCB,0xCA,0xCE,0xDF,0xDC,0xDB,0xFE,0xF2, - 0xB3,0xC4,0xDA,0xBF,0xC0,0xD9,0xC3,0xB4,0xC2,0xC1,0xC5,0xB0,0xB1,0xB2,0xD5,0x9F, - 0xFF,0xAD,0xBD,0x9C,0xCF,0xBE,0xDD,0xF5,0xF9,0xB8,0xA6,0xAE,0xAA,0xF0,0xA9,0xEE, - 0xF8,0xF1,0xFD,0xFC,0xEF,0xE6,0xF4,0xFA,0xF7,0xFB,0xA7,0xAF,0xAC,0xAB,0xF3,0xA8, - 0xB7,0xB5,0xB6,0xC7,0x8E,0x8F,0x92,0x80,0xD4,0x90,0xD2,0xD3,0xDE,0xD6,0xD7,0xD8, - 0xD1,0xA5,0xE3,0xE0,0xE2,0xE5,0x99,0x9E,0x9D,0xEB,0xE9,0xEA,0x9A,0xED,0xE8,0xE1, - 0x85,0xA0,0x83,0xC6,0x84,0x86,0x91,0x87,0x8A,0x82,0x88,0x89,0x8D,0xA1,0x8C,0x8B, - 0xD0,0xA4,0x95,0xA2,0x93,0xE4,0x94,0xF6,0x9B,0x97,0xA3,0x96,0x81,0xEC,0xE7,0x98 - }; - - if(kar & 0x80) - return translationTable[kar & 0x7F]; - else - return kar; - /* return kar & 0x80 ? (unsigned char)translationTable[kar & 0x7F] : kar;*/ - } - -static unsigned char CodePage850toISO8859(unsigned char kar) - { - static unsigned char translationTable[] = - { - 0xC7,0xFC,0xE9,0xE2,0xE4,0xE0,0xE5,0xE7,0xEA,0xEB,0xE8,0xEF,0xEE,0xEC,0xC4,0xC5, - 0xC9,0xE6,0xC6,0xF4,0xF6,0xF2,0xFB,0xF9,0xFF,0xD6,0xDC,0xF8,0xA3,0xD8,0xD7,0x9F, - 0xE1,0xED,0xF3,0xFA,0xF1,0xD1,0xAA,0xBA,0xBF,0xAE,0xAC,0xBD,0xBC,0xA1,0xAB,0xBB, - 0x9B,0x9C,0x9D,0x90,0x97,0xC1,0xC2,0xC0,0xA9,0x87,0x80,0x83,0x85,0xA2,0xA5,0x93, - 0x94,0x99,0x98,0x96,0x91,0x9A,0xE3,0xC3,0x84,0x82,0x89,0x88,0x86,0x81,0x8A,0xA4, - 0xF0,0xD0,0xCA,0xCB,0xC8,0x9E,0xCD,0xCE,0xCF,0x95,0x92,0x8D,0x8C,0xA6,0xCC,0x8B, - 0xD3,0xDF,0xD4,0xD2,0xF5,0xD5,0xB5,0xFE,0xDE,0xDA,0xDB,0xD9,0xFD,0xDD,0xAF,0xB4, - 0xAD,0xB1,0x8F,0xBE,0xB6,0xA7,0xF7,0xB8,0xB0,0xA8,0xB7,0xB9,0xB3,0xB2,0x8E,0xA0, - }; - - /* 0x7F = 127, 0xFF = 255 */ - /* delete bit-7 before search in tabel (0-6 is unchanged) */ - /* delete bit 15-8 */ - - if(kar & 0x80) - return translationTable[kar & 0x7F]; - else - return kar; - /* return kar & 0x80 ? (unsigned char)translationTable[kar & 0x7F] : kar;*/ - } -#endif - -/* extern, is called from xml.c json.c */ -unsigned char* putCodePoint(ULONG val, unsigned char* s) - { - /* Converts Unicode character w to 1,2,3 or 4 bytes of UTF8 in s. */ - if(val < 0x80) - { - *s++ = (char)val; - } - else - { - if(val < 0x0800) /* 7FF = 1 1111 111111 */ - { - *s++ = (char)(0xc0 | (val >> 6)); - } - else - { - if(val < 0x10000) /* FFFF = 1111 111111 111111 */ - { - *s++ = (char)(0xe0 | (val >> 12)); - } - else - { - if(val < 0x200000) - { /* 10000 = 010000 000000 000000, 10ffff = 100 001111 111111 111111 */ - *s++ = (char)(0xf0 | (val >> 18)); - } - else - { - if(val < 0x4000000) - { - *s++ = (char)(0xf8 | (val >> 24)); - } - else - { - if(val < 0x80000000) - { - *s++ = (char)(0xfc | (val >> 30)); - *s++ = (char)(0x80 | ((val >> 24) & 0x3f)); - } - else - return NULL; - } - *s++ = (char)(0x80 | ((val >> 18) & 0x3f)); - } - *s++ = (char)(0x80 | ((val >> 12) & 0x3f)); - } - *s++ = (char)(0x80 | ((val >> 6) & 0x3f)); - } - *s++ = (char)(0x80 | (val & 0x3f)); - } - *s = (char)0; - return s; - } - -static int utf8bytes(ULONG val) - { - if(val < 0x80) - { - return 1; - } - else if(val < 0x0800) /* 7FF = 1 1111 111111 */ - { - return 2; - } - else if(val < 0x10000) /* FFFF = 1111 111111 111111 */ - { - return 3; - } - else if(val < 0x200000) - { /* 10000 = 010000 000000 000000, 10ffff = 100 001111 111111 111111 */ - return 4; - } - else if(val < 0x4000000) - { - return 5; - } - else - { - return 6; - } - } - -int getCodePoint(const char** ps) - { - /* - return values: - > 0: code point - -1: no UTF-8 - -2: too short for being UTF-8 - */ - int K; - const char* s = *ps; - if((K = (const unsigned char)*s++) != 0) - { - if((K & 0xc0) == 0xc0) /* 11bbbbbb */ - { - int k[6]; - int i; - int I; - if((K & 0xfe) == 0xfe) /* 11111110 */ - { - return -1; - } - /* Start of multibyte */ - - k[0] = K; - for(i = 1; (K << i) & 0x80; ++i) - { - k[i] = (const unsigned char)*s++; - if((k[i] & 0xc0) != 0x80) /* 10bbbbbb */ - { - if(k[i]) - { - return -1; - } - return -2; - } - } - K = ((k[0] << i) & 0xff) << (5 * i - 6); - I = --i; - while(i > 0) - { - K |= (k[i] & 0x3f) << ((I - i) * 6); - --i; - } - if(K <= 0x7F) /* ASCII, must be a single byte */ - { - return -1; - } - } - else if((K & 0xc0) == 0x80) /* 10bbbbbb, wrong first byte */ - { - return -1; - } - } - *ps = s; /* next character */ - return K; - } - -int getCodePoint2(const char** ps, int* isutf) - { - int ks = *isutf ? getCodePoint(ps) : (const unsigned char)*(*ps)++; - if(ks < 0) - { - *isutf = 0; - ks = (const unsigned char)*(*ps)++; - } - assert(ks >= 0); - return ks; - } - -static psk changeCase(psk Pnode -#if CODEPAGE850 - , int dos -#endif - , int low) - { -#if !CODEPAGE850 - const -#endif - char* s; - psk pnode; - size_t len; - pnode = same_as_w(Pnode); - s = SPOBJ(Pnode); - len = strlen((const char*)s); - if(len > 0) - { - char* d; - char* dwarn; - char* buf = NULL; - char* obuf; - pnode = isolated(pnode); - d = SPOBJ(pnode); - obuf = d; - dwarn = obuf + strlen((const char*)obuf) - 6; -#if CODEPAGE850 - if(dos) - { - if(low) - { - for(; *s; ++s) - { - *s = ISO8859toCodePage850(lowerEquivalent[(int)(const unsigned char)*s]); - } - } - else - { - for(; *s; ++s) - { - *s = ISO8859toCodePage850(upperEquivalent[(int)(const unsigned char)*s]); - } - } - } - else -#endif - { - int isutf = 1; - struct ccaseconv* t = low ? u2l : l2u; - for(; *s;) - { - int S = getCodePoint2(&s, &isutf); - int D = convertLetter(S, t); - if(isutf) - { - if(d >= dwarn) - { - int nb = utf8bytes(D); - if(d + nb >= dwarn + 6) - { - /* overrun */ - buf = (char*)bmalloc(2 * ((dwarn + 6) - obuf)); - dwarn = buf + 2 * ((dwarn + 6) - obuf) - 6; - memcpy(buf, obuf, d - obuf); - d = buf + (d - obuf); - if(obuf != SPOBJ(pnode)) - bfree(obuf); - obuf = buf; - } - } - d = (char*)putCodePoint(D, (unsigned char*)d); - } - else - *d++ = (unsigned char)D; - } - *d = 0; - if(buf) - { - wipe(pnode); - pnode = scopy(buf); - bfree(buf); - } - } - } - return pnode; - } - -static int hasUTF8MultiByteCharacters(const char* s) - { /* returns 0 if s is not valid UTF-8 or if s is pure 7-bit ASCII */ - int ret; - int multiByteCharSeen = 0; - for(; (ret = getCodePoint(&s)) > 0;) - if(ret > 0x7F) - ++multiByteCharSeen; - return ret == 0 ? multiByteCharSeen : 0; - } - -static int strcasecompu(char** S, char** P, char* cutoff) -/* Additional argument cutoff */ - { - int sutf = 1; - int putf = 1; - char* s = *S; - char* p = *P; - while(s < cutoff && *s && *p) - { - int diff; - char* ns = s; - char* np = p; - int ks = getCodePoint2((const char**)&ns, &sutf); - int kp = getCodePoint2((const char**)&np, &putf); - assert(ks >= 0 && kp >= 0); - diff = toLowerUnicode(ks) - toLowerUnicode(kp); - if(diff) - { - *S = s; - *P = p; - return diff; - } - s = ns; - p = np; - } - *S = s; - *P = p; - return (s < cutoff ? (int)(unsigned char)*s : 0) - (int)(unsigned char)*p; - } - -static int strcasecomp(const char* s, const char* p) - { - int sutf = 1; /* assume UTF-8, becomes 0 if it is not */ - int putf = 1; - while(*s && *p) - { - int ks = getCodePoint2((const char**)&s, &sutf); - int kp = getCodePoint2((const char**)&p, &putf); - int diff = toLowerUnicode(ks) - toLowerUnicode(kp); - if(diff) - { - return diff; - } - } - return (int)(const unsigned char)*s - (int)(const unsigned char)*p; - } - -#if CODEPAGE850 -static int strcasecmpDOS(const char* s, const char* p) - { - while(*s && *p) - { - int diff = (int)ISO8859toCodePage850(lowerEquivalent[CodePage850toISO8859((unsigned char)*s)]) - (int)ISO8859toCodePage850(lowerEquivalent[CodePage850toISO8859((unsigned char)*p)]); - if(diff) - return diff; - ++s; - ++p; - } - return (int)*s - (int)*p; - } -#endif -/* End of encoding.c */ - -/* Begin of json.c */ -/* - Bracmat. Programming language with pattern matching on tree structures. - Copyright (C) 2002 Bart Jongejan - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - 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, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -/* -json.c -Convert JSONL file to Bracmat file. -*/ - -/* Begin of input.h */ - -void stringEval(const char* s, const char** out, int* err); -/* End of input.h */ - -#if defined _WIN64 -/*Microsoft*/ -#define LONG long long -#else -#define LONG long -#endif - -#define TRUE 1 -#define FALSE 0 - -typedef enum {nojson,json} jstate; - -#define BUFSIZE 35000 - -static int decimals; -static int leadingzeros; - -static void startString(void) - { - putOperatorChar(' '); - putOperatorChar('('); - putOperatorChar('.'); - } - -static void endString(void) - { - putOperatorChar(')'); - } - -static void firstValue(void) - { - putOperatorChar(' '); - putOperatorChar('('); - } - -static void nextValue(void) - { - putOperatorChar(')'); - putOperatorChar('+'); - putOperatorChar('('); - } - -static void lastValue(void) - { - putOperatorChar(')'); - } - -static void startArray(void)/* called when [ has been read */ - { - putOperatorChar(' '); - putOperatorChar('('); - putOperatorChar(','); - putOperatorChar('('); - } - -static void endArray(void)/* called when ] has been read */ - { - putOperatorChar(')'); - putOperatorChar(')'); - } - -static void startObject(void)/* called when { has been read */ - { - putOperatorChar(' '); - putOperatorChar('('); - putOperatorChar('('); - } - -static void endObject(void)/* called when } has been read */ - { - putOperatorChar(')'); - putOperatorChar(','); - putOperatorChar(')'); - } - -typedef jstate (*stateFncTp)(int); -static unsigned int stacksiz; -static stateFncTp * theStack; -static stateFncTp * stackpointer; -static stateFncTp action; - -static stateFncTp push(stateFncTp arg) - { - ++stackpointer; - if(stackpointer == theStack + stacksiz) - { - stateFncTp* newstack; - unsigned int newsiz = (2 * stacksiz + 1); - newstack = (stateFncTp *)realloc(theStack,newsiz * sizeof(stateFncTp)); - if(newstack) - { - theStack = newstack; - stackpointer = theStack + stacksiz; - stacksiz = newsiz; - } - else - { - errorprintf( - "memory full (requested block of %d bytes could not be allocated)", - newsiz * sizeof(stateFncTp)); - exit(1); - } - } - return *stackpointer=(arg); - } - -static stateFncTp popj(void) - { - --stackpointer; - assert(stackpointer >= theStack); - return *stackpointer; - } - -static int needed; -static unsigned LONG hexvalue; - -static jstate hexdigits(int arg) - { - if ('0' <= arg && arg <= '9') - arg -= '0'; - else if('A' <= arg && arg <= 'F') - arg -= ('A'-10); - else if('a' <= arg && arg <= 'f') - arg -= ('a'-10); - else return nojson; - hexvalue = (hexvalue << 4) + arg; - if(--needed == 0) - { - unsigned char tmp[22]; - if(putCodePoint(hexvalue,tmp)) - { - unsigned char * c = tmp; - while(*c) - putLeafChar(*c++); - } - action = popj(); - } - return json; - } - -static jstate escape(int arg) - { - switch(arg) - { - case '"': - putLeafChar('\"'); break; - case '\\': - putLeafChar('\\'); break; - case '/': - putLeafChar('/'); break; - case 'b': - putLeafChar('\b'); break; - case 'f': - putLeafChar('\f'); break; - case 'n': - putLeafChar('\n'); break; - case 'r': - putLeafChar('\r'); break; - case 't': - putLeafChar('\t'); break; - case 'u': - popj(); needed = 4; hexvalue = 0L; action = push(hexdigits); return json; - default: - action = popj(); return nojson; - } - action = popj(); - return json; - } - -static jstate string(int arg) - { - switch(arg) - { - case '"': - endString(); action = popj(); break; - case '\\': - action = push(escape); break; - default: - if(0 < arg && arg < ' ') - switch(arg) - { - case 8: - case 9: - case 10: - case 12: - case 13: - /*See http://www.bennadel.com/blog/2576-testing-which-ascii-characters-break-json-javascript-object-notation-parsing.htm*/ - break; - default: - return nojson; - } - putLeafChar(arg); - } - return json; - } - -static jstate name(int arg) - { - if(arg == '"') - { - action = popj(); - return json; - } - else - return string(arg); - } - -static jstate value(int arg); - -static jstate commaOrCloseSquareBracket(int arg) - { - switch(arg) - { - case ']': - action = popj(); lastValue(); endArray(); return json; - case ',': - action = push(value); lastValue(); firstValue(); return json; - case ' ': - case '\t': - case '\r': - case '\n': - return json; - default: - return nojson; - } - } - -static jstate startNamestring(int arg); - -static jstate commaOrCloseBrace(int arg) - { - switch(arg) - { - case '}': - action = popj(); lastValue(); endObject(); return json; - case ',': - popj(); action = push(startNamestring); nextValue(); return json; - case ' ': - case '\t': - case '\r': - case '\n': - return json; - default: - return nojson; - } - } - -static jstate colon(int arg) - { - switch(arg) - { - case ':': - popj(); putOperatorChar('.'); push(commaOrCloseBrace); action = push(value); - case ' ': - case '\t': - case '\r': - case '\n': - return json; - default: - return nojson; - } - } - -static jstate startNamestring(int arg) - { - switch(arg) - { - case '"': - popj(); push(colon); action = push(name); - case ' ': - case '\t': - case '\r': - case '\n': - return json; - default: - return nojson; - } - } - -static jstate valueOrCloseSquareBracket(int arg) - { - switch(arg) - { - case ']': - action = popj(); endArray(); - case ' ': - case '\t': - case '\r': - case '\n': - return json; - default: - popj(); - firstValue(); - push(commaOrCloseSquareBracket); - action = push(value); - return value(arg); - } - } - -static const char * FIXED; - -static jstate fixed(int arg) - { - int next; - next = *FIXED++; - if(arg == next) - { - if(!*FIXED) - { - action = popj(); - } - putLeafChar(next); - return json; - } - return nojson; - } - -static int signj; -static int Nexp; - -static void aftermath(int zeros) - { - if(leadingzeros) - { - putLeafChar('0'); - } - else - { - if(zeros < 0) - { - putLeafChar('/'); - putLeafChar('1'); - zeros = -zeros; - } - while(zeros--) - putLeafChar('0'); - } - } - -static jstate exponentdigits(int arg) - { - if('0' <= arg && arg <= '9') - { - Nexp = 10*Nexp + arg - '0'; - return json; - } - aftermath(signj*Nexp - decimals); - action = popj(); - return action(arg); - } - -static jstate exponent(int arg) - { - if('0' <= arg && arg <= '9') - { - Nexp = 10*Nexp + arg - '0'; - popj(); - action = push(exponentdigits); - return json; - } - return nojson; - } - -static jstate plusOrMinusOrDigit(int arg) - { - switch(arg) - { - case '-': - signj = -1; - case '+': - popj(); - action = push(exponent); - return json; - default: - return exponent(arg); - } - } - -static jstate decimal(int arg) - { - switch(arg) - { - case 'e': - case 'E': - popj(); - signj = 1; - Nexp = 0; - action = push(plusOrMinusOrDigit); - return json; - case '0': - ++decimals; - if(!leadingzeros) - putLeafChar(arg); - return json; - default: - if('1' <= arg && arg <= '9') - { - leadingzeros = FALSE; - ++decimals; - putLeafChar(arg); - return json; - } - } - aftermath(-decimals); - action = popj(); - return action(arg); - } - -static jstate firstdecimal(int arg) - { - if('0' == arg) - { - popj(); - decimals = 1; - if(!leadingzeros) - putLeafChar(arg); - action = push(decimal); - return json; - } - else if('1' <= arg && arg <= '9') - { - popj(); - decimals = 1; - leadingzeros = FALSE; - putLeafChar(arg); - action = push(decimal); - return json; - } - return nojson; - } - -static jstate dotOrE(int arg) - { - switch(arg) - { - case 'e': - case 'E': - popj(); - signj = 1; - Nexp = 0; - action = push(plusOrMinusOrDigit); - return json; - case '.': - popj(); action = push(firstdecimal); return json; - default: - action = popj(); aftermath(0); return action(arg); - } - } - -static jstate digitsOrDotOrE(int arg) - { - if('0' <= arg && arg <= '9') - { - putLeafChar(arg); - return json; - } - else - return dotOrE(arg); - } - -static jstate firstdigit(int arg) - { - decimals = 0; - switch(arg) - { - case '0': - popj(); action = push(dotOrE); leadingzeros = TRUE; - case ' ': - case '\t': - case '\r': - case '\n': - return json; - default: - if('1' <= arg && arg <= '9') - { - leadingzeros = FALSE; - putLeafChar(arg); - popj(); - action = push(digitsOrDotOrE); - return json; - } - } - return nojson; - } - -static jstate startNamestringOrCloseBrace(int arg) - { - switch(arg) - { - case '"': - popj(); push(colon); action = push(name); return json; - case '}': - action = popj(); putLeafChar('0'); lastValue(); endObject(); return json; - case ' ': - case '\t': - case '\r': - case '\n': - return json; - default: - return nojson; - } - } - -static jstate value(int arg) - { - switch(arg) - { - case '"': - popj(); action = push(string); startString(); return json; - case '[': - popj - (); action = push(valueOrCloseSquareBracket); startArray(); return json; - case '{': - popj(); action = push(startNamestringOrCloseBrace); startObject(); firstValue(); return json; - case 't': - popj(); action = push(fixed); putLeafChar('t'); FIXED = "rue"; return json; - case 'f': - popj(); action = push(fixed); putLeafChar('f'); FIXED = "alse"; return json; - case 'n': - popj(); action = push(fixed); putLeafChar('n'); FIXED = "ull"; return json; - case '-': - popj(); action = push(firstdigit); putOperatorChar(arg); return json; - default: - return firstdigit(arg); - } - } - -static jstate top(int arg) - { - switch(arg) - { - case '{': - action = push(startNamestringOrCloseBrace); startObject(); firstValue(); return json; - case '[': - action = push(valueOrCloseSquareBracket); startArray(); return json; - case ' ': - case '\t': - case '\r': - case '\n': - return json; - default: - return nojson; - } - } - -static int doit(char * arg) - { - stacksiz = 1; - theStack = (stateFncTp *)malloc(stacksiz * sizeof(stateFncTp)); - if(theStack) - { - int R; - *theStack = 0; - stackpointer = theStack + 0; - - action = top; - for(; *arg && action; ++arg) - { - if(action(*arg) == nojson) - return FALSE; - } - for(; *arg; ++arg) - { - switch(*arg) - { - case ' ': - case '\t': - case '\r': - case '\n': - break; - default: - return FALSE; - } - } - R = stackpointer == theStack; - free(theStack); - return R; - } - return 0; - } - -static int JSONtext(FILE * fpi,char * bron) - { - int kar; - int inc = 0x10000; - int incs = 1; - int ok = 1; - LONG filesize; - if(fpi) - { - if(fpi == stdin) - { - filesize = inc - 1; - } - else - { - fseek(fpi,0,SEEK_END); - filesize = ftell(fpi); - rewind(fpi); - } - } - else if(bron) - { - filesize = strlen(bron); - } - else - return 0; - if(filesize > 0) - { - char * alltext = fpi ? (char*)malloc(filesize+1) : bron; - if(alltext) - { - if(fpi) - { - char * p = alltext; - while((kar = getc(fpi)) != EOF) - { - *p++ = (char)kar; - if(p >= alltext + incs * inc) - { - size_t dif = p - alltext; - char* newalltext; - ++incs; - newalltext = (char *)realloc(alltext,incs * inc); - if(newalltext) - { - alltext = newalltext; - p = alltext + dif; - } - else - break; /* out of memory! */ - } - } - *p = '\0'; - } - ok = doit(alltext); - if(alltext != bron) - free(alltext); - } - } - return !ok; - } -/* End of json.c */ - -/* Begin of xml.c */ -/* - Bracmat. Programming language with pattern matching on tree structures. - Copyright (C) 2002 Bart Jongejan - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - 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, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -/* -xml.c -Convert XML file to Bracmat file. -XML entities are converted to their UTF-8 equivalents. - -Each tag is output to the Bracmat file. Combining opening tags with their -closing tags must be done elsewhere, if needed. - -Because the program does not make an attempt at nesting, combining -closing tags with their opening tags, the program can handle SGML and HTML as -well as XML. - -Attribute values need not be surrounded in ' ' or " ". -Attribute values need not even be present. -A closing angled parenthesis > is implied in certain circumstances: - is interpreted as

-attributes can be empty (no =[valuex]) -*/ - -#if defined _WIN64 -/*Microsoft*/ -#define LONG long long -#else -#define LONG long -#endif - -#define TRUE 1 -#define FALSE 0 - -typedef enum {notag,tag,endoftag,endoftag_startoftag} estate; -static estate (*tagState)(const unsigned char * pkar); - -static int Put(const unsigned char * c); -static int (*xput)(const unsigned char * c) = Put; - -static int assumeUTF8 = 1; /* Turned off when a non-UTF-8 sequence is seen. */ - -static int rawput(int c) - { - putLeafChar(c); - return TRUE; - } - -static int nrawput(const unsigned char * c) - { - while(*c) - if(!rawput(*c++)) - return FALSE; - return TRUE; - } - -struct lowup - { - int l; - int u; - int s; /* NameStartChar */ - }; - -struct lowup lu[] = - { {'-','-',FALSE} - , {'.','.',FALSE} - , {'0','9',FALSE} - , {':',':',TRUE} - , {'A','Z',TRUE} - , {'_','_',TRUE} - , {'a','z',TRUE} - , {0xB7,0xB7,FALSE} - , {0xC0,0xD6,TRUE} - , {0xD8,0xF6,TRUE} - , {0xF8,0x2FF,TRUE} - , {0x300,0x36F,FALSE} - , {0x370,0x37D,TRUE} - , {0x37F,0x1FFF,TRUE} - , {0x200C,0x200D,TRUE} - , {0x203F,0x2040,FALSE} - , {0x2070,0x218F,TRUE} - , {0x2C00,0x2FEF,TRUE} - , {0x3001,0xD7FF,TRUE} - , {0xF900,0xFDCF,TRUE} - , {0xFDF0,0xFFFD,TRUE} - , {0x10000,0xEFFFF,TRUE} - , {0x7FFFFFFF,0x7FFFFFFF,TRUE} - }; - -#define BUFSIZE 35000 - -static unsigned char * bufx; -static unsigned char * glob_p; -static int anychar = FALSE; - -static int (*namechar)(int c); - -static int NameChar(int c) - { - int i; - for( i = 0 - ; c > lu[i].u - ; ++i - ) - ; - return c >= lu[i].l && (anychar || lu[i].s); - } - -static int decimalx(int c) - { - if('0' <= c && c <= '9') - return TRUE; - return FALSE; - } - -static int hex(int c) - { - if( ('0' <= c && c <= '9') - || ('A' <= c && c <= 'F') - || ('a' <= c && c <= 'f') - ) - return TRUE; - return FALSE; - } - -static int number(int c) - { - if(c == 'x' || c == 'X') - { - namechar = hex; - return TRUE; - } - if(decimalx(c)) - { - namechar = decimalx; - return TRUE; - } - return FALSE; - } - -static int entity(int c) - { - if(c == '#') - { - namechar = number; - return TRUE; - } - else - { - anychar = FALSE; - if(NameChar(c)) - { - anychar = TRUE; - namechar = NameChar; - return TRUE; - } - } - return FALSE; - } - -typedef struct Entity { const char * ent; int code; int morecode; } Entity; -static Entity entities[] = { - { "AElig", 198, 0 }, /* latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 */ - { "AMP", 38, 0 }, - { "Aacute", 193, 0 }, /* latin capital letter A with acute, U+00C1 ISOlat1 */ - { "Abreve", 258, 0 }, - { "Acirc", 194, 0 }, /* latin capital letter A with circumflex, U+00C2 ISOlat1 */ - { "Acy", 1040, 0 }, - { "Afr", 120068, 0 }, - { "Agrave", 192, 0 }, /* latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1 */ - { "Alpha", 913, 0 }, /* greek capital letter alpha, U+0391 */ - { "Amacr", 256, 0 }, - { "And", 10835, 0 }, - { "Aogon", 260, 0 }, - { "Aopf", 120120, 0 }, - { "ApplyFunction", 8289, 0 }, - { "Aring", 197, 0 }, /* latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1 */ - { "Ascr", 119964, 0 }, - { "Assign", 8788, 0 }, - { "Atilde", 195, 0 }, /* latin capital letter A with tilde, U+00C3 ISOlat1 */ - { "Auml", 196, 0 }, /* latin capital letter A with diaeresis, U+00C4 ISOlat1 */ - { "Backslash", 8726, 0 }, - { "Barv", 10983, 0 }, - { "Barwed", 8966, 0 }, - { "Bcy", 1041, 0 }, - { "Because", 8757, 0 }, - { "Bernoullis", 8492, 0 }, - { "Beta", 914, 0 }, /* greek capital letter beta, U+0392 */ - { "Bfr", 120069, 0 }, - { "Bopf", 120121, 0 }, - { "Breve", 728, 0 }, - { "Bscr", 8492, 0 }, - { "Bumpeq", 8782, 0 }, - { "CHcy", 1063, 0 }, - { "COPY", 169, 0 }, - { "Cacute", 262, 0 }, - { "Cap", 8914, 0 }, - { "CapitalDifferentialD", 8517, 0 }, - { "Cayleys", 8493, 0 }, - { "Ccaron", 268, 0 }, - { "Ccedil", 199, 0 }, /* latin capital letter C with cedilla, U+00C7 ISOlat1 */ - { "Ccirc", 264, 0 }, - { "Cconint", 8752, 0 }, - { "Cdot", 266, 0 }, - { "Cedilla", 184, 0 }, - { "CenterDot", 183, 0 }, - { "Cfr", 8493, 0 }, - { "Chi", 935, 0 }, /* greek capital letter chi, U+03A7 */ - { "CircleDot", 8857, 0 }, - { "CircleMinus", 8854, 0 }, - { "CirclePlus", 8853, 0 }, - { "CircleTimes", 8855, 0 }, - { "ClockwiseContourIntegral", 8754, 0 }, - { "CloseCurlyDoubleQuote", 8221, 0 }, - { "CloseCurlyQuote", 8217, 0 }, - { "Colon", 8759, 0 }, - { "Colone", 10868, 0 }, - { "Congruent", 8801, 0 }, - { "Conint", 8751, 0 }, - { "ContourIntegral", 8750, 0 }, - { "Copf", 8450, 0 }, - { "Coproduct", 8720, 0 }, - { "CounterClockwiseContourIntegral", 8755, 0 }, - { "Cross", 10799, 0 }, - { "Cscr", 119966, 0 }, - { "Cup", 8915, 0 }, - { "CupCap", 8781, 0 }, - { "DD", 8517, 0 }, - { "DDotrahd", 10513, 0 }, - { "DJcy", 1026, 0 }, - { "DScy", 1029, 0 }, - { "DZcy", 1039, 0 }, - { "Dagger", 8225, 0 }, /* double dagger, U+2021 ISOpub */ - { "Darr", 8609, 0 }, - { "Dashv", 10980, 0 }, - { "Dcaron", 270, 0 }, - { "Dcy", 1044, 0 }, - { "Del", 8711, 0 }, - { "Delta", 916, 0 }, /* greek capital letter delta, U+0394 ISOgrk3 */ - { "Dfr", 120071, 0 }, - { "DiacriticalAcute", 180, 0 }, - { "DiacriticalDot", 729, 0 }, - { "DiacriticalDoubleAcute", 733, 0 }, - { "DiacriticalGrave", 96, 0 }, - { "DiacriticalTilde", 732, 0 }, - { "Diamond", 8900, 0 }, - { "DifferentialD", 8518, 0 }, - { "Dopf", 120123, 0 }, - { "Dot", 168, 0 }, - { "DotDot", 8412, 0 }, - { "DotEqual", 8784, 0 }, - { "DoubleContourIntegral", 8751, 0 }, - { "DoubleDot", 168, 0 }, - { "DoubleDownArrow", 8659, 0 }, - { "DoubleLeftArrow", 8656, 0 }, - { "DoubleLeftRightArrow", 8660, 0 }, - { "DoubleLeftTee", 10980, 0 }, - { "DoubleLongLeftArrow", 10232, 0 }, - { "DoubleLongLeftRightArrow", 10234, 0 }, - { "DoubleLongRightArrow", 10233, 0 }, - { "DoubleRightArrow", 8658, 0 }, - { "DoubleRightTee", 8872, 0 }, - { "DoubleUpArrow", 8657, 0 }, - { "DoubleUpDownArrow", 8661, 0 }, - { "DoubleVerticalBar", 8741, 0 }, - { "DownArrow", 8595, 0 }, - { "DownArrowBar", 10515, 0 }, - { "DownArrowUpArrow", 8693, 0 }, - { "DownBreve", 785, 0 }, - { "DownLeftRightVector", 10576, 0 }, - { "DownLeftTeeVector", 10590, 0 }, - { "DownLeftVector", 8637, 0 }, - { "DownLeftVectorBar", 10582, 0 }, - { "DownRightTeeVector", 10591, 0 }, - { "DownRightVector", 8641, 0 }, - { "DownRightVectorBar", 10583, 0 }, - { "DownTee", 8868, 0 }, - { "DownTeeArrow", 8615, 0 }, - { "Downarrow", 8659, 0 }, - { "Dscr", 119967, 0 }, - { "Dstrok", 272, 0 }, - { "ENG", 330, 0 }, - { "ETH", 208, 0 }, /* latin capital letter ETH, U+00D0 ISOlat1 */ - { "Eacute", 201, 0 }, /* latin capital letter E with acute, U+00C9 ISOlat1 */ - { "Ecaron", 282, 0 }, - { "Ecirc", 202, 0 }, /* latin capital letter E with circumflex, U+00CA ISOlat1 */ - { "Ecy", 1069, 0 }, - { "Edot", 278, 0 }, - { "Efr", 120072, 0 }, - { "Egrave", 200, 0 }, /* latin capital letter E with grave, U+00C8 ISOlat1 */ - { "Element", 8712, 0 }, - { "Emacr", 274, 0 }, - { "EmptySmallSquare", 9723, 0 }, - { "EmptyVerySmallSquare", 9643, 0 }, - { "Eogon", 280, 0 }, - { "Eopf", 120124, 0 }, - { "Epsilon", 917, 0 }, /* greek capital letter epsilon, U+0395 */ - { "Equal", 10869, 0 }, - { "EqualTilde", 8770, 0 }, - { "Equilibrium", 8652, 0 }, - { "Escr", 8496, 0 }, - { "Esim", 10867, 0 }, - { "Eta", 919, 0 }, /* greek capital letter eta, U+0397 */ - { "Euml", 203, 0 }, /* latin capital letter E with diaeresis, U+00CB ISOlat1 */ - { "Exists", 8707, 0 }, - { "ExponentialE", 8519, 0 }, - { "Fcy", 1060, 0 }, - { "Ffr", 120073, 0 }, - { "FilledSmallSquare", 9724, 0 }, - { "FilledVerySmallSquare", 9642, 0 }, - { "Fopf", 120125, 0 }, - { "ForAll", 8704, 0 }, - { "Fouriertrf", 8497, 0 }, - { "Fscr", 8497, 0 }, - { "GJcy", 1027, 0 }, - { "GT", 62, 0 }, - { "Gamma", 915, 0 }, /* greek capital letter gamma, U+0393 ISOgrk3 */ - { "Gammad", 988, 0 }, - { "Gbreve", 286, 0 }, - { "Gcedil", 290, 0 }, - { "Gcirc", 284, 0 }, - { "Gcy", 1043, 0 }, - { "Gdot", 288, 0 }, - { "Gfr", 120074, 0 }, - { "Gg", 8921, 0 }, - { "Gopf", 120126, 0 }, - { "GreaterEqual", 8805, 0 }, - { "GreaterEqualLess", 8923, 0 }, - { "GreaterFullEqual", 8807, 0 }, - { "GreaterGreater", 10914, 0 }, - { "GreaterLess", 8823, 0 }, - { "GreaterSlantEqual", 10878, 0 }, - { "GreaterTilde", 8819, 0 }, - { "Gscr", 119970, 0 }, - { "Gt", 8811, 0 }, - { "HARDcy", 1066, 0 }, - { "Hacek", 711, 0 }, - { "Hat", 94, 0 }, - { "Hcirc", 292, 0 }, - { "Hfr", 8460, 0 }, - { "HilbertSpace", 8459, 0 }, - { "Hopf", 8461, 0 }, - { "HorizontalLine", 9472, 0 }, - { "Hscr", 8459, 0 }, - { "Hstrok", 294, 0 }, - { "HumpDownHump", 8782, 0 }, - { "HumpEqual", 8783, 0 }, - { "IEcy", 1045, 0 }, - { "IJlig", 306, 0 }, - { "IOcy", 1025, 0 }, - { "Iacute", 205, 0 }, /* latin capital letter I with acute, U+00CD ISOlat1 */ - { "Icirc", 206, 0 }, /* latin capital letter I with circumflex, U+00CE ISOlat1 */ - { "Icy", 1048, 0 }, - { "Idot", 304, 0 }, - { "Ifr", 8465, 0 }, - { "Igrave", 204, 0 }, /* latin capital letter I with grave, U+00CC ISOlat1 */ - { "Im", 8465, 0 }, - { "Imacr", 298, 0 }, - { "ImaginaryI", 8520, 0 }, - { "Implies", 8658, 0 }, - { "Int", 8748, 0 }, - { "Integral", 8747, 0 }, - { "Intersection", 8898, 0 }, - { "InvisibleComma", 8291, 0 }, - { "InvisibleTimes", 8290, 0 }, - { "Iogon", 302, 0 }, - { "Iopf", 120128, 0 }, - { "Iota", 921, 0 }, /* greek capital letter iota, U+0399 */ - { "Iscr", 8464, 0 }, - { "Itilde", 296, 0 }, - { "Iukcy", 1030, 0 }, - { "Iuml", 207, 0 }, /* latin capital letter I with diaeresis, U+00CF ISOlat1 */ - { "Jcirc", 308, 0 }, - { "Jcy", 1049, 0 }, - { "Jfr", 120077, 0 }, - { "Jopf", 120129, 0 }, - { "Jscr", 119973, 0 }, - { "Jsercy", 1032, 0 }, - { "Jukcy", 1028, 0 }, - { "KHcy", 1061, 0 }, - { "KJcy", 1036, 0 }, - { "Kappa", 922, 0 }, /* greek capital letter kappa, U+039A */ - { "Kcedil", 310, 0 }, - { "Kcy", 1050, 0 }, - { "Kfr", 120078, 0 }, - { "Kopf", 120130, 0 }, - { "Kscr", 119974, 0 }, - { "LJcy", 1033, 0 }, - { "LT", 60, 0 }, - { "Lacute", 313, 0 }, - { "Lambda", 923, 0 }, /* greek capital letter lambda, U+039B ISOgrk3 */ - { "Lang", 10218, 0 }, - { "Laplacetrf", 8466, 0 }, - { "Larr", 8606, 0 }, - { "Lcaron", 317, 0 }, - { "Lcedil", 315, 0 }, - { "Lcy", 1051, 0 }, - { "LeftAngleBracket", 10216, 0 }, /* U+27E8⟨ */ - { "LeftArrow", 8592, 0 }, - { "LeftArrowBar", 8676, 0 }, - { "LeftArrowRightArrow", 8646, 0 }, - { "LeftCeiling", 8968, 0 }, - { "LeftDoubleBracket", 10214, 0 }, - { "LeftDownTeeVector", 10593, 0 }, - { "LeftDownVector", 8643, 0 }, - { "LeftDownVectorBar", 10585, 0 }, - { "LeftFloor", 8970, 0 }, - { "LeftRightArrow", 8596, 0 }, - { "LeftRightVector", 10574, 0 }, - { "LeftTee", 8867, 0 }, - { "LeftTeeArrow", 8612, 0 }, - { "LeftTeeVector", 10586, 0 }, - { "LeftTriangle", 8882, 0 }, - { "LeftTriangleBar", 10703, 0 }, - { "LeftTriangleEqual", 8884, 0 }, - { "LeftUpDownVector", 10577, 0 }, - { "LeftUpTeeVector", 10592, 0 }, - { "LeftUpVector", 8639, 0 }, - { "LeftUpVectorBar", 10584, 0 }, - { "LeftVector", 8636, 0 }, - { "LeftVectorBar", 10578, 0 }, - { "Leftarrow", 8656, 0 }, - { "Leftrightarrow", 8660, 0 }, - { "LessEqualGreater", 8922, 0 }, - { "LessFullEqual", 8806, 0 }, - { "LessGreater", 8822, 0 }, - { "LessLess", 10913, 0 }, - { "LessSlantEqual", 10877, 0 }, - { "LessTilde", 8818, 0 }, - { "Lfr", 120079, 0 }, - { "Ll", 8920, 0 }, - { "Lleftarrow", 8666, 0 }, - { "Lmidot", 319, 0 }, - { "LongLeftArrow", 10229, 0 }, - { "LongLeftRightArrow", 10231, 0 }, - { "LongRightArrow", 10230, 0 }, - { "Longleftarrow", 10232, 0 }, - { "Longleftrightarrow", 10234, 0 }, - { "Longrightarrow", 10233, 0 }, - { "Lopf", 120131, 0 }, - { "LowerLeftArrow", 8601, 0 }, - { "LowerRightArrow", 8600, 0 }, - { "Lscr", 8466, 0 }, - { "Lsh", 8624, 0 }, - { "Lstrok", 321, 0 }, - { "Lt", 8810, 0 }, - { "Map", 10501, 0 }, - { "Mcy", 1052, 0 }, - { "MediumSpace", 8287, 0 }, - { "Mellintrf", 8499, 0 }, - { "Mfr", 120080, 0 }, - { "MinusPlus", 8723, 0 }, - { "Mopf", 120132, 0 }, - { "Mscr", 8499, 0 }, - { "Mu", 924, 0 }, /* greek capital letter mu, U+039C */ - { "NJcy", 1034, 0 }, - { "Nacute", 323, 0 }, - { "Ncaron", 327, 0 }, - { "Ncedil", 325, 0 }, - { "Ncy", 1053, 0 }, - { "NegativeMediumSpace", 8203, 0 }, - { "NegativeThickSpace", 8203, 0 }, - { "NegativeThinSpace", 8203, 0 }, - { "NegativeVeryThinSpace", 8203, 0 }, - { "NestedGreaterGreater", 8811, 0 }, - { "NestedLessLess", 8810, 0 }, - { "NewLine", 10, 0 }, /* U+A - */ - { "Nfr", 120081, 0 }, - { "NoBreak", 8288, 0 }, - { "NonBreakingSpace", 160, 0 }, - { "Nopf", 8469, 0 }, - { "Not", 10988, 0 }, - { "NotCongruent", 8802, 0 }, - { "NotCupCap", 8813, 0 }, - { "NotDoubleVerticalBar", 8742, 0 }, - { "NotElement", 8713, 0 }, - { "NotEqual", 8800, 0 }, - { "NotEqualTilde", 8770, 824 }, - { "NotExists", 8708, 0 }, - { "NotGreater", 8815, 0 }, - { "NotGreaterEqual", 8817, 0 }, - { "NotGreaterFullEqual", 8807, 824 }, - { "NotGreaterGreater", 8811, 824 }, - { "NotGreaterLess", 8825, 0 }, - { "NotGreaterSlantEqual", 10878, 824 }, - { "NotGreaterTilde", 8821, 0 }, - { "NotHumpDownHump", 8782, 824 }, - { "NotHumpEqual", 8783, 824 }, - { "NotLeftTriangle", 8938, 0 }, - { "NotLeftTriangleBar", 10703, 824 }, - { "NotLeftTriangleEqual", 8940, 0 }, - { "NotLess", 8814, 0 }, - { "NotLessEqual", 8816, 0 }, - { "NotLessGreater", 8824, 0 }, - { "NotLessLess", 8810, 824 }, - { "NotLessSlantEqual", 10877, 824 }, - { "NotLessTilde", 8820, 0 }, - { "NotNestedGreaterGreater", 10914, 824 }, - { "NotNestedLessLess", 10913, 824 }, - { "NotPrecedes", 8832, 0 }, - { "NotPrecedesEqual", 10927, 824 }, - { "NotPrecedesSlantEqual", 8928, 0 }, - { "NotReverseElement", 8716, 0 }, - { "NotRightTriangle", 8939, 0 }, - { "NotRightTriangleBar", 10704, 824 }, - { "NotRightTriangleEqual", 8941, 0 }, - { "NotSquareSubset", 8847, 824 }, - { "NotSquareSubsetEqual", 8930, 0 }, - { "NotSquareSuperset", 8848, 824 }, - { "NotSquareSupersetEqual", 8931, 0 }, - { "NotSubset", 8834, 8402 }, - { "NotSubsetEqual", 8840, 0 }, - { "NotSucceeds", 8833, 0 }, - { "NotSucceedsEqual", 10928, 824 }, - { "NotSucceedsSlantEqual", 8929, 0 }, - { "NotSucceedsTilde", 8831, 824 }, - { "NotSuperset", 8835, 8402 }, - { "NotSupersetEqual", 8841, 0 }, - { "NotTilde", 8769, 0 }, - { "NotTildeEqual", 8772, 0 }, - { "NotTildeFullEqual", 8775, 0 }, - { "NotTildeTilde", 8777, 0 }, - { "NotVerticalBar", 8740, 0 }, - { "Nscr", 119977, 0 }, - { "Ntilde", 209, 0 }, /* latin capital letter N with tilde, U+00D1 ISOlat1 */ - { "Nu", 925, 0 }, /* greek capital letter nu, U+039D */ - { "OElig", 338, 0 }, /* latin capital ligature OE, U+0152 ISOlat2 */ - { "Oacute", 211, 0 }, /* latin capital letter O with acute, U+00D3 ISOlat1 */ - { "Ocirc", 212, 0 }, /* latin capital letter O with circumflex, U+00D4 ISOlat1 */ - { "Ocy", 1054, 0 }, - { "Odblac", 336, 0 }, - { "Ofr", 120082, 0 }, - { "Ograve", 210, 0 }, /* latin capital letter O with grave, U+00D2 ISOlat1 */ - { "Omacr", 332, 0 }, - { "Omega", 937, 0 }, /* greek capital letter omega, U+03A9 ISOgrk3 */ - { "Omicron", 927, 0 }, /* greek capital letter omicron, U+039F */ - { "Oopf", 120134, 0 }, - { "OpenCurlyDoubleQuote", 8220, 0 }, - { "OpenCurlyQuote", 8216, 0 }, - { "Or", 10836, 0 }, - { "Oscr", 119978, 0 }, - { "Oslash", 216, 0 }, /* latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1 */ - { "Otilde", 213, 0 }, /* latin capital letter O with tilde, U+00D5 ISOlat1 */ - { "Otimes", 10807, 0 }, - { "Ouml", 214, 0 }, /* latin capital letter O with diaeresis, U+00D6 ISOlat1 */ - { "OverBar", 8254, 0 }, - { "OverBrace", 9182, 0 }, - { "OverBracket", 9140, 0 }, - { "OverParenthesis", 9180, 0 }, - { "PartialD", 8706, 0 }, - { "Pcy", 1055, 0 }, - { "Pfr", 120083, 0 }, - { "Phi", 934, 0 }, /* greek capital letter phi, U+03A6 ISOgrk3 */ - { "Pi", 928, 0 }, /* greek capital letter pi, U+03A0 ISOgrk3 */ - { "PlusMinus", 177, 0 }, - { "Poincareplane", 8460, 0 }, - { "Popf", 8473, 0 }, - { "Pr", 10939, 0 }, - { "Precedes", 8826, 0 }, - { "PrecedesEqual", 10927, 0 }, - { "PrecedesSlantEqual", 8828, 0 }, - { "PrecedesTilde", 8830, 0 }, - { "Prime", 8243, 0 }, /* double prime = seconds = inches, U+2033 ISOtech */ - { "Product", 8719, 0 }, - { "Proportion", 8759, 0 }, - { "Proportional", 8733, 0 }, - { "Pscr", 119979, 0 }, - { "Psi", 936, 0 }, /* greek capital letter psi, U+03A8 ISOgrk3 */ - { "QUOT", 34, 0 }, - { "Qfr", 120084, 0 }, - { "Qopf", 8474, 0 }, - { "Qscr", 119980, 0 }, - { "RBarr", 10512, 0 }, - { "REG", 174, 0 }, - { "Racute", 340, 0 }, - { "Rang", 10219, 0 }, - { "Rarr", 8608, 0 }, - { "Rarrtl", 10518, 0 }, - { "Rcaron", 344, 0 }, - { "Rcedil", 342, 0 }, - { "Rcy", 1056, 0 }, - { "Re", 8476, 0 }, - { "ReverseElement", 8715, 0 }, - { "ReverseEquilibrium", 8651, 0 }, - { "ReverseUpEquilibrium", 10607, 0 }, - { "Rfr", 8476, 0 }, - { "Rho", 929, 0 }, /* greek capital letter rho, U+03A1 */ - { "RightAngleBracket", 10217, 0 }, /* U+27E9⟩ */ - { "RightArrow", 8594, 0 }, - { "RightArrowBar", 8677, 0 }, - { "RightArrowLeftArrow", 8644, 0 }, - { "RightCeiling", 8969, 0 }, - { "RightDoubleBracket", 10215, 0 }, - { "RightDownTeeVector", 10589, 0 }, - { "RightDownVector", 8642, 0 }, - { "RightDownVectorBar", 10581, 0 }, - { "RightFloor", 8971, 0 }, - { "RightTee", 8866, 0 }, - { "RightTeeArrow", 8614, 0 }, - { "RightTeeVector", 10587, 0 }, - { "RightTriangle", 8883, 0 }, - { "RightTriangleBar", 10704, 0 }, - { "RightTriangleEqual", 8885, 0 }, - { "RightUpDownVector", 10575, 0 }, - { "RightUpTeeVector", 10588, 0 }, - { "RightUpVector", 8638, 0 }, - { "RightUpVectorBar", 10580, 0 }, - { "RightVector", 8640, 0 }, - { "RightVectorBar", 10579, 0 }, - { "Rightarrow", 8658, 0 }, - { "Ropf", 8477, 0 }, - { "RoundImplies", 10608, 0 }, - { "Rrightarrow", 8667, 0 }, - { "Rscr", 8475, 0 }, - { "Rsh", 8625, 0 }, - { "RuleDelayed", 10740, 0 }, - { "SHCHcy", 1065, 0 }, - { "SHcy", 1064, 0 }, - { "SOFTcy", 1068, 0 }, - { "Sacute", 346, 0 }, - { "Sc", 10940, 0 }, - { "Scaron", 352, 0 }, /* latin capital letter S with caron, U+0160 ISOlat2 */ - { "Scedil", 350, 0 }, - { "Scirc", 348, 0 }, - { "Scy", 1057, 0 }, - { "Sfr", 120086, 0 }, - { "ShortDownArrow", 8595, 0 }, - { "ShortLeftArrow", 8592, 0 }, - { "ShortRightArrow", 8594, 0 }, - { "ShortUpArrow", 8593, 0 }, - { "Sigma", 931, 0 }, /* greek capital letter sigma, U+03A3 ISOgrk3 */ - { "SmallCircle", 8728, 0 }, - { "Sopf", 120138, 0 }, - { "Sqrt", 8730, 0 }, - { "Square", 9633, 0 }, - { "SquareIntersection", 8851, 0 }, - { "SquareSubset", 8847, 0 }, - { "SquareSubsetEqual", 8849, 0 }, - { "SquareSuperset", 8848, 0 }, - { "SquareSupersetEqual", 8850, 0 }, - { "SquareUnion", 8852, 0 }, - { "Sscr", 119982, 0 }, - { "Star", 8902, 0 }, - { "Sub", 8912, 0 }, - { "Subset", 8912, 0 }, - { "SubsetEqual", 8838, 0 }, - { "Succeeds", 8827, 0 }, - { "SucceedsEqual", 10928, 0 }, - { "SucceedsSlantEqual", 8829, 0 }, - { "SucceedsTilde", 8831, 0 }, - { "SuchThat", 8715, 0 }, - { "Sum", 8721, 0 }, - { "Sup", 8913, 0 }, - { "Superset", 8835, 0 }, - { "SupersetEqual", 8839, 0 }, - { "Supset", 8913, 0 }, - { "THORN", 222, 0 }, /* latin capital letter THORN, U+00DE ISOlat1 */ - { "TRADE", 8482, 0 }, - { "TSHcy", 1035, 0 }, - { "TScy", 1062, 0 }, - { "Tab", 9, 0 }, /* U+9 */ - { "Tau", 932, 0 }, /* greek capital letter tau, U+03A4 */ - { "Tcaron", 356, 0 }, - { "Tcedil", 354, 0 }, - { "Tcy", 1058, 0 }, - { "Tfr", 120087, 0 }, - { "Therefore", 8756, 0 }, - { "Theta", 920, 0 }, /* greek capital letter theta, U+0398 ISOgrk3 */ - { "ThickSpace", 8287, 8202 }, - { "ThinSpace", 8201, 0 }, - { "Tilde", 8764, 0 }, - { "TildeEqual", 8771, 0 }, - { "TildeFullEqual", 8773, 0 }, - { "TildeTilde", 8776, 0 }, - { "Topf", 120139, 0 }, - { "TripleDot", 8411, 0 }, - { "Tscr", 119983, 0 }, - { "Tstrok", 358, 0 }, - { "Uacute", 218, 0 }, /* latin capital letter U with acute, U+00DA ISOlat1 */ - { "Uarr", 8607, 0 }, - { "Uarrocir", 10569, 0 }, - { "Ubrcy", 1038, 0 }, - { "Ubreve", 364, 0 }, - { "Ucirc", 219, 0 }, /* latin capital letter U with circumflex, U+00DB ISOlat1 */ - { "Ucy", 1059, 0 }, - { "Udblac", 368, 0 }, - { "Ufr", 120088, 0 }, - { "Ugrave", 217, 0 }, /* latin capital letter U with grave, U+00D9 ISOlat1 */ - { "Umacr", 362, 0 }, - { "UnderBar", 95, 0 }, - { "UnderBrace", 9183, 0 }, - { "UnderBracket", 9141, 0 }, - { "UnderParenthesis", 9181, 0 }, - { "Union", 8899, 0 }, - { "UnionPlus", 8846, 0 }, - { "Uogon", 370, 0 }, - { "Uopf", 120140, 0 }, - { "UpArrow", 8593, 0 }, - { "UpArrowBar", 10514, 0 }, - { "UpArrowDownArrow", 8645, 0 }, - { "UpDownArrow", 8597, 0 }, - { "UpEquilibrium", 10606, 0 }, - { "UpTee", 8869, 0 }, - { "UpTeeArrow", 8613, 0 }, - { "Uparrow", 8657, 0 }, - { "Updownarrow", 8661, 0 }, - { "UpperLeftArrow", 8598, 0 }, - { "UpperRightArrow", 8599, 0 }, - { "Upsi", 978, 0 }, - { "Upsilon", 933, 0 }, /* greek capital letter upsilon, U+03A5 ISOgrk3 */ - { "Uring", 366, 0 }, - { "Uscr", 119984, 0 }, - { "Utilde", 360, 0 }, - { "Uuml", 220, 0 }, /* latin capital letter U with diaeresis, U+00DC ISOlat1 */ - { "VDash", 8875, 0 }, - { "Vbar", 10987, 0 }, - { "Vcy", 1042, 0 }, - { "Vdash", 8873, 0 }, - { "Vdashl", 10982, 0 }, - { "Vee", 8897, 0 }, - { "Verbar", 8214, 0 }, - { "Vert", 8214, 0 }, - { "VerticalBar", 8739, 0 }, - { "VerticalLine", 124, 0 }, - { "VerticalSeparator", 10072, 0 }, - { "VerticalTilde", 8768, 0 }, - { "VeryThinSpace", 8202, 0 }, - { "Vfr", 120089, 0 }, - { "Vopf", 120141, 0 }, - { "Vscr", 119985, 0 }, - { "Vvdash", 8874, 0 }, - { "Wcirc", 372, 0 }, - { "Wedge", 8896, 0 }, - { "Wfr", 120090, 0 }, - { "Wopf", 120142, 0 }, - { "Wscr", 119986, 0 }, - { "Xfr", 120091, 0 }, - { "Xi", 926, 0 }, /* greek capital letter xi, U+039E ISOgrk3 */ - { "Xopf", 120143, 0 }, - { "Xscr", 119987, 0 }, - { "YAcy", 1071, 0 }, - { "YIcy", 1031, 0 }, - { "YUcy", 1070, 0 }, - { "Yacute", 221, 0 }, /* latin capital letter Y with acute, U+00DD ISOlat1 */ - { "Ycirc", 374, 0 }, - { "Ycy", 1067, 0 }, - { "Yfr", 120092, 0 }, - { "Yopf", 120144, 0 }, - { "Yscr", 119988, 0 }, - { "Yuml", 376, 0 }, /* latin capital letter Y with diaeresis, U+0178 ISOlat2 */ - { "ZHcy", 1046, 0 }, - { "Zacute", 377, 0 }, - { "Zcaron", 381, 0 }, - { "Zcy", 1047, 0 }, - { "Zdot", 379, 0 }, - { "ZeroWidthSpace", 8203, 0 }, - { "Zeta", 918, 0 }, /* greek capital letter zeta, U+0396 */ - { "Zfr", 8488, 0 }, - { "Zopf", 8484, 0 }, - { "Zscr", 119989, 0 }, - { "aacute", 225, 0 }, /* latin small letter a with acute, U+00E1 ISOlat1 */ - { "abreve", 259, 0 }, - { "ac", 8766, 0 }, - { "acE", 8766, 819 }, - { "acd", 8767, 0 }, - { "acirc", 226, 0 }, /* latin small letter a with circumflex, U+00E2 ISOlat1 */ - { "acute", 180, 0 }, /* acute accent = spacing acute, U+00B4 ISOdia */ - { "acy", 1072, 0 }, - { "aelig", 230, 0 }, /* latin small letter ae = latin small ligature ae, U+00E6 ISOlat1 */ - { "af", 8289, 0 }, - { "afr", 120094, 0 }, - { "agrave", 224, 0 }, /* latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1 */ - { "alefsym", 8501, 0 }, /* alef symbol = first transfinite cardinal, U+2135 NEW */ - { "aleph", 8501, 0 }, - { "alpha", 945, 0 }, /* greek small letter alpha, U+03B1 ISOgrk3 */ - { "amacr", 257, 0 }, - { "amalg", 10815, 0 }, - { "amp", 38, 0 }, /* ampersand, U+0026 ISOnum */ - { "and", 8743, 0 }, /* logical and = wedge, U+2227 ISOtech */ - { "andand", 10837, 0 }, - { "andd", 10844, 0 }, - { "andslope", 10840, 0 }, - { "andv", 10842, 0 }, - { "ang", 8736, 0 }, /* angle, U+2220 ISOamso */ - { "ange", 10660, 0 }, - { "angle", 8736, 0 }, - { "angmsd", 8737, 0 }, - { "angmsdaa", 10664, 0 }, - { "angmsdab", 10665, 0 }, - { "angmsdac", 10666, 0 }, - { "angmsdad", 10667, 0 }, - { "angmsdae", 10668, 0 }, - { "angmsdaf", 10669, 0 }, - { "angmsdag", 10670, 0 }, - { "angmsdah", 10671, 0 }, - { "angrt", 8735, 0 }, - { "angrtvb", 8894, 0 }, - { "angrtvbd", 10653, 0 }, - { "angsph", 8738, 0 }, - { "angst", 197, 0 }, - { "angzarr", 9084, 0 }, - { "aogon", 261, 0 }, - { "aopf", 120146, 0 }, - { "ap", 8776, 0 }, - { "apE", 10864, 0 }, - { "apacir", 10863, 0 }, - { "ape", 8778, 0 }, - { "apid", 8779, 0 }, - { "apos", 39, 0 }, - { "approx", 8776, 0 }, - { "approxeq", 8778, 0 }, - { "aring", 229, 0 }, /* latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1 */ - { "ascr", 119990, 0 }, - { "ast", 42, 0 }, - { "asymp", 8776, 0 }, /* almost equal to = asymptotic to, U+2248 ISOamsr */ - { "asympeq", 8781, 0 }, - { "atilde", 227, 0 }, /* latin small letter a with tilde, U+00E3 ISOlat1 */ - { "auml", 228, 0 }, /* latin small letter a with diaeresis, U+00E4 ISOlat1 */ - { "awconint", 8755, 0 }, - { "awint", 10769, 0 }, - { "bNot", 10989, 0 }, - { "backcong", 8780, 0 }, - { "backepsilon", 1014, 0 }, - { "backprime", 8245, 0 }, - { "backsim", 8765, 0 }, - { "backsimeq", 8909, 0 }, - { "barvee", 8893, 0 }, - { "barwed", 8965, 0 }, - { "barwedge", 8965, 0 }, - { "bbrk", 9141, 0 }, - { "bbrktbrk", 9142, 0 }, - { "bcong", 8780, 0 }, - { "bcy", 1073, 0 }, - { "bdquo", 8222, 0 }, /* double low-9 quotation mark, U+201E NEW */ - { "becaus", 8757, 0 }, - { "because", 8757, 0 }, - { "bemptyv", 10672, 0 }, - { "bepsi", 1014, 0 }, - { "bernou", 8492, 0 }, - { "beta", 946, 0 }, /* greek small letter beta, U+03B2 ISOgrk3 */ - { "beth", 8502, 0 }, - { "between", 8812, 0 }, - { "bfr", 120095, 0 }, - { "bigcap", 8898, 0 }, - { "bigcirc", 9711, 0 }, - { "bigcup", 8899, 0 }, - { "bigodot", 10752, 0 }, - { "bigoplus", 10753, 0 }, - { "bigotimes", 10754, 0 }, - { "bigsqcup", 10758, 0 }, - { "bigstar", 9733, 0 }, - { "bigtriangledown", 9661, 0 }, - { "bigtriangleup", 9651, 0 }, - { "biguplus", 10756, 0 }, - { "bigvee", 8897, 0 }, - { "bigwedge", 8896, 0 }, - { "bkarow", 10509, 0 }, - { "blacklozenge", 10731, 0 }, - { "blacksquare", 9642, 0 }, - { "blacktriangle", 9652, 0 }, - { "blacktriangledown", 9662, 0 }, - { "blacktriangleleft", 9666, 0 }, - { "blacktriangleright", 9656, 0 }, - { "blank", 9251, 0 }, - { "blk12", 9618, 0 }, - { "blk14", 9617, 0 }, - { "blk34", 9619, 0 }, - { "block", 9608, 0 }, - { "bne", 61, 8421 }, - { "bnequiv", 8801, 8421 }, - { "bnot", 8976, 0 }, - { "bopf", 120147, 0 }, - { "bot", 8869, 0 }, - { "bottom", 8869, 0 }, - { "bowtie", 8904, 0 }, - { "boxDL", 9559, 0 }, - { "boxDR", 9556, 0 }, - { "boxDl", 9558, 0 }, - { "boxDr", 9555, 0 }, - { "boxH", 9552, 0 }, - { "boxHD", 9574, 0 }, - { "boxHU", 9577, 0 }, - { "boxHd", 9572, 0 }, - { "boxHu", 9575, 0 }, - { "boxUL", 9565, 0 }, - { "boxUR", 9562, 0 }, - { "boxUl", 9564, 0 }, - { "boxUr", 9561, 0 }, - { "boxV", 9553, 0 }, - { "boxVH", 9580, 0 }, - { "boxVL", 9571, 0 }, - { "boxVR", 9568, 0 }, - { "boxVh", 9579, 0 }, - { "boxVl", 9570, 0 }, - { "boxVr", 9567, 0 }, - { "boxbox", 10697, 0 }, - { "boxdL", 9557, 0 }, - { "boxdR", 9554, 0 }, - { "boxdl", 9488, 0 }, - { "boxdr", 9484, 0 }, - { "boxh", 9472, 0 }, - { "boxhD", 9573, 0 }, - { "boxhU", 9576, 0 }, - { "boxhd", 9516, 0 }, - { "boxhu", 9524, 0 }, - { "boxminus", 8863, 0 }, - { "boxplus", 8862, 0 }, - { "boxtimes", 8864, 0 }, - { "boxuL", 9563, 0 }, - { "boxuR", 9560, 0 }, - { "boxul", 9496, 0 }, - { "boxur", 9492, 0 }, - { "boxv", 9474, 0 }, - { "boxvH", 9578, 0 }, - { "boxvL", 9569, 0 }, - { "boxvR", 9566, 0 }, - { "boxvh", 9532, 0 }, - { "boxvl", 9508, 0 }, - { "boxvr", 9500, 0 }, - { "bprime", 8245, 0 }, - { "breve", 728, 0 }, - { "brvbar", 166, 0 }, /* broken bar = broken vertical bar, U+00A6 ISOnum */ - { "bscr", 119991, 0 }, - { "bsemi", 8271, 0 }, - { "bsim", 8765, 0 }, - { "bsime", 8909, 0 }, - { "bsol", 92, 0 }, - { "bsolb", 10693, 0 }, - { "bsolhsub", 10184, 0 }, - { "bull", 8226, 0 }, /* bullet = black small circle, U+2022 ISOpub */ - { "bullet", 8226, 0 }, - { "bump", 8782, 0 }, - { "bumpE", 10926, 0 }, - { "bumpe", 8783, 0 }, - { "bumpeq", 8783, 0 }, - { "cacute", 263, 0 }, - { "cap", 8745, 0 }, /* intersection = cap, U+2229 ISOtech */ - { "capand", 10820, 0 }, - { "capbrcup", 10825, 0 }, - { "capcap", 10827, 0 }, - { "capcup", 10823, 0 }, - { "capdot", 10816, 0 }, - { "caps", 8745, 65024 }, - { "caret", 8257, 0 }, - { "caron", 711, 0 }, - { "ccaps", 10829, 0 }, - { "ccaron", 269, 0 }, - { "ccedil", 231, 0 }, /* latin small letter c with cedilla, U+00E7 ISOlat1 */ - { "ccirc", 265, 0 }, - { "ccups", 10828, 0 }, - { "ccupssm", 10832, 0 }, - { "cdot", 267, 0 }, - { "cedil", 184, 0 }, /* cedilla = spacing cedilla, U+00B8 ISOdia */ - { "cemptyv", 10674, 0 }, - { "cent", 162, 0 }, /* cent sign, U+00A2 ISOnum */ - { "centerdot", 183, 0 }, - { "cfr", 120096, 0 }, - { "chcy", 1095, 0 }, - { "check", 10003, 0 }, - { "checkmark", 10003, 0 }, - { "chi", 967, 0 }, /* greek small letter chi, U+03C7 ISOgrk3 */ - { "cir", 9675, 0 }, - { "cirE", 10691, 0 }, - { "circ", 710, 0 }, /* modifier letter circumflex accent, U+02C6 ISOpub */ - { "circeq", 8791, 0 }, - { "circlearrowleft", 8634, 0 }, - { "circlearrowright", 8635, 0 }, - { "circledR", 174, 0 }, - { "circledS", 9416, 0 }, - { "circledast", 8859, 0 }, - { "circledcirc", 8858, 0 }, - { "circleddash", 8861, 0 }, - { "cire", 8791, 0 }, - { "cirfnint", 10768, 0 }, - { "cirmid", 10991, 0 }, - { "cirscir", 10690, 0 }, - { "clubs", 9827, 0 }, /* black club suit = shamrock, U+2663 ISOpub */ - { "clubsuit", 9827, 0 }, - { "colon", 58, 0 }, - { "colone", 8788, 0 }, - { "coloneq", 8788, 0 }, - { "comma", 44, 0 }, - { "commat", 64, 0 }, - { "comp", 8705, 0 }, - { "compfn", 8728, 0 }, - { "complement", 8705, 0 }, - { "complexes", 8450, 0 }, - { "cong", 8773, 0 }, /* approximately equal to, U+2245 ISOtech */ - { "congdot", 10861, 0 }, - { "conint", 8750, 0 }, - { "copf", 120148, 0 }, - { "coprod", 8720, 0 }, - { "copy", 169, 0 }, /* copyright sign, U+00A9 ISOnum */ - { "copysr", 8471, 0 }, - { "crarr", 8629, 0 }, /* downwards arrow with corner leftwards = carriage return, U+21B5 NEW */ - { "cross", 10007, 0 }, - { "cscr", 119992, 0 }, - { "csub", 10959, 0 }, - { "csube", 10961, 0 }, - { "csup", 10960, 0 }, - { "csupe", 10962, 0 }, - { "ctdot", 8943, 0 }, - { "cudarrl", 10552, 0 }, - { "cudarrr", 10549, 0 }, - { "cuepr", 8926, 0 }, - { "cuesc", 8927, 0 }, - { "cularr", 8630, 0 }, - { "cularrp", 10557, 0 }, - { "cup", 8746, 0 }, /* union = cup, U+222A ISOtech */ - { "cupbrcap", 10824, 0 }, - { "cupcap", 10822, 0 }, - { "cupcup", 10826, 0 }, - { "cupdot", 8845, 0 }, - { "cupor", 10821, 0 }, - { "cups", 8746, 65024 }, - { "curarr", 8631, 0 }, - { "curarrm", 10556, 0 }, - { "curlyeqprec", 8926, 0 }, - { "curlyeqsucc", 8927, 0 }, - { "curlyvee", 8910, 0 }, - { "curlywedge", 8911, 0 }, - { "curren", 164, 0 }, /* currency sign, U+00A4 ISOnum */ - { "curvearrowleft", 8630, 0 }, - { "curvearrowright", 8631, 0 }, - { "cuvee", 8910, 0 }, - { "cuwed", 8911, 0 }, - { "cwconint", 8754, 0 }, - { "cwint", 8753, 0 }, - { "cylcty", 9005, 0 }, - { "dArr", 8659, 0 }, /* downwards double arrow, U+21D3 ISOamsa */ - { "dHar", 10597, 0 }, - { "dagger", 8224, 0 }, /* dagger, U+2020 ISOpub */ - { "daleth", 8504, 0 }, - { "darr", 8595, 0 }, /* downwards arrow, U+2193 ISOnum */ - { "dash", 8208, 0 }, - { "dashv", 8867, 0 }, - { "dbkarow", 10511, 0 }, - { "dblac", 733, 0 }, - { "dcaron", 271, 0 }, - { "dcy", 1076, 0 }, - { "dd", 8518, 0 }, - { "ddagger", 8225, 0 }, - { "ddarr", 8650, 0 }, - { "ddotseq", 10871, 0 }, - { "deg", 176, 0 }, /* degree sign, U+00B0 ISOnum */ - { "delta", 948, 0 }, /* greek small letter delta, U+03B4 ISOgrk3 */ - { "demptyv", 10673, 0 }, - { "dfisht", 10623, 0 }, - { "dfr", 120097, 0 }, - { "dharl", 8643, 0 }, - { "dharr", 8642, 0 }, - { "diam", 8900, 0 }, - { "diamond", 8900, 0 }, - { "diamondsuit", 9830, 0 }, - { "diams", 9830, 0 }, /* black diamond suit, U+2666 ISOpub */ - { "die", 168, 0 }, - { "digamma", 989, 0 }, - { "disin", 8946, 0 }, - { "div", 247, 0 }, - { "divide", 247, 0 }, /* division sign, U+00F7 ISOnum */ - { "divideontimes", 8903, 0 }, - { "divonx", 8903, 0 }, - { "djcy", 1106, 0 }, - { "dlcorn", 8990, 0 }, - { "dlcrop", 8973, 0 }, - { "dollar", 36, 0 }, - { "dopf", 120149, 0 }, - { "dot", 729, 0 }, - { "doteq", 8784, 0 }, - { "doteqdot", 8785, 0 }, - { "dotminus", 8760, 0 }, - { "dotplus", 8724, 0 }, - { "dotsquare", 8865, 0 }, - { "doublebarwedge", 8966, 0 }, - { "downarrow", 8595, 0 }, - { "downdownarrows", 8650, 0 }, - { "downharpoonleft", 8643, 0 }, - { "downharpoonright", 8642, 0 }, - { "drbkarow", 10512, 0 }, - { "drcorn", 8991, 0 }, - { "drcrop", 8972, 0 }, - { "dscr", 119993, 0 }, - { "dscy", 1109, 0 }, - { "dsol", 10742, 0 }, - { "dstrok", 273, 0 }, - { "dtdot", 8945, 0 }, - { "dtri", 9663, 0 }, - { "dtrif", 9662, 0 }, - { "duarr", 8693, 0 }, - { "duhar", 10607, 0 }, - { "dwangle", 10662, 0 }, - { "dzcy", 1119, 0 }, - { "dzigrarr", 10239, 0 }, - { "eDDot", 10871, 0 }, - { "eDot", 8785, 0 }, - { "eacute", 233, 0 }, /* latin small letter e with acute, U+00E9 ISOlat1 */ - { "easter", 10862, 0 }, - { "ecaron", 283, 0 }, - { "ecir", 8790, 0 }, - { "ecirc", 234, 0 }, /* latin small letter e with circumflex, U+00EA ISOlat1 */ - { "ecolon", 8789, 0 }, - { "ecy", 1101, 0 }, - { "edot", 279, 0 }, - { "ee", 8519, 0 }, - { "efDot", 8786, 0 }, - { "efr", 120098, 0 }, - { "eg", 10906, 0 }, - { "egrave", 232, 0 }, /* latin small letter e with grave, U+00E8 ISOlat1 */ - { "egs", 10902, 0 }, - { "egsdot", 10904, 0 }, - { "el", 10905, 0 }, - { "elinters", 9191, 0 }, - { "ell", 8467, 0 }, - { "els", 10901, 0 }, - { "elsdot", 10903, 0 }, - { "emacr", 275, 0 }, - { "empty", 8709, 0 }, /* empty set = null set = diameter, U+2205 ISOamso */ - { "emptyset", 8709, 0 }, - { "emptyv", 8709, 0 }, - { "emsp", 8195, 0 }, /* em space, U+2003 ISOpub */ - { "emsp13", 8196, 0 }, - { "emsp14", 8197, 0 }, - { "eng", 331, 0 }, - { "ensp", 8194, 0 }, /* en space, U+2002 ISOpub */ - { "eogon", 281, 0 }, - { "eopf", 120150, 0 }, - { "epar", 8917, 0 }, - { "eparsl", 10723, 0 }, - { "eplus", 10865, 0 }, - { "epsi", 949, 0 }, - { "epsilon", 949, 0 }, /* greek small letter epsilon, U+03B5 ISOgrk3 */ - { "epsiv", 1013, 0 }, - { "eqcirc", 8790, 0 }, - { "eqcolon", 8789, 0 }, - { "eqsim", 8770, 0 }, - { "eqslantgtr", 10902, 0 }, - { "eqslantless", 10901, 0 }, - { "equals", 61, 0 }, - { "equest", 8799, 0 }, - { "equiv", 8801, 0 }, /* identical to, U+2261 ISOtech */ - { "equivDD", 10872, 0 }, - { "eqvparsl", 10725, 0 }, - { "erDot", 8787, 0 }, - { "erarr", 10609, 0 }, - { "escr", 8495, 0 }, - { "esdot", 8784, 0 }, - { "esim", 8770, 0 }, - { "eta", 951, 0 }, /* greek small letter eta, U+03B7 ISOgrk3 */ - { "eth", 240, 0 }, /* latin small letter eth, U+00F0 ISOlat1 */ - { "euml", 235, 0 }, /* latin small letter e with diaeresis, U+00EB ISOlat1 */ - { "euro", 8364, 0 }, /* euro sign, U+20AC NEW */ - { "excl", 33, 0 }, - { "exist", 8707, 0 }, /* there exists, U+2203 ISOtech */ - { "expectation", 8496, 0 }, - { "exponentiale", 8519, 0 }, - { "fallingdotseq", 8786, 0 }, - { "fcy", 1092, 0 }, - { "female", 9792, 0 }, - { "ffilig", 64259, 0 }, - { "fflig", 64256, 0 }, - { "ffllig", 64260, 0 }, - { "ffr", 120099, 0 }, - { "filig", 64257, 0 }, - { "fjlig", 102, 106 }, - { "flat", 9837, 0 }, - { "fllig", 64258, 0 }, - { "fltns", 9649, 0 }, - { "fnof", 402, 0 }, /* latin small f with hook = function = florin, U+0192 ISOtech */ - { "fopf", 120151, 0 }, - { "forall", 8704, 0 }, /* for all, U+2200 ISOtech */ - { "fork", 8916, 0 }, - { "forkv", 10969, 0 }, - { "fpartint", 10765, 0 }, - { "frac12", 189, 0 }, /* vulgar fraction one half = fraction one half, U+00BD ISOnum */ - { "frac13", 8531, 0 }, - { "frac14", 188, 0 }, /* vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum */ - { "frac15", 8533, 0 }, - { "frac16", 8537, 0 }, - { "frac18", 8539, 0 }, - { "frac23", 8532, 0 }, - { "frac25", 8534, 0 }, - { "frac34", 190, 0 }, /* vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum */ - { "frac35", 8535, 0 }, - { "frac38", 8540, 0 }, - { "frac45", 8536, 0 }, - { "frac56", 8538, 0 }, - { "frac58", 8541, 0 }, - { "frac78", 8542, 0 }, - { "frasl", 8260, 0 }, /* fraction slash, U+2044 NEW */ - { "frown", 8994, 0 }, - { "fscr", 119995, 0 }, - { "gE", 8807, 0 }, - { "gEl", 10892, 0 }, - { "gacute", 501, 0 }, - { "gamma", 947, 0 }, /* greek small letter gamma, U+03B3 ISOgrk3 */ - { "gammad", 989, 0 }, - { "gap", 10886, 0 }, - { "gbreve", 287, 0 }, - { "gcirc", 285, 0 }, - { "gcy", 1075, 0 }, - { "gdot", 289, 0 }, - { "ge", 8805, 0 }, /* greater-than or equal to, U+2265 ISOtech */ - { "gel", 8923, 0 }, - { "geq", 8805, 0 }, - { "geqq", 8807, 0 }, - { "geqslant", 10878, 0 }, - { "ges", 10878, 0 }, - { "gescc", 10921, 0 }, - { "gesdot", 10880, 0 }, - { "gesdoto", 10882, 0 }, - { "gesdotol", 10884, 0 }, - { "gesl", 8923, 65024 }, - { "gesles", 10900, 0 }, - { "gfr", 120100, 0 }, - { "gg", 8811, 0 }, - { "ggg", 8921, 0 }, - { "gimel", 8503, 0 }, - { "gjcy", 1107, 0 }, - { "gl", 8823, 0 }, - { "glE", 10898, 0 }, - { "gla", 10917, 0 }, - { "glj", 10916, 0 }, - { "gnE", 8809, 0 }, - { "gnap", 10890, 0 }, - { "gnapprox", 10890, 0 }, - { "gne", 10888, 0 }, - { "gneq", 10888, 0 }, - { "gneqq", 8809, 0 }, - { "gnsim", 8935, 0 }, - { "gopf", 120152, 0 }, - { "grave", 96, 0 }, - { "gscr", 8458, 0 }, - { "gsim", 8819, 0 }, - { "gsime", 10894, 0 }, - { "gsiml", 10896, 0 }, - { "gt", 62, 0 }, /* greater-than sign, U+003E ISOnum */ - { "gtcc", 10919, 0 }, - { "gtcir", 10874, 0 }, - { "gtdot", 8919, 0 }, - { "gtlPar", 10645, 0 }, - { "gtquest", 10876, 0 }, - { "gtrapprox", 10886, 0 }, - { "gtrarr", 10616, 0 }, - { "gtrdot", 8919, 0 }, - { "gtreqless", 8923, 0 }, - { "gtreqqless", 10892, 0 }, - { "gtrless", 8823, 0 }, - { "gtrsim", 8819, 0 }, - { "gvertneqq", 8809, 65024 }, - { "gvnE", 8809, 65024 }, - { "hArr", 8660, 0 }, /* left right double arrow, U+21D4 ISOamsa */ - { "hairsp", 8202, 0 }, - { "half", 189, 0 }, - { "hamilt", 8459, 0 }, - { "hardcy", 1098, 0 }, - { "harr", 8596, 0 }, /* left right arrow, U+2194 ISOamsa */ - { "harrcir", 10568, 0 }, - { "harrw", 8621, 0 }, - { "hbar", 8463, 0 }, - { "hcirc", 293, 0 }, - { "hearts", 9829, 0 }, /* black heart suit = valentine, U+2665 ISOpub */ - { "heartsuit", 9829, 0 }, - { "hellip", 8230, 0 }, /* horizontal ellipsis = three dot leader, U+2026 ISOpub */ - { "hercon", 8889, 0 }, - { "hfr", 120101, 0 }, - { "hksearow", 10533, 0 }, - { "hkswarow", 10534, 0 }, - { "hoarr", 8703, 0 }, - { "homtht", 8763, 0 }, - { "hookleftarrow", 8617, 0 }, - { "hookrightarrow", 8618, 0 }, - { "hopf", 120153, 0 }, - { "horbar", 8213, 0 }, - { "hscr", 119997, 0 }, - { "hslash", 8463, 0 }, - { "hstrok", 295, 0 }, - { "hybull", 8259, 0 }, - { "hyphen", 8208, 0 }, - { "iacute", 237, 0 }, /* latin small letter i with acute, U+00ED ISOlat1 */ - { "ic", 8291, 0 }, - { "icirc", 238, 0 }, /* latin small letter i with circumflex, U+00EE ISOlat1 */ - { "icy", 1080, 0 }, - { "iecy", 1077, 0 }, - { "iexcl", 161, 0 }, /* inverted exclamation mark, U+00A1 ISOnum */ - { "iff", 8660, 0 }, - { "ifr", 120102, 0 }, - { "igrave", 236, 0 }, /* latin small letter i with grave, U+00EC ISOlat1 */ - { "ii", 8520, 0 }, - { "iiiint", 10764, 0 }, - { "iiint", 8749, 0 }, - { "iinfin", 10716, 0 }, - { "iiota", 8489, 0 }, - { "ijlig", 307, 0 }, - { "imacr", 299, 0 }, - { "image", 8465, 0 }, /* blackletter capital I = imaginary part, U+2111 ISOamso */ - { "imagline", 8464, 0 }, - { "imagpart", 8465, 0 }, - { "imath", 305, 0 }, - { "imof", 8887, 0 }, - { "imped", 437, 0 }, - { "in", 8712, 0 }, - { "incare", 8453, 0 }, - { "infin", 8734, 0 }, /* infinity, U+221E ISOtech */ - { "infintie", 10717, 0 }, - { "inodot", 305, 0 }, - { "int", 8747, 0 }, /* integral, U+222B ISOtech */ - { "intcal", 8890, 0 }, - { "integers", 8484, 0 }, - { "intercal", 8890, 0 }, - { "intlarhk", 10775, 0 }, - { "intprod", 10812, 0 }, - { "iocy", 1105, 0 }, - { "iogon", 303, 0 }, - { "iopf", 120154, 0 }, - { "iota", 953, 0 }, /* greek small letter iota, U+03B9 ISOgrk3 */ - { "iprod", 10812, 0 }, - { "iquest", 191, 0 }, /* inverted question mark = turned question mark, U+00BF ISOnum */ - { "iscr", 119998, 0 }, - { "isin", 8712, 0 }, /* element of, U+2208 ISOtech */ - { "isinE", 8953, 0 }, - { "isindot", 8949, 0 }, - { "isins", 8948, 0 }, - { "isinsv", 8947, 0 }, - { "isinv", 8712, 0 }, - { "it", 8290, 0 }, - { "itilde", 297, 0 }, - { "iukcy", 1110, 0 }, - { "iuml", 239, 0 }, /* latin small letter i with diaeresis, U+00EF ISOlat1 */ - { "jcirc", 309, 0 }, - { "jcy", 1081, 0 }, - { "jfr", 120103, 0 }, - { "jmath", 567, 0 }, - { "jopf", 120155, 0 }, - { "jscr", 119999, 0 }, - { "jsercy", 1112, 0 }, - { "jukcy", 1108, 0 }, - { "kappa", 954, 0 }, /* greek small letter kappa, U+03BA ISOgrk3 */ - { "kappav", 1008, 0 }, - { "kcedil", 311, 0 }, - { "kcy", 1082, 0 }, - { "kfr", 120104, 0 }, - { "kgreen", 312, 0 }, - { "khcy", 1093, 0 }, - { "kjcy", 1116, 0 }, - { "kopf", 120156, 0 }, - { "kscr", 120000, 0 }, - { "lAarr", 8666, 0 }, - { "lArr", 8656, 0 }, /* leftwards double arrow, U+21D0 ISOtech */ - { "lAtail", 10523, 0 }, - { "lBarr", 10510, 0 }, - { "lE", 8806, 0 }, - { "lEg", 10891, 0 }, - { "lHar", 10594, 0 }, - { "lacute", 314, 0 }, - { "laemptyv", 10676, 0 }, - { "lagran", 8466, 0 }, - { "lambda", 955, 0 }, /* greek small letter lambda, U+03BB ISOgrk3 */ - { "lang", 9001, 0 }, /* left-pointing angle bracket = bra, U+2329 ISOtech */ - { "langd", 10641, 0 }, - { "langle", 10216, 0 }, /* U+27E8⟨ */ - { "lap", 10885, 0 }, - { "laquo", 171, 0 }, /* left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum */ - { "larr", 8592, 0 }, /* leftwards arrow, U+2190 ISOnum */ - { "larrb", 8676, 0 }, - { "larrbfs", 10527, 0 }, - { "larrfs", 10525, 0 }, - { "larrhk", 8617, 0 }, - { "larrlp", 8619, 0 }, - { "larrpl", 10553, 0 }, - { "larrsim", 10611, 0 }, - { "larrtl", 8610, 0 }, - { "lat", 10923, 0 }, - { "latail", 10521, 0 }, - { "late", 10925, 0 }, - { "lates", 10925, 65024 }, - { "lbarr", 10508, 0 }, - { "lbbrk", 10098, 0 }, - { "lbrace", 123, 0 }, - { "lbrack", 91, 0 }, - { "lbrke", 10635, 0 }, - { "lbrksld", 10639, 0 }, - { "lbrkslu", 10637, 0 }, - { "lcaron", 318, 0 }, - { "lcedil", 316, 0 }, - { "lceil", 8968, 0 }, /* left ceiling = apl upstile, U+2308 ISOamsc */ - { "lcub", 123, 0 }, - { "lcy", 1083, 0 }, - { "ldca", 10550, 0 }, - { "ldquo", 8220, 0 }, /* left double quotation mark, U+201C ISOnum */ - { "ldquor", 8222, 0 }, - { "ldrdhar", 10599, 0 }, - { "ldrushar", 10571, 0 }, - { "ldsh", 8626, 0 }, - { "le", 8804, 0 }, /* less-than or equal to, U+2264 ISOtech */ - { "leftarrow", 8592, 0 }, - { "leftarrowtail", 8610, 0 }, - { "leftharpoondown", 8637, 0 }, - { "leftharpoonup", 8636, 0 }, - { "leftleftarrows", 8647, 0 }, - { "leftrightarrow", 8596, 0 }, - { "leftrightarrows", 8646, 0 }, - { "leftrightharpoons", 8651, 0 }, - { "leftrightsquigarrow", 8621, 0 }, - { "leftthreetimes", 8907, 0 }, - { "leg", 8922, 0 }, - { "leq", 8804, 0 }, - { "leqq", 8806, 0 }, - { "leqslant", 10877, 0 }, - { "les", 10877, 0 }, - { "lescc", 10920, 0 }, - { "lesdot", 10879, 0 }, - { "lesdoto", 10881, 0 }, - { "lesdotor", 10883, 0 }, - { "lesg", 8922, 65024 }, - { "lesges", 10899, 0 }, - { "lessapprox", 10885, 0 }, - { "lessdot", 8918, 0 }, - { "lesseqgtr", 8922, 0 }, - { "lesseqqgtr", 10891, 0 }, - { "lessgtr", 8822, 0 }, - { "lesssim", 8818, 0 }, - { "lfisht", 10620, 0 }, - { "lfloor", 8970, 0 }, /* left floor = apl downstile, U+230A ISOamsc */ - { "lfr", 120105, 0 }, - { "lg", 8822, 0 }, - { "lgE", 10897, 0 }, - { "lhard", 8637, 0 }, - { "lharu", 8636, 0 }, - { "lharul", 10602, 0 }, - { "lhblk", 9604, 0 }, - { "ljcy", 1113, 0 }, - { "ll", 8810, 0 }, - { "llarr", 8647, 0 }, - { "llcorner", 8990, 0 }, - { "llhard", 10603, 0 }, - { "lltri", 9722, 0 }, - { "lmidot", 320, 0 }, - { "lmoust", 9136, 0 }, - { "lmoustache", 9136, 0 }, - { "lnE", 8808, 0 }, - { "lnap", 10889, 0 }, - { "lnapprox", 10889, 0 }, - { "lne", 10887, 0 }, - { "lneq", 10887, 0 }, - { "lneqq", 8808, 0 }, - { "lnsim", 8934, 0 }, - { "loang", 10220, 0 }, - { "loarr", 8701, 0 }, - { "lobrk", 10214, 0 }, - { "longleftarrow", 10229, 0 }, - { "longleftrightarrow", 10231, 0 }, - { "longmapsto", 10236, 0 }, - { "longrightarrow", 10230, 0 }, - { "looparrowleft", 8619, 0 }, - { "looparrowright", 8620, 0 }, - { "lopar", 10629, 0 }, - { "lopf", 120157, 0 }, - { "loplus", 10797, 0 }, - { "lotimes", 10804, 0 }, - { "lowast", 8727, 0 }, /* asterisk operator, U+2217 ISOtech */ - { "lowbar", 95, 0 }, - { "loz", 9674, 0 }, /* lozenge, U+25CA ISOpub */ - { "lozenge", 9674, 0 }, - { "lozf", 10731, 0 }, - { "lpar", 40, 0 }, - { "lparlt", 10643, 0 }, - { "lrarr", 8646, 0 }, - { "lrcorner", 8991, 0 }, - { "lrhar", 8651, 0 }, - { "lrhard", 10605, 0 }, - { "lrm", 8206, 0 }, /* left-to-right mark, U+200E NEW RFC 2070 */ - { "lrtri", 8895, 0 }, - { "lsaquo", 8249, 0 }, /* single left-pointing angle quotation mark, U+2039 ISO proposed */ - { "lscr", 120001, 0 }, - { "lsh", 8624, 0 }, - { "lsim", 8818, 0 }, - { "lsime", 10893, 0 }, - { "lsimg", 10895, 0 }, - { "lsqb", 91, 0 }, - { "lsquo", 8216, 0 }, /* left single quotation mark, U+2018 ISOnum */ - { "lsquor", 8218, 0 }, - { "lstrok", 322, 0 }, - { "lt", 60, 0 }, /* less-than sign, U+003C ISOnum */ - { "ltcc", 10918, 0 }, - { "ltcir", 10873, 0 }, - { "ltdot", 8918, 0 }, - { "lthree", 8907, 0 }, - { "ltimes", 8905, 0 }, - { "ltlarr", 10614, 0 }, - { "ltquest", 10875, 0 }, - { "ltrPar", 10646, 0 }, - { "ltri", 9667, 0 }, - { "ltrie", 8884, 0 }, - { "ltrif", 9666, 0 }, - { "lurdshar", 10570, 0 }, - { "luruhar", 10598, 0 }, - { "lvertneqq", 8808, 65024 }, - { "lvnE", 8808, 65024 }, - { "mDDot", 8762, 0 }, - { "macr", 175, 0 }, /* macron = spacing macron = overline = APL overbar, U+00AF ISOdia */ - { "male", 9794, 0 }, - { "malt", 10016, 0 }, - { "maltese", 10016, 0 }, - { "map", 8614, 0 }, - { "mapsto", 8614, 0 }, - { "mapstodown", 8615, 0 }, - { "mapstoleft", 8612, 0 }, - { "mapstoup", 8613, 0 }, - { "marker", 9646, 0 }, - { "mcomma", 10793, 0 }, - { "mcy", 1084, 0 }, - { "mdash", 8212, 0 }, /* em dash, U+2014 ISOpub */ - { "measuredangle", 8737, 0 }, - { "mfr", 120106, 0 }, - { "mho", 8487, 0 }, - { "micro", 181, 0 }, /* micro sign, U+00B5 ISOnum */ - { "mid", 8739, 0 }, - { "midast", 42, 0 }, - { "midcir", 10992, 0 }, - { "middot", 183, 0 }, /* middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum */ - { "minus", 8722, 0 }, /* minus sign, U+2212 ISOtech */ - { "minusb", 8863, 0 }, - { "minusd", 8760, 0 }, - { "minusdu", 10794, 0 }, - { "mlcp", 10971, 0 }, - { "mldr", 8230, 0 }, - { "mnplus", 8723, 0 }, - { "models", 8871, 0 }, - { "mopf", 120158, 0 }, - { "mp", 8723, 0 }, - { "mscr", 120002, 0 }, - { "mstpos", 8766, 0 }, - { "mu", 956, 0 }, /* greek small letter mu, U+03BC ISOgrk3 */ - { "multimap", 8888, 0 }, - { "mumap", 8888, 0 }, - { "nGg", 8921, 824 }, - { "nGt", 8811, 8402 }, - { "nGtv", 8811, 824 }, - { "nLeftarrow", 8653, 0 }, - { "nLeftrightarrow", 8654, 0 }, - { "nLl", 8920, 824 }, - { "nLt", 8810, 8402 }, - { "nLtv", 8810, 824 }, - { "nRightarrow", 8655, 0 }, - { "nVDash", 8879, 0 }, - { "nVdash", 8878, 0 }, - { "nabla", 8711, 0 }, /* nabla = backward difference, U+2207 ISOtech */ - { "nacute", 324, 0 }, - { "nang", 8736, 8402 }, - { "nap", 8777, 0 }, - { "napE", 10864, 824 }, - { "napid", 8779, 824 }, - { "napos", 329, 0 }, - { "napprox", 8777, 0 }, - { "natur", 9838, 0 }, - { "natural", 9838, 0 }, - { "naturals", 8469, 0 }, - { "nbsp", 160, 0 }, /* no-break space = non-breaking space, U+00A0 ISOnum */ - { "nbump", 8782, 824 }, - { "nbumpe", 8783, 824 }, - { "ncap", 10819, 0 }, - { "ncaron", 328, 0 }, - { "ncedil", 326, 0 }, - { "ncong", 8775, 0 }, - { "ncongdot", 10861, 824 }, - { "ncup", 10818, 0 }, - { "ncy", 1085, 0 }, - { "ndash", 8211, 0 }, /* en dash, U+2013 ISOpub */ - { "ne", 8800, 0 }, /* not equal to, U+2260 ISOtech */ - { "neArr", 8663, 0 }, - { "nearhk", 10532, 0 }, - { "nearr", 8599, 0 }, - { "nearrow", 8599, 0 }, - { "nedot", 8784, 824 }, - { "nequiv", 8802, 0 }, - { "nesear", 10536, 0 }, - { "nesim", 8770, 824 }, - { "nexist", 8708, 0 }, - { "nexists", 8708, 0 }, - { "nfr", 120107, 0 }, - { "ngE", 8807, 824 }, - { "nge", 8817, 0 }, - { "ngeq", 8817, 0 }, - { "ngeqq", 8807, 824 }, - { "ngeqslant", 10878, 824 }, - { "nges", 10878, 824 }, - { "ngsim", 8821, 0 }, - { "ngt", 8815, 0 }, - { "ngtr", 8815, 0 }, - { "nhArr", 8654, 0 }, - { "nharr", 8622, 0 }, - { "nhpar", 10994, 0 }, - { "ni", 8715, 0 }, /* contains as member, U+220B ISOtech */ - { "nis", 8956, 0 }, - { "nisd", 8954, 0 }, - { "niv", 8715, 0 }, - { "njcy", 1114, 0 }, - { "nlArr", 8653, 0 }, - { "nlE", 8806, 824 }, - { "nlarr", 8602, 0 }, - { "nldr", 8229, 0 }, - { "nle", 8816, 0 }, - { "nleftarrow", 8602, 0 }, - { "nleftrightarrow", 8622, 0 }, - { "nleq", 8816, 0 }, - { "nleqq", 8806, 824 }, - { "nleqslant", 10877, 824 }, - { "nles", 10877, 824 }, - { "nless", 8814, 0 }, - { "nlsim", 8820, 0 }, - { "nlt", 8814, 0 }, - { "nltri", 8938, 0 }, - { "nltrie", 8940, 0 }, - { "nmid", 8740, 0 }, - { "nopf", 120159, 0 }, - { "not", 172, 0 }, /* not sign, U+00AC ISOnum */ - { "notin", 8713, 0 }, /* not an element of, U+2209 ISOtech */ - { "notinE", 8953, 824 }, - { "notindot", 8949, 824 }, - { "notinva", 8713, 0 }, - { "notinvb", 8951, 0 }, - { "notinvc", 8950, 0 }, - { "notni", 8716, 0 }, - { "notniva", 8716, 0 }, - { "notnivb", 8958, 0 }, - { "notnivc", 8957, 0 }, - { "npar", 8742, 0 }, - { "nparallel", 8742, 0 }, - { "nparsl", 11005, 8421 }, - { "npart", 8706, 824 }, - { "npolint", 10772, 0 }, - { "npr", 8832, 0 }, - { "nprcue", 8928, 0 }, - { "npre", 10927, 824 }, - { "nprec", 8832, 0 }, - { "npreceq", 10927, 824 }, - { "nrArr", 8655, 0 }, - { "nrarr", 8603, 0 }, - { "nrarrc", 10547, 824 }, - { "nrarrw", 8605, 824 }, - { "nrightarrow", 8603, 0 }, - { "nrtri", 8939, 0 }, - { "nrtrie", 8941, 0 }, - { "nsc", 8833, 0 }, - { "nsccue", 8929, 0 }, - { "nsce", 10928, 824 }, - { "nscr", 120003, 0 }, - { "nshortmid", 8740, 0 }, - { "nshortparallel", 8742, 0 }, - { "nsim", 8769, 0 }, - { "nsime", 8772, 0 }, - { "nsimeq", 8772, 0 }, - { "nsmid", 8740, 0 }, - { "nspar", 8742, 0 }, - { "nsqsube", 8930, 0 }, - { "nsqsupe", 8931, 0 }, - { "nsub", 8836, 0 }, /* not a subset of, U+2284 ISOamsn */ - { "nsubE", 10949, 824 }, - { "nsube", 8840, 0 }, - { "nsubset", 8834, 8402 }, - { "nsubseteq", 8840, 0 }, - { "nsubseteqq", 10949, 824 }, - { "nsucc", 8833, 0 }, - { "nsucceq", 10928, 824 }, - { "nsup", 8837, 0 }, - { "nsupE", 10950, 824 }, - { "nsupe", 8841, 0 }, - { "nsupset", 8835, 8402 }, - { "nsupseteq", 8841, 0 }, - { "nsupseteqq", 10950, 824 }, - { "ntgl", 8825, 0 }, - { "ntilde", 241, 0 }, /* latin small letter n with tilde, U+00F1 ISOlat1 */ - { "ntlg", 8824, 0 }, - { "ntriangleleft", 8938, 0 }, - { "ntrianglelefteq", 8940, 0 }, - { "ntriangleright", 8939, 0 }, - { "ntrianglerighteq", 8941, 0 }, - { "nu", 957, 0 }, /* greek small letter nu, U+03BD ISOgrk3 */ - { "num", 35, 0 }, - { "numero", 8470, 0 }, - { "numsp", 8199, 0 }, - { "nvDash", 8877, 0 }, - { "nvHarr", 10500, 0 }, - { "nvap", 8781, 8402 }, - { "nvdash", 8876, 0 }, - { "nvge", 8805, 8402 }, - { "nvgt", 62, 8402 }, - { "nvinfin", 10718, 0 }, - { "nvlArr", 10498, 0 }, - { "nvle", 8804, 8402 }, - { "nvlt", 60, 8402 }, - { "nvltrie", 8884, 8402 }, - { "nvrArr", 10499, 0 }, - { "nvrtrie", 8885, 8402 }, - { "nvsim", 8764, 8402 }, - { "nwArr", 8662, 0 }, - { "nwarhk", 10531, 0 }, - { "nwarr", 8598, 0 }, - { "nwarrow", 8598, 0 }, - { "nwnear", 10535, 0 }, - { "oS", 9416, 0 }, - { "oacute", 243, 0 }, /* latin small letter o with acute, U+00F3 ISOlat1 */ - { "oast", 8859, 0 }, - { "ocir", 8858, 0 }, - { "ocirc", 244, 0 }, /* latin small letter o with circumflex, U+00F4 ISOlat1 */ - { "ocy", 1086, 0 }, - { "odash", 8861, 0 }, - { "odblac", 337, 0 }, - { "odiv", 10808, 0 }, - { "odot", 8857, 0 }, - { "odsold", 10684, 0 }, - { "oelig", 339, 0 }, /* latin small ligature oe, U+0153 ISOlat2 */ - { "ofcir", 10687, 0 }, - { "ofr", 120108, 0 }, - { "ogon", 731, 0 }, - { "ograve", 242, 0 }, /* latin small letter o with grave, U+00F2 ISOlat1 */ - { "ogt", 10689, 0 }, - { "ohbar", 10677, 0 }, - { "ohm", 937, 0 }, - { "oint", 8750, 0 }, - { "olarr", 8634, 0 }, - { "olcir", 10686, 0 }, - { "olcross", 10683, 0 }, - { "oline", 8254, 0 }, /* overline = spacing overscore, U+203E NEW */ - { "olt", 10688, 0 }, - { "omacr", 333, 0 }, - { "omega", 969, 0 }, /* greek small letter omega, U+03C9 ISOgrk3 */ - { "omicron", 959, 0 }, /* greek small letter omicron, U+03BF NEW */ - { "omid", 10678, 0 }, - { "ominus", 8854, 0 }, - { "oopf", 120160, 0 }, - { "opar", 10679, 0 }, - { "operp", 10681, 0 }, - { "oplus", 8853, 0 }, /* circled plus = direct sum, U+2295 ISOamsb */ - { "or", 8744, 0 }, /* logical or = vee, U+2228 ISOtech */ - { "orarr", 8635, 0 }, - { "ord", 10845, 0 }, - { "order", 8500, 0 }, - { "orderof", 8500, 0 }, - { "ordf", 170, 0 }, /* feminine ordinal indicator, U+00AA ISOnum */ - { "ordm", 186, 0 }, /* masculine ordinal indicator, U+00BA ISOnum */ - { "origof", 8886, 0 }, - { "oror", 10838, 0 }, - { "orslope", 10839, 0 }, - { "orv", 10843, 0 }, - { "oscr", 8500, 0 }, - { "oslash", 248, 0 }, /* latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1 */ - { "osol", 8856, 0 }, - { "otilde", 245, 0 }, /* latin small letter o with tilde, U+00F5 ISOlat1 */ - { "otimes", 8855, 0 }, /* circled times = vector product, U+2297 ISOamsb */ - { "otimesas", 10806, 0 }, - { "ouml", 246, 0 }, /* latin small letter o with diaeresis, U+00F6 ISOlat1 */ - { "ovbar", 9021, 0 }, - { "par", 8741, 0 }, - { "para", 182, 0 }, /* pilcrow sign = paragraph sign, U+00B6 ISOnum */ - { "parallel", 8741, 0 }, - { "parsim", 10995, 0 }, - { "parsl", 11005, 0 }, - { "part", 8706, 0 }, /* partial differential, U+2202 ISOtech */ - { "pcy", 1087, 0 }, - { "percnt", 37, 0 }, - { "period", 46, 0 }, - { "permil", 8240, 0 }, /* per mille sign, U+2030 ISOtech */ - { "perp", 8869, 0 }, /* up tack = orthogonal to = perpendicular, U+22A5 ISOtech */ - { "pertenk", 8241, 0 }, - { "pfr", 120109, 0 }, - { "phi", 966, 0 }, /* greek small letter phi, U+03C6 ISOgrk3 */ - { "phiv", 981, 0 }, - { "phmmat", 8499, 0 }, - { "phone", 9742, 0 }, - { "pi", 960, 0 }, /* greek small letter pi, U+03C0 ISOgrk3 */ - { "pitchfork", 8916, 0 }, - { "piv", 982, 0 }, /* greek pi symbol, U+03D6 ISOgrk3 */ - { "planck", 8463, 0 }, - { "planckh", 8462, 0 }, - { "plankv", 8463, 0 }, - { "plus", 43, 0 }, - { "plusacir", 10787, 0 }, - { "plusb", 8862, 0 }, - { "pluscir", 10786, 0 }, - { "plusdo", 8724, 0 }, - { "plusdu", 10789, 0 }, - { "pluse", 10866, 0 }, - { "plusmn", 177, 0 }, /* plus-minus sign = plus-or-minus sign, U+00B1 ISOnum */ - { "plussim", 10790, 0 }, - { "plustwo", 10791, 0 }, - { "pm", 177, 0 }, - { "pointint", 10773, 0 }, - { "popf", 120161, 0 }, - { "pound", 163, 0 }, /* pound sign, U+00A3 ISOnum */ - { "pr", 8826, 0 }, - { "prE", 10931, 0 }, - { "prap", 10935, 0 }, - { "prcue", 8828, 0 }, - { "pre", 10927, 0 }, - { "prec", 8826, 0 }, - { "precapprox", 10935, 0 }, - { "preccurlyeq", 8828, 0 }, - { "preceq", 10927, 0 }, - { "precnapprox", 10937, 0 }, - { "precneqq", 10933, 0 }, - { "precnsim", 8936, 0 }, - { "precsim", 8830, 0 }, - { "prime", 8242, 0 }, /* prime = minutes = feet, U+2032 ISOtech */ - { "primes", 8473, 0 }, - { "prnE", 10933, 0 }, - { "prnap", 10937, 0 }, - { "prnsim", 8936, 0 }, - { "prod", 8719, 0 }, /* n-ary product = product sign, U+220F ISOamsb */ - { "profalar", 9006, 0 }, - { "profline", 8978, 0 }, - { "profsurf", 8979, 0 }, - { "prop", 8733, 0 }, /* proportional to, U+221D ISOtech */ - { "propto", 8733, 0 }, - { "prsim", 8830, 0 }, - { "prurel", 8880, 0 }, - { "pscr", 120005, 0 }, - { "psi", 968, 0 }, /* greek small letter psi, U+03C8 ISOgrk3 */ - { "puncsp", 8200, 0 }, - { "qfr", 120110, 0 }, - { "qint", 10764, 0 }, - { "qopf", 120162, 0 }, - { "qprime", 8279, 0 }, - { "qscr", 120006, 0 }, - { "quaternions", 8461, 0 }, - { "quatint", 10774, 0 }, - { "quest", 63, 0 }, - { "questeq", 8799, 0 }, - { "quot", 34, 0 }, /* quotation mark = APL quote, U+0022 ISOnum */ - { "rAarr", 8667, 0 }, - { "rArr", 8658, 0 }, /* rightwards double arrow, U+21D2 ISOtech */ - { "rAtail", 10524, 0 }, - { "rBarr", 10511, 0 }, - { "rHar", 10596, 0 }, - { "race", 8765, 817 }, - { "racute", 341, 0 }, - { "radic", 8730, 0 }, /* square root = radical sign, U+221A ISOtech */ - { "raemptyv", 10675, 0 }, - { "rang", 9002, 0 }, /* right-pointing angle bracket = ket, U+232A ISOtech */ - { "rangd", 10642, 0 }, - { "range", 10661, 0 }, - { "rangle", 10217, 0 }, /* U+27E9⟩ */ - { "raquo", 187, 0 }, /* right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum */ - { "rarr", 8594, 0 }, /* rightwards arrow, U+2192 ISOnum */ - { "rarrap", 10613, 0 }, - { "rarrb", 8677, 0 }, - { "rarrbfs", 10528, 0 }, - { "rarrc", 10547, 0 }, - { "rarrfs", 10526, 0 }, - { "rarrhk", 8618, 0 }, - { "rarrlp", 8620, 0 }, - { "rarrpl", 10565, 0 }, - { "rarrsim", 10612, 0 }, - { "rarrtl", 8611, 0 }, - { "rarrw", 8605, 0 }, - { "ratail", 10522, 0 }, - { "ratio", 8758, 0 }, - { "rationals", 8474, 0 }, - { "rbarr", 10509, 0 }, - { "rbbrk", 10099, 0 }, - { "rbrace", 125, 0 }, - { "rbrack", 93, 0 }, - { "rbrke", 10636, 0 }, - { "rbrksld", 10638, 0 }, - { "rbrkslu", 10640, 0 }, - { "rcaron", 345, 0 }, - { "rcedil", 343, 0 }, - { "rceil", 8969, 0 }, /* right ceiling, U+2309 ISOamsc */ - { "rcub", 125, 0 }, - { "rcy", 1088, 0 }, - { "rdca", 10551, 0 }, - { "rdldhar", 10601, 0 }, - { "rdquo", 8221, 0 }, /* right double quotation mark, U+201D ISOnum */ - { "rdquor", 8221, 0 }, - { "rdsh", 8627, 0 }, - { "real", 8476, 0 }, /* blackletter capital R = real part symbol, U+211C ISOamso */ - { "realine", 8475, 0 }, - { "realpart", 8476, 0 }, - { "reals", 8477, 0 }, - { "rect", 9645, 0 }, - { "reg", 174, 0 }, /* registered sign = registered trade mark sign, U+00AE ISOnum */ - { "rfisht", 10621, 0 }, - { "rfloor", 8971, 0 }, /* right floor, U+230B ISOamsc */ - { "rfr", 120111, 0 }, - { "rhard", 8641, 0 }, - { "rharu", 8640, 0 }, - { "rharul", 10604, 0 }, - { "rho", 961, 0 }, /* greek small letter rho, U+03C1 ISOgrk3 */ - { "rhov", 1009, 0 }, - { "rightarrow", 8594, 0 }, - { "rightarrowtail", 8611, 0 }, - { "rightharpoondown", 8641, 0 }, - { "rightharpoonup", 8640, 0 }, - { "rightleftarrows", 8644, 0 }, - { "rightleftharpoons", 8652, 0 }, - { "rightrightarrows", 8649, 0 }, - { "rightsquigarrow", 8605, 0 }, - { "rightthreetimes", 8908, 0 }, - { "ring", 730, 0 }, - { "risingdotseq", 8787, 0 }, - { "rlarr", 8644, 0 }, - { "rlhar", 8652, 0 }, - { "rlm", 8207, 0 }, /* right-to-left mark, U+200F NEW RFC 2070 */ - { "rmoust", 9137, 0 }, - { "rmoustache", 9137, 0 }, - { "rnmid", 10990, 0 }, - { "roang", 10221, 0 }, - { "roarr", 8702, 0 }, - { "robrk", 10215, 0 }, - { "ropar", 10630, 0 }, - { "ropf", 120163, 0 }, - { "roplus", 10798, 0 }, - { "rotimes", 10805, 0 }, - { "rpar", 41, 0 }, - { "rpargt", 10644, 0 }, - { "rppolint", 10770, 0 }, - { "rrarr", 8649, 0 }, - { "rsaquo", 8250, 0 }, /* single right-pointing angle quotation mark, U+203A ISO proposed */ - { "rscr", 120007, 0 }, - { "rsh", 8625, 0 }, - { "rsqb", 93, 0 }, - { "rsquo", 8217, 0 }, /* right single quotation mark, U+2019 ISOnum */ - { "rsquor", 8217, 0 }, - { "rthree", 8908, 0 }, - { "rtimes", 8906, 0 }, - { "rtri", 9657, 0 }, - { "rtrie", 8885, 0 }, - { "rtrif", 9656, 0 }, - { "rtriltri", 10702, 0 }, - { "ruluhar", 10600, 0 }, - { "rx", 8478, 0 }, - { "sacute", 347, 0 }, - { "sbquo", 8218, 0 }, /* single low-9 quotation mark, U+201A NEW */ - { "sc", 8827, 0 }, - { "scE", 10932, 0 }, - { "scap", 10936, 0 }, - { "scaron", 353, 0 }, /* latin small letter s with caron, U+0161 ISOlat2 */ - { "sccue", 8829, 0 }, - { "sce", 10928, 0 }, - { "scedil", 351, 0 }, - { "scirc", 349, 0 }, - { "scnE", 10934, 0 }, - { "scnap", 10938, 0 }, - { "scnsim", 8937, 0 }, - { "scpolint", 10771, 0 }, - { "scsim", 8831, 0 }, - { "scy", 1089, 0 }, - { "sdot", 8901, 0 }, /* dot operator, U+22C5 ISOamsb */ - { "sdotb", 8865, 0 }, - { "sdote", 10854, 0 }, - { "seArr", 8664, 0 }, - { "searhk", 10533, 0 }, - { "searr", 8600, 0 }, - { "searrow", 8600, 0 }, - { "sect", 167, 0 }, /* section sign, U+00A7 ISOnum */ - { "semi", 59, 0 }, - { "seswar", 10537, 0 }, - { "setminus", 8726, 0 }, - { "setmn", 8726, 0 }, - { "sext", 10038, 0 }, - { "sfr", 120112, 0 }, - { "sfrown", 8994, 0 }, - { "sharp", 9839, 0 }, - { "shchcy", 1097, 0 }, - { "shcy", 1096, 0 }, - { "shortmid", 8739, 0 }, - { "shortparallel", 8741, 0 }, - { "shy", 173, 0 }, /* soft hyphen = discretionary hyphen, U+00AD ISOnum */ - { "sigma", 963, 0 }, /* greek small letter sigma, U+03C3 ISOgrk3 */ - { "sigmaf", 962, 0 }, /* greek small letter final sigma, U+03C2 ISOgrk3 */ - { "sigmav", 962, 0 }, - { "sim", 8764, 0 }, /* tilde operator = varies with = similar to, U+223C ISOtech */ - { "simdot", 10858, 0 }, - { "sime", 8771, 0 }, - { "simeq", 8771, 0 }, - { "simg", 10910, 0 }, - { "simgE", 10912, 0 }, - { "siml", 10909, 0 }, - { "simlE", 10911, 0 }, - { "simne", 8774, 0 }, - { "simplus", 10788, 0 }, - { "simrarr", 10610, 0 }, - { "slarr", 8592, 0 }, - { "smallsetminus", 8726, 0 }, - { "smashp", 10803, 0 }, - { "smeparsl", 10724, 0 }, - { "smid", 8739, 0 }, - { "smile", 8995, 0 }, - { "smt", 10922, 0 }, - { "smte", 10924, 0 }, - { "smtes", 10924, 65024 }, - { "softcy", 1100, 0 }, - { "sol", 47, 0 }, - { "solb", 10692, 0 }, - { "solbar", 9023, 0 }, - { "sopf", 120164, 0 }, - { "spades", 9824, 0 }, /* black spade suit, U+2660 ISOpub */ - { "spadesuit", 9824, 0 }, - { "spar", 8741, 0 }, - { "sqcap", 8851, 0 }, - { "sqcaps", 8851, 65024 }, - { "sqcup", 8852, 0 }, - { "sqcups", 8852, 65024 }, - { "sqsub", 8847, 0 }, - { "sqsube", 8849, 0 }, - { "sqsubset", 8847, 0 }, - { "sqsubseteq", 8849, 0 }, - { "sqsup", 8848, 0 }, - { "sqsupe", 8850, 0 }, - { "sqsupset", 8848, 0 }, - { "sqsupseteq", 8850, 0 }, - { "squ", 9633, 0 }, - { "square", 9633, 0 }, - { "squarf", 9642, 0 }, - { "squf", 9642, 0 }, - { "srarr", 8594, 0 }, - { "sscr", 120008, 0 }, - { "ssetmn", 8726, 0 }, - { "ssmile", 8995, 0 }, - { "sstarf", 8902, 0 }, - { "star", 9734, 0 }, - { "starf", 9733, 0 }, - { "straightepsilon", 1013, 0 }, - { "straightphi", 981, 0 }, - { "strns", 175, 0 }, - { "sub", 8834, 0 }, /* subset of, U+2282 ISOtech */ - { "subE", 10949, 0 }, - { "subdot", 10941, 0 }, - { "sube", 8838, 0 }, /* subset of or equal to, U+2286 ISOtech */ - { "subedot", 10947, 0 }, - { "submult", 10945, 0 }, - { "subnE", 10955, 0 }, - { "subne", 8842, 0 }, - { "subplus", 10943, 0 }, - { "subrarr", 10617, 0 }, - { "subset", 8834, 0 }, - { "subseteq", 8838, 0 }, - { "subseteqq", 10949, 0 }, - { "subsetneq", 8842, 0 }, - { "subsetneqq", 10955, 0 }, - { "subsim", 10951, 0 }, - { "subsub", 10965, 0 }, - { "subsup", 10963, 0 }, - { "succ", 8827, 0 }, - { "succapprox", 10936, 0 }, - { "succcurlyeq", 8829, 0 }, - { "succeq", 10928, 0 }, - { "succnapprox", 10938, 0 }, - { "succneqq", 10934, 0 }, - { "succnsim", 8937, 0 }, - { "succsim", 8831, 0 }, - { "sum", 8721, 0 }, /* n-ary sumation, U+2211 ISOamsb */ - { "sung", 9834, 0 }, - { "sup", 8835, 0 }, /* superset of, U+2283 ISOtech */ - { "sup1", 185, 0 }, /* superscript one = superscript digit one, U+00B9 ISOnum */ - { "sup2", 178, 0 }, /* superscript two = superscript digit two = squared, U+00B2 ISOnum */ - { "sup3", 179, 0 }, /* superscript three = superscript digit three = cubed, U+00B3 ISOnum */ - { "supE", 10950, 0 }, - { "supdot", 10942, 0 }, - { "supdsub", 10968, 0 }, - { "supe", 8839, 0 }, /* superset of or equal to, U+2287 ISOtech */ - { "supedot", 10948, 0 }, - { "suphsol", 10185, 0 }, - { "suphsub", 10967, 0 }, - { "suplarr", 10619, 0 }, - { "supmult", 10946, 0 }, - { "supnE", 10956, 0 }, - { "supne", 8843, 0 }, - { "supplus", 10944, 0 }, - { "supset", 8835, 0 }, - { "supseteq", 8839, 0 }, - { "supseteqq", 10950, 0 }, - { "supsetneq", 8843, 0 }, - { "supsetneqq", 10956, 0 }, - { "supsim", 10952, 0 }, - { "supsub", 10964, 0 }, - { "supsup", 10966, 0 }, - { "swArr", 8665, 0 }, - { "swarhk", 10534, 0 }, - { "swarr", 8601, 0 }, - { "swarrow", 8601, 0 }, - { "swnwar", 10538, 0 }, - { "szlig", 223, 0 }, /* latin small letter sharp s = ess-zed, U+00DF ISOlat1 */ - { "target", 8982, 0 }, - { "tau", 964, 0 }, /* greek small letter tau, U+03C4 ISOgrk3 */ - { "tbrk", 9140, 0 }, - { "tcaron", 357, 0 }, - { "tcedil", 355, 0 }, - { "tcy", 1090, 0 }, - { "tdot", 8411, 0 }, - { "telrec", 8981, 0 }, - { "tfr", 120113, 0 }, - { "there4", 8756, 0 }, /* therefore, U+2234 ISOtech */ - { "therefore", 8756, 0 }, - { "theta", 952, 0 }, /* greek small letter theta, U+03B8 ISOgrk3 */ - { "thetasym", 977, 0 }, /* greek small letter theta symbol, U+03D1 NEW */ - { "thetav", 977, 0 }, - { "thickapprox", 8776, 0 }, - { "thicksim", 8764, 0 }, - { "thinsp", 8201, 0 }, /* thin space, U+2009 ISOpub */ - { "thkap", 8776, 0 }, - { "thksim", 8764, 0 }, - { "thorn", 254, 0 }, /* latin small letter thorn, U+00FE ISOlat1 */ - { "tilde", 732, 0 }, /* small tilde, U+02DC ISOdia */ - { "times", 215, 0 }, /* multiplication sign, U+00D7 ISOnum */ - { "timesb", 8864, 0 }, - { "timesbar", 10801, 0 }, - { "timesd", 10800, 0 }, - { "tint", 8749, 0 }, - { "toea", 10536, 0 }, - { "top", 8868, 0 }, - { "topbot", 9014, 0 }, - { "topcir", 10993, 0 }, - { "topf", 120165, 0 }, - { "topfork", 10970, 0 }, - { "tosa", 10537, 0 }, - { "tprime", 8244, 0 }, - { "trade", 8482, 0 }, /* trade mark sign, U+2122 ISOnum */ - { "triangle", 9653, 0 }, - { "triangledown", 9663, 0 }, - { "triangleleft", 9667, 0 }, - { "trianglelefteq", 8884, 0 }, - { "triangleq", 8796, 0 }, - { "triangleright", 9657, 0 }, - { "trianglerighteq", 8885, 0 }, - { "tridot", 9708, 0 }, - { "trie", 8796, 0 }, - { "triminus", 10810, 0 }, - { "triplus", 10809, 0 }, - { "trisb", 10701, 0 }, - { "tritime", 10811, 0 }, - { "trpezium", 9186, 0 }, - { "tscr", 120009, 0 }, - { "tscy", 1094, 0 }, - { "tshcy", 1115, 0 }, - { "tstrok", 359, 0 }, - { "twixt", 8812, 0 }, - { "twoheadleftarrow", 8606, 0 }, - { "twoheadrightarrow", 8608, 0 }, - { "uArr", 8657, 0 }, /* upwards double arrow, U+21D1 ISOamsa */ - { "uHar", 10595, 0 }, - { "uacute", 250, 0 }, /* latin small letter u with acute, U+00FA ISOlat1 */ - { "uarr", 8593, 0 }, /* upwards arrow, U+2191 ISOnum */ - { "ubrcy", 1118, 0 }, - { "ubreve", 365, 0 }, - { "ucirc", 251, 0 }, /* latin small letter u with circumflex, U+00FB ISOlat1 */ - { "ucy", 1091, 0 }, - { "udarr", 8645, 0 }, - { "udblac", 369, 0 }, - { "udhar", 10606, 0 }, - { "ufisht", 10622, 0 }, - { "ufr", 120114, 0 }, - { "ugrave", 249, 0 }, /* latin small letter u with grave, U+00F9 ISOlat1 */ - { "uharl", 8639, 0 }, - { "uharr", 8638, 0 }, - { "uhblk", 9600, 0 }, - { "ulcorn", 8988, 0 }, - { "ulcorner", 8988, 0 }, - { "ulcrop", 8975, 0 }, - { "ultri", 9720, 0 }, - { "umacr", 363, 0 }, - { "uml", 168, 0 }, /* diaeresis = spacing diaeresis, U+00A8 ISOdia */ - { "uogon", 371, 0 }, - { "uopf", 120166, 0 }, - { "uparrow", 8593, 0 }, - { "updownarrow", 8597, 0 }, - { "upharpoonleft", 8639, 0 }, - { "upharpoonright", 8638, 0 }, - { "uplus", 8846, 0 }, - { "upsi", 965, 0 }, - { "upsih", 978, 0 }, /* greek upsilon with hook symbol, U+03D2 NEW */ - { "upsilon", 965, 0 }, /* greek small letter upsilon, U+03C5 ISOgrk3 */ - { "upuparrows", 8648, 0 }, - { "urcorn", 8989, 0 }, - { "urcorner", 8989, 0 }, - { "urcrop", 8974, 0 }, - { "uring", 367, 0 }, - { "urtri", 9721, 0 }, - { "uscr", 120010, 0 }, - { "utdot", 8944, 0 }, - { "utilde", 361, 0 }, - { "utri", 9653, 0 }, - { "utrif", 9652, 0 }, - { "uuarr", 8648, 0 }, - { "uuml", 252, 0 }, /* latin small letter u with diaeresis, U+00FC ISOlat1 */ - { "uwangle", 10663, 0 }, - { "vArr", 8661, 0 }, - { "vBar", 10984, 0 }, - { "vBarv", 10985, 0 }, - { "vDash", 8872, 0 }, - { "vangrt", 10652, 0 }, - { "varepsilon", 1013, 0 }, - { "varkappa", 1008, 0 }, - { "varnothing", 8709, 0 }, - { "varphi", 981, 0 }, - { "varpi", 982, 0 }, - { "varpropto", 8733, 0 }, - { "varr", 8597, 0 }, - { "varrho", 1009, 0 }, - { "varsigma", 962, 0 }, - { "varsubsetneq", 8842, 65024 }, - { "varsubsetneqq", 10955, 65024 }, - { "varsupsetneq", 8843, 65024 }, - { "varsupsetneqq", 10956, 65024 }, - { "vartheta", 977, 0 }, - { "vartriangleleft", 8882, 0 }, - { "vartriangleright", 8883, 0 }, - { "vcy", 1074, 0 }, - { "vdash", 8866, 0 }, - { "vee", 8744, 0 }, - { "veebar", 8891, 0 }, - { "veeeq", 8794, 0 }, - { "vellip", 8942, 0 }, - { "verbar", 124, 0 }, - { "vert", 124, 0 }, - { "vfr", 120115, 0 }, - { "vltri", 8882, 0 }, - { "vnsub", 8834, 8402 }, - { "vnsup", 8835, 8402 }, - { "vopf", 120167, 0 }, - { "vprop", 8733, 0 }, - { "vrtri", 8883, 0 }, - { "vscr", 120011, 0 }, - { "vsubnE", 10955, 65024 }, - { "vsubne", 8842, 65024 }, - { "vsupnE", 10956, 65024 }, - { "vsupne", 8843, 65024 }, - { "vzigzag", 10650, 0 }, - { "wcirc", 373, 0 }, - { "wedbar", 10847, 0 }, - { "wedge", 8743, 0 }, - { "wedgeq", 8793, 0 }, - { "weierp", 8472, 0 }, /* script capital P = power set = Weierstrass p, U+2118 ISOamso */ - { "wfr", 120116, 0 }, - { "wopf", 120168, 0 }, - { "wp", 8472, 0 }, - { "wr", 8768, 0 }, - { "wreath", 8768, 0 }, - { "wscr", 120012, 0 }, - { "xcap", 8898, 0 }, - { "xcirc", 9711, 0 }, - { "xcup", 8899, 0 }, - { "xdtri", 9661, 0 }, - { "xfr", 120117, 0 }, - { "xhArr", 10234, 0 }, - { "xharr", 10231, 0 }, - { "xi", 958, 0 }, /* greek small letter xi, U+03BE ISOgrk3 */ - { "xlArr", 10232, 0 }, - { "xlarr", 10229, 0 }, - { "xmap", 10236, 0 }, - { "xnis", 8955, 0 }, - { "xodot", 10752, 0 }, - { "xopf", 120169, 0 }, - { "xoplus", 10753, 0 }, - { "xotime", 10754, 0 }, - { "xrArr", 10233, 0 }, - { "xrarr", 10230, 0 }, - { "xscr", 120013, 0 }, - { "xsqcup", 10758, 0 }, - { "xuplus", 10756, 0 }, - { "xutri", 9651, 0 }, - { "xvee", 8897, 0 }, - { "xwedge", 8896, 0 }, - { "yacute", 253, 0 }, /* latin small letter y with acute, U+00FD ISOlat1 */ - { "yacy", 1103, 0 }, - { "ycirc", 375, 0 }, - { "ycy", 1099, 0 }, - { "yen", 165, 0 }, /* yen sign = yuan sign, U+00A5 ISOnum */ - { "yfr", 120118, 0 }, - { "yicy", 1111, 0 }, - { "yopf", 120170, 0 }, - { "yscr", 120014, 0 }, - { "yucy", 1102, 0 }, - { "yuml", 255, 0 }, /* latin small letter y with diaeresis, U+00FF ISOlat1 */ - { "zacute", 378, 0 }, - { "zcaron", 382, 0 }, - { "zcy", 1079, 0 }, - { "zdot", 380, 0 }, - { "zeetrf", 8488, 0 }, - { "zeta", 950, 0 }, /* greek small letter zeta, U+03B6 ISOgrk3 */ - { "zfr", 120119, 0 }, - { "zhcy", 1078, 0 }, - { "zigrarr", 8669, 0 }, - { "zopf", 120171, 0 }, - { "zscr", 120015, 0 }, - { "zwj", 8205, 0 }, /* zero width joiner, U+200D NEW RFC 2070 */ - { "zwnj", 8204, 0 } }; /* zero width non-joiner, U+200C NEW RFC 2070 */ - -static int compareEntities(const void * a, const void * b) - { - return strcmp(((Entity*)a)->ent,((Entity*)b)->ent); - } - -static int HTvar = 0; -static int Xvar = 0; -static int charref(const unsigned char * c) - { - if(*c == ';') - { - *glob_p = '\0'; - if( !strcmp((const char *)bufx,"amp") - || !strcmp((const char*)bufx,"#38") - || !strcmp((const char*)bufx,"#x26") - ) - rawput('&'); - else if(!strcmp((const char*)bufx,"apos")) - rawput('\''); - else if(!strcmp((const char*)bufx,"quot")) - { - rawput('\"'); - } - else if(!strcmp((const char*)bufx,"lt")) - rawput('<'); - else if(!strcmp((const char*)bufx,"gt")) - rawput('>'); - else if(bufx[0] == '#') - { - unsigned long N; - unsigned char tmp[22]; - N = (bufx[1] == 'x') ? strtoul((const char*)(bufx+2),NULL,16) : strtoul((const char*)(bufx+1),NULL,10); - glob_p = bufx; - xput = Put; - if(putCodePoint(N,tmp)) - { - return nrawput(tmp); - } - else - return 0; - } - else - { - if(HTvar) - { - Entity * pItem; - Entity key; - key.ent = (const char*)bufx; - pItem = (Entity*)bsearch( &key - , entities - , sizeof(entities)/sizeof(entities[0]) - , sizeof(entities[0]) - , compareEntities - ); - if (pItem!=NULL) - { - unsigned char tmp[100]; - unsigned char * endp; - glob_p = bufx; - xput = Put; - endp = putCodePoint(pItem->code, tmp); - if(endp) - { - if (pItem->morecode) - { - endp = putCodePoint(pItem->morecode, endp); - if (endp) - return nrawput(tmp); - } - else - return nrawput(tmp); - } - } - } - rawput(127); /* Escape with DEL */ - rawput('&'); - nrawput(bufx); - rawput(';'); - glob_p = bufx; - xput = Put; - return FALSE; - } - glob_p = bufx; - xput = Put; - } - else if(!namechar(*c)) - { - rawput('&'); - *glob_p = '\0'; - nrawput(bufx); - if(*c > 0) - rawput(*c); - glob_p = bufx; - xput = Put; - return FALSE; - } - else if(glob_p < bufx+BUFSIZE-1) - { - *glob_p++ = *c; - } - return TRUE; - } - -static int Put(const unsigned char * c) - { - if(*c == '&') - { - xput = charref; - namechar = entity; - return TRUE; - } - else if(*c == 127) /* DEL, used as escape character for & before unrecognised entity reference */ - rawput(*c); /* double the escape character */ - if(*c & 0x80) - { - /* Since entities always are converted to UTF-8 encoded characters, we have to do the same - with ALL characters. */ - unsigned char tmp[8]; - if(assumeUTF8) - { - static ptrdiff_t safebytes = 0; /* Number of future bytes that can be safely regarded as part of UTF-8 char. */ - if(*c & 0x40) /* first byte of multibyte char */ - { - const char* d = (const char*)c; - int R = getCodePoint(&d); /* look ahead. Is it UTF-8 encoded ? */ - if(R >= 0) - { - safebytes = (d - (const char*)c) - 1; - return rawput(*c); - } - else - assumeUTF8 = FALSE; - } - else if(safebytes > 0) - { - --safebytes; - return rawput(*c); /* second or later byte of multubyte char */ - } - else - assumeUTF8 = FALSE; - } - if(putCodePoint(*c, tmp)) - return nrawput(tmp); - else - return 0; - } - return rawput(*c); - } - -static void flushx(void) - { - if(xput != Put) - xput((const unsigned char*)""); - } - -static void nxput(unsigned char * start,unsigned char *end) - { - for(;start < end;++start) - xput(start); - flushx(); - } - -static void nxputWithoutEntityUnfolding(unsigned char * start,unsigned char *end) - { - for(;start < end;++start) - rawput(*start); - } - -static void nonTagWithoutEntityUnfolding(const char * kind,unsigned char * start,unsigned char * end) - { - nrawput((const unsigned char*)kind); - putOperatorChar('.'); - nxputWithoutEntityUnfolding(start,end); - putOperatorChar(')'); - } - -static void nonTag(const char * kind,unsigned char * start,unsigned char * end) - { - nrawput((const unsigned char*)kind); - putOperatorChar('.'); - nxput(start,end); - putOperatorChar(')'); - } - -static unsigned char * ch; -static unsigned char * StaRt = 0; -static int isMarkup = 0; - -static void cbStartMarkUp(void) - { - flushx(); - StaRt = ch+2; - isMarkup = 1; - putOperatorChar(' '); - putOperatorChar('('); - } - -static void cbEndMarkUp(void)/* called when > has been read */ - { - if(isMarkup) - nonTag("!",StaRt,ch); - } - -static void cbEndDOCTYPE(void)/* called when > has been read */ - { - isMarkup = 0; - nonTagWithoutEntityUnfolding("!DOCTYPE",StaRt,ch); - } - -static unsigned char * endElementName; -static void cbEndElementName(void) - { - nxput(StaRt,endElementName ? endElementName : ch); - putOperatorChar('.'); - endElementName = NULL; - } - -static void cbEndAttributeName(void) - { - nxput(StaRt,ch); - putOperatorChar('.'); - } - -static void cbEndAttribute(void) - { - putOperatorChar(')'); - putOperatorChar(' '); - } - -static estate def_pcdata(const unsigned char * pkar); -static estate (*defx)(const unsigned char * pkar) = def_pcdata; -static estate def_cdata(const unsigned char * pkar); -static estate lt(const unsigned char * pkar); -static estate lt_cdata(const unsigned char * pkar); -static estate lts_cdata(const unsigned char * pkar); -static estate element(const unsigned char * pkar); -static estate elementonly(const unsigned char * pkar); -static estate gt(const unsigned char * pkar); -static estate emptytag(const unsigned char * pkar); -static estate atts(const unsigned char * pkar); -static estate namex(const unsigned char * pkar); -static estate valuex(const unsigned char * pkar); -static estate atts_or_value(const unsigned char * pkar); -static estate invalue(const unsigned char * pkar); -static estate singlequotes(const unsigned char * pkar); -static estate doublequotes(const unsigned char * pkar); -static estate insinglequotedvalue(const unsigned char * pkar); -static estate indoublequotedvalue(const unsigned char * pkar); -static estate endvalue(const unsigned char * pkar); -static estate markup(const unsigned char * pkar); /* (XML) or (non-XML) */ -static estate endPI(const unsigned char * pkar); -static estate DOCTYPE1(const unsigned char * pkar); /* ': - tagState = defx; - return notag; - case '!': - tagState = markup; - return tag; - case '?': - StaRt = ch; - tagState = PrInstr; - return tag; - case '/': - tagState = endtag; - /* fall through */ - return tag; - case 's': - case 'S': - if(HTvar && !Xvar) - { - tagState = perhapsScriptOrStyle; - StaRt = ch; - return tag; - } - /* fall through */ - default: - if(':' == kar || ('A' <= kar && kar <= 'Z') || '_' == kar || ('a' <= kar && kar <= 'z') || (kar & 0x80)) - { - tagState = element; - StaRt = ch; - return tag; - } - else - { - tagState = defx; - return notag; - } - } - } - -static estate lt_cdata(const unsigned char * pkar) - { - switch(*pkar) - { - case '/': - tagState = lts_cdata; - return tag; - default: - tagState = def_cdata; - return notag; - } - } - -static int ScriptStyleiMax = 0; -static int scriptstylei = 0; -static int scriptstylei2 = 0; -static int scriptstyleimax = 0; -static unsigned char * elementEndNameLower; -static unsigned char * elementEndNameUpper; -static estate scriptOrStyleEndElement(const unsigned char * pkar) /* ': - flushx(); - isMarkup = 1; - putOperatorChar(' '); - putOperatorChar('('); - putOperatorChar('.'); - cbEndElementName(); - putOperatorChar(')'); - defx = def_pcdata; - tagState = defx; - StaRt = ch+1; - return endoftag; - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - if(endElementName == NULL) - endElementName = ch; - return tag; - default: - endElementName = NULL; - scriptstylei2 = 0; - tagState = def_cdata; - return notag; - } - } - -static estate lts_cdata(const unsigned char * pkar) - { - const int kar = *pkar; - scriptstyleimax = ScriptStyleiMax; - scriptstylei2 = 0; - if( kar == elementEndNameLower[scriptstylei2] - || kar == elementEndNameUpper[scriptstylei2] - ) - { - StaRt = ch; - ++scriptstylei2; - tagState = scriptOrStyleEndElement; - return tag; - } - tagState = def_cdata; - return notag; - } - -static void stillCdata(void) - { - if(scriptstylei > 0 && defx == def_cdata) - { - defx = def_pcdata; - scriptstylei = 0; - } - } - -static estate element(const unsigned char * pkar) - { - const int kar = *pkar; - switch(kar) - { - case '<': - tagState = lt; - cbEndElementName(); - putOperatorChar(')'); - cbStartMarkUp(); - return endoftag_startoftag; - case '>': - tagState = defx; - cbEndElementName(); - putOperatorChar(')'); - return endoftag; - case '-': - case '_': - case ':': - case '.': - stillCdata(); - return tag; - case 0xA0: - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - cbEndElementName(); - tagState = atts; - return tag; - case '/': - cbEndElementName(); - putOperatorChar(','); - putOperatorChar(')'); - tagState = emptytag; - return tag; - default: - if(('0' <= kar && kar <= '9') || ('A' <= kar && kar <= 'Z') || ('a' <= kar && kar <= 'z') || (kar & 0x80)) - { - stillCdata(); - return tag; - } - else - { - stillCdata(); - tagState = defx; - return notag; - } - } - } - -static estate elementonly(const unsigned char * pkar) - { - const int kar = *pkar; - switch(kar) - { - case '<': - tagState = lt; - putOperatorChar('.'); - cbEndElementName(); - putOperatorChar(')'); - cbStartMarkUp(); - return endoftag_startoftag; - case '>': - tagState = defx; - putOperatorChar('.'); - cbEndElementName(); - putOperatorChar(')'); - return endoftag; - case '-': - case '_': - case ':': - case '.': - return tag; - case 0xA0: - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - if(endElementName == NULL) - endElementName = ch; - tagState = gt; - return tag; - default: - if(('0' <= kar && kar <= '9') || ('A' <= kar && kar <= 'Z') || ('a' <= kar && kar <= 'z') || (kar & 0x80)) - return tag; - else - { - tagState = defx; - return notag; - } - } - } - -static estate gt(const unsigned char * pkar) - { - switch(*pkar) - { - case '<': - tagState = lt; - putOperatorChar('.'); - cbEndElementName(); - putOperatorChar(')'); - cbStartMarkUp(); - return endoftag_startoftag; - case '>': - tagState = defx; - putOperatorChar('.'); - cbEndElementName(); - putOperatorChar(')'); - return endoftag; - case 0xA0: - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - return tag; - default: - tagState = defx; - return notag; - } - } - -static estate emptytag(const unsigned char * pkar) - { - switch(*pkar) - { - case '<': - tagState = lt; - cbStartMarkUp(); - return endoftag_startoftag; - case '>': - tagState = defx; - return endoftag; - default: - tagState = defx; - return notag; - } - } - -static estate atts(const unsigned char * pkar) - { - const int kar = *pkar; - switch(kar) - { - case '<': - tagState = lt; - putOperatorChar(')'); - cbStartMarkUp(); - return endoftag_startoftag; - case '>': - tagState = defx; - putOperatorChar(')'); - return endoftag; - case 0xA0: - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - return tag; - case '/': - putOperatorChar(','); - putOperatorChar(')'); - tagState = emptytag; - return tag; - default: - if(':' == kar || ('A' <= kar && kar <= 'Z') || '_' == kar || ('a' <= kar && kar <= 'z') || (kar & 0x80)) - { - putOperatorChar('('); - StaRt = ch; - tagState = namex; - return tag; - } - else - { - tagState = defx; - return notag; - } - } - } - -static estate namex(const unsigned char * pkar) - { - const int kar = *pkar; - switch(kar) - { - case '<': - tagState = lt; - cbEndAttributeName(); - cbEndAttribute(); - putOperatorChar(')'); - cbStartMarkUp(); - return endoftag_startoftag; - case '>': - tagState = defx; - cbEndAttributeName(); - cbEndAttribute(); - putOperatorChar(')'); - return endoftag; - case '-': - case '_': - case ':': - case '.': - return tag; - case 0xA0: - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - cbEndAttributeName(); - tagState = atts_or_value; - return tag; - case '/': - cbEndAttributeName(); - cbEndAttribute(); - putOperatorChar(','); - putOperatorChar(')'); - tagState = emptytag; - return tag; - case '=': - cbEndAttributeName(); - tagState = valuex; - return tag; - default: - if(('0' <= kar && kar <= '9') || ('A' <= kar && kar <= 'Z') || ('a' <= kar && kar <= 'z') || (kar & 0x80)) - return tag; - else - { - tagState = defx; - return notag; - } - } - } - -static estate valuex(const unsigned char * pkar) - { - switch(*pkar) - { - case '>': - case '/': - case '=': - tagState = defx; - return notag; - case 0xA0: - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - return tag; - case '\'': - tagState = singlequotes; - return tag; - case '"': - tagState = doublequotes; - return tag; - default: - StaRt = ch; - tagState = invalue; - return tag; - } - } - -static estate atts_or_value(const unsigned char * pkar) - { - const int kar = *pkar; - switch(kar) - { - case '<': - tagState = lt; - cbEndAttribute(); - putOperatorChar(')'); - cbStartMarkUp(); - return endoftag_startoftag; - case '>': - tagState = defx; - cbEndAttribute(); - putOperatorChar(')'); - return endoftag; - case '-': - /*case '_': - case ':':*/ - case '.': - tagState = defx; - return notag; - case 0xA0: - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - return tag; - case '/': - cbEndAttribute(); - putOperatorChar(','); - putOperatorChar(')'); - tagState = emptytag; - return tag; - case '=': - tagState = valuex; - return tag; - default: - if(':' == kar || ('A' <= kar && kar <= 'Z') || '_' == kar || ('a' <= kar && kar <= 'z') || (kar & 0x80)) - { - cbEndAttribute(); - putOperatorChar('('); - StaRt = ch; - tagState = namex; - return tag; - } - else - { - tagState = defx; - return notag; - } - } - } - -/* This is far from conforming to and more forgiving than -https://html.spec.whatwg.org/multipage/syntax.html#unquoted -*/ -static estate invalue(const unsigned char * pkar) - { - switch(*pkar) - { - case '<': - tagState = lt; - nxput(StaRt,ch); - cbEndAttribute(); - putOperatorChar(')'); - cbStartMarkUp(); - return endoftag_startoftag; - case '>': - tagState = defx; - nxput(StaRt,ch); - cbEndAttribute(); - putOperatorChar(')'); - return endoftag; - case 0xA0: - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - nxput(StaRt,ch); - cbEndAttribute(); - tagState = atts; - return tag; - /* Unsafe to end valuex at first / - See fx get$("",HT ML MEM) - */ - case '/': - if (*(pkar + 1) == '>') - { - nxput(StaRt, ch); - cbEndAttribute(); - putOperatorChar(','); - putOperatorChar(')'); - tagState = emptytag; - return tag; - } - /* fall through */ - default: - return tag; - } - } - -static estate singlequotes(const unsigned char * pkar) - { - StaRt = ch; - switch(*pkar) - { - case '\'': - nxput(StaRt,ch); - cbEndAttribute(); - tagState = endvalue; - return tag; - default: - tagState = insinglequotedvalue; - return tag; - } - } - -static estate doublequotes(const unsigned char * pkar) - { - StaRt = ch; - switch(*pkar) - { - case '\"': - nxput(StaRt,ch); - cbEndAttribute(); - tagState = endvalue; - return tag; - default: - tagState = indoublequotedvalue; - return tag; - } - } - -static estate insinglequotedvalue(const unsigned char * pkar) - { - switch(*pkar) - { - case '\'': - nxput(StaRt,ch); - cbEndAttribute(); - tagState = endvalue; - return tag; - default: - return tag; - } - } - -static estate indoublequotedvalue(const unsigned char * pkar) - { - switch(*pkar) - { - case '\"': - nxput(StaRt,ch); - cbEndAttribute(); - tagState = endvalue; - return tag; - default: - return tag; - } - } - -static estate endvalue(const unsigned char * pkar) - { - switch(*pkar) - { - case '<': - tagState = lt; - putOperatorChar(')'); - cbStartMarkUp(); - return endoftag_startoftag; - case '>': - tagState = defx; - putOperatorChar(')'); - return endoftag; - case 0xA0: - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - tagState = atts; - return tag; - case '/': - putOperatorChar(','); - putOperatorChar(')'); - tagState = emptytag; - return tag; - default: - tagState = defx; - return notag; - } - } - -static unsigned char * elementNameLower; -static unsigned char * elementNameUpper; -static estate scriptOrStyleElement(const unsigned char * pkar) /* ': - tagState = defx; - cbEndMarkUp(); - return endoftag; - case '-': - tagState = h1; - return tag; - case '[': - tagState = CDATA1; - return tag; - case 'D': - tagState = DOCTYPE1; - return tag; - default: - tagState = unknownmarkup; - return tag; - } - } - -static estate unknownmarkup(const unsigned char * pkar) /* ': - tagState = defx; - cbEndMarkUp(); - return endoftag; - default: - return tag; - } - } - -static estate PrInstr(const unsigned char * pkar) - { - if(Xvar) - switch(*pkar) - { - case '?': - tagState = endPI; - return tag; - default: - return tag; - } - else - switch(*pkar) - { - case '>': - tagState = defx; - nonTagWithoutEntityUnfolding("?",StaRt+1,ch); - return endoftag; - default: - return tag; - } - } - -static estate endPI(const unsigned char * pkar) - { - switch(*pkar) - { - case '>': - tagState = defx; - nonTagWithoutEntityUnfolding("?",StaRt+1,ch-1); - return endoftag; - case '?': - return tag; - default: - tagState = PrInstr; - return tag; - } - } - -static int doctypei = 0; -static estate DOCTYPE1(const unsigned char * pkar) /* ': - tagState = defx; - doctypei = 0; - return endoftag; - default: - if(kar == octype[doctypei]) - { - if(doctypei == sizeof(octype) - 2) - { - tagState = DOCTYPE7; - } - else - ++doctypei; - return tag; - } - else - { - doctypei = 0; - tagState = unknownmarkup; - return tag; - } - } - } - -static estate DOCTYPE7(const unsigned char * pkar) /* ': - tagState = defx; - cbEndDOCTYPE(); - return endoftag; - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - StaRt = ch; - tagState = DOCTYPE8; - return tag; - default: - tagState = unknownmarkup; - return tag; - } - } - -static estate DOCTYPE8(const unsigned char * pkar) /* ': - tagState = defx; - cbEndDOCTYPE(); - return endoftag; - case '[': - tagState = DOCTYPE9; - return tag; - default: - return tag; - } - } - -static estate DOCTYPE9(const unsigned char * pkar) /* ': - tagState = defx; - cbEndDOCTYPE(); - return endoftag; - case ' ': - case '\f': - case '\n': - case '\r': - case '\t': - tagState = DOCTYPE10; - return tag; - default: - tagState = markup; - return tag; - } - } - -static int cdatai = 0; -static estate CDATA1(const unsigned char * pkar) /* ': - tagState = defx; - cdatai = 0; - return endoftag; - default: - if(cdata[cdatai] == kar) - { - if(cdatai == sizeof(cdata) - 2) - { - tagState = CDATA7; - StaRt = ch+1; - cdatai = 0; - } - else - ++cdatai; - return tag; - } - else - { - tagState = unknownmarkup; - cdatai = 0; - return tag; - } - } - } - -static estate CDATA7(const unsigned char * pkar) /* ': /* */ - tagState = defx; - isMarkup = 0; - nonTagWithoutEntityUnfolding("![CDATA[",StaRt,ch-2); - return endoftag; - default: - tagState = CDATA7; - return tag; - } - } - -static estate h1(const unsigned char * pkar) /* ': - tagState = defx; - return notag; - case '-': - tagState = h2; - StaRt = ch+1; - return tag; - default: - tagState = unknownmarkup; - return tag; - } - } - -static estate h2(const unsigned char * pkar) /* stack", getVarName(mem, (wordp->u.valp)), (*(wordp->u.valp)).floating); - (++sp)->val = *(wordp++->u.valp); - break; - } - case var2stack: - { - printf("%s %.2f --> stack", getVarName(mem, (wordp->u.valp)), (*(wordp->u.valp)).floating); - sp->val = *(wordp++->u.valp); - break; - } - case var2stackBranch: - { - printf("%s %.2f --> stack unconditional jump to %u", getVarName(mem, (wordp->u.valp)), (*(wordp->u.valp)).floating, wordp->offset); - sp->val = *(wordp->u.valp); - wordp = word + wordp->offset; - break; - } - case stack2var: - { - assert(sp >= mem->stack); - *(wordp->u.valp) = sp->val; - printf("%s %.2f <-- stack", getVarName(mem, wordp->u.valp), sp->val.floating); - ++wordp; - break; - } - case stack2varBranch: - { - assert(sp >= mem->stack); - printf("%s %.2f <-- stack unconditional jump to %u", getVarName(mem, (wordp->u.valp)), (*(wordp->u.valp)).floating, wordp->offset); - *(wordp->u.valp) = sp->val; - wordp = word + wordp->offset; - break; - } - case ArrElmValPush: - { - printf("%s %.2f --> stack", wordp->u.arrp->name, (wordp->u.arrp->pval)[wordp->u.arrp->index].floating); - (++sp)->val = (wordp->u.arrp->pval)[wordp->u.arrp->index]; - ++wordp; - break; - } - case stack2ArrElm: - { - assert(sp >= mem->stack); - (wordp->u.arrp->pval)[wordp->u.arrp->index] = sp->val; - printf("%s %.2f <-- stack", wordp->u.arrp->name, (wordp->u.arrp->pval)[wordp->u.arrp->index].floating); - ++wordp; - break; - } - case val2stack: - { - printf("%.2f %p ", wordp->u.val.floating, (void*)wordp->u.arrp); - sp->val = wordp++->u.val; - break; - } - case valPush: - { - printf("%.2f %p ", wordp->u.val.floating, (void*)wordp->u.arrp); - (++sp)->val = wordp++->u.val; - break; - } - case Afunction: - { - double ret = 0; - naam = wordp->u.that->name; - printf("%s\n", naam); - stackvalue* res = ftrc(sp, wordp, &ret); // May fail! - printf("%s DONE\n", naam); - if(!res) - return 0; - sp = res; - (++sp)->val.floating = ret; - ++wordp; - break; - } - case Pop: - { - naam = getLogiName(wordp->u.logic); - printf(" %s", naam); - printf(" conditional jump to %u", wordp->offset); - assert(sp >= mem->stack); - --sp; - ++wordp; - break; - } - case Branch: - printf("unconditional jump to %u", wordp->offset); - wordp = word + wordp->offset; - break; - case PopBranch: - { - naam = getLogiName(wordp->u.logic); - printf(" %s", naam); - printf(" unconditional jump to %u", wordp->offset); - assert(sp >= mem->stack); - --sp; - wordp = word + wordp->offset; - break; - } - case valPushBranch: - { - printf("%.2f %p ", wordp->u.val.floating, (void*)wordp->u.arrp); - printf(" unconditional jump to %u", wordp->offset); - (++sp)->val = wordp->u.val; - wordp = word + wordp->offset; - break; - } - case val2stackBranch: - { - printf("%.2f %p ", wordp->u.val.floating, (void*)wordp->u.arrp); - printf(" unconditional jump to %u", wordp->offset); - sp->val = wordp->u.val; - wordp = word + wordp->offset; - break; - } - case Fless: - printf("PopB < "); - b = ((sp--)->val).floating; if((sp->val).floating >= b) wordp = word + wordp->offset; else ++wordp; break; - case Fless_equal: - printf("PopB <="); - b = ((sp--)->val).floating; if((sp->val).floating > b) wordp = word + wordp->offset; else ++wordp; break; - case Fmore_equal: - printf("PopB >="); - b = ((sp--)->val).floating; if((sp->val).floating < b) wordp = word + wordp->offset; else ++wordp; break; - case Fmore: - printf("PopB > "); - b = ((sp--)->val).floating; if((sp->val).floating <= b) wordp = word + wordp->offset; else ++wordp; break; - case Funequal: - printf("PopB !="); - b = ((sp--)->val).floating; if((sp->val).floating == b) wordp = word + wordp->offset; else ++wordp; break; - case Fequal: - printf("PopB =="); - b = ((sp--)->val).floating; if((sp->val).floating != b) wordp = word + wordp->offset; else ++wordp; break; - case FlessP: - printf("PopPopB < "); - b = ((sp--)->val).floating; if(((sp--)->val).floating >= b) wordp = word + wordp->offset; else ++wordp; break; - case Fless_equalP: - printf("PopPopB <="); - b = ((sp--)->val).floating; if(((sp--)->val).floating > b) wordp = word + wordp->offset; else ++wordp; break; - case Fmore_equalP: - printf("PopPopB >="); - b = ((sp--)->val).floating; if(((sp--)->val).floating < b) wordp = word + wordp->offset; else ++wordp; break; - case FmoreP: - printf("PopPopB > "); - b = ((sp--)->val).floating; if(((sp--)->val).floating <= b) wordp = word + wordp->offset; else ++wordp; break; - case FunequalP: - printf("PopPopB !="); - b = ((sp--)->val).floating; if(((sp--)->val).floating == b) wordp = word + wordp->offset; else ++wordp; break; - case FequalP: - printf("PopPopB =="); - b = ((sp--)->val).floating; if(((sp--)->val).floating != b) wordp = word + wordp->offset; else ++wordp; break; - case Plus: - printf("Pop plus "); - a = ((sp--)->val).floating; sp->val.floating += a; ++wordp; break; - case varPlus: - printf("varPlus "); - sp->val.floating += wordp++->u.valp->floating; break; - case valPlus: - printf("valPlus "); - sp->val.floating += wordp++->u.val.floating; break; - case Times: - printf("Pop times "); - a = ((sp--)->val).floating; sp->val.floating *= a; ++wordp; break; - case varTimes: - printf("varTimes "); - sp->val.floating *= wordp++->u.valp->floating; break; - case valTimes: - printf("valTimes "); - sp->val.floating *= wordp++->u.val.floating; break; - case Acos: - printf("acos "); - sp->val.floating = acos((sp->val).floating); ++wordp; break; - case Acosh: - printf("acosh "); - sp->val.floating = acosh((sp->val).floating); ++wordp; break; - case Asin: - printf("asin "); - sp->val.floating = asin((sp->val).floating); ++wordp; break; - case Asinh: - printf("asinh "); - sp->val.floating = asinh((sp->val).floating); ++wordp; break; - case Atan: - printf("atan "); - sp->val.floating = atan((sp->val).floating); ++wordp; break; - case Atanh: - printf("atanh "); - sp->val.floating = atanh((sp->val).floating); ++wordp; break; - case Cbrt: - printf("cbrt "); - sp->val.floating = cbrt((sp->val).floating); ++wordp; break; - case Ceil: - printf("ceil "); - sp->val.floating = ceil((sp->val).floating); ++wordp; break; - case Cos: - printf("cos "); - sp->val.floating = cos((sp->val).floating); ++wordp; break; - case Cosh: - printf("cosh "); - sp->val.floating = cosh((sp->val).floating); ++wordp; break; - case Exp: - printf("exp "); - sp->val.floating = exp((sp->val).floating); ++wordp; break; - case Fabs: - printf("fabs "); - sp->val.floating = fabs((sp->val).floating); ++wordp; break; - case Floor: - printf("floor "); - sp->val.floating = floor((sp->val).floating); ++wordp; break; - case Log: - printf("log "); - sp->val.floating = log((sp->val).floating); ++wordp; break; - case Log10: - printf("log10 "); - sp->val.floating = log10((sp->val).floating); ++wordp; break; - case Sign: - printf("sign "); - b = (sp->val).floating; if(b != 0.0) { if(b > 0) sp->val.floating = 1.0; else if(b < 0) sp->val.floating = -1.0; } ++wordp; break; - case Sin: - printf("sin "); - sp->val.floating = sin((sp->val).floating); ++wordp; break; - case Sinh: - printf("sinh "); - sp->val.floating = sinh((sp->val).floating); ++wordp; break; - case Cube: - printf("cube "); - sp->val.floating *= sp->val.floating * sp->val.floating; ++wordp; break; - case Sqr: - printf("sqr "); - sp->val.floating *= sp->val.floating; ++wordp; break; - case Sqrt: - printf("sqrt "); - sp->val.floating = sqrt((sp->val).floating); ++wordp; break; - case Tan: - printf("tan "); - sp->val.floating = tan((sp->val).floating); ++wordp; break; - case Tanh: - printf("tanh "); - sp->val.floating = tanh((sp->val).floating); ++wordp; break; - case Atan2: - printf("Pop fmax "); - a = ((sp--)->val).floating; sp->val.floating = atan2(a, (sp->val).floating); ++wordp; break; - case Fdim: - printf("Pop fmin "); - a = ((sp--)->val).floating; sp->val.floating = fdim(a, (sp->val).floating); ++wordp; break; - case Fmax: - printf("Pop fdim "); - a = ((sp--)->val).floating; sp->val.floating = fmax(a, (sp->val).floating); ++wordp; break; - case Fmin: - printf("Pop atan2 "); - a = ((sp--)->val).floating; sp->val.floating = fmin(a, (sp->val).floating); ++wordp; break; - case Fmod: - printf("Pop fmod "); - a = ((sp--)->val).floating; sp->val.floating = fmod(a, (sp->val).floating); ++wordp; break; - case Hypot: - printf("Pop hypot "); - a = ((sp--)->val).floating; sp->val.floating = hypot(a, (sp->val).floating); ++wordp; break; - case Pow: - printf("Pop pow "); - a = ((sp--)->val).floating; sp->val.floating = pow(a, (sp->val).floating); ++wordp; break; - case Subtract: - printf("Pop subtract"); - a = ((sp--)->val).floating; sp->val.floating = (sp->val).floating - a; ++wordp; break; - case varSubtract: - printf("varSubtract"); - sp->val.floating -= wordp++->u.valp->floating; break; - case valSubtract: - printf("valSubtract"); - sp->val.floating -= wordp++->u.val.floating; break; - case Divide: - printf("Pop divide"); - a = ((sp--)->val).floating; sp->val.floating = (sp->val).floating / a; ++wordp; break; - case varDivide: - printf("varDivide"); - sp->val.floating /= wordp++->u.valp->floating; break; - case valDivide: - printf("valDivide"); - sp->val.floating /= wordp++->u.val.floating; break; - case Drand: - printf("Pop rand"); - sp->val.floating = drand((sp->val).floating); ++wordp; break; - case Tbl: - { - fortharray* arr = 0; - sp = doTbl(sp, wordp, &arr); - if(!sp) - return 0; - printf("Pop tbl %p size %zu index %zu", (void*)arr, arr->size, arr->index); - ++wordp; - break; - } - case Out: - printf("%f ", (sp--)->val.floating); ++wordp; break; - break; - case Outln: - printf("%f\n", (sp--)->val.floating); ++wordp; break; - break; - case Idx: - { - if((sp = getArrayIndex(sp, wordp)) == 0) - return 0; - printf("Pop index "); - ++wordp; - --sp; - break; - } - case QIdx: - { - if((sp = getArrayIndex(sp, wordp)) == 0) - return 0; - i = sp->arrp->index; - - forthvalue* val = sp->arrp->pval + i; - - printf("PopPop ?index "); - assert(sp >= mem->stack); - assert(sp >= mem->stack); - *val = (--sp)->val; - ++wordp; - break; - } - case EIdx: - { - if((sp = getArrayIndex(sp, wordp)) == 0) - return 0; - i = sp->arrp->index; - - printf("Pop !index "); - assert(sp >= mem->stack); - sp->arrp->index = i; - sp->val = (sp->arrp->pval)[i]; - ++wordp; - break; - } - case Extent: - { - printf("Extent "); - assert(sp >= mem->stack); - sp = getArrayExtent(sp); - ++wordp; - break; - } - case Rank: - { - printf("Rank "); - assert(sp >= mem->stack); - sp = getArrayRank(sp); - ++wordp; - break; - } - case NoOp: - printf("NoOp "); - ++wordp; - break; - case TheEnd: - printf("TheEnd "); - break; - default: - break; - } - assert(sp + 1 >= mem->stack); - printf("\n"); - } - return sp; - } - -static Boolean trc(struct typedObjectnode* This, ppsk arg) - { - psk Arg = (*arg)->RIGHT; - forthMemory* mem = (forthMemory*)(This->voiddata); - if(mem) - { - parameter* curparm = mem->parameters; - if(!curparm || setArgs(mem, 0, Arg) > 0) - { - stackvalue* sp = trcBody(mem); - if(sp) - { - printf("calculation DONE. On Stack %d\n", (int)(sp - mem->stack)); - assert(sp + 1 >= mem->stack); - for(; sp >= mem->stack;) - { - psk res; - size_t len; - char buf[64]; /* 64 bytes is even enough for quad https://people.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF*/ - double sv = (sp--)->val.floating; - int flags; - if(isnan(sv)) - { - strcpy(buf, "NAN"); - flags = READY BITWISE_OR_SELFMATCHING; - } - else if(isinf(sv)) - { - if(sv > DBL_MAX) - strcpy(buf, "INF"); - else - strcpy(buf, "-INF"); - flags = READY BITWISE_OR_SELFMATCHING; - } - else - { - sprintf(buf, "%.16E", sv); - flags = READY | SUCCESS | QNUMBER | QDOUBLE BITWISE_OR_SELFMATCHING; - } - len = offsetof(sk, u.obj) + strlen(buf); - res = (psk)bmalloc(len + 1); - - if(res) - { - strcpy((char*)(res)+offsetof(sk, u.sobj), buf); - printf("value on stack %s\n", buf); - wipe(*arg); - *arg = res; - res->v.fl = flags; - return TRUE; - } - } - } - else - return FALSE; - } - else - return FALSE; - } - return FALSE; - } - -static stackvalue* ftrc(stackvalue* sp, forthword* wordp, double* ret) - { - forthMemory* thatmem = wordp->u.that; - if(sp && thatmem) - { - stackvalue* sp2; - sp = fsetArgs(sp, wordp->offset, thatmem); - sp2 = trcBody(thatmem); - if(sp2 && sp2 >= thatmem->stack) - { - *ret = thatmem->stack->val.floating; - } - } - return sp; - } - -static long argumentArrayNumber(psk code) - { - if((code->u.sobj) == 'a' && (&(code->u.sobj))[1]) - { - const char* str = &(code->u.sobj) + 1; - char* endptr; - long nr; - nr = strtol(str, &endptr, 10); - if(!*endptr) - return nr; - } - return -1L; - } - -static Boolean StaticArray(psk declaration) - { - if(is_op(declaration)) - { - for(psk extents = declaration->RIGHT;; extents = extents->RIGHT) - { - if(is_op(extents)) - { - if(!INTEGER_POS(extents->LEFT)) - return FALSE; - } - else - { - if(INTEGER_POS(extents)) - return TRUE; - else - return FALSE; - } - } - return FALSE; - } - return FALSE; - } - -static int polish1(psk code, Boolean commentsAllowed) - { - int C; - int R; - switch(Op(code)) - { - case EQUALS: - return 0; /* Function definition disappears in final compiled code. */ - case PLUS: - case TIMES: - case EXP: - case LOG: - { - R = polish1(code->LEFT, FALSE); - if(R == -1) - return -1; - C = polish1(code->RIGHT, FALSE); - if(C == -1) - return -1; - return 1 + R + C; - } - case AND: - { - R = polish1(code->LEFT, TRUE); - if(R == -1) - return -1; - C = polish1(code->RIGHT, TRUE); - if(C == -1) - return -1; - if(C == 0) // This results in a NoOp - return 7 + R + C; - if(R == 0 || C == 0) - return R + C; /* Function definition on the left and/or right side. */ - return 7 + R + C; - /* 0: jump +5 1: pop 2 : jump to success branch 3: pop 4: jump to fail branch. - Two more for jumps after lhs and rhs*/ - } - case OR: - { - R = polish1(code->LEFT, TRUE); - if(R == -1) - return -1; - if(R == 0) - return 0; /* (|...) means: ignore ..., do nothing. */ - C = polish1(code->RIGHT, TRUE); - if(C == -1) - return -1; - return 7 + R + C; - /* 0: jump +5 1: pop 2 : jump to success branch 3: pop 4: jump to fail branch. - Two more for jumps after lhs and rhs*/ - } - case MATCH: - { - R = polish1(code->LEFT, FALSE); - if(R == -1) - return -1; - C = polish1(code->RIGHT, FALSE); - if(C == -1) - return -1; - if(Op(code->RIGHT) == MATCH || code->RIGHT->v.fl & UNIFY) - return R + C; - else - return 1 + R + C; - } - case FUN: - if(is_op(code->LEFT)) - { - errorprintf("calculation: lhs of $ is operator\n"); - return -1; - } - if(!strcmp(&(code->LEFT->u.sobj), "tbl") && StaticArray(code->RIGHT)) - { - // printf("Static:"); result(code); printf("\n"); - return 0; - } - - C = polish1(code->RIGHT, FALSE); - if(C == 1 && code->RIGHT->u.sobj == '\0') /* No parameters at all. */ - C = 0; - if(C == -1) - return -1; - return 1 + C; - case FUU: - if(is_op(code->LEFT)) - { - errorprintf("calculation: lhs of ' is operator\n"); - return -1; - } - C = polish1(code->RIGHT, FALSE); - if(C == -1) - return -1; - return 6 + C; - /* 0: jump +5 1: pop 2 : jump to wstart of loop 3: pop 4: jump out of the loop. - One more for jump after loop*/ - default: - if(is_op(code)) - { - R = polish1(code->LEFT, FALSE); - if(R == -1) - return -1; - C = polish1(code->RIGHT, FALSE); - if(C == -1) - return -1; - return R + C; /* Do not reserve room for operator! */ - } - else - { - if((code->v.fl & QDOUBLE) || INTEGER_COMP(code) || RAT_RAT_COMP(code)) - return 1; - else if(code->v.fl & (UNIFY | INDIRECT)) - return 1; /* variable */ - else if(/*code->u.sobj == '\0' ||*/ commentsAllowed) - return 0; - else - { - if(argumentArrayNumber(code) >= 0) - return 1; /* aN (N >= 0): name of implicit array passed as argument */ - return 1; /* Variables & arrays explicitly declared in the code. */ - } - } - } - } - -static Boolean printmem(forthMemory* mem) - { - if(mem == 0) - return FALSE; - char* naam; - int In = 0; - forthword* wordp = mem->word; - printf("print %s\n", mem->name == 0 ? "(main)" : mem->name); - for(; wordp->action != TheEnd; ++wordp) - { - actionType act = wordp->action; - char* Act = ActionAsWord[act]; - switch(act) - { - case varPush: - printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, Act, getVarName(mem, (wordp->u.valp))); - ++In; - break; - case var2stack: - printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, Act, getVarName(mem, (wordp->u.valp))); - ++In; - break; - case var2stackBranch: - printf(INDNT); printf("%*td" " %-24s " LONGnD " %s\n", 5, wordp - mem->word, Act, 5, (LONG)(wordp->offset), getVarName(mem, (wordp->u.valp))); - ++In; - break; - case stack2var: - printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, Act, getVarName(mem, (wordp->u.valp))); - break; - case stack2varBranch: - printf(INDNT); printf("%*td" " %-24s " LONGnD " %s\n", 5, wordp - mem->word, Act, 5, (LONG)(wordp->offset), getVarName(mem, (wordp->u.valp))); - ++In; - break; - case ArrElmValPush: - printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, Act, wordp->u.arrp->name); - break; - case stack2ArrElm: - printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, Act, wordp->u.arrp->name); - break; - case val2stack: - { - forthvalue val = wordp->u.val; - printf(INDNT); printf("%*td" " %-32s %f\n", 5, wordp - mem->word, Act, val.floating); - ++In; - break; - } - case valPush: - { - forthvalue val = wordp->u.val; - printf(INDNT); printf("%*td" " %-32s %f\n", 5, wordp - mem->word, Act, val.floating); - ++In; - break; - } - case Afunction: - naam = wordp->u.that->name; - printf(INDNT); printf("%*td" " %s \"%-12s\" " LONGnD "\n", 5, wordp - mem->word, Act, naam, 5, (LONG)(wordp->offset)); - break; - case Pop: - naam = getLogiName(wordp->u.logic); - printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, Act, naam); - --In; - break; - case Branch: - naam = getLogiName(wordp->u.logic); - printf(INDNT); printf("%*td" " %-24s " LONGnD " %s\n", 5, wordp - mem->word, Act, 5, (LONG)(wordp->offset), naam); - break; - case PopBranch: - naam = getLogiName(wordp->u.logic); - printf(INDNT); printf("%*td" " %-24s " LONGnD " %s\n", 5, wordp - mem->word, Act, 5, (LONG)(wordp->offset), naam); - --In; - break; - case valPushBranch: - { - forthvalue val = wordp->u.val; - printf(INDNT); printf("%*td" " %-24s " LONGnD " %f\n", 5, wordp - mem->word, Act, 5, (LONG)(wordp->offset), val.floating); - ++In; - break; - } - case val2stackBranch: - { - forthvalue val = wordp->u.val; - printf(INDNT); - printf("%*td" " %-24s " LONGnD " %f\n", 5, wordp - mem->word, Act, 5, (LONG)(wordp->offset), val.floating); - ++In; - break; - } - case Fless: printf(INDNT); - printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopB <", 5, (LONG)(wordp->offset)); - --In; --In; break; - case Fless_equal: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopB <=", 5, (LONG)(wordp->offset)); --In; --In; break; - case Fmore_equal: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopB >=", 5, (LONG)(wordp->offset)); --In; --In; break; - case Fmore: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopB >", 5, (LONG)(wordp->offset)); --In; --In; break; - case Funequal: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopB !=", 5, (LONG)(wordp->offset)); --In; --In; break; - case Fequal: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopB ==", 5, (LONG)(wordp->offset)); --In; --In; break; - - case FlessP: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopPopB <", 5, (LONG)(wordp->offset)); --In; --In; break; - case Fless_equalP: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopPopB <=", 5, (LONG)(wordp->offset)); --In; --In; break; - case Fmore_equalP: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopPopB >=", 5, (LONG)(wordp->offset)); --In; --In; break; - case FmoreP: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopPopB >", 5, (LONG)(wordp->offset)); --In; --In; break; - case FunequalP: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopPopB !=", 5, (LONG)(wordp->offset)); --In; --In; break; - case FequalP: printf(INDNT); printf("%*td" " %-24s " LONGnD "\n", 5, wordp - mem->word, "PopPop ==", 5, (LONG)(wordp->offset)); --In; --In; break; - - case Plus: printf(INDNT); printf("%*td" " Pop plus\n", 5, wordp - mem->word); --In; break; - case varPlus: printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, "varPlus", getVarName(mem, (wordp->u.valp))); break; - case valPlus: printf(INDNT); printf("%*td" " %-32s %f\n", 5, wordp - mem->word, "valPlus", wordp->u.val.floating); break; - case Times: printf(INDNT); printf("%*td" " Pop times\n", 5, wordp - mem->word); --In; break; - case varTimes: printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, "varTimes", getVarName(mem, (wordp->u.valp))); break; - case valTimes: printf(INDNT); printf("%*td" " %-32s %f\n", 5, wordp - mem->word, "valTimes", wordp->u.val.floating); break; - case Acos: printf(INDNT); printf("%*td" " acos\n", 5, wordp - mem->word); break; - case Acosh: printf(INDNT); printf("%*td" " acosh\n", 5, wordp - mem->word); break; - case Asin: printf(INDNT); printf("%*td" " asin\n", 5, wordp - mem->word); break; - case Asinh: printf(INDNT); printf("%*td" " asinh\n", 5, wordp - mem->word); break; - case Atan: printf(INDNT); printf("%*td" " atan\n", 5, wordp - mem->word); break; - case Atanh: printf(INDNT); printf("%*td" " atanh\n", 5, wordp - mem->word); break; - case Cbrt: printf(INDNT); printf("%*td" " cbrt\n", 5, wordp - mem->word); break; - case Ceil: printf(INDNT); printf("%*td" " ceil\n", 5, wordp - mem->word); break; - case Cos: - printf(INDNT); - printf("%*td" " cos\n", 5, wordp - mem->word); - break; - case Cosh: printf(INDNT); printf("%*td" " cosh\n", 5, wordp - mem->word); break; - case Exp: printf(INDNT); printf("%*td" " exp\n", 5, wordp - mem->word); break; - case Fabs: printf(INDNT); printf("%*td" " fabs\n", 5, wordp - mem->word); break; - case Floor: printf(INDNT); printf("%*td" " floor\n", 5, wordp - mem->word); break; - case Log: printf(INDNT); printf("%*td" " log\n", 5, wordp - mem->word); break; - case Log10: printf(INDNT); printf("%*td" " log10\n", 5, wordp - mem->word); break; - case Sign: printf(INDNT); printf("%*td" " sign\n", 5, wordp - mem->word); break; - case Sin: printf(INDNT); printf("%*td" " sin\n", 5, wordp - mem->word); break; - case Sinh: printf(INDNT); printf("%*td" " sinh\n", 5, wordp - mem->word); break; - case Cube: printf(INDNT); printf("%*td" " cube\n", 5, wordp - mem->word); break; - case Sqr: printf(INDNT); printf("%*td" " sqr\n", 5, wordp - mem->word); break; - case Sqrt: printf(INDNT); printf("%*td" " sqrt\n", 5, wordp - mem->word); break; - case Tan: printf(INDNT); printf("%*td" " tan\n", 5, wordp - mem->word); break; - case Tanh: printf(INDNT); printf("%*td" " tanh\n", 5, wordp - mem->word); break; - case Atan2: printf(INDNT); printf("%*td" " Pop atan2\n", 5, wordp - mem->word); --In; break; - case Fdim: printf(INDNT); printf("%*td" " Pop fdim\n", 5, wordp - mem->word); --In; break; - case Fmax: printf(INDNT); printf("%*td" " Pop fmax\n", 5, wordp - mem->word); --In; break; - case Fmin: printf(INDNT); printf("%*td" " Pop fmin\n", 5, wordp - mem->word); --In; break; - case Fmod: printf(INDNT); printf("%*td" " Pop fmod\n", 5, wordp - mem->word); --In; break; - case Hypot: printf(INDNT); printf("%*td" " Pop hypot\n", 5, wordp - mem->word); --In; break; - case Pow: printf(INDNT); printf("%*td" " Pop pow\n", 5, wordp - mem->word); --In; break; - case Subtract: printf(INDNT); printf("%*td" " Pop subtract\n", 5, wordp - mem->word); --In; break; - case varSubtract: printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, "varSubtract", getVarName(mem, (wordp->u.valp))); break; - case valSubtract: printf(INDNT); printf("%*td" " %-32s %f\n", 5, wordp - mem->word, "valSubtract", wordp->u.val.floating); break; - case Divide: printf(INDNT); printf("%*td" " Pop divide\n", 5, wordp - mem->word); --In; break; - case varDivide: printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, "varDivide", getVarName(mem, (wordp->u.valp))); break; - case valDivide: printf(INDNT); printf("%*td" " %-32s %f\n", 5, wordp - mem->word, "valDivide", wordp->u.val.floating); break; - case Drand: printf(INDNT); printf("%*td" " Pop rand\n", 5, wordp - mem->word); --In; break; - case Tbl: printf(INDNT); printf("%*td" " Pop tbl\n", 5, wordp - mem->word); --In; break; - case Out: printf(INDNT); printf("%*td" " Pop out\n", 5, wordp - mem->word); --In; break; - case Outln: printf(INDNT); printf("%*td" " Pop outln\n", 5, wordp - mem->word); --In; break; - case Idx: printf(INDNT); printf("%*td" " Pop idx\n", 5, wordp - mem->word); --In; break; - case QIdx: printf(INDNT); printf("%*td" " PopPop Qidx\n", 5, wordp - mem->word); --In; --In; break; - case EIdx: printf(INDNT); printf("%*td" " Pop Eidx\n", 5, wordp - mem->word); --In; break; - case Extent: printf(INDNT); printf("%*td" " Pop extent\n", 5, wordp - mem->word); --In; break; - case Rank: printf(INDNT); printf("%*td" " Pop rank\n", 5, wordp - mem->word); --In; break; - case NoOp: - naam = "";// getLogiName(wordp->u.logic); - printf(INDNT); printf("%*td" " %-32s %s\n", 5, wordp - mem->word, "NoOp", naam); - break; - case TheEnd: - default: - printf(INDNT); printf("%*td" " %-32s %d\n", 5, wordp - mem->word, "default", wordp->action); - ; - } - } - printf(INDNT); printf("%*td" " TheEnd\n", 5, wordp - mem->word); - if(mem->functions) - printmem(mem->functions); - if(mem->nextFnc) - printmem(mem->nextFnc); - return TRUE; - } - -static Boolean print(struct typedObjectnode* This, ppsk arg) - { - forthMemory* mem = (forthMemory*)(This->voiddata); - return printmem(mem); - } - -enum formt { floating, integer, fraction, hexadecimal }; - -static enum formt getFormat(char* psobj) - { - if(!strcmp(psobj, "R")) - return floating; - else if(!strcmp(psobj, "N")) - return integer; - else if(!strcmp(psobj, "Q")) - return fraction; - else if(!strcmp(psobj, "%a")) - return hexadecimal; - return floating; - } - -static psk createOperatorNode(int operator) - { - assert(operator == DOT || operator == COMMA || operator == WHITE); - psk operatorNode = (psk)bmalloc(sizeof(knode)); - if(operatorNode) - { - operatorNode->v.fl = (operator | SUCCESS | READY) & COPYFILTER; - //operatorNode->v.fl &= COPYFILTER; - operatorNode->LEFT = 0; - operatorNode->RIGHT = 0; - } - return operatorNode; - } - -static psk FloatNode(double val) - { - char jotter[500]; - size_t bytes = offsetof(sk, u.obj) + 1; - bytes += sprintf(jotter, "%e", val); - psk res = (psk)bmalloc(bytes); - if(res) - { - strcpy((char*)(res)+offsetof(sk, u.sobj), jotter); - res->v.fl = READY | SUCCESS BITWISE_OR_SELFMATCHING; - res->v.fl &= COPYFILTER; - } - return res; - } - -static psk HexNode(double val) - { - char jotter[500]; - size_t bytes = offsetof(sk, u.obj) + 1; - bytes += sprintf(jotter, "%a", val); - psk res = (psk)bmalloc(bytes); - if(res) - { - strcpy((char*)(res)+offsetof(sk, u.sobj), jotter); - res->v.fl = READY | SUCCESS BITWISE_OR_SELFMATCHING; - res->v.fl &= COPYFILTER; - } - return res; - } - -static psk IntegerNode(double val) - { - char jotter[512]; - if(val <= (double)INT64_MIN || val > (double)INT64_MAX) - { -#if defined __EMSCRIPTEN__ -// long long long1 = (long long)1; - int64_t long1 = (int64_t)1; -#else - int64_t long1 = (int64_t)1; -#endif - double fcac = (double)(long1 << 52); - int exponent; - ULONG flg = 0; - if(val < 0) - { - flg = MINUS; - val = -val; - } - double mantissa = frexp(val, &exponent); - /* - The IEEE-754 double-precision float uses 11 bits for the exponent. - The exponent field is an unsigned integer from 0 to 2047, in biased form: - an exponent value of 1023 represents the actual zero. - Exponents range from −1022 to +1023 because exponents of −1023 (all 0s) - and +1024 (all 1s) are reserved for special numbers. - */ - int64_t Mantissa = (int64_t)(fcac * mantissa); - int shft; - assert(Mantissa < (long1 << 52)); - assert(Mantissa != 0); - for(shft = 52 - exponent; (Mantissa & long1) == 0; --shft, Mantissa >>= 1) - ; - - if(flg & MINUS) - sprintf(jotter, "-%" PRId64 "*2^%d", Mantissa, (-shft)); - else - sprintf(jotter, "%" PRId64 "*2^%d", Mantissa, (-shft)); - return build_up(NULL, jotter, NULL); - } - else - { - size_t bytes = offsetof(sk, u.obj) + 1; - if(val < 0) - bytes += sprintf(jotter, "%" PRId64, -(int64_t)val); - else - bytes += sprintf(jotter, "%" PRId64, (int64_t)val); - psk res = (psk)bmalloc(bytes); - if(res) - { - strcpy((char*)(res)+offsetof(sk, u.sobj), jotter); - res->v.fl = READY | SUCCESS | QNUMBER BITWISE_OR_SELFMATCHING; - res->v.fl &= COPYFILTER; - if((int64_t)val < 0) - res->v.fl |= MINUS; - else if((int64_t)val == 0) - res->v.fl |= QNUL; - res->v.fl &= ~DEFINITELYNONUMBER; - } - return res; - } - } - -static psk FractionNode(double val) - { - char jotter[512]; - size_t bytes = offsetof(sk, u.obj) + 1; -#if defined __EMSCRIPTEN__ -// long long long1 = (long long)1; - int64_t long1 = (int64_t)1; -#else - int64_t long1 = (int64_t)1; -#endif - double fcac = (double)(long1 << 52); - int exponent; - ULONG flg = READY | SUCCESS | QNUMBER BITWISE_OR_SELFMATCHING; - if(val < 0) - { - flg |= MINUS; - val = -val; - } - else if(val == 0) - flg |= QNUL; - double mantissa = frexp(val, &exponent); - /* - The IEEE-754 double-precision float uses 11 bits for the exponent. - The exponent field is an unsigned integer from 0 to 2047, in biased form: - an exponent value of 1023 represents the actual zero. - Exponents range from −1022 to +1023 because exponents of −1023 (all 0s) - and +1024 (all 1s) are reserved for special numbers. - */ - int64_t Mantissa = (int64_t)(fcac * mantissa); - psk res; - assert(Mantissa < (long1 << 52)); - if(Mantissa) - { - int shft; - for(shft = 52 - exponent; (Mantissa & long1) == 0; --shft, Mantissa >>= 1) - ; - - if(shft == 0) - bytes += sprintf(jotter, "%" PRId64, Mantissa); - else if(shft < 0) - { /* DANGER: multiplication can easily overflow! */ - if(shft > -12) - bytes += sprintf(jotter, "%" PRId64, Mantissa << (-shft)); - else - { - if(flg & MINUS) - sprintf(jotter, "-%" PRId64 "*2^%d", Mantissa, (-shft)); - else - sprintf(jotter, "%" PRId64 "*2^%d", Mantissa, (-shft)); - return build_up(NULL, jotter, NULL); - } - } - else - { /* DANGER: multiplication can easily overflow! */ - if(shft < 64) - { - bytes += sprintf(jotter, "%" PRId64 "/" "%" PRId64, Mantissa, (int64_t)(long1 << shft)); - flg |= QFRACTION; - } - else - { - if(flg & MINUS) - sprintf(jotter, "-%" PRId64 "*2^%d", Mantissa, (-shft)); - else - sprintf(jotter, "%" PRId64 "*2^%d", Mantissa, (-shft)); - return build_up(NULL, jotter, NULL); - } - } - } - else - bytes += sprintf(jotter, "0"); - - res = (psk)bmalloc(bytes); - if(res) - { - strcpy((char*)(res)+offsetof(sk, u.sobj), jotter); - res->v.fl = flg; - res->v.fl &= COPYFILTER; - } - return res; - } - -static psk eksportArray(forthvalue* val, size_t rank, size_t* extent) - { - psk res; - psk head = createOperatorNode(COMMA); - res = head; - head->LEFT = same_as_w(&nilNode); - if(rank > 1) - { /* Go deeper */ - size_t stride = 1; - for(size_t k = 0; k < rank - 1; ++k) - stride *= extent[k]; - for(size_t r = extent[rank - 1]; --r > 0; val += stride) - { - head->RIGHT = createOperatorNode(WHITE); - head = head->RIGHT; - head->LEFT = eksportArray(val, rank - 1, extent); - } - head->RIGHT = eksportArray(val, rank - 1, extent); - } - else - { /* Export list of values. */ - for(size_t r = *extent; --r > 0; ++val) - { - head->RIGHT = createOperatorNode(WHITE); - head = head->RIGHT; - head->LEFT = xprtfnc(val->floating); - } - head->RIGHT = xprtfnc(val->floating); - } - return res; - } - -static Boolean eksport(struct typedObjectnode* This, ppsk arg) - { - forthMemory* mem = (forthMemory*)(This->voiddata); - if(mem) - { - fortharray** arrp = &(mem->arr); - forthvariable* varp = (mem->var); - psk Arg = (*arg)->RIGHT; - char* name = ""; - if(is_op(Arg)) - { - psk lhs = Arg->LEFT; - psk rhs = Arg->RIGHT; - enum formt format = floating; - if(!is_op(lhs)) - { - format = getFormat(&lhs->u.sobj); - } - switch(format) - { - case floating: - xprtfnc = FloatNode; - break; - case integer: - xprtfnc = IntegerNode; - break; - case fraction: - xprtfnc = FractionNode; - break; - case hexadecimal: - xprtfnc = HexNode; - break; - } - if(!is_op(rhs)) - { - name = &rhs->u.sobj; - forthvariable* v = getVariablePointer(varp, name); - - if(v) - { - psk res = 0; - res = xprtfnc(v->val.floating); - if(res) - { - wipe(*arg); - *arg = res; - //*arg = same_as_w(res); - //res->v.fl = READY | SUCCESS; - return TRUE; - } - } - else - { - fortharray* a = getArrayPointer(arrp, name); - if(a) - { - psk res = 0; - res = eksportArray(a->pval, a->rank, a->extent); - if(res) - { - wipe(*arg); - *arg = res; - return TRUE; - } - } - } - } - } - } - return TRUE; - } - -static Boolean shortcutJumpChains(forthword* wordp) - { - forthword* wstart = wordp; - Boolean res = FALSE; - for(; wordp->action != TheEnd; ++wordp) - { - if(wordp->action == Branch) - { - forthword* label = wstart + wordp->offset; - while(label->action == Branch) - { - label = wstart + label->offset; - res = TRUE; - } - wordp->offset = (unsigned int)(label - wstart); - } - } - //#define SHOWOPTIMIZATIONS -#ifdef SHOWOPTIMIZATIONS - if(res) printf("shortcutJumpChains\n"); -#endif - return res; - } - -static Boolean combinePopBranch(forthword* wordp) - { - Boolean res = FALSE; - for(; wordp->action != TheEnd; ++wordp) - { - if(wordp->action == Pop) - { - if(wordp[1].action == Branch) - { - wordp->action = PopBranch; - wordp->offset = wordp[1].offset; - res = TRUE; - } - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("combinePopBranch\n"); -#endif - return res; - } - -static Boolean combineBranchPopBranch(forthword* wstart) - { - Boolean res = FALSE; - forthword* wordp = wstart; - for(; wordp->action != TheEnd; ++wordp) - { - if(wordp->action == Branch) - { - forthword* label = wstart + wordp->offset; - if(label->action == PopBranch) - { - wordp->action = PopBranch; - wordp->offset = label->offset; - wordp->u.logic = label->u.logic; - res = TRUE; - } - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("combineBranchPopBranch\n"); -#endif - return res; - } - -static void markReachable(forthword* wordp, forthword* wstart, char* marks) - { - if(marks[wordp - wstart] == 1) - return; /* Already visited! */ - - for(; wordp->action != TheEnd; ++wordp) - { - marks[wordp - wstart] = 1; - switch(wordp->action) - { - case var2stackBranch: - case stack2varBranch: - case Branch: - case PopBranch: - case valPushBranch: - case val2stackBranch: - markReachable(wstart + wordp->offset, wstart, marks); - return; - case Fless: - case Fless_equal: - case Fmore_equal: - case Fmore: - case Funequal: - case Fequal: - case FlessP: - case Fless_equalP: - case Fmore_equalP: - case FmoreP: - case FunequalP: - case FequalP: - markReachable(wstart + wordp->offset, wstart, marks); - break; - default: - ; - } - } - } - -static Boolean markUnReachable(forthword* wstart, char* marks) - { - Boolean res = FALSE; - markReachable(wstart, wstart, marks); - for(forthword* wordp = wstart; wordp->action != TheEnd; ++wordp) - { - if(wordp->action != NoOp && marks[wordp - wstart] != 1) - { - wordp->action = NoOp; - res = TRUE; - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("markUnReachable\n"); -#endif - return res; - } - -static Boolean dissolveNextWordBranches(forthword* wstart) - { - Boolean res = FALSE; - for(forthword* wordp = wstart; wordp->action != TheEnd; ++wordp) - { - switch(wordp->action) - { - case var2stackBranch: - if(wstart + wordp->offset == wordp + 1) - { - wordp->action = var2stack; - res = TRUE; - } - break; - case stack2varBranch: - if(wstart + wordp->offset == wordp + 1) - { - wordp->action = stack2var; - res = TRUE; - } - break; - case Branch: - if(wstart + wordp->offset == wordp + 1) - { - wordp->action = NoOp; - res = TRUE; - } - break; - case PopBranch: - { - if(wstart + wordp->offset == wordp + 1) - { - wordp->action = Pop; - res = TRUE; - } - break; - } - case valPushBranch: - { - if(wstart + wordp->offset == wordp + 1) - { - wordp->action = valPush; - res = TRUE; - } - break; - } - case val2stackBranch: - { - if(wstart + wordp->offset == wordp + 1) - { - wordp->action = val2stack; - res = TRUE; - } - break; - } - default: - ; - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("dissolveNextWordBranches\n"); -#endif - return res; - } - -static Boolean combineUnconditionalBranchTovalPush(forthword* wstart) - { - Boolean res = FALSE; - for(forthword* wordp = wstart; wordp->action != TheEnd; ++wordp) - { - switch(wordp->action) - { - case Branch: - { - forthword* label = wstart + wordp->offset; - if(label->action == valPush) - { - wordp->action = valPushBranch; - wordp->u.val = label->u.val; - wordp->offset += 1; - res = TRUE; - } - break; - } - case PopBranch: - { - forthword* label = wstart + wordp->offset; - if(label->action == valPush) - { - wordp->action = val2stackBranch; - wordp->u.val = label->u.val; - wordp->offset += 1; - res = TRUE; - } - break; - } - default: - ; - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("combineUnconditionalBranchTovalPush\n"); -#endif - return res; - } - -static Boolean stack2var_var2stack(forthword* wstart) - { - Boolean res = FALSE; - for(forthword* wordp = wstart; wordp->action != TheEnd; ++wordp) - { - switch(wordp->action) - { - case stack2var: - { - switch(wordp[1].action) - { - case var2stackBranch: - { - if(wordp->u.valp == wordp[1].u.valp) - { - *wordp = wordp[1]; - wordp->action = stack2varBranch; - res = TRUE; - } - break; - } - default: - ; - } - break; - } - default: - ; - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("stack2var_var2stack\n"); -#endif - return res; - } - -static Boolean removeIdempotentActions(forthword* wstart) - { - Boolean res = FALSE; - for(forthword* wordp = wstart; wordp->action != TheEnd; ++wordp) - { - switch(wordp->action) - { - case stack2var: - { - switch(wordp[1].action) - { - case stack2var: - case stack2varBranch: - if(wordp->u.valp == wordp[1].u.valp) - { - wordp->action = NoOp; - res = TRUE; - } - break; - default: - ; - } - break; - } - case val2stack: - { - switch(wordp[1].action) - { - case val2stack: - case val2stackBranch: - if(wordp->u.val.floating == wordp[1].u.val.floating) - { - wordp->action = NoOp; - res = TRUE; - } - break; - default: - ; - } - break; - } - case var2stack: - { - switch(wordp[1].action) - { - case var2stack: - case var2stackBranch: - if(wordp->u.valp == wordp[1].u.valp) - { - wordp->action = NoOp; - res = TRUE; - } - break; - default: - ; - } - break; - } - default: - ; - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("removeIdempotentActions\n"); -#endif - return res; - } - -static Boolean combinePushAndOperation(forthword* wstart) - { - Boolean res = FALSE; - for(forthword* wordp = wstart; wordp->action != TheEnd; ++wordp) - { - switch(wordp->action) - { - case varPush: - { - switch(wordp[1].action) - { - case Plus: - wordp->action = varPlus; - wordp[1].action = NoOp; - res = TRUE; - break; - case Times: - wordp->action = varTimes; - wordp[1].action = NoOp; - res = TRUE; - break; - case Subtract: - wordp->action = varSubtract; - wordp[1].action = NoOp; - res = TRUE; - break; - case Divide: - wordp->action = varDivide; - wordp[1].action = NoOp; - res = TRUE; - break; - default: - ; - } - break; - } - case valPush: - { - switch(wordp[1].action) - { - case Plus: - wordp->action = valPlus; - wordp[1].action = NoOp; - res = TRUE; - break; - case Times: - wordp->action = valTimes; - wordp[1].action = NoOp; - res = TRUE; - break; - case Subtract: - wordp->action = valSubtract; - wordp[1].action = NoOp; - res = TRUE; - break; - case Divide: - wordp->action = valDivide; - wordp[1].action = NoOp; - res = TRUE; - break; - default: - ; - } - break; - } - default: - ; - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("combinePushAndPlus\n"); -#endif - return res; - } - -static void markLabels(forthword* wstart, char* marks) - { - for(forthword* wordp = wstart; wordp->action != TheEnd; ++wordp) - { - switch(wordp->action) - { - case var2stackBranch: - case stack2varBranch: - case Branch: - case PopBranch: - case valPushBranch: - case val2stackBranch: - case Fless: - case Fless_equal: - case Fmore_equal: - case Fmore: - case Funequal: - case Fequal: - case FlessP: - case Fless_equalP: - case Fmore_equalP: - case FmoreP: - case FunequalP: - case FequalP: - marks[wordp->offset] = 1; - break; - default: - ; - } - } - } - -static Boolean combineval2stack(forthword* wstart, char* marks) - { - Boolean res = FALSE; - markLabels(wstart, marks); - for(forthword* wordp = wstart; wordp->action != TheEnd; ++wordp) - { - switch(wordp->action) - { - case Pop: - { - if(marks[1 + (wordp - wstart)] != 1) - { - switch(wordp[1].action) - { - case valPush: - { - wordp->action = NoOp; - wordp[1].action = val2stack; - res = TRUE; - break; - } - case varPush: - { - wordp->action = NoOp; - wordp[1].action = var2stack; - res = TRUE; - break; - } - default: - ; - } - } - else - { - switch(wordp[1].action) - { - case varPush: - { - *wordp = wordp[1]; - wordp->action = var2stackBranch; - wordp->offset = (unsigned int)((wordp + 2) - wstart); - res = TRUE; - break; - } - default: - ; - } - } - break; - } - case PopBranch: - { - forthword* label = wstart + wordp->offset; - switch(label->action) - { - case varPush: - { - *wordp = *label; - wordp->action = var2stackBranch; - wordp->offset = (unsigned int)((label + 1) - wstart); - res = TRUE; - break; - } - default: - ; - } - } - default: - ; - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("combineval2stack\n"); -#endif - return res; - } - -static Boolean UnconditionalBranch(actionType calcaction) - { - switch(calcaction) - { - case var2stackBranch: - case stack2varBranch: - case Branch: - case PopBranch: - case valPushBranch: - case val2stackBranch: - return TRUE; - default: - return FALSE; - } - } -static Boolean IdemPotent(forthword* maybebranch, forthword* notbranch) - { - switch(notbranch->action) - { - case stack2var: - { - switch(maybebranch->action) - { - case stack2var: - case stack2varBranch: - if(notbranch->u.valp == maybebranch->u.valp) - { - return TRUE; - } - break; - default: - ; - } - break; - } - case val2stack: - { - switch(maybebranch->action) - { - case val2stack: - case val2stackBranch: - if(notbranch->u.val.floating == maybebranch->u.val.floating) - { - return TRUE; - } - break; - default: - ; - } - break; - } - case var2stack: - { - switch(maybebranch->action) - { - case var2stack: - case var2stackBranch: - if(notbranch->u.valp == maybebranch->u.valp) - { - return TRUE; - } - break; - default: - ; - } - break; - } - default: - ; - } - return FALSE; - } - -static Boolean eliminateBranch(forthword* wstart) -/* - 118 Branch 120 fand - 119 val2stackBranch 129 0.000000 - 120 varPush J - 121 valPush 10.000000 - 122 PopB < 119 - 123 var2stack J - 124 valPush 25.600000 - 125 Pop times - 126 floor - 127 stack2ArrElm T - 128 var2stackBranch 131 j // This must be some unconditional branch - 129 stack2ArrElm T - - 118 NoOp fand // Branch -> NoOp - 119 varPush J - 120 valPush 10.000000 - 121 PopB < 128 // 119 -> 129 -> 128 - 122 var2stack J - 123 valPush 25.600000 - 124 Pop times - 125 floor - 126 stack2ArrElm T - 127 var2stackBranch 131 j - 128 val2stack 0.000000 //val2stackBranch -> val2stack - 129 stack2ArrElm T - -Label 119 replaced by (label of 119) -Labels [119 - 129) decremented by 1 -*/ - { - Boolean res = FALSE; - for(forthword* wordp = wstart; wordp->action != TheEnd; ++wordp) - { - if(UnconditionalBranch(wordp->action)) - { - if(wordp->offset + wstart == wordp + 2) - { - unsigned int lo = (unsigned int)((wordp + 1) - wstart); - forthword tmp = wordp[1]; - if(UnconditionalBranch(tmp.action)) - { - unsigned int hi = tmp.offset - 1; - if(hi > lo) - { - forthword* high = wstart + hi; - if(UnconditionalBranch(high->action) || IdemPotent(wordp + 1, high)) - { - switch(tmp.action) - { - case var2stackBranch: - { - tmp.action = var2stack; - break; - } - case stack2varBranch: - { - tmp.action = stack2var; - break; - } - case Branch: - { - tmp.action = NoOp; - break; - } - case PopBranch: - { - tmp.action = Pop; - break; - } - case valPushBranch: - { - tmp.action = valPush; - break; - } - case val2stackBranch: - { - tmp.action = val2stack; - break; - } - default: - ; - } - - forthword* w; - for(w = wordp + 1; w < high; ++w) - { - *w = w[1]; - } - *w = tmp; - switch(wordp->action) - { - case var2stackBranch: - wordp->action = var2stack; - break; - case stack2varBranch: - wordp->action = stack2var; - break; - case Branch: - wordp->action = NoOp; - break; - case PopBranch: - wordp->action = Pop; - break; - case valPushBranch: - wordp->action = valPush; - break; - case val2stackBranch: - wordp->action = val2stack; - break; - default: - ; - } - for(w = wstart; w->action != TheEnd; ++w) - { - switch(w->action) - { - case var2stackBranch: - case stack2varBranch: - case Branch: - case PopBranch: - case valPushBranch: - case val2stackBranch: - case Fless: - case Fless_equal: - case Fmore_equal: - case Fmore: - case Funequal: - case Fequal: - case FlessP: - case Fless_equalP: - case Fmore_equalP: - case FmoreP: - case FunequalP: - case FequalP: - if(w->offset == lo) - w->offset = hi; - else if(w->offset > lo && w->offset <= hi) - --(w->offset); - break; - default: - ; - } - } - res = TRUE; - } - } - } - } - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("eliminateBranch\n"); -#endif - return res; - } - -static int removeNoOp(forthMemory* mem, int length) - { - forthword* wstart = mem->word; - unsigned int* deltaoffset = calloc(length, sizeof(unsigned int)); - int newlength = 0; - if(deltaoffset) - { - memset(deltaoffset, 0, length * sizeof(char)); - unsigned int delta = 0; - forthword* wordp; - for(wordp = wstart; wordp->action != TheEnd; ++wordp) - { - deltaoffset[wordp - wstart] = delta; - if(wordp->action == NoOp) - ++delta; - } - deltaoffset[wordp - wstart] = delta; - for(wordp = wstart; wordp->action != TheEnd; ++wordp) - { - switch(wordp->action) - { - case var2stackBranch: - case stack2varBranch: - case Branch: - case PopBranch: - case valPushBranch: - case val2stackBranch: - case Fless: - case Fless_equal: - case Fmore_equal: - case Fmore: - case Funequal: - case Fequal: - case FlessP: - case Fless_equalP: - case Fmore_equalP: - case FmoreP: - case FunequalP: - case FequalP: - wordp->offset -= deltaoffset[wordp->offset]; - break; - default: - ; - } - } - newlength = length - delta; - forthword* newword = bmalloc(newlength * sizeof(forthword)); - if(newword) - { - mem->word = newword; - for(wordp = wstart; wordp->action != TheEnd; ++wordp) - { - if(wordp->action != NoOp) - { - *newword++ = *wordp; - } - } - *newword = *wordp; - bfree(wstart); - } - free(deltaoffset); - } - return newlength; - } - -static Boolean combinePopThenPop(forthword* wstart, char* marks) - { - Boolean res = FALSE; - markLabels(wstart, marks); - for(forthword* wordp = wstart; wordp->action != TheEnd; ++wordp) - { - forthword* label; - if(marks[(wordp + 1) - wstart] != 1) // Nobody is jumping to the next word - { - switch(wordp->action) - { - case Fless: - case Fless_equal: - case Fmore_equal: - case Fmore: - case Funequal: - case Fequal: - label = wstart + wordp->offset; - switch(wordp[1].action) - { - case Pop: - { - if(label->action == PopBranch) - { - wordp->action = extraPopped(wordp->action, extraPop); - wordp->offset = label->offset; - wordp[1].action = NoOp; - res = TRUE; - } - else if(label->action == val2stackBranch) - { - wordp->action = extraPopped(wordp->action, extraPop); - label->action = valPushBranch; - wordp[1].action = NoOp; - res = TRUE; - } - break; - } - case val2stack: - { - if(label->action == PopBranch) - { - wordp->action = extraPopped(wordp->action, extraPop); - wordp->offset = label->offset; - wordp[1].action = valPush; - res = TRUE; - } - break; - } - case PopBranch: - { - if(label->action == PopBranch) - { /* see if backwards branch can be converted to branch to wordp+2 */ - if(label->offset == (wordp + 2) - wstart) - { - wordp->action = extraPopped(wordp->action, negations); - wordp->offset = wordp[1].offset; - wordp[1].action = NoOp; - res = TRUE; - } - else /* We can still eliminate the backward branch */ - { - wordp->action = extraPopped(wordp->action, extraPop); - wordp->offset = label->offset; - wordp[1].action = Branch; - res = TRUE; - } - } - else if(label->action == val2stackBranch) - { - wordp->offset = wordp[1].offset; - wordp->action = extraPopped(wordp->action, negations); - wordp[1] = *label; - wordp[1].action = valPushBranch; - res = TRUE; - } - break; - } - case val2stackBranch: - { - if(label->action == PopBranch) - { - wordp->action = extraPopped(wordp->action, extraPop); - wordp->offset = label->offset; - wordp[1].action = valPushBranch; - res = TRUE; - } - break; - } - default: - ; - } - default: - ; - } - } - } -#ifdef SHOWOPTIMIZATIONS - if(res) printf("combinePopThenPop\n"); -#endif - return res; - } - -#define VARCOMP (NOT|GREATER_THAN|SMALLER_THAN|INDIRECT) - -#define VLESS(psk) (((psk)->v.fl & (VARCOMP)) == (INDIRECT|SMALLER_THAN)) -#define VLESS_EQUAL(psk) (((psk)->v.fl & (VARCOMP)) == (INDIRECT|NOT|GREATER_THAN)) -#define VMORE_EQUAL(psk) (((psk)->v.fl & (VARCOMP)) == (INDIRECT|NOT|SMALLER_THAN)) -#define VMORE(psk) (((psk)->v.fl & (VARCOMP)) == (INDIRECT|GREATER_THAN)) -#define VUNEQUAL(psk) (((psk)->v.fl & (VARCOMP)) == (INDIRECT|NOT)) -#define VLESSORMORE(psk) (((psk)->v.fl & (VARCOMP)) == (INDIRECT|SMALLER_THAN|GREATER_THAN)) -#define VEQUAL(psk) (((psk)->v.fl & (VARCOMP)) == (INDIRECT)) -#define VNOTLESSORMORE(psk) (((psk)->v.fl & (VARCOMP)) == (INDIRECT|NOT|SMALLER_THAN|GREATER_THAN)) - -static forthMemory* calcnew(psk arg, forthMemory* parent, Boolean in_function); - -static Boolean setArity(forthword* wordp, psk code, unsigned int expectedArity) - { - unsigned int arity = 1; - psk tmp = code->RIGHT; - for(; is_op(tmp) && Op(tmp) == COMMA; tmp = tmp->RIGHT) - ++arity; - if(expectedArity > 0 && arity != expectedArity) - { - /*TODO: check whether function does not take a single argument!*/ - errorprintf("The arity is %u, but %u arguments found.\n", expectedArity, arity); - return FALSE; - } - wordp->offset = arity; - return TRUE; - } - -static fortharray* haveArray(forthMemory* forthstuff, psk declaration, Boolean in_function) - { - psk pname = 0; - psk extents = 0; - //printf("haveArray:"); result(declaration); printf("\n"); - if(is_op(declaration)) - { - if(is_op(declaration->LEFT)) - { - errorprintf("Array parameter declaration requires name.\n"); - return 0; - } - pname = declaration->LEFT; - extents = declaration->RIGHT; - - if(in_function) - { - errorprintf("In functions, array parameter (here: [%s]) declarations do not take extent specs.\n", &(pname->u.sobj)); - } - } - else - { - pname = declaration; - } - - if(HAS_VISIBLE_FLAGS_OR_MINUS(pname)) - { - errorprintf("Array name may not have any prefixes.\n"); - return 0; - } - - fortharray* a = getOrCreateArrayPointer(&(forthstuff->arr), &(pname->u.sobj), 0); - if(!in_function && a && extents) - { - size_t rank = 1; - psk kn; - for(kn = extents; is_op(kn); kn = kn->RIGHT) - { - ++rank; - } - - a->rank = rank; - assert(a->extent == 0); - a->extent = (size_t*)bmalloc(2 * rank * sizeof(size_t));/* twice: both extents and strides */ - if(a->extent) - { - a->stride = a->extent + rank; - size_t* pextent; - size_t totsize = 1; - for(kn = extents, pextent = a->extent + rank - 1;; ) - { - psk H; - - if(is_op(kn)) - H = kn->LEFT; - else - H = kn; - - if(INTEGER_POS(H)) - *pextent = strtol(&(H->u.sobj), 0, 10); - else if((H->v.fl & VISIBLE_FLAGS) == INDIRECT) - *pextent = 0; /* extent still unknown. */ - else - { - errorprintf("Extent specification of array \"%s\" invalid. It must be a positive number or a variable name prefixed with '!'\n", a->name); - return 0; - } - - totsize *= *pextent; - if(!is_op(kn)) - break; - kn = kn->RIGHT; - --pextent; - } - a->stride[0] = a->extent[0]; - for(size_t extent_index = 1; extent_index < rank;) - { - a->stride[extent_index] = a->stride[extent_index - 1] * a->extent[extent_index]; - ++extent_index; - } - - if(totsize > 0) - { - if(!initialise(a, totsize)) - { - bfree(a->extent); - a->extent = 0; - a->stride = 0; - return 0; - } - } - else - a->size = 0; - } - } - return a; - } - -static Boolean okatomicarg(psk code) - { - if((code->v.fl & QNUMBER) - || (code->v.fl & QDOUBLE) - || (code->v.fl & (INDIRECT | UNIFY)) - ) - return TRUE; - return FALSE; - } - -static int argcount(psk rhs) - { - if(is_op(rhs)) - { - if(Op(rhs) == FUN) - return 1; - else if(is_op(rhs->LEFT)) - { - switch(Op(rhs->LEFT)) - { - case FUN: - case PLUS: - case TIMES: - case EXP: - case LOG: - return 1; - } - showProblematicNode("Function argument must be atomic. (A number or a variable prefixed with \"!\")\n", rhs); - return -1; - } - else if((rhs->LEFT->u.sobj) == 0) - { - errorprintf("Function argument is empty string. (It must be a number or a variable prefixed with \"!\")\n"); - return -1; - } - else if(!okatomicarg(rhs->LEFT)) - { - errorprintf("Function argument is not valid. (It must be a number or a variable prefixed with \"!\")\n"); - return -1; - } - else - { - static int deep; - deep = argcount(rhs->RIGHT); - if(deep <= 0) - { - return deep; - } - return 1 + deep; - } - } - else if((rhs->u.sobj) == 0) - { - errorprintf("Last (or only) function argument is empty string. (It must be a number or a variable prefixed with \"!\")\n"); - return -1; - } - else if(!okatomicarg(rhs)) - { - errorprintf("Last function argument is not valid. (It must be a number or a variable prefixed with \"!\")\n"); - return -1; - } - return 1; - } - -static fortharray* namedArray(char* name, forthMemory* mem, psk node) - { - if(!is_op(node)) - { - if((node->v.fl & VISIBLE_FLAGS) == 0) - { - char* arrname = &node->u.sobj; - fortharray* arr; - for(arr = mem->arr; arr; arr = arr->next) - { - if(!strcmp(arr->name, arrname)) - { - return arr; - } - } - return 0; - - } - else - { - errorprintf("First argument of \"%s\" must be without any prefixes.\n", name); - return 0; - } - } - else - { - errorprintf("First argument of \"%s\" must be an atom.\n", name); - return 0; - } - } - -static forthword* polish2(forthMemory* mem, jumpblock* jumps, psk code, forthword* wordp, Boolean commentsAllowed) -/* jumps points to 5 words as explained for AND and OR */ - { - if(wordp == 0) - return 0; /* Something wrong happened. */ - forthvariable** varp = &(mem->var); - fortharray** arrp = &(mem->arr); - switch(Op(code)) - { - case EQUALS: - { - if(!calcnew(code, mem, TRUE)) - return 0; - mustpop = enopop; - return wordp; - } - case PLUS: - wordp = polish2(mem, jumps, code->LEFT, wordp, FALSE); - wordp = polish2(mem, jumps, code->RIGHT, wordp, FALSE); - if(wordp == 0) - return 0; /* Something wrong happened. */ - wordp->action = Plus; - wordp->offset = 0; - mustpop = epop; - return ++wordp; - case TIMES: - wordp = polish2(mem, jumps, code->LEFT, wordp, FALSE); - wordp = polish2(mem, jumps, code->RIGHT, wordp, FALSE); - if(wordp == 0) - return 0; /* Something wrong happened. */ - wordp->action = Times; - wordp->offset = 0; - mustpop = epop; - return ++wordp; - case EXP: - wordp = polish2(mem, jumps, code->RIGHT, wordp, FALSE); /* SIC! */ - wordp = polish2(mem, jumps, code->LEFT, wordp, FALSE); - if(wordp == 0) - return 0; /* Something wrong happened. */ - wordp->action = Pow; - wordp->offset = 0; - mustpop = epop; - return ++wordp; - case LOG: - wordp = polish2(mem, jumps, code->LEFT, wordp, FALSE); - wordp = polish2(mem, jumps, code->RIGHT, wordp, FALSE); - if(wordp == 0) - return 0; /* Something wrong happened. */ - wordp->action = Log; - wordp->offset = 0; - mustpop = epop; - return ++wordp; - case AND: - { - /* - 0 or 1 Result of comparison between to doubles - AND @1 address to jump to 'if false' == end of RIGHT - RIGHT wstart of 'if true' branch - .... - .... end of 'if true' branch (RIGHT) - @1: .... - .... - - */ - forthword* saveword; - saveword = wordp; - forthword* lhs = wordp + sizeof(jumpblock) / sizeof(forthword); - jumpblock* j5 = (jumpblock*)wordp; - wordp = polish2(mem, j5, code->LEFT, lhs, TRUE); - if(wordp == 0) - { - mustpop = enopop; - return 0; /* Something wrong happened. */ - } - else if(wordp == lhs) /* LHS is function definition or another empty statement. Ignore this & operator. */ - { - wordp = polish2(mem, jumps, code->RIGHT, saveword, TRUE); - return wordp; - } - else - { - wordp->action = Branch; - wordp->u.logic = fand; - wordp->offset = (unsigned int)((j5->j + ((mustpop == epop) ? epopS : eS)) - mem->word); - ++wordp; - j5->j[estart].offset = (unsigned int)(((j5->j + estart) + sizeof(jumpblock) / sizeof(forthword)) - mem->word); - j5->j[estart].action = Branch; - j5->j[estart].u.logic = fand; - j5->j[epopS].offset = 1; - j5->j[epopS].action = Pop; - j5->j[epopS].u.logic = fand; - j5->j[eS].offset = (unsigned int)(wordp - mem->word); - j5->j[eS].action = Branch; - j5->j[eS].u.logic = fand; - j5->j[epopF].offset = 1; - j5->j[epopF].action = Pop; - j5->j[epopF].u.logic = fand; - j5->j[eF].offset = (unsigned int)((jumps->j + eF) - mem->word); - j5->j[eF].action = Branch; - j5->j[eF].u.logic = fand; - saveword = wordp; - wordp = polish2(mem, jumps, code->RIGHT, wordp, TRUE); - if(!wordp) - { - //showProblematicNode("wordp==0", code->RIGHT); - return 0; - } - if(wordp == saveword) - { - wordp->action = NoOp; - wordp->u.logic = fand; - } - else - { - wordp->action = Branch; - wordp->u.logic = fand; - wordp->offset = (unsigned int)((jumps->j + ((mustpop == epop) ? epopS : eS)) - mem->word); - } - ++wordp; - } - mustpop = enopop; - return wordp; - } - case OR: /* jump if true, continue if false */ - { - /* - 0 or 1 Result of comparison between to doubles - OR @1 address to jump to 'if true' == end of RIGHT - RIGHT wstart of 'if false' branch - .... - .... end of 'if false' branch (RIGHT) - @1: .... - .... - - */ - forthword* saveword = wordp; - forthword* lhs = wordp + sizeof(jumpblock) / sizeof(forthword); - jumpblock* j5 = (jumpblock*)wordp; - wordp = polish2(mem, j5, code->LEFT, lhs, TRUE); - if(wordp == 0) - { - mustpop = enopop; - return 0; /* Something wrong happened. */ - } - else if(wordp == lhs) /* LHS is empty. Ignore this | operator. */ - { - return saveword; - } - else - { - wordp->action = Branch; - wordp->u.logic = fOr; - wordp->offset = (unsigned int)((j5->j + ((mustpop == epop) ? epopS : eS)) - mem->word); - ++wordp; - j5->j[estart].offset = (unsigned int)(((j5->j + estart) + sizeof(jumpblock) / sizeof(forthword)) - mem->word); - j5->j[estart].action = Branch; - j5->j[estart].u.logic = fOr; - j5->j[epopS].offset = 1; - j5->j[epopS].action = Pop; - j5->j[epopS].u.logic = fOr; - j5->j[eS].offset = (unsigned int)(&(jumps->j[eS]) - mem->word); - j5->j[eS].action = Branch; - j5->j[eS].u.logic = fOr; - j5->j[epopF].offset = 1; - j5->j[epopF].action = Pop; - j5->j[epopF].u.logic = fOr; - j5->j[eF].offset = (unsigned int)(wordp - mem->word); - j5->j[eF].action = Branch; - j5->j[eF].u.logic = fOr; - saveword = wordp; - wordp = polish2(mem, jumps, code->RIGHT, wordp, TRUE); - if(wordp == 0) - { - return 0; - } - wordp->action = Branch; - wordp->u.logic = fOr; - wordp->offset = (unsigned int)((jumps->j + ((mustpop == epop) ? epopS : eS)) - mem->word); - ++wordp; - } - mustpop = enopop; - return wordp; - } - case MATCH: - { - wordp = polish2(mem, jumps, code->LEFT, wordp, FALSE); - wordp = polish2(mem, jumps, code->RIGHT, wordp, FALSE); - if(wordp == 0) - { - mustpop = enopop; - return 0; /* Something wrong happened. */ - } - if(!(code->RIGHT->v.fl & UNIFY) & !is_op(code->RIGHT)) - { - if(FLESS(code->RIGHT)) - { - wordp->action = Fless; - } - else if(FLESS_EQUAL(code->RIGHT)) - { - wordp->action = Fless_equal; - } - else if(FMORE_EQUAL(code->RIGHT)) - { - wordp->action = Fmore_equal; - } - else if(FMORE(code->RIGHT)) - { - wordp->action = Fmore; - } - else if(FUNEQUAL(code->RIGHT)) - { - wordp->action = Funequal; - } - else if(FLESSORMORE(code->RIGHT)) - { - wordp->action = Funequal; - } - else if(FEQUAL(code->RIGHT)) - { - wordp->action = Fequal; - } - else if(FNOTLESSORMORE(code->RIGHT)) - { - wordp->action = Fequal; - } - else if(VLESS(code->RIGHT)) - { - wordp->action = Fless; - } - else if(VLESS_EQUAL(code->RIGHT)) - { - wordp->action = Fless_equal; - } - else if(VMORE_EQUAL(code->RIGHT)) - { - wordp->action = Fmore_equal; - } - else if(VMORE(code->RIGHT)) - { - wordp->action = Fmore; - } - else if(VUNEQUAL(code->RIGHT)) - { - wordp->action = Funequal; - } - else if(VLESSORMORE(code->RIGHT)) - { - wordp->action = Funequal; - } - else if(VEQUAL(code->RIGHT)) - { - wordp->action = Fequal; - } - else if(VNOTLESSORMORE(code->RIGHT)) - { - wordp->action = Fequal; - } - else if(ILESS(code->RIGHT)) - { - wordp->action = Fless; - } - else if(ILESS_EQUAL(code->RIGHT)) - { - wordp->action = Fless_equal; - } - else if(IMORE_EQUAL(code->RIGHT)) - { - wordp->action = Fmore_equal; - } - else if(IMORE(code->RIGHT)) - { - wordp->action = Fmore; - } - else if(IUNEQUAL(code->RIGHT)) - { - wordp->action = Funequal; - } - else if(ILESSORMORE(code->RIGHT)) - { - wordp->action = Funequal; - } - else if(IEQUAL(code->RIGHT)) - { - wordp->action = Fequal; - } - else if(INOTLESSORMORE(code->RIGHT)) - { - wordp->action = Fequal; - } - else - return wordp; - wordp->offset = (unsigned int)(&(jumps->j[epopF]) - mem->word); - mustpop = epop; - return ++wordp; - } - return wordp; - } - case FUU: /* whl'(blbla) */ - { - forthword* saveword = wordp; - forthword* loop = wordp + sizeof(jumpblock) / sizeof(forthword); - jumpblock* j5 = (jumpblock*)wordp; - wordp = polish2(mem, j5, code->RIGHT, loop, FALSE); - if(wordp == 0) - { - mustpop = enopop; - return 0; /* Something wrong happened. */ - } - else if(wordp == loop) /* Loop body is function definition. Ignore this ' operator. */ - { - mustpop = enopop; - return saveword; - } - else - { - wordp->action = Branch; - wordp->u.logic = fwhl; - wordp->offset = (unsigned int)((j5->j + ((mustpop == epop) ? epopS : eS)) - mem->word); /* If all good, jump back to wstart of loop */ - - ++wordp; - - j5->j[estart].offset = (unsigned int)(((j5->j + estart) + sizeof(jumpblock) / sizeof(forthword)) - mem->word); - j5->j[estart].action = Branch; - j5->j[estart].u.logic = fwhl; - j5->j[epopS].offset = 1; - j5->j[epopS].action = Pop; - j5->j[epopS].u.logic = fwhl; - j5->j[eS].offset = j5->j[estart].offset; - j5->j[eS].action = Branch; - j5->j[eS].u.logic = fwhl; - j5->j[epopF].offset = 1; - j5->j[epopF].action = Pop; - j5->j[epopF].u.logic = fwhl; - j5->j[eF].offset = (unsigned int)(&(jumps->j[eS]) - mem->word); /* whl loop terminates when one of the steps in the loop failed */ - j5->j[eF].action = Branch; - j5->j[eF].u.logic = fwhl; - mustpop = enopop; - return wordp; - } - } - case FUN: - { - Etriple* ep = etriples; - char* name = &code->LEFT->u.sobj; - psk rhs = code->RIGHT; - if(!strcmp(name, "tbl")) - { /* Check that name is array name and that arity is correct. */ - if(is_op(rhs)) - { - fortharray* arr = namedArray("tbl", mem, rhs->LEFT); - if(arr == 0) - { - arr = haveArray(mem, rhs, FALSE); - if(arr->size != 0) - return wordp; /* Arguments are fixed. Memory is allocated foNo nr array cells. No need to reevaluate. */ - } - - if(arr == 0) - { - errorprintf("tbl:Array is not declared\n"); - return 0; - } - } - else - { - errorprintf("Right hand side of \"tbl$\" must be at least two arguments: an array name and one or more extents.\n"); - return 0; - } - } - else if(!strcmp(name, "idx")) - { /* Check that name is array name and that arity is correct. */ - if(is_op(rhs)) - { - fortharray* arr = namedArray("idx", mem, rhs->LEFT); - if(arr == 0) - { - showProblematicNode("idx:Array is not declared: ", code); - return 0; - } - - size_t h = 1; - psk R; - for(R = rhs; Op(R->RIGHT) == COMMA; R = R->RIGHT) - ++h; - size_t rank = arr->rank; - if(rank == 0) - { - // errorprintf( "idx: Array \"%s\" has unknown rank and extent(s). Assuming %zu, based on idx.\n", arrname, h); - rank = arr->rank = h; - // return 0; - } - if(h != rank) - { - errorprintf("idx: Array \"%s\" expects %zu arguments. %zu have been found\n", arr->name, rank, h); - return 0; - } - if(arr->extent != 0) - { - size_t* rng = arr->extent + rank; - for(R = rhs->RIGHT; ; R = R->RIGHT) - { - psk Arg; - --rng; - if(*rng != 0) /* If 0, extent is still unknown. Has to wait until running. */ - { - if(is_op(R)) - Arg = R->LEFT; - else - Arg = R; - if(INTEGER_NOT_NEG(Arg)) - { - long index = strtol(&(Arg->u.sobj), 0, 10); - if(index < 0 || index >= (long)(*rng)) - { - errorprintf("idx: Array \"%s\": index %zu is out of bounds 0 <= index < %zu, found %ld\n", arr->name, rank - (rng - arr->extent), *rng, index); - return 0; - } - } - } - if(!is_op(R)) - break; - } - } - } - else - { - errorprintf("Right hand side of \"idx$\" must be at least two arguments: an array name and one or more extents.\n"); - return 0; - } - } - else if(!strcmp(name, "rank")) - { - fortharray* arr = namedArray("rank", mem, rhs); - if(arr == 0) - { - errorprintf("\"extent\" takes one argument: the name of an array.\n"); - return 0; - } - } - else if(!strcmp(name, "extent")) - { - if(!is_op(rhs) || namedArray("extent", mem, rhs->LEFT) == 0 || argcount(rhs->RIGHT) != 1) - { - errorprintf("\"extent\" takes two arguments: the name of an array and the extent index.\n"); - showProblematicNode("Here", rhs); - return 0; - } - } - else - { - /* Check whether built in or user defined. */ - - forthMemory* func = 0, * childMem = 0; - for(forthMemory* currentMem = mem; currentMem && !func; childMem = currentMem, currentMem = currentMem->parent) - { - for(func = currentMem->functions; func; func = func->nextFnc) - { - if(func != childMem // No recursion! (Has to be tested during compilation) - && func->name - && !strcmp(func->name, name) - ) - break; - } - } - - if(func) - { - parameter* parms; - if(func->nparameters > 0) - { - for(parms = func->parameters + func->nparameters; --parms >= func->parameters;) - { - if(!is_op(rhs) && parms > func->parameters) - { - errorprintf("Too few parameters.\n"); - // return 0; - } - psk parm; - if(Op(rhs) == COMMA) - parm = rhs->LEFT; - else - parm = rhs; - if(parms->scalar_or_array == Array) - { - if(is_op(parm)) - { - errorprintf("Array name expected.\n"); - return 0; - } - else - { - if(HAS_VISIBLE_FLAGS_OR_MINUS(parm)) - { - errorprintf("When passing an array to a function, the array name must be free of any prefixes.\n"); - return 0; - } - } - } - if(is_op(rhs)) - rhs = rhs->RIGHT; - else - { - assert(parms == func->parameters); - } - } - } - } - else - { - int ArgCount = argcount(rhs); - if(ArgCount < 0) - { - errorprintf("Function \"%s\" has an invalid argument.\n", name); - return 0; - } - else if(ArgCount == 0) - { - errorprintf("Function \"%s\" used without argument(s).\n", name); - return 0; - } - } - } - wordp = polish2(mem, jumps, code->RIGHT, wordp, FALSE); - if(wordp == 0) - return 0; /* Something wrong happened. */ - wordp->offset = 0; - if(code->v.fl & INDIRECT) - { - for(; ep->name != 0; ++ep) - { - if(!strcmp(ep->name + 1, name) && ep->name[0] == 'E') /* ! -> E(xclamation) */ - { - wordp->action = ep->action; - if(wordp->action == EIdx) - if(!setArity(wordp, code, ep->arity)) - return 0; - mustpop = epop; - return ++wordp; - } - } - } - else if(code->v.fl & UNIFY) - { - for(; ep->name != 0; ++ep) - { - if(!strcmp(ep->name + 1, name) && ep->name[0] == 'Q') /* ? -> Q(uestion)*/ - { - wordp->action = ep->action; - if(wordp->action == QIdx) - if(!setArity(wordp, code, ep->arity)) - return 0; - mustpop = epop; - return ++wordp; - } - } - } - else - { - for(; ep->name != 0; ++ep) - { - if(!strcmp(ep->name, name)) - { - wordp->action = ep->action; - //if(wordp->action == Idx || wordp->action == Tbl) - if(!setArity(wordp, code, ep->arity)) - { - errorprintf("Argument error in call to \"%s\".\n", name); - return 0; - } - mustpop = enopop; - return ++wordp; - } - } - } - - wordp->action = Afunction; - forthMemory* func = 0, * childMem = 0; - for(forthMemory* currentMem = mem; currentMem && !func; childMem = currentMem, currentMem = currentMem->parent) - { - for(func = currentMem->functions; func; func = func->nextFnc) - { - if(func != childMem // No recursion! (Has to be tested during compilation) - && func->name - && !strcmp(func->name, name) - ) - { - setArity(wordp, code, (unsigned int)func->nparameters); - wordp->action = Afunction; - wordp->u.that = func; - mustpop = epop; - return ++wordp; - } - } - } - - errorprintf("Function named \"%s\" not found.\n", name); - return 0; /* Something wrong happened. */ - } - default: - { - if(is_op(code)) /* e.g. COMMA */ - { - wordp = polish2(mem, jumps, code->LEFT, wordp, FALSE); - wordp = polish2(mem, jumps, code->RIGHT, wordp, FALSE); - mustpop = enopop; - return wordp; - } - else - { - if(INTEGER_COMP(code)) - { - wordp->u.val.floating = strtod(&(code->u.sobj), 0); - if(HAS_MINUS_SIGN(code)) - { - wordp->u.val.floating = -(wordp->u.val.floating); - } - wordp->action = valPush; - /*When executing, push number onto the data stack*/ - } - else if(code->v.fl & QDOUBLE) - { - wordp->u.val.floating = strtod(&(code->u.sobj), 0); - if(HAS_MINUS_SIGN(code)) - { - wordp->u.val.floating = -(wordp->u.val.floating); - } - wordp->action = valPush; - /*When executing, push number onto the data stack*/ - } - else if(RAT_RAT_COMP(code)) - { - char* slash = strchr(&(code->u.sobj), '/'); - if(slash) - { - double numerator; - double denominator; - *slash = '\0'; - numerator = strtod(&(code->u.sobj), 0); - denominator = strtod(slash + 1, 0); - *slash = '/'; - wordp->u.val.floating = numerator / denominator; - if(HAS_MINUS_SIGN(code)) - wordp->u.val.floating = -wordp->u.val.floating; - wordp->action = valPush; - } - } - else - { - if(code->v.fl & (INDIRECT | UNIFY)) - { - /*variable*/ - forthvariable* v = getVariablePointer(*varp, &(code->u.sobj)); - if(v == 0) - { - if(argumentArrayNumber(code) >= 0) - { - fortharray* a = getOrCreateArrayPointerButNoArray(arrp, &(code->u.sobj)); - if(a == 0) - return 0; /* Something wrong happened. */ - wordp->u.arrp = a; - wordp->action = (code->v.fl & INDIRECT) ? ArrElmValPush : stack2ArrElm; - } - else - { - fortharray* a = getArrayPointer(arrp, &(code->u.sobj)); - if(a) - { - wordp->u.arrp = a; - wordp->action = (code->v.fl & INDIRECT) ? ArrElmValPush : stack2ArrElm; - } - else - { - forthvariable* var = createVariablePointer(varp, &(code->u.sobj)); - if(var) - wordp->u.valp = &(var->val); - wordp->action = (code->v.fl & INDIRECT) ? varPush : stack2var; - } - } - } - else - { - wordp->u.valp = &(v->val); - wordp->action = (code->v.fl & INDIRECT) ? varPush : stack2var; - /* When executing, - * varPush: follow the pointer wordp->u.valp and push the pointed-at value onto the stack. - * stack2var: follow the pointer wordp->u.valp and assign to that address the value that is on top of the stack. Do not change the stack. - */ - } - } - else if(/*code->u.sobj == '\0' || */ commentsAllowed) - { - return wordp; - } - else - { - /*array*/ - fortharray* a = getOrCreateArrayPointerButNoArray(arrp, &(code->u.sobj)); - if(a != 0 || argumentArrayNumber(code) >= 0) - { - wordp->u.arrp = a; - wordp->action = valPush; - /* When executing, - * valPush: valPush the value wordp->u.arrp onto the stack. - */ - } - else - { - mustpop = enopop; - if(a == 0) - return 0; - return wordp; - } - } - wordp->offset = 0; - } - ++wordp; - mustpop = epop; - return wordp; - } - } - } - } - -static Boolean setparm(size_t Ndecl, forthMemory* forthstuff, psk declaration, Boolean in_function) - { - parameter* npar; - if(is_op(declaration->LEFT)) - { - errorprintf("Parameter declaration requires 's' or 'a'.\n"); - return FALSE; - } - - if(declaration->LEFT->u.sobj == 's') // scalar - { - if(is_op(declaration->RIGHT)) - { - errorprintf("Scalar parameter declaration doesn't take extent.\n"); - return FALSE; - } - forthvariable* var = getVariablePointer(forthstuff->var, &(declaration->RIGHT->u.sobj)); - - if(!var) - { - var = createVariablePointer(&(forthstuff->var), &(declaration->RIGHT->u.sobj)); - } - - if(var) - { - npar = forthstuff->parameters + Ndecl; - npar->scalar_or_array = Scalar; - npar->u.v = var; - } - } - else // array - { - fortharray* a = haveArray(forthstuff, declaration->RIGHT, in_function); - if(a) - { - npar = forthstuff->parameters + Ndecl; - if(npar) - { - npar->scalar_or_array = Array; - npar->u.a = a; - } - } - else - return FALSE; - } - return TRUE; - } - -static Boolean calcdie(forthMemory* mem); - -static Boolean functiondie(forthMemory* mem) - { - if(!mem) - { - errorprintf("calculation.functiondie does not deallocate, member \"mem\" is zero.\n"); - return FALSE; - } - forthvariable* curvarp = mem->var; - fortharray* curarr = mem->arr; - forthMemory* functions = mem->functions; - parameter* parameters = mem->parameters; - while(curvarp) - { - forthvariable* nextvarp = curvarp->next; - if(curvarp->name) - { - bfree(curvarp->name); - curvarp->name = 0; - } - bfree(curvarp); - curvarp = nextvarp; - } - while(curarr) - { - fortharray* nextarrp = curarr->next; - if(curarr->name) - { - /* extent and pval are not allocated when function is called. - Instead, pointers are set to caller's pointers. */ - parameter* pars = 0; - for(pars = parameters; pars < parameters + mem->nparameters; ++pars) - { - if(pars->scalar_or_array == Array) - { - if(!strcmp(pars->u.a->name, curarr->name)) - { - pars->scalar_or_array = Neither; - break; - } - } - } - - if(pars == parameters + mem->nparameters) - { /* Reached end of loop without matching a parameter name. - So this array is not a function parameter. - So the function owns the data and should delete them. - */ - if(curarr->extent) - { - bfree(curarr->extent); - curarr->extent = 0; - curarr->stride = 0; - } - if(curarr->pval) - { - bfree(curarr->pval); - curarr->pval = 0; - } - } - bfree(curarr->name); - curarr->name = 0; - } - - bfree(curarr); - curarr = nextarrp; - } - mem->arr = 0; - if(mem->parameters) - { - bfree(mem->parameters); - mem->parameters = 0; - } - for(; functions;) - { - forthMemory* nextfunc = functions->nextFnc; - functiondie(functions); - functions = nextfunc; - } - mem->functions = 0; - if(mem->name) - { - bfree(mem->name); - mem->name = 0; - } - if(mem->word) - { - bfree(mem->word); - mem->word = 0; - } - bfree(mem); - return TRUE; - } - -static forthMemory* calcnew(psk arg, forthMemory* parent, Boolean in_function) - { - int newval = 0; - psk code, fullcode; - psk declarations = 0; - code = getValue(arg, &newval); - fullcode = code; - if(is_op(code) && Op(code) == DOT) - { - declarations = code->LEFT; - code = code->RIGHT; - } - if(code) - { - char* name; - forthword* lastword; - forthMemory* forthstuff; - int length; - length = polish1(code, FALSE) + sizeof(jumpblock) / sizeof(forthword) + 1; /* 1 for TheEnd */ - if(length < 1) - { - errorprintf("polish1 returns length < 0 [%d]\n", length); - return 0; /* Something wrong happened. */ - } - forthstuff = (forthMemory*)bmalloc(sizeof(forthMemory)); - if(forthstuff) - { - memset(forthstuff, 0, sizeof(forthMemory)); - if(parent) - { - forthstuff->parent = parent; - forthMemory* funcs = parent->functions; - parent->functions = forthstuff; - forthstuff->nextFnc = funcs; - } - forthstuff->name = 0; - if(is_op(arg) && !is_op(arg->LEFT)) - { - name = &(arg->LEFT->u.sobj); - if(*name) - { - //printf("Creating function [%s]\n", name); - assert(forthstuff->name == 0); - forthstuff->name = (char*)bmalloc(strlen(name) + 1); - if(forthstuff->name) - { - strcpy(forthstuff->name, name); - } - } - } - /* - forthstuff->functions = 0; - forthstuff->nextFnc = 0; - forthstuff->var = 0; - forthstuff->arr = 0; - */ - assert(forthstuff->word == 0); - forthstuff->word = bmalloc(length * sizeof(forthword)); - if(forthstuff->word) - { - memset(forthstuff->word, 0, length * sizeof(forthword)); - forthstuff->wordp = forthstuff->word; - forthstuff->sp = forthstuff->stack; - forthstuff->parameters = 0; - if(declarations) - { - psk decl; - size_t Ndecl = 0; - for(decl = declarations; decl && is_op(decl); decl = decl->RIGHT) - { - ++Ndecl; - if(Op(decl) == DOT) /*Just one parameter that is an array*/ - break; - } - - forthstuff->nparameters = Ndecl; - if(Ndecl > 0) - { - forthstuff->parameters = bmalloc(Ndecl * sizeof(parameter)); - if(forthstuff->parameters != 0) - { - for(decl = declarations; Ndecl-- > 0 && decl && is_op(decl); decl = decl->RIGHT) - { - if(Op(decl) == DOT) - { - if(!setparm(Ndecl, forthstuff, decl, in_function)) - { - errorprintf("Error in parameter declaration.\n"); - return 0; /* Something wrong happened. */ - } - break; - } - else - { - if(is_op(decl->LEFT) && Op(decl->LEFT) == DOT) - if(!setparm(Ndecl, forthstuff, decl->LEFT, in_function)) - { - errorprintf("Error in parameter declaration.\n"); - return 0; /* Something wrong happened. */ - } - } - } - } - } - } - jumpblock* j5 = (jumpblock*)(forthstuff->word); - j5->j[estart].offset = (unsigned int)((&(j5->j[0]) + sizeof(jumpblock) / sizeof(forthword)) - forthstuff->word); - j5->j[estart].action = Branch; - //j5->j[epopS].offset = 1; - //j5->j[epopS].action = Pop; - //j5->j[eS].offset = 0; - //j5->j[eS].action = TheEnd; - j5->j[epopF].offset = 1; - j5->j[epopF].action = Pop; - //j5->j[eF].offset = 0; - //j5->j[eF].action = TheEnd; - - mustpop = enopop; - - lastword = polish2(forthstuff, j5, code, forthstuff->word + sizeof(jumpblock) / sizeof(forthword), FALSE); - if(lastword != 0) - { - unsigned int theend = (unsigned int)(lastword - forthstuff->word); - if(theend + 1 == (unsigned int)length) - { - j5->j[epopS].offset = theend; - j5->j[epopS].action = Branch; /* Leave last value on the stack. (If there is one.) */ - j5->j[eS].offset = theend; - j5->j[eS].action = Branch; - j5->j[eF].offset = theend; - j5->j[eF].action = Branch; - - lastword->action = TheEnd; - if(newval) - wipe(fullcode); - char* marks = calloc(length, sizeof(char)); - if(marks) - { -#ifdef SHOWOPTIMIZATIONS - int loop = 0; -#endif - for(;;) - { -#ifdef SHOWOPTIMIZATIONS - printf("\nOptimization loop %d\n", ++loop); -#endif - Boolean somethingdone = FALSE; - somethingdone |= shortcutJumpChains(forthstuff->word); - somethingdone |= combinePopBranch(forthstuff->word); - somethingdone |= combineBranchPopBranch(forthstuff->word); - memset(marks, 0, length * sizeof(char)); - somethingdone |= markUnReachable(forthstuff->word, marks); - //somethingdone |= moveBranchesTowardsEndOverNoOp(forthstuff->word); - if(somethingdone) - { - length = removeNoOp(forthstuff, length); - continue; - } - somethingdone |= dissolveNextWordBranches(forthstuff->word); - somethingdone |= combineUnconditionalBranchTovalPush(forthstuff->word); - memset(marks, 0, length * sizeof(char)); - somethingdone |= combineval2stack(forthstuff->word, marks); // FAULTY! - memset(marks, 0, length * sizeof(char)); - somethingdone |= combinePopThenPop(forthstuff->word, marks); - somethingdone |= eliminateBranch(forthstuff->word); - somethingdone |= stack2var_var2stack(forthstuff->word); - somethingdone |= removeIdempotentActions(forthstuff->word); - somethingdone |= combinePushAndOperation(forthstuff->word); - if(somethingdone) - { - length = removeNoOp(forthstuff, length); - continue; - } - break; - } - free(marks); - } - return forthstuff; - } - } - } - if(!in_function) - { - calcdie(forthstuff); - } - else - { - showProblematicNode("In function:", 0); - showProblematicNode(forthstuff->name, 0); - } - } - } - wipe(fullcode); - return 0; /* Something wrong happened. */ - } - -static Boolean calculationnew(struct typedObjectnode* This, ppsk arg) - { - //printf("sizeof forthword %zu\n", sizeof(forthword)); - if(is_op(*arg)) - { - forthMemory* forthstuff = calcnew((*arg)->RIGHT, 0, FALSE); - if(forthstuff) - { - This->voiddata = forthstuff; - return TRUE; - } - } - return FALSE; - } - -static Boolean calcdie(forthMemory* mem) - { - if(mem != 0) - { - if(mem->word) - { - bfree(mem->word); - mem->word = 0; - } - forthvariable* curvarp = mem->var; - fortharray* curarr = mem->arr; - forthMemory* functions = mem->functions; - while(curvarp) - { - forthvariable* nextvarp = curvarp->next; - bfree(curvarp->name); - curvarp->name = 0; - bfree(curvarp); - curvarp = nextvarp; - } - while(curarr) - { - fortharray* nextarrp = curarr->next; - bfree(curarr->name); - curarr->name = 0; - if(curarr->extent) - { - bfree(curarr->extent); - curarr->extent = 0; - curarr->stride = 0; - } - if(curarr->pval) - { - bfree(curarr->pval); - curarr->pval = 0; - } - bfree(curarr); - curarr = nextarrp; - } - mem->arr = 0; - if(mem->parameters) - { - bfree(mem->parameters); - mem->parameters = 0; - } - for(; functions;) - { - forthMemory* nextfunc = functions->nextFnc; - functiondie(functions); - functions = nextfunc; - } - mem->functions = 0; - if(mem->name) - { - bfree(mem->name); - mem->name = 0; - } - bfree(mem); - } - return TRUE; - } - -static Boolean calculationdie(struct typedObjectnode* This, ppsk arg) - { - return calcdie((forthMemory*)(This->voiddata)); - } - -static method calculation[] = { - {"calculate",calculate}, - {"run",calculate}, /*Alternative to `calculate' and `go'*/ - {"go",calculate}, /*Alternative to calculate and `run'*/ - {"trc",trc}, - {"print",print}, - {"export",eksport}, - {"New",calculationnew}, - {"Die",calculationdie}, - {NULL,NULL} }; -/* -Standard methods are 'New' and 'Die'. -A user defined 'die' can be added after creation of the object and will be invoked just before 'Die'. - -Example: - -new$hash:?h; - - (=(Insert=.out$Insert & lst$its & lst$Its & (Its..insert)$!arg) - (die = .out$"Oh dear") - ):(=?(h.)); - - (h..Insert)$(X.x); - - :?h; - - (=(Insert=.out$Insert & lst$its & lst$Its & (Its..insert)$!arg) - (die = .out$"The end.") - ):(=?(new$hash:?k)); - - (k..Insert)$(Y.y); - - :?k; - -A little problem is that in the last example, the '?' ends up as a flag on the '=' node. - -Bart 20010222 - -*/ - -/* End of calculation.c */ - -/* Begin of binding.c */ - -static psk SymbolBinding(psk variabele, int* newval, int twolevelsofindirection) - { - psk pbinding; - *newval = 0; - if((pbinding = getValue(variabele, newval)) != NULL) - { - if(twolevelsofindirection) - { - psk peval; - - if(pbinding->v.fl & INDIRECT) - { - peval = subtreecopy(pbinding); - peval = eval(peval); - if(!isSUCCESS(peval) - || (is_op(peval) - && Op(peval) != EQUALS - && Op(peval) != DOT - ) - ) - { - wipe(peval); - return 0; - } - if(*newval) - wipe(pbinding); - *newval = TRUE; - pbinding = peval; - } - if(is_op(pbinding)) - { - if(is_object(pbinding)) - { - peval = same_as_w(pbinding); - } - else - { - peval = subtreecopy(pbinding); - /* - a=b=(c.d) - c=(d=e) - f:?!!(a.b) - !e - f - */ - peval = eval(peval); - if(!isSUCCESS(peval) - || (is_op(peval) - && Op(peval) != EQUALS - && Op(peval) != DOT - ) - ) - { - wipe(peval); - if(*newval) - { - *newval = FALSE; - wipe(pbinding); - } - return NULL; - } - } - assert(pbinding); - if(*newval) - { - *newval = FALSE; - wipe(pbinding); - } - pbinding = SymbolBinding(peval, newval, (peval->v.fl & DOUBLY_INDIRECT)); - wipe(peval); - } - else - { - int newv = *newval; - psk binding; - *newval = FALSE; - binding = SymbolBinding(pbinding, newval, pbinding->v.fl & DOUBLY_INDIRECT); - if(newv) - { - wipe(pbinding); - } - pbinding = binding; - } - } - } - return pbinding; - } - -static psk SymbolBinding_w(psk variabele, int twolevelsofindirection) -/* twolevelsofindirection because the variable not always can have the -bangs. Example: - (A==B) & a b c:? [?!!A -first finds (=B), which is an object that should not obtain the flags !! as in -!!(=B), because that would have a side effect on A as A=!!(=B) -*/ - { - psk pbinding; - int newval; - newval = FALSE; - if((pbinding = SymbolBinding(variabele, &newval, twolevelsofindirection)) != NULL) - { - ULONG nameflags, valueflags; - nameflags = (variabele->v.fl & (BEQUEST | SUCCESS)); - if(ANYNEGATION(variabele->v.fl)) - nameflags |= NOT; - - valueflags = (pbinding)->v.fl; - valueflags |= (nameflags & (BEQUEST | NOT)); - valueflags ^= ((nameflags & SUCCESS) ^ SUCCESS); - - assert(pbinding != NULL); - - if(Op(pbinding) == EQUALS) - { - if(!newval) - { - pbinding->RIGHT = Head(pbinding->RIGHT); - pbinding = same_as_w(pbinding); - } - } - else if((pbinding)->v.fl == valueflags) - { - if(!newval) - { - pbinding = same_as_w(pbinding); - } - } - else - { - assert(Op(pbinding) != EQUALS); - if(newval) - { - pbinding = isolated(pbinding); - } - else - { - pbinding = subtreecopy(pbinding); - } - (pbinding)->v.fl = valueflags & COPYFILTER; /* ~ALL_REFCOUNT_BITS_SET;*/ - } - } - return pbinding; - } -/* End of binding.c */ - -/* Begin of position.c */ - -static LONG expressionLength(psk Pnode, unsigned int op) - { - if(!is_op(Pnode) && Pnode->u.lobj == knil[op >> OPSH]->u.lobj) - return 0; - else - { - LONG len = 1; - while(Op(Pnode) == op) - { - ++len; - Pnode = Pnode->RIGHT; - } - return len; - } - } - -static char doPosition(matchstate s, psk pat, LONG pposition, size_t stringLength, psk expr -#if CUTOFFSUGGEST - , char** mayMoveStartOfSubject -#endif - , unsigned int op -) - { - ULONG Flgs; - psk name; - LONG pos; - Flgs = pat->v.fl; -#if CUTOFFSUGGEST - if(((Flgs & (SUCCESS | VISIBLE_FLAGS_POS0 | IS_OPERATOR)) == (SUCCESS | QNUMBER)) - && mayMoveStartOfSubject - && *mayMoveStartOfSubject != 0 - ) - { - pos = toLong(pat); /* [20 */ - if(pos < 0) - pos += (expr == NULL ? (LONG)stringLength : expr ? expressionLength(expr, op) : 0) + 1; /* [(20+-1*(!len+1)) -> `-7 */ - - if(pposition < pos - && (MORE_EQUAL(pat) || EQUAL(pat) || NOTLESSORMORE(pat)) - ) - { - if((long)stringLength > pos) - *mayMoveStartOfSubject += pos - pposition; - s.c.rmr = FALSE; /* [20 */ - return s.c.rmr; - } - else if(pposition <= pos - && MORE(pat) - ) - { - if((long)stringLength > pos) - *mayMoveStartOfSubject += pos - pposition + 1; - s.c.rmr = FALSE; /* [>5 */ - return s.c.rmr; - } - } -#endif - Flgs = pat->v.fl & (UNIFY | INDIRECT | DOUBLY_INDIRECT); - - name = subtreecopy(pat); - name->v.fl |= SUCCESS; - if((Flgs & UNIFY) && (is_op(pat) || (Flgs & INDIRECT))) - { - name->v.fl &= ~VISIBLE_FLAGS; - if(!is_op(name)) - name->v.fl |= READY; - s.c.rmr = (char)evaluate(name) & TRUE; - - if(!(s.c.rmr)) - { - wipe(name); - return FALSE; - } - } - else - { - s.c.rmr = (char)evaluate(name) & TRUE; - - if(!(s.c.rmr)) - { - wipe(name); - return FALSE; - } - - Flgs = pat->v.fl & UNIFY; - Flgs |= name->v.fl; - } - pat = name; - if(Flgs & UNIFY) - { - if(is_op(pat) - || pat->u.obj - ) - { - if(Flgs & INDIRECT) /* ?! of ?!! */ - { - psk loc; - if((loc = SymbolBinding_w(pat, Flgs & DOUBLY_INDIRECT)) != NULL) - { - if(is_object(loc)) - s.c.rmr = (char)icopy_insert(loc, pposition); - else - { - s.c.rmr = (char)evaluate(loc) & (TRUE | FENCE); - if(!icopy_insert(loc, pposition)) - s.c.rmr = FALSE; - } - wipe(loc); - } - else - s.c.rmr = FALSE; - } - else - { - s.c.rmr = (char)icopy_insert(pat, pposition); /* [?a */ - } - } - else - s.c.rmr = TRUE; - - if(name) - wipe(name); /* [?a */ - /* - ( ( CharacterLength - = length c p q - . 0:?length:?p - & @( !arg - : ? - ( [!p %?c [?q - & utf$!c:?k - & !q:?p - & 1+!length:?length - & ~ - ) - ? - ) - | !length - ) - & CharacterLength$str$(a chu$1000 b chu$100000 c):5 - ) - */ - return (char)(ONCE | POSITION_ONCE | s.c.rmr); - } - - if(((pat->v.fl & (SUCCESS | VISIBLE_FLAGS_POS0 | IS_OPERATOR)) == (SUCCESS | QNUMBER))) - { - pos = toLong(pat); /* [20 */ - if(pos < 0) - pos += (expr == NULL ? (LONG)stringLength : expressionLength(expr, op)) + 1; /* [(20+-1*(!len+1)) -> `-7 */ - if(LESS(pat)) - { /* [<18 */ - if(pposition < pos) - { - s.c.rmr = TRUE;/* [<18 */ - } - else - { - s.c.rmr = FALSE | POSITION_MAX_REACHED; - } - } - else if(LESS_EQUAL(pat)) - { - if(pposition < pos) - { - s.c.rmr = TRUE; - } - else if(pposition == pos) - { - s.c.rmr = TRUE | POSITION_MAX_REACHED; - } - else - { - s.c.rmr = FALSE | POSITION_MAX_REACHED; - } - } - else if(MORE_EQUAL(pat)) - { /* [~<13 */ - if(pposition >= pos) - { - s.c.rmr = TRUE; /* [~<13 */ - } - else - { - s.c.rmr = FALSE; /* [~<13 */ - } - } - else if(MORE(pat)) - { /* [>5 */ - if(pposition > pos) - { - s.c.rmr = TRUE; /* [>5 */ - } - else - { - s.c.rmr = FALSE; /* [>5 */ - } - } - else if(UNEQUAL(pat) || LESSORMORE(pat)) - { /* [~13 */ - if(pposition != pos) - { - s.c.rmr = TRUE; /* [~13 */ - } - else - { - s.c.rmr = FALSE; /* [~13 */ - } - } - else if(EQUAL(pat) || NOTLESSORMORE(pat)) - { - if(pposition == pos) - { - s.c.rmr = TRUE | POSITION_MAX_REACHED; /* [20 */ - } - else if(pposition > pos) - { - s.c.rmr = FALSE | POSITION_MAX_REACHED; - } - else - s.c.rmr = FALSE; /* [20 */ - } - } - else - { - s.c.rmr = FALSE; - } - wipe(pat); /* [20 */ - s.c.rmr |= ONCE | POSITION_ONCE; - return s.c.rmr; - } - -/* End of position.c */ - -/* Begin of stringmatch.c */ - -static int stringOncePattern(psk pat) - { - /* - This function has a side effect: it sets a flag in all pattern nodes that - can be matched by at most one non-trivial list element (a nonzero term in - a sum, a factor in a product that is not 1, or a nonempty word in a - sentence. Because the function depends on ATOMFILTERS, the algorithm - should be slightly different for normal matches and for string matches. - Ideally, two flags should be reserved. - */ - if(pat->v.fl & IMPLIEDFENCE) - { - return TRUE; - } - if(pat->v.fl & SATOMFILTERS) - { - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - } - else if(pat->v.fl & ATOMFILTERS) - { - return FALSE; - } - else if(IS_VARIABLE(pat) - || NOTHING(pat) - || (pat->v.fl & NONIDENT) /* @(abc:% c) */ - ) - { - return FALSE; - } - else if(!is_op(pat)) - { - if(!pat->u.obj) - { - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - } - else - { - return FALSE; - } - } - else - { - switch(Op(pat)) - { - case DOT: - case COMMA: - case EQUALS: - case EXP: - case LOG: - case DIF: - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - case OR: - if(stringOncePattern(pat->LEFT) && stringOncePattern(pat->RIGHT)) - { - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - } - break; - case MATCH: - if(stringOncePattern(pat->LEFT) || stringOncePattern(pat->RIGHT)) - { - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - } - break; - case AND: - if(stringOncePattern(pat->LEFT)) - { - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - } - break; - default: - break; - } - } - return FALSE; - } - -static char sdoEval(char* sub, char* cutoff, psk pat, psk subkn) - { - char ret; - psk loc; - psh(&sjtNode, &nilNode, NULL); - string_copy_insert(&sjtNode, subkn, sub, cutoff); - loc = subtreecopy(pat); - loc->v.fl &= ~(POSITION | NONIDENT | IMPLIEDFENCE | ONCE); - loc = eval(loc); - deleteNode(&sjtNode); - if(isSUCCESS(loc)) - { - ret = (loc->v.fl & FENCE) ? (TRUE | ONCE) : TRUE; - } - else - { - ret = (loc->v.fl & FENCE) ? ONCE : FALSE; - } - wipe(loc); - return ret; - } - -#if CUTOFFSUGGEST -static char stringmatch -(int ind - , char* wh - , char* sub - , char* cutoff - , psk pat - , psk subkn - , LONG pposition - , size_t stringLength - , char** suggestedCutOff - , char** mayMoveStartOfSubject -) -#else -char stringmatch -(int ind - , char* wh - , unsigned char* sub - , unsigned char* cutoff - , psk pat - , psk subkn - , LONG pposition - , size_t stringLength -) -#endif - { - /* - s.c.lmr and s.c.rmr have 3 independent bit fields : TRUE/FALSE, ONCE en FENCE. - TRUE/FALSE Whether the match succeeds or fails. - ONCE Unwillingness of the pattern to match subjects that start in - the same position, but end further "to the right". - Of importance for pattern with space, + or * operator. - Is turned on in pattern by the `@#/ prefixes and by the operators - other than space + * _ & : | = $ '. - Is turned of in pattern with space + * or | operator. - FENCE Unwillingness of the subject to be matched by alternative patterns. - Of importance for the | and : operators in a pattern. - Is turned on by the ` prefix (whether or not in a pattern). - Is turned off in pattern with space + * | or : operator. - (With | and : operators this is only the case for the left operand, - with the other operators this is the case for all except the last - operand in a list.) - */ - psk loc; - char* sloc; - ULONG Flgs; - matchstate s; - int ci; - psk name = NULL; - assert(sizeof(s) == 4); - if(!cutoff) - cutoff = sub + stringLength; -#if CUTOFFSUGGEST - if((pat->v.fl & ATOM) - || (NOTHING(pat) - && (is_op(pat) - || !pat->u.obj) - ) - ) - { - suggestedCutOff = NULL; - } -#endif - DBGSRC(int saveNice; int redhum; saveNice = beNice; redhum = hum; beNice = FALSE; \ - hum = FALSE; Printf("%d %.*s|%s", ind, (int)(cutoff - sub), sub, cutoff); \ - Printf(":"); result(pat); \ - Printf(",pos=" LONGD ",sLen=%ld,sugCut=%s,mayMoveStart=%s)"\ - , pposition\ - , (long int)stringLength\ - , suggestedCutOff ? *suggestedCutOff ? *suggestedCutOff : (char*)"(0)" : (char*)"0"\ - , mayMoveStartOfSubject ? *mayMoveStartOfSubject ? *mayMoveStartOfSubject : (char*)"(0)" : (char*)"0"\ - ); \ - Printf("\n"); beNice = saveNice; hum = redhum;) - s.i = (PRISTINE << SHIFT_LMR) + (PRISTINE << SHIFT_RMR); - - Flgs = pat->v.fl; - if(Flgs & POSITION) - { - if(Flgs & NONIDENT) - return sdoEval(sub, cutoff, pat, subkn); - else if(cutoff > sub) - { -#if CUTOFFSUGGEST - if(mayMoveStartOfSubject && *mayMoveStartOfSubject) - { - *mayMoveStartOfSubject = cutoff; - } -#endif - return FALSE | ONCE | POSITION_ONCE; - } - else - return doPosition(s, pat, pposition, stringLength, NULL -#if CUTOFFSUGGEST - , mayMoveStartOfSubject -#endif - , 12345 - ); - } - if(!(((Flgs & NONIDENT) - && (NEGATION(Flgs, NONIDENT) - ? ((s.c.once = ONCE), cutoff > sub) - : cutoff == sub - ) - ) - || ((Flgs & ATOM) - && (NEGATION(Flgs, ATOM) - ? (cutoff < sub + 2) /*!(sub[0] && sub[1])*/ - : cutoff > sub - && ((s.c.once = ONCE), cutoff > sub + 1 /*sub[1]*/) - ) - ) - || ((Flgs & (FRACTION | NUMBER)) - && ((ci = sfullnumbercheck(sub, cutoff)) - , (((Flgs & FRACTION) - && ((ci != (QFRACTION | QNUMBER)) ^ NEGATION(Flgs, FRACTION)) - ) - || ((Flgs & NUMBER) - && (((ci & QNUMBER) == 0) ^ NEGATION(Flgs, NUMBER)) - ) - ) - ) - && (s.c.rmr = (ci == DEFINITELYNONUMBER) ? ONCE : FALSE - , (s.c.lmr = PRISTINE) /* Single = is correct! */ - ) - ) - ) - ) - { - if(IS_VARIABLE(pat)) - { - int ok = TRUE; - if(is_op(pat)) - { - ULONG saveflgs = Flgs & VISIBLE_FLAGS; - name = subtreecopy(pat); - name->v.fl &= ~VISIBLE_FLAGS; - name->v.fl |= SUCCESS; - if((s.c.rmr = (char)evaluate(name)) != TRUE) - ok = FALSE; - if(Op(name) != EQUALS) - { - name = isolated(name); - name->v.fl |= saveflgs; - } - pat = name; - } - if(ok) - { - if(Flgs & UNIFY) /* ? */ - { - if(!NOTHING(pat) || cutoff > sub) - { - if(is_op(pat) - || pat->u.obj - ) - { - if(Flgs & INDIRECT) /* ?! of ?!! */ - { - if((loc = SymbolBinding_w(pat, Flgs & DOUBLY_INDIRECT)) != NULL) - { - if(is_object(loc)) - s.c.rmr = (char)string_copy_insert(loc, subkn, sub, cutoff); - else - { - s.c.rmr = (char)evaluate(loc); - if(!string_copy_insert(loc, subkn, sub, cutoff)) - s.c.rmr = FALSE; - } - wipe(loc); - } - else - s.c.rmr = (char)NOTHING(pat); - } - else - { - s.c.rmr = (char)string_copy_insert(pat, subkn, sub, cutoff); - } - } - else - s.c.rmr = TRUE; - } - } - else if(Flgs & INDIRECT) /* ! or !! */ - { - if((loc = SymbolBinding_w(pat, Flgs & DOUBLY_INDIRECT)) != NULL) - { - cleanOncePattern(loc); -#if CUTOFFSUGGEST - if(mayMoveStartOfSubject) - { - *mayMoveStartOfSubject = 0; - } - s.c.rmr = (char)(stringmatch(ind + 1, "A", sub, cutoff, loc, subkn, pposition, stringLength - , suggestedCutOff - , 0 - ) ^ NOTHING(pat)); -#else - s.c.rmr = (char)(stringmatch(ind + 1, "A", sub, cutoff, loc, subkn, pposition, stringLength - ) ^ NOTHING(pat)); -#endif - wipe(loc); - } - else - s.c.rmr = (char)NOTHING(pat); - } - } - } - else - { - switch(Op(pat)) - { - case PLUS: - case TIMES: - break; - case WHITE: - { - LONG locpos = pposition; -#if CUTOFFSUGGEST - char* suggested_Cut_Off = sub; - char* may_Move_Start_Of_Subject; - may_Move_Start_Of_Subject = sub; -#endif - /* This code mirrors that of match(). (see below)*/ - - sloc = sub; /* A divisionPoint=S */ - -#if CUTOFFSUGGEST - s.c.lmr = stringmatch(ind + 1, "I", sub, sloc /* B leftResult=0(P):car(P) */ - , pat->LEFT, subkn, pposition - , stringLength, &suggested_Cut_Off - , mayMoveStartOfSubject); - if((s.c.lmr & ONCE) && mayMoveStartOfSubject && *mayMoveStartOfSubject > sub) - { - return ONCE; - } -#else - s.c.lmr = stringmatch(ind + 1, "I", sub, sloc, pat->LEFT, subkn, pposition, stringLength); -#endif - -#if CUTOFFSUGGEST - if(suggested_Cut_Off > sloc) - { - if(cutoff && suggested_Cut_Off > cutoff) - { - if(suggestedCutOff) - { - locpos += suggested_Cut_Off - sloc; - cutoff = sloc = *suggestedCutOff = suggested_Cut_Off; - } - else - { - locpos += cutoff - sloc; - sloc = cutoff; - s.c.lmr &= ~TRUE; - } - } - else - { - assert(suggested_Cut_Off > sloc); - locpos += suggested_Cut_Off - sloc; - sloc = suggested_Cut_Off; - } - } - else -#endif - s.c.lmr &= ~ONCE; - while(sloc < cutoff) /* C while divisionPoint */ - { - if(s.c.lmr & TRUE) /* D if leftResult.success */ - { -#if CUTOFFSUGGEST - if(s.c.lmr & ONCE) - may_Move_Start_Of_Subject = 0; - else if(may_Move_Start_Of_Subject != 0) - may_Move_Start_Of_Subject = sloc; - s.c.rmr = stringmatch(ind + 1, "J", sloc /* E rightResult=SR:cdr(P) */ - , cutoff, pat->RIGHT, subkn - , locpos, stringLength, suggestedCutOff - , &may_Move_Start_Of_Subject); - if(may_Move_Start_Of_Subject != sloc && may_Move_Start_Of_Subject != 0) - { - assert(may_Move_Start_Of_Subject > sloc); - locpos += may_Move_Start_Of_Subject - sloc; - sloc = may_Move_Start_Of_Subject; - } - else - { - ++sloc; - ++locpos; - } -#else - s.c.rmr = stringmatch(ind + 1, "J", sloc, cutoff, pat->RIGHT, subkn, locpos, stringLength); - ++sloc; - ++locpos; -#endif - if(!(s.c.lmr & ONCE)) - s.c.rmr &= ~ONCE; - } - else - { - ++sloc; - ++locpos; - } - if((s.c.rmr & TRUE) /* F if(1) full success */ - || (s.c.lmr & (POSITION_ONCE /* or (2) may not be shifted. In the first pass, a position flag on car(P) counts as criterion for being done. */ - | ONCE - ) - ) /* In all but the first pass, the left and right */ - || (s.c.rmr & (ONCE /* results can indicate that the loop is done. */ - | POSITION_MAX_REACHED /* In all passes a position_max_reached on the */ - ) /* rightResult indicates that the loop is done. */ - ) - ) - { /* G return */ - if(sloc > sub + 1) /* Also return whether sub has reached max position.*/ - s.c.rmr &= ~POSITION_MAX_REACHED; /* This flag is reason to stop increasing the position of the division any further, but it must not be signalled back to the caller if the lhs is not nil ... */ - s.c.rmr |= (char)(s.c.lmr & POSITION_MAX_REACHED); /* ... unless it is the lhs that signals it. */ - if(stringOncePattern(pat)) /* Also return whether the pattern as a whole */ - { /* doesn't want longer subjects, which can be */ - s.c.rmr |= ONCE; /* found out by looking at the pattern */ - s.c.rmr |= (char)(pat->v.fl & FENCE); - } /* or by looking at whether both lhs and rhs */ - else if(!(s.c.lmr & ONCE)) /* results indicated this, in which case both */ - s.c.rmr &= ~ONCE; /* sides must be non-zero size subjects. */ - return s.c.rmr ^ (char)NOTHING(pat); - } - /* H SL,SR=shift_right divisionPoint */ - /* SL = lhs divisionPoint S, SR = rhs divisionPoint S */ - /* I leftResult=SL:car(P) */ -#if CUTOFFSUGGEST - suggested_Cut_Off = sub; - s.c.lmr = stringmatch(ind + 1, "I", sub, sloc, pat->LEFT, subkn,/* 0 ? */pposition,/* strlen(sub) ? */ stringLength, &suggested_Cut_Off, mayMoveStartOfSubject); - if(suggested_Cut_Off > sloc) - { - if(!(cutoff && suggested_Cut_Off > cutoff)) - { - assert(suggested_Cut_Off > sloc); - locpos += suggested_Cut_Off - sloc; - sloc = suggested_Cut_Off; - } - } -#else - s.c.lmr = stringmatch(ind + 1, "I", sub, sloc, pat->LEFT, subkn,/* 0 ? */pposition,/* strlen(sub) ? */ stringLength); -#endif - } - - if(s.c.lmr & TRUE) /* J if leftResult.success */ - { -#if CUTOFFSUGGEST - s.c.rmr = stringmatch(ind + 1, "J", sloc, cutoff /* K rightResult=0(P):cdr(pat) */ - , pat->RIGHT, subkn, locpos, stringLength - , suggestedCutOff, mayMoveStartOfSubject); -#else - s.c.rmr = stringmatch(ind + 1, "J", sloc, cutoff, pat->RIGHT, subkn, locpos, stringLength); -#endif - s.c.rmr &= ~ONCE; - } - /* L return */ - if(!(s.c.rmr & POSITION_MAX_REACHED)) - s.c.rmr &= ~POSITION_ONCE; - if(/*(cutoff > sub) &&*/ stringOncePattern(pat)) /* The test cutoff > sub merely avoids that stringOncePattern is called when it is useless. */ - {/* Test: - @(abcde:`(a ?x) (?z:d) ? ) - z=b - */ - s.c.rmr |= ONCE; - s.c.rmr |= (char)(pat->v.fl & FENCE); - } - return s.c.rmr ^ (char)NOTHING(pat); /* end */ - } - case UNDERSCORE: - if(cutoff > sub + 1) - { -#if CUTOFFSUGGEST - s.c.lmr = stringmatch(ind + 1, "M", sub, sub + 1, pat->LEFT, subkn, pposition, stringLength, NULL, mayMoveStartOfSubject); -#else - s.c.lmr = stringmatch(ind + 1, "M", sub, sub + 1, pat->LEFT, subkn, pposition, stringLength); -#endif - if((s.c.lmr & TRUE) -#if CUTOFFSUGGEST - && ((s.c.rmr = stringmatch(ind + 1, "N", sub + 1, cutoff, pat->RIGHT, subkn, pposition, stringLength, suggestedCutOff, mayMoveStartOfSubject)) & TRUE) -#else - && ((s.c.rmr = stringmatch(ind + 1, "N", sub + 1, cutoff, pat->RIGHT, subkn, pposition, stringLength)) & TRUE) -#endif - ) - { - dummy_op = WHITE; - } - s.c.rmr |= (char)(s.c.lmr & (FENCE | ONCE)); - } - break; - case AND: -#if CUTOFFSUGGEST - if((s.c.lmr = stringmatch(ind + 1, "O", sub, cutoff, pat->LEFT, subkn, pposition, stringLength, suggestedCutOff, mayMoveStartOfSubject)) & TRUE) -#else - if((s.c.lmr = stringmatch(ind + 1, "O", sub, cutoff, pat->LEFT, subkn, pposition, stringLength)) & TRUE) -#endif - { - loc = same_as_w(pat->RIGHT); - loc = eval(loc); - if(loc->v.fl & SUCCESS) - { - s.c.rmr = TRUE; - if(loc->v.fl & FENCE) - s.c.rmr |= ONCE; - } - else - { - s.c.rmr = FALSE; - if(loc->v.fl & FENCE) - s.c.rmr |= (FENCE | ONCE); - if(loc->v.fl & IMPLIEDFENCE) /* (for function utf$) */ - s.c.rmr |= ONCE; - } - wipe(loc); - } - s.c.rmr |= (char)(s.c.lmr & (FENCE | ONCE)); - break; - case MATCH: -#if CUTOFFSUGGEST - if((s.c.lmr = stringmatch(ind + 1, "P", sub, cutoff, pat->LEFT, subkn, pposition, stringLength, suggestedCutOff, mayMoveStartOfSubject)) & TRUE) -#else - if((s.c.lmr = stringmatch(ind + 1, "P", sub, cutoff, pat->LEFT, subkn, pposition, stringLength)) & TRUE) -#endif - { -#if CUTOFFSUGGEST - if(suggestedCutOff && *suggestedCutOff > cutoff) - { - cutoff = *suggestedCutOff; - } - - s.c.rmr = (char)(stringmatch(ind + 1, "Q", sub, cutoff, pat->RIGHT, subkn, pposition, stringLength, 0, 0)); -#else - s.c.rmr = (char)(stringmatch(ind + 1, "Q", sub, cutoff, pat->RIGHT, subkn, pposition, stringLength)); -#endif - } - else - s.c.rmr = FALSE; - s.c.rmr |= (char)(s.c.lmr & (FENCE | ONCE | POSITION_MAX_REACHED)); - break; - case OR: -#if CUTOFFSUGGEST - if(mayMoveStartOfSubject) - *mayMoveStartOfSubject = 0; - if((s.c.lmr = (char)(stringmatch(ind + 1, "R", sub, cutoff, pat->LEFT, subkn, pposition, stringLength, NULL, 0))) -#else - if((s.c.lmr = (char)(stringmatch(ind + 1, "R", sub, cutoff, pat->LEFT, subkn, pposition, stringLength))) -#endif - & (TRUE | FENCE) - ) - { - if((s.c.lmr & ONCE) && !stringOncePattern(pat->RIGHT)) - { - s.c.rmr = (char)(s.c.lmr & TRUE); - } - else - { - s.c.rmr = (char)(s.c.lmr & (TRUE | ONCE)); - } - } - else - { -#if CUTOFFSUGGEST - s.c.rmr = stringmatch(ind + 1, "S", sub, cutoff, pat->RIGHT, subkn, pposition, stringLength, NULL, 0); -#else - s.c.rmr = stringmatch(ind + 1, "S", sub, cutoff, pat->RIGHT, subkn, pposition, stringLength); -#endif - if((s.c.rmr & ONCE) - && !(s.c.lmr & ONCE) - ) - { - s.c.rmr &= ~(ONCE | POSITION_ONCE); - } - if((s.c.rmr & POSITION_MAX_REACHED) - && !(s.c.lmr & POSITION_MAX_REACHED) - ) - { - s.c.rmr &= ~(POSITION_MAX_REACHED | POSITION_ONCE); - } - } - break; - /* - This is now much quicker than previously, because the whole expression - (|bc|x) is ONCE if the start of the subject does not match the start of any of - the alternations: - dbg'@(hhhhhhhhhbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbhhhabcd:?X (|bc|x) d) - */ - case FUN: - case FUU: - psh(&sjtNode, &nilNode, NULL); - string_copy_insert(&sjtNode, subkn, sub, cutoff); - if(NOTHING(pat)) - { - loc = _copyop(pat); - loc->v.fl &= ~NOT; - loc->v.fl |= SUCCESS; - } - else - loc = same_as_w(pat); - loc = eval(loc); - deleteNode(&sjtNode); -#if CUTOFFSUGGEST - if(mayMoveStartOfSubject) - *mayMoveStartOfSubject = 0; -#endif - if(isSUCCESS(loc)) - { - if(((loc->v.fl & (UNIFY | FILTERS)) == UNIFY) && !is_op(loc) && !loc->u.obj) - { - s.c.rmr = (char)TRUE; - wipe(loc); - break; - } - else - { - loc = setflgs(loc, pat->v.fl); - if(equal(pat, loc)) - { -#if CUTOFFSUGGEST - s.c.rmr = (char)(stringmatch(ind + 1, "T", sub, cutoff, loc, subkn, pposition, stringLength, NULL, 0) ^ NOTHING(loc)); -#else - s.c.rmr = (char)(stringmatch(ind + 1, "T", sub, cutoff, loc, subkn, pposition, stringLength) ^ NOTHING(loc)); -#endif - wipe(loc); - break; - } - } - } - else - { - if(loc->v.fl & (FENCE | IMPLIEDFENCE)) - s.c.rmr = ONCE; /* '~ as return value from function stops stretching subject */ - } - wipe(loc); - break; - default: - if(!is_op(pat)) - { - if(!pat->u.obj - && (Flgs & (FRACTION | NUMBER | NONIDENT | ATOM | IDENT)) - ) - { /* e.g. a b c : % */ - s.c.rmr = TRUE; - } - else - { -#if CUTOFFSUGGEST - s.c.rmr = (char)(scompare((char*)sub, cutoff, pat - , ((!(Flgs & ATOM) - || NEGATION(Flgs, ATOM) - ) - ? suggestedCutOff - : NULL - ) - , mayMoveStartOfSubject - ) - ); -#else - s.c.rmr = (char)(scompare((unsigned char*)sub, cutoff, pat)); -#endif - DBGSRC(Printf("%s %d%*sscompare(%.*s,", wh, ind, ind, "", (int)(cutoff - sub), sub); result(pat); Printf(") "); \ - if(s.c.rmr & ONCE) Printf("ONCE|"); \ - if(s.c.rmr & TRUE) Printf("TRUE"); else Printf("FALSE"); \ - Printf("\n");) - } - } - } - } - } - DBGSRC(if(s.c.rmr & (FENCE | ONCE))\ - {Printf("%s %d%*s+", wh, ind, ind, ""); if(s.c.rmr & FENCE)\ - Printf(" FENCE "); if(s.c.rmr & ONCE)Printf(" ONCE "); Printf("\n"); }) - s.c.rmr |= (char)(pat->v.fl & FENCE); - if(stringOncePattern(pat) || /* @("abXk":(|? b|`) X ?id) must fail*/ (s.c.rmr & (TRUE | FENCE | ONCE)) == FENCE) - { - s.c.rmr |= ONCE; - DBGSRC(int saveNice; int redhum; saveNice = beNice; redhum = hum; \ - beNice = FALSE; hum = FALSE; \ - Printf("%d%*sstringmatch(%.*s", ind, ind, "", (int)(cutoff - sub), sub); \ - Printf(":"); result(pat); \ - beNice = saveNice; hum = redhum; \ - Printf(") s.c.rmr %d (B)", s.c.rmr); \ - if(pat->v.fl & POSITION) Printf("POSITION "); \ - if(pat->v.fl & FRACTION)Printf("FRACTION "); \ - if(pat->v.fl & NUMBER)Printf("NUMBER "); \ - if(pat->v.fl & SMALLER_THAN)Printf("SMALLER_THAN "); \ - if(pat->v.fl & GREATER_THAN) Printf("GREATER_THAN "); \ - if(pat->v.fl & ATOM) Printf("ATOM "); \ - if(pat->v.fl & FENCE) Printf("FENCE "); \ - if(pat->v.fl & IDENT) Printf("IDENT"); \ - Printf("\n");) - } - if(is_op(pat)) - s.c.rmr ^= (char)NOTHING(pat); - if(name) - wipe(name); - return (char)(s.c.once | s.c.rmr); - } -/* End of stringmatch.c */ - -/* Begin of treematch.c */ - -/*#define SUBJECTNOTNIL(sub,pat) (is_op(sub) || HAS_UNOPS(sub) || (PIOBJ(sub) != PIOBJ(nil(pat))))*/ -#define SUBJECTNOTNIL(sub,pat) (is_op(sub) || HAS_UNOPS(sub) || (PLOBJ(sub) != PLOBJ(nil(pat)))) - -/* - ( Dogs and Cats are friends: ? [%(out$(!sjt SJT)&~) (|))& - ( Dogs and Cats are friends: ? [%(out$(!sjt)&~) (|))& -*/ -static char doEval(psk sub, psk cutoff, psk pat) - { - char ret; - psk loc; - psh(&sjtNode, &nilNode, NULL); - copy_insert(&sjtNode, sub, cutoff); - loc = subtreecopy(pat); - loc->v.fl &= ~(POSITION | NONIDENT | IMPLIEDFENCE | ONCE); - loc = eval(loc); - deleteNode(&sjtNode); - if(isSUCCESS(loc)) - { - ret = (loc->v.fl & FENCE) ? (TRUE | ONCE) : TRUE; - } - else - { - ret = (loc->v.fl & FENCE) ? ONCE : FALSE; - } - wipe(loc); - - return ret; - } - -static int oncePattern(psk pat) - { - /* - This function has a side effect: it sets a flag IMPLIEDFENCE in all - pattern nodes that can be matched by at most one non-trivial list element - (a nonzero term in a sum, a factor in a product that is not 1, or a - nonempty word in a sentence. Because the function depends on ATOMFILTERS, - the algorithm should be slightly different for normal matches and for - string matches. Ideally, two flags should be reserved. - */ - if(pat->v.fl & IMPLIEDFENCE) - { - return TRUE; - } - if((pat->v.fl & ATOM) && NEGATION(pat->v.fl, ATOM)) - { - return FALSE; - } - else if(pat->v.fl & ATOMFILTERS) - { - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - } - else if(IS_VARIABLE(pat) - || NOTHING(pat) - || (pat->v.fl & NONIDENT) /*{?} a b c:% c => a b c */ - ) - return FALSE; - else if(!is_op(pat)) - { - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - } - else - switch(Op(pat)) - { - case DOT: - case COMMA: - case EQUALS: - case LOG: - case DIF: - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - case OR: - if(oncePattern(pat->LEFT) && oncePattern(pat->RIGHT)) - { - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - } - break; - case MATCH: - if(oncePattern(pat->LEFT) || oncePattern(pat->RIGHT)) - { - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - } - break; - case AND: - if(oncePattern(pat->LEFT)) - { - pat->v.fl |= IMPLIEDFENCE; - return TRUE; - } - break; - default: - break; - } - return FALSE; - } - -static char match(int ind, psk sub, psk pat, psk cutoff, LONG pposition, psk expr, unsigned int op) - { - /* - s.c.lmr or s.c.rmr have three independent flags: TRUE/FALSE, ONCE and FENCE. - - TRUE/FALSE The success or failure of the match. - - ONCE Unwillingness of the pattern to match longer substrings from the - subject. Example: - - {?} a b c d:?x @?y d - {!} a b c d - {?} !y - {!} c - {?} !x - {!} a b - In fact, the pattern @?y first matches the empty string and then, - after backtracking from the failing match of the last subpattern d, - a single element from the string. Thereafter, when again - backtracking, the subpattern @?y denies to even try to match a - substring that is one element longer (two elements, in this example) - and the subpattern preceding @?y is offered an enlarged substring - from the subject, while @?y itself starts with the empty element. - - This flag is of importance for patterns with the space, + or - * operator. - The flag is turned on in patterns by the `@#/ flags and by operators - other than space + * _ & : | = $ ' - The flag is turned off "after consumption", i.e. it does not - percolate upwards through patterns with space + or * operators. - - (once= - (p=?`Y) - & a b c d - : ?X !p (d|?&(p=`?Z&foo:?Y)&~) - & out$(X !X Y !Y Z !Z)); - - (once=a b c d:?X (?|?) d & out$(X !X)) - (once=a b c d:?X (@|@) d & out$(X !X)) - (once=a b c d:?X (?|@) d & out$(X !X)) - (once=a b c d:?X (@|?) d & out$(X !X)) - (once=a b c d:?X (@|`) d & out$(X !X)) - (once=a b c d:?X (`|?) d & out$(X !X)) - (once=a b c d:?X (`c|?) d & out$(X !X)) - - FENCE Unwillingness of the subject to be matched by alternative patterns. - Of importance for the | and : operators in a pattern. - Is turned on by the ` prefix (whether or not in a pattern). - Is turned off in pattern with space + * | or : operator. - (With | and : operators this is only the case for the left operand, - with the other operators this is the case for all except the last - operand in a list.) - */ - matchstate s; - psk loc; - ULONG Flgs; - psk name = NULL; - DBGSRC(Printf("%d%*smatch(", ind, ind, ""); results(sub, cutoff); Printf(":"); \ - result(pat); Printf(")"); Printf("\n");) - if(is_op(sub)) - { - if(Op(sub) == EQUALS) - sub->RIGHT = Head(sub->RIGHT); - - if(sub->RIGHT == cutoff) - return match(ind + 1, sub->LEFT, pat, NULL, pposition, expr, op); - } - s.i = (PRISTINE << SHIFT_LMR) + (PRISTINE << SHIFT_RMR); - Flgs = pat->v.fl; - if(Flgs & POSITION) - { - if(Flgs & NONIDENT) - return doEval(sub, cutoff, pat); - else if(cutoff || !(sub->v.fl & IDENT)) - return FALSE | ONCE | POSITION_ONCE; - else - return doPosition(s, pat, pposition, 0, expr -#if CUTOFFSUGGEST - , 0 -#endif - , op - ); - } - if(!(((Flgs & NONIDENT) && (((sub->v.fl & IDENT) && 1) ^ NEGATION(Flgs, NONIDENT))) - || ((Flgs & ATOM) && ((is_op(sub) && 1) ^ NEGATION(Flgs, ATOM))) - || ((Flgs & FRACTION) && (!RAT_RAT(sub) ^ NEGATION(Flgs, FRACTION))) - || ((Flgs & NUMBER) && (!RATIONAL_COMP(sub) ^ NEGATION(Flgs, NUMBER))) - ) - ) - { - if(IS_VARIABLE(pat)) - { - int ok = TRUE; - if(is_op(pat)) - { - ULONG saveflgs = Flgs & VISIBLE_FLAGS; - name = subtreecopy(pat); - name->v.fl &= ~VISIBLE_FLAGS; - name->v.fl |= SUCCESS; - if((s.c.rmr = (char)evaluate(name)) != TRUE) - ok = FALSE; - if(Op(name) != EQUALS) - { - name = isolated(name);/*Is this needed? 20220913*/ - /* Yes, it is. Otherwise a '?' flag is permanently attached to name. 20230130*/ - name->v.fl |= saveflgs; - } - pat = name; - /* name is wiped later in this function! */ - } - if(ok) - { - if(Flgs & UNIFY) /* ? */ - { - if(!NOTHING(pat) || is_op(sub) || (sub->u.obj)) - { - if(is_op(pat) - || pat->u.obj - ) - if(Flgs & INDIRECT) /* ?! of ?!! */ - { - if((loc = SymbolBinding_w(pat, Flgs & DOUBLY_INDIRECT)) != NULL) - { - if(is_object(loc)) - s.c.rmr = (char)copy_insert(loc, sub, cutoff); - else - { - s.c.rmr = (char)evaluate(loc); - if(!copy_insert(loc, sub, cutoff)) - s.c.rmr = FALSE; - /* Previously, s.c.rmr was not influenced by failure of copy_insert */ - - } - wipe(loc); - } - else - s.c.rmr = (char)NOTHING(pat); - } - else - { - s.c.rmr = (char)copy_insert(pat, sub, cutoff); - /* Previously, s.c.rmr was unconditionally set to TRUE */ - } - - else - s.c.rmr = TRUE; - } - /* - * else NOTHING(pat) && !is_op(sub) && !sub->u.obj - * which means ~?[`][!][!] - */ - } - else if(Flgs & INDIRECT) /* ! or !! */ - { - if((loc = SymbolBinding_w(pat, Flgs & DOUBLY_INDIRECT)) != NULL) - { - cleanOncePattern(loc); - s.c.rmr = (char)(match(ind + 1, sub, loc, cutoff, pposition, expr, op) ^ NOTHING(pat)); - wipe(loc); - } - else - s.c.rmr = (char)NOTHING(pat); - } - } - } - else - { -#if DATAMATCHESITSELF - if(pat == sub && (pat->v.fl & SELFMATCHING)) - { - return TRUE | ONCE; - } -#endif - switch(Op(pat)) - { - case WHITE: - case PLUS: - case TIMES: - { - LONG locpos = pposition; - if(Op(pat) == WHITE) - { - if(sub == &zeroNode /*&& Op(pat) != PLUS*/) - { - sub = &zeroNodeNotNeutral; - locpos = 0; - } - else if(sub == &oneNode) - { - sub = &oneNodeNotNeutral; - locpos = 0; - } - } - else if(sub == &nilNode) - { - sub = &nilNodeNotNeutral; - locpos = 0; - } - else if(sub == &oneNode && Op(pat) == PLUS) - { - sub = &oneNodeNotNeutral; - locpos = 0; - } - /* Optimal sructure for this code: - A0 (B A)* B0 - S:P ::= - A divisionPoint=S - B leftResult=0(P):car(P) - C while divisionPoint - D if leftResult.success - E rightResult=SR:cdr(P) - F if(done) - G return - H SL,SR=shift_right divisionPoint - I leftResult=SL:car(P) - J if leftResult.success - K rightResult=0(P):cdr(pat) - L return - - 0(P)=nil(pat): nil(WHITE)="", nil(+)=0,nil(*)=1 - In stringmatch, there is no need for L0; the empty string "" - is part of the string. - */ - /* A divisionPoint=S */ - /* B leftResult=0(P):car(P) */ - /* C while divisionPoint */ - /* D if leftResult.success */ - /* E rightResult=SR:cdr(P) */ - /* F if(done) */ - /* done = (1) full success */ - /* or (2) may not be shifted. - ad (2): In the first pass, a position - flag on car(P) counts as criterion for being done. */ - /* In all but the first pass, the left and right - results can indicate that the loop is done. */ - /* In all passes a position_max_reached on the - rightResult indicates that the loop is done. */ - /* G return */ - /* Return true if full success. - Also return whether lhs experienced max position - being reached. */ - /* Also return whether the pattern as a whole doesn't - want longer subjects, which can be found out by - looking at the pattern */ - /* or by looking at whether both lhs and rhs results - indicated this, in which case both sides must be - non-zero size subjects. */ - /* POSITION_ONCE, on the other hand, requires zero size - subjects. */ - /* Also return the fence flag, if present in rmr. - (This flag in lmr has no influence.) - */ - /* H SL,SR=shift_right divisionPoint */ - /* SL = lhs divisionPoint S, SR = rhs divisionPoint S - */ - /* I leftResult=SL:car(P) */ - /* J if leftResult.success */ - /* K rightResult=0(P):cdr(pat) */ - /* L return */ - /* Return true if full success. - - Also return whether lhs experienced max position - being reached. */ - /* Also return whether the pattern as a whole doesn't - want longer subjects, which can be found out by - looking at the pattern or by looking at whether */ - /* both lhs and rhs results indicated this. - These come in two sorts: POSITION_ONCE requires */ - /* zero size subjects, ONCE requires non-zero size - subjects. */ - /* Also return the fence flag, which can be found on - the pattern or in the result of the lhs or the rhs. - (Not necessary that both have this flag.) - */ - /* end */ - if(SUBJECTNOTNIL(sub, pat)) /* A divisionPoint=S */ - loc = sub; - else - loc = NULL; - /* B leftResult=0(P):car(P) */ - s.c.lmr = (char)match(ind + 1, nil(pat), pat->LEFT /* a*b+c*d:?+[1+?*[1*%@?q*?+? (q = c) */ - , NULL, pposition, expr /* a b c d:? [1 (? [1 %@?q ?) ? (q = b) */ - , Op(pat)); /* a b c d:? [1 ? [1 %@?q ? ? (q = b) */ - s.c.lmr &= ~ONCE; - while(loc) /* C while divisionPoint */ - { - if(s.c.lmr & TRUE) /* D if leftResult.success */ - { /* E rightResult=SR:cdr(P) */ - s.c.rmr = match(ind + 1, loc, pat->RIGHT, cutoff, locpos, expr, op); - if(!(s.c.lmr & ONCE)) - s.c.rmr &= ~ONCE; - } - if((s.c.rmr & TRUE) /* F if(1) full success */ - || (s.c.lmr & (POSITION_ONCE /* or (2) may not be shifted. In the first pass, a position flag on car(P) counts as criterion for being done. */ - | ONCE - ) - ) /* In all but the first pass, the left and right */ - || (s.c.rmr & (ONCE /* results can indicate that the loop is done. */ - | POSITION_MAX_REACHED /* In all passes a position_max_reached on the */ - ) /* rightResult indicates that the loop is done. */ - ) - ) - { /* G return */ - if(loc != sub) - s.c.rmr &= ~POSITION_MAX_REACHED; /* This flag is reason to stop increasing the position of the division any further, but it must not be signalled back to the caller if the lhs is not nil ... */ - s.c.rmr |= (char)(s.c.lmr & POSITION_MAX_REACHED); /* ... unless it is the lhs that signals it. */ - if(oncePattern(pat)) /* Also return whether the pattern as a whole doesn't want longer subjects, which can be found out by looking at the pattern */ - { /* For example, */ - s.c.rmr |= ONCE; /* a b c d:`(?x ?y) (?z:c) ? */ - s.c.rmr |= (char)(pat->v.fl & FENCE); /* must fail and set x==nil, y==a and z==b */ - } - else if(!(s.c.lmr & ONCE)) - s.c.rmr &= ~ONCE; - DBGSRC(Printf("%d%*smatch(", ind, ind, ""); \ - results(sub, cutoff); Printf(":"); result(pat);) -#ifndef NDEBUG - DBGSRC(printMatchState("EXIT-MID", s, pposition, 0);) -#endif - DBGSRC(if(pat->v.fl & FRACTION) Printf("FRACTION "); \ - if(pat->v.fl & NUMBER) Printf("NUMBER "); \ - if(pat->v.fl & SMALLER_THAN)\ - Printf("SMALLER_THAN "); \ - if(pat->v.fl & GREATER_THAN)\ - Printf("GREATER_THAN "); \ - if(pat->v.fl & ATOM) Printf("ATOM "); \ - if(pat->v.fl & FENCE) Printf("FENCE "); \ - if(pat->v.fl & IDENT) Printf("IDENT"); \ - Printf("\n");) - return s.c.rmr ^ (char)NOTHING(pat); - } - /* H SL,SR=shift_right divisionPoint */ - if(Op(loc) == Op(pat) - && loc->RIGHT != cutoff - ) - loc = loc->RIGHT; - else - loc = NULL; - /* SL = lhs divisionPoint S, SR = rhs divisionPoint S - */ - ++locpos; - /* I leftResult=SL:car(P) */ - s.c.lmr = match(ind + 1, sub, pat->LEFT, loc, pposition, sub, Op(pat)); - } - /* J if leftResult.success */ - if(s.c.lmr & TRUE) - /* K rightResult=0(P):cdr(pat) */ - { - s.c.rmr = match(ind + 1, nil(pat), pat->RIGHT, NULL, locpos, expr, Op(pat)); - s.c.rmr &= ~ONCE; - } - /* L return */ - /* Return true if full success. - - Also return whether lhs experienced max position - being reached. */ - if(!(s.c.rmr & POSITION_MAX_REACHED)) - s.c.rmr &= ~POSITION_ONCE; - /* Also return whether the pattern as a whole doesn't - want longer subjects, which can be found out by - looking at the pattern. */ - if(/*cutoff &&*/ oncePattern(pat)) - /* The test cutoff != NULL merely avoids that - oncePattern is called when it is useless. */ - { /* Test: - a b c d e:`(a ?x) (?z:d) ? - x= - z=b - */ - s.c.rmr |= ONCE; - s.c.rmr |= (char)(pat->v.fl & FENCE); - } - /* POSITION_ONCE requires zero size subjects. */ - /* Also return the fence flag, which can be found on - the pattern or in the result of the lhs or the rhs. - (Not necessary that both have this flag.) - */ - s.c.rmr ^= (char)NOTHING(pat); - return s.c.rmr; - /* end */ - } - case EXP: - if(Op(sub) == EXP) - { - if((s.c.lmr = match(ind + 1, sub->LEFT, pat->LEFT, NULL, 0, sub->LEFT, 12345)) & TRUE) - s.c.rmr = match(ind + 1, sub->RIGHT, pat->RIGHT, NULL, 0, sub->RIGHT, 12345); -#ifndef NDEBUG - DBGSRC(printMatchState("EXP:EXIT-MID", s, pposition, 0);) -#endif - s.c.rmr |= (char)(s.c.lmr & (FENCE | ONCE)); /* a*b^2*c:?x*?y^(~1:?t)*?z */ - } - if(!(s.c.rmr & TRUE) - && ((s.c.lmr = match(ind + 1, sub, pat->LEFT, cutoff, pposition, expr, op)) & TRUE) - && ((s.c.rmr = match(ind + 1, &oneNode, pat->RIGHT, NULL, 0, &oneNode, 1234567)) & TRUE) - ) - { /* a^2*b*c*d^3 : ?x^(?s:~1)*?y^?t*?z^(>2:?u) */ - s.c.rmr |= (char)(s.c.lmr & (FENCE | ONCE)); - } - s.c.rmr &= ~POSITION_MAX_REACHED; - break; - case UNDERSCORE: - if(is_op(sub)) - { - if(Op(sub) == EQUALS) - { - if(ISBUILTIN((objectnode*)sub)) - { - errorprintf("You cannot match an object '=' with '_' if the object is built-in\n"); - s.c.rmr = ONCE; - } - else - { - if((s.c.lmr = match(ind + 1, sub->LEFT, pat->LEFT, NULL, 0, sub->LEFT, 12345)) & TRUE) - { - loc = same_as_w(sub->RIGHT); /* Object might change as a side effect!*/ - if((s.c.rmr = match(ind + 1, loc, pat->RIGHT, cutoff, 0, loc, 123)) & TRUE) - { - dummy_op = Op(sub); - } - wipe(loc); - } - } - } - else if(((s.c.lmr = match(ind + 1, sub->LEFT, pat->LEFT, NULL, 0, sub->LEFT, 12345)) & TRUE) - && ((s.c.rmr = match(ind + 1, sub->RIGHT, pat->RIGHT, cutoff, 0, sub->RIGHT, 123)) & TRUE) - ) - { - dummy_op = Op(sub); - } -#ifndef NDEBUG - DBGSRC(printMatchState("UNDERSCORE:EXIT-MID", s, pposition, 0);) -#endif - switch(Op(sub)) - { - case WHITE: - case PLUS: - case TIMES: - break; - default: - s.c.rmr &= ~POSITION_MAX_REACHED; - } -#ifndef NDEBUG - DBGSRC(printMatchState("streep:EXIT-MID", s, pposition, 0);) -#endif - } - if(s.c.lmr != PRISTINE) - s.c.rmr |= (char)(s.c.lmr & (FENCE | ONCE)); - break; - case AND: - if((s.c.lmr = match(ind + 1, sub, pat->LEFT, cutoff, pposition, expr, op)) & TRUE) - { - loc = same_as_w(pat->RIGHT); - loc = eval(loc); - if(loc->v.fl & SUCCESS) - { - s.c.rmr = TRUE; - if(loc->v.fl & FENCE) - s.c.rmr |= ONCE; - } - else - { - s.c.rmr = FALSE; - if(loc->v.fl & FENCE) - s.c.rmr |= (FENCE | ONCE); - } - wipe(loc); - } - s.c.rmr |= (char)(s.c.lmr & (FENCE | ONCE)); - break; - case MATCH: - if((s.c.lmr = match(ind + 1, sub, pat->LEFT, cutoff, pposition, expr, op)) & TRUE) - { - if((pat->v.fl & ATOM) -#if !STRINGMATCH_CAN_BE_NEGATED - && !NEGATION(pat->v.fl, ATOM) -#endif - ) -#if CUTOFFSUGGEST - s.c.rmr = (char)(stringmatch(ind + 1, "U", SPOBJ(sub), NULL, pat->RIGHT, sub, 0, strlen((char*)SPOBJ(sub)), NULL, 0) & TRUE); -#else - s.c.rmr = (char)(stringmatch(ind + 1, "U", POBJ(sub), NULL, pat->RIGHT, sub, 0, strlen((char*)POBJ(sub))) & TRUE); -#endif - else - s.c.rmr = (char)(match(ind + 1, sub, pat->RIGHT, cutoff, pposition, expr, op) & TRUE); - } - else - s.c.rmr = FALSE; - s.c.rmr |= (char)(s.c.lmr & (FENCE | ONCE | POSITION_MAX_REACHED)); - /* - dbg'(x y z f t m a i n l:? ((m a i n|f t):?X) ?W) & out$(X !X W !W) - correct:X f t W m a i n l - - @(jfhljkhlhfgjkhfas:? ((lh|jk):?W) ?) & !W - wrong: jf - correct: jk - */ - break; - case OR: - if((s.c.lmr = (char)match(ind + 1, sub, pat->LEFT, cutoff, pposition, expr, op)) - & (TRUE | FENCE) - ) - { - if((s.c.lmr & ONCE) && !oncePattern(pat->RIGHT)) - { - s.c.rmr = (char)(s.c.lmr & TRUE); - } - else - { - s.c.rmr = (char)(s.c.lmr & (TRUE | ONCE)); - } - } - else - { - s.c.rmr = match(ind + 1, sub, pat->RIGHT, cutoff, pposition, expr, op); - if((s.c.rmr & ONCE) - && !(s.c.lmr & ONCE) - ) - { - s.c.rmr &= ~(ONCE | POSITION_ONCE); - } - if((s.c.rmr & POSITION_MAX_REACHED) - && !(s.c.lmr & POSITION_MAX_REACHED) - ) - { - s.c.rmr &= ~(POSITION_MAX_REACHED | POSITION_ONCE); - } - } - DBGSRC(Printf("%d%*s", ind, ind, ""); \ - Printf("OR s.c.lmr %d s.c.rmr %d\n", s.c.lmr, s.c.rmr);) - /* - :?W:?X:?Y:?Z & dbg'(a b c d:?X (((a ?:?W) & ~`|?Y)|?Z) d) & out$(X !X W !W Y !Y Z !Z) - erroneous: X a W a b c d Y b c Z - expected: X W a b c Y Z a b c - */ - break; - /* - This is now much quicker than previously, because the whole expression - (|bc|x) is ONCE if the start of the subject does not match the start of any of - the alternations: - dbg'(h h h h h h h h h b b b b b b b b b b b b b b b b b b b b b b b b b b b b - b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b - b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b - b b h h h a b c d:?X (|b c|x) d) - */ - case FUN: - /* Test whether $ is escape */ - if(atomtest(pat->LEFT) == 0) - { - if(((sub->v.fl & (UNIFY | FLGS | NOT)) & (pat->RIGHT->v.fl & (UNIFY | FLGS | NOT))) - == (pat->RIGHT->v.fl & (UNIFY | FLGS | NOT)) - ) - { - if(is_op(pat->RIGHT)) - { - if(Op(sub) == Op(pat->RIGHT)) - { - if((s.c.lmr = match(ind + 1, sub->LEFT, pat->RIGHT->LEFT, NULL, 0, sub->LEFT, 9999)) & TRUE) - s.c.rmr = match(ind + 1, sub->RIGHT, pat->RIGHT->RIGHT, NULL, 0, sub->RIGHT, 8888); - s.c.rmr |= (char)(s.c.lmr & ONCE); /*{?} (=!(a.b)):(=$!(a.b)) => =!(a.b)*/ - } - else - s.c.rmr = (char)ONCE; /*{?} (=!(a.b)):(=$!(a,b)) => F */ - } - else - { - if(!(pat->RIGHT->v.fl & MINUS) - || (!is_op(sub) - && (sub->v.fl & MINUS) - ) - ) - { - if(!pat->RIGHT->u.obj) - { - if(pat->RIGHT->v.fl & UNOPS) - s.c.rmr = (char)(TRUE | ONCE); /*{?} (=!):(=$!) => =! */ - /*{?} (=!(a.b)):(=$!) => =!(a.b) */ - /*{?} (=-a):(=$-) => =-a */ - else if(!(sub->v.fl & (UNIFY | FLGS | NOT)) - && (is_op(sub) || !(sub->v.fl & MINUS)) - ) - { - s.c.rmr = (char)(TRUE | ONCE); /*{?} (=):(=$) => = */ - /*{?} (=(a.b)):(=$) => =a.b */ - } - else - s.c.rmr = (char)ONCE;/*{?} (=-a):(=$) => F */ - /*{?} (=-):(=$) => F */ - /*{?} (=#):(=$) => F */ - } - else if(!is_op(sub) - && pat->RIGHT->u.obj == sub->u.obj - ) - s.c.rmr = (char)(TRUE | ONCE); /*{?} (=-!a):(=$-!a) => =!-a */ - else - s.c.rmr = (char)ONCE;/*{?} (=-!a):(=$-!b) => F */ - } - else - s.c.rmr = (char)ONCE; /*{?} (=):(=$-) => F */ - /*{?} (=(a.b)):(=$-) => F */ - /*{?} (=a):(=$-) => F */ - } - } - else - s.c.rmr = (char)ONCE; /*{?} (=!):(=$!!) => F */ - s.c.rmr &= ~POSITION_MAX_REACHED; - break; - } - /* fall through */ - case FUU: - psh(&sjtNode, &nilNode, NULL); - copy_insert(&sjtNode, sub, cutoff); - if(NOTHING(pat)) - { - loc = _copyop(pat); - loc->v.fl &= ~NOT; - loc->v.fl |= SUCCESS; - } - else - loc = same_as_w(pat); - loc = eval(loc); - deleteNode(&sjtNode); - if(isSUCCESS(loc)) - { - if(((loc->v.fl & (UNIFY | FILTERS)) == UNIFY) && !is_op(loc) && !loc->u.obj) - { - s.c.rmr = (char)TRUE; - wipe(loc); - break; - } - else - { - loc = setflgs(loc, pat->v.fl); - if(equal(pat, loc)) - { - s.c.rmr = (char)(match(ind + 1, sub, loc, cutoff, pposition, expr, op) ^ NOTHING(loc)); - wipe(loc); - break; - } - } - } - else /*"cat" as return value is used as pattern, ~"cat" however is not, because the function failed. */ - { - if(loc->v.fl & FENCE) - s.c.rmr = ONCE; /* '~ as return value from function stops stretching subject */ - } - wipe(loc); - /* fall through */ - default: - if(is_op(pat)) - { - if(Op(sub) == Op(pat)) - { - if((s.c.lmr = match(ind + 1, sub->LEFT, pat->LEFT, NULL, 0, sub->LEFT, 4432)) & TRUE) - { - if(Op(sub) == EQUALS) - { - loc = same_as_w(sub->RIGHT); /* Object might change as a side effect!*/ - s.c.rmr = match(ind + 1, loc, pat->RIGHT, NULL, 0, loc, 2234); - wipe(loc); - } - else - s.c.rmr = match(ind + 1, sub->RIGHT, pat->RIGHT, NULL, 0, sub->RIGHT, 2234); - } - s.c.rmr |= (char)(s.c.lmr & (FENCE | ONCE)); - s.c.rmr &= ~POSITION_MAX_REACHED; - } -#ifndef NDEBUG - DBGSRC(printMatchState("DEFAULT:EXIT-MID", s, pposition, 0);) -#endif - } - else - { - if(pat->u.obj - || !(Flgs & (FRACTION | NUMBER | NONIDENT | ATOM | IDENT)) - ) - { - - s.c.rmr = (char)(ONCE | compare(sub, pat)); - } - else /* e.g. a b c : % */ - { - s.c.rmr = TRUE; - } - } - } - } - } - if(oncePattern(pat) || /* (a b X k:(|? b|`) X ?id) must fail*/ (s.c.rmr & (TRUE | FENCE | ONCE)) == FENCE) - { - s.c.rmr |= (char)(pat->v.fl & FENCE); - s.c.rmr |= ONCE; - DBGSRC(Printf("%d%*smatch(", ind, ind, ""); results(sub, cutoff); \ - Printf(":"); result(pat); Printf(") (B)");) -#ifndef NDEBUG - DBGSRC(Printf(" rmr t %d o %d p %d m %d f %d ", \ - s.b.brmr_true, s.b.brmr_once, s.b.brmr_position_once, s.b.brmr_position_max_reached, s.b.brmr_fence);) -#endif - DBGSRC(if(pat->v.fl & POSITION) Printf("POSITION "); \ - if(pat->v.fl & FRACTION) Printf("FRACTION "); \ - if(pat->v.fl & NUMBER) Printf("NUMBER "); \ - if(pat->v.fl & SMALLER_THAN) Printf("SMALLER_THAN "); \ - if(pat->v.fl & GREATER_THAN) Printf("GREATER_THAN "); \ - if(pat->v.fl & ATOM) Printf("ATOM "); \ - if(pat->v.fl & FENCE) Printf("FENCE "); \ - if(pat->v.fl & IDENT) Printf("IDENT"); \ - Printf("\n");) - } - if(is_op(pat)) - s.c.rmr ^= (char)NOTHING(pat); - if(name) - wipe(name); - return s.c.rmr; - } -/* End of treematch.c */ - -/* Begin of filestatus.c */ - -#if !defined NO_FOPEN - -enum { NoPending, Writing, Reading }; -typedef struct fileStatus - { - char* fname; - FILE* fp; - struct fileStatus* next; -#if !defined NO_LOW_LEVEL_FILE_HANDLING - Boolean dontcloseme; - LONG filepos; /* Normally -1. If >= 0, then the file is closed. - When reopening, filepos is used to find the position - before the file was closed. */ - LONG mode; - LONG type; - LONG size; - LONG number; - LONG time; - int rwstatus; - char* stop; /* contains characters to stop reading at, default NULL */ -#endif - } fileStatus; - -static fileStatus* fs0 = NULL; -#endif - -#if !defined NO_FOPEN -static fileStatus* findFileStatusByName(const char* name) - { - fileStatus* fs; - for(fs = fs0 - ; fs - ; fs = fs->next - ) - if(!strcmp(fs->fname, name)) - return fs; - return NULL; - } - -static fileStatus* allocateFileStatus(const char* name, FILE* fp -#if !defined NO_LOW_LEVEL_FILE_HANDLING - , Boolean dontcloseme -#endif -) - { - fileStatus* fs = (fileStatus*)bmalloc(sizeof(fileStatus)); - fs->fname = (char*)bmalloc(strlen(name) + 1); - strcpy(fs->fname, name); - fs->fp = fp; -#if !defined NO_LOW_LEVEL_FILE_HANDLING - fs->dontcloseme = dontcloseme; -#endif - fs->next = fs0; - fs0 = fs; - return fs0; - } - -static void deallocateFileStatus(fileStatus* fs) - { - fileStatus* fsPrevious, * fsaux; - for(fsPrevious = NULL, fsaux = fs0 - ; fsaux != fs - ; fsPrevious = fsaux, fsaux = fsaux->next - ) - ; - if(fsPrevious) - fsPrevious->next = fs->next; - else - fs0 = fs->next; - if(fs->fp) - fclose(fs->fp); - bfree(fs->fname); -#if !defined NO_LOW_LEVEL_FILE_HANDLING - if(fs->stop) -#ifdef BMALLLOC - bfree(fs->stop); -#else - free(fs->stop); -#endif -#endif - bfree(fs); - } - -static fileStatus* mygetFileStatus(const char* filename, const char* mode -#if !defined NO_LOW_LEVEL_FILE_HANDLING - , Boolean dontcloseme -#endif -) - { - FILE* fp = fopen(filename, mode); - if(fp) - { - fileStatus* fs = allocateFileStatus(filename, fp -#if !defined NO_LOW_LEVEL_FILE_HANDLING - , dontcloseme -#endif - ); - return fs; - } - return NULL; - } - -static fileStatus* myfopen(const char* filename, const char* mode -#if !defined NO_LOW_LEVEL_FILE_HANDLING - , Boolean dontcloseme -#endif -) - { -#if !defined NO_FOPEN - if(!findFileStatusByName(filename)) - { - fileStatus* fs = mygetFileStatus(filename, mode -#if !defined NO_LOW_LEVEL_FILE_HANDLING - , dontcloseme -#endif - ); - if(!fs && targetPath && strchr(mode, 'r')) - { - const char* p = filename; - char* q; - size_t len; - while(*p) - { - if(*p == '\\' || *p == '/') - { - if(p == filename) - return NULL; - break; - } - else if((*p == ':') && (p == filename + 1)) - return NULL; - ++p; - } - q = (char*)malloc((len = strlen(targetPath)) + strlen(filename) + 1); - if(q) - { - strcpy(q, targetPath); - strcpy(q + len, filename); - fs = mygetFileStatus(q, mode -#if !defined NO_LOW_LEVEL_FILE_HANDLING - , dontcloseme -#endif - ); - free(q); - } - } - return fs; - } -#endif - return NULL; - } -#endif - -#if !defined NO_LOW_LEVEL_FILE_HANDLING -static LONG someopt(psk pnode, LONG opt[]) - { - int i; - assert(!is_op(pnode)); - for(i = 0; opt[i]; i++) - if(PLOBJ(pnode) == opt[i]) - return opt[i]; - return 0L; - } - -#if !defined NO_FOPEN - -static LONG tijdnr = 0L; - -static int closeAFile(void) - { - fileStatus* fs, * fsmin; - if(fs0 == NULL) - return FALSE; - for(fs = fs0, fsmin = fs0; - fs != NULL; - fs = fs->next) - { - if(!fs->dontcloseme - && fs->filepos == -1L - && fs->time < fsmin->time - ) - fsmin = fs; - } - if(fsmin == NULL || fsmin->dontcloseme) - { - return FALSE; - } - fsmin->filepos = FTELL(fsmin->fp); - /* fs->filepos != -1 means that the file is closed */ - fclose(fsmin->fp); - fsmin->fp = NULL; - return TRUE; - } -#if defined NDEBUG -#define preparefp(fs,name,mode) preparefp(fs,mode) -#endif - -static fileStatus* preparefp(fileStatus* fs, char* name, LONG mode) - { - assert(fs != NULL); - assert(!strcmp(fs->fname, name)); - if(mode != 0L - && mode != fs->mode - && fs->fp != NULL) - { - fs->mode = mode; - if((fs->fp = freopen(fs->fname, (char*)&(fs->mode), fs->fp)) == NULL) - return NULL; - fs->rwstatus = NoPending; - } - else if(fs->filepos >= 0L) - { - if((fs->fp = fopen(fs->fname, (char*)&(fs->mode))) == NULL) - { - if(closeAFile()) - fs->fp = fopen(fs->fname, (char*)&(fs->mode)); - } - if(fs->fp == NULL) - return NULL; - fs->rwstatus = NoPending; - FSEEK(fs->fp, fs->filepos, SEEK_SET); - } - fs->filepos = -1L; - fs->time = tijdnr++; - return fs; - } -/* -Find an existing or create a fresh file handle for a known file name -If the file mode differs from the current file mode, - reopen the file with the new file mode. -If the file is known but has been closed (e.g. to save file handles), - open the file with the memorized file mode and go to the memorized position -*/ -static fileStatus* search_fp(char* name, LONG mode) - { - fileStatus* fs; - for(fs = fs0; fs; fs = fs->next) - if(!strcmp(name, fs->fname)) - return preparefp(fs, name, mode); - return NULL; - } - -static void setStop(fileStatus* fs, char* stopstring) - { - if(fs->stop) -#ifdef BMALLLOC - bfree(fs->stop); - fs->stop = (char*)bmalloc(strlen(stopstring + 1); -#else - free(fs->stop); - fs->stop = (char*)malloc(strlen(stopstring) + 1); -#endif - if(fs->stop) - strcpy(fs->stop, stopstring); - } - -static int fil(ppsk PPnode) - { - FILE* fp; - psk kns[4]; - LONG ind; - int sh; - psk pnode; - static fileStatus* fs = NULL; - char* name; - - static LONG types[] = { CHR,DEC,STRt,0L }; - static LONG whences[] = { SET,CUR,END,0L }; - static LONG modes[] = { - O('r', 0 , 0),/*open text file for reading */ - O('w', 0 , 0),/*create text file for writing, or trucate to zero length */ - O('a', 0 , 0),/*append; open text file or create for writing at eof */ - O('r','b', 0),/*open binary file for reading */ - O('w','b', 0),/*create binary file for writing, or trucate to zero length */ - O('a','b', 0),/*append; open binary file or create for writing at eof */ - O('r','+', 0),/*open text file for update (reading and writing) */ - O('w','+', 0),/*create text file for update, or trucate to zero length */ - O('a','+', 0),/*append; open text file or create for update, writing at eof */ - O('r','+','b'), - O('r','b','+'),/*open binary file for update (reading and writing) */ - O('w','+','b'), - O('w','b','+'),/*create binary file for update, or trucate to zero length */ - O('a','+','b'), - O('a','b','+'),/*append;open binary file or create for update, writing at eof*/ - 0L }; - - static LONG type, numericalvalue, whence; - union - { - LONG l; - char c[4]; - } mode; - - union - { - short s; - INT32_T i; - char c[4]; - } snum; - - /* - Fail if there are more than four arguments or if an argument is non-atomic - */ - for(ind = 0, pnode = (*PPnode)->RIGHT; - is_op(pnode); - pnode = pnode->RIGHT) - { - if(is_op(pnode->LEFT) || ind > 2) - { - return FALSE; - } - kns[ind++] = pnode->LEFT; - } - kns[ind++] = pnode; - for(; ind < 4;) - kns[ind++] = NULL; - - /* - FIRST ARGUMENT: File name - if the current file name is different from the argument, - reset the current file name - if the first argument is empty, the current file name must not be NULL - fil$(name) - fil$(name,...) - name field is optional in all fil$ operations - */ - if(kns[0]->u.obj) - { - name = (char*)POBJ(kns[0]); - if(fs && strcmp(name, fs->fname)) - { - fs = NULL; - } - } - else - { - if(fs) - name = fs->fname; - else - { - return FALSE; - } - } - - /* - SECOND ARGUMENT: mode, type, whence or TEL - if the second argument is a mode string, - the file handel is found and adapted to the mode - or a new file handel is made - else - file handel is set to current name - - If the second argument is set, fil$ does never read or write! - */ - if(kns[1] && kns[1]->u.obj) - { - /* - SECOND ARGUMENT:FILE MODE - fil$(,"r") - fil$(,"b") - fil$(,"a") - etc. - */ - if((mode.l = someopt(kns[1], modes)) != 0L) - { - if(fs) - fs = preparefp(fs, name, mode.l); - else - fs = search_fp(name, mode.l); - if(fs == NULL) - { - if((fs = myfopen(name, (char*)&mode, FALSE)) == NULL) - { - if(closeAFile()) - fs = myfopen(name, (char*)&mode, FALSE); - } - if(fs == NULL) - { - return FALSE; - } - fs->filepos = -1L; - fs->mode = mode.l; - fs->type = CHR; - fs->size = 1; - fs->number = 1; - fs->time = tijdnr++; - fs->rwstatus = NoPending; - fs->stop = NULL; - assert(fs->fp != 0); - } - assert(fs->fp != 0); - return TRUE; - } - else - { - /* - We do not open a file now, so we should have a file handle in memory. - */ - if(fs) - { - fs = preparefp(fs, name, 0L); - } - else - { - fs = search_fp(name, 0L); - } - - if(!fs) - { - return FALSE; - } - assert(fs->fp != 0); - - /* - SECOND ARGUMENT:TYPE - fil$(,CHR) - fil$(,DEC) - fil$(,CHR,size) - fil$(,DEC,size) - fil$(,CHR,size,number) - fil$(,DEC,size,number) - fil$(,STR) (stop == NULL) - fil$(,STR,stop) - */ - if((type = someopt(kns[1], types)) != 0L) - { - fs->type = type; - if(type == STRt) - { - /* - THIRD ARGUMENT: primary stopping character (e.g. "\n") - - An empty string "" sets stopping string to NULL, - (Changed behaviour! Previously default stop was newline!) - */ - if(kns[2] && kns[2]->u.obj) - { - setStop(fs, (char*)&kns[2]->u.obj); - } - else - { - if(fs->stop) -#ifdef BMALLLOC - bfree(fs->stop); - fs->stop = NULL; -#else - free(fs->stop); - fs->stop = NULL; -#endif - } - } - else - { - /* - THIRD ARGUMENT: a size of elements to read or write - */ - if(kns[2] && kns[2]->u.obj) - { - if(!INTEGER(kns[2])) - { - return FALSE; - } - fs->size = toLong(kns[2]); - } - else - { - fs->size = 1; - fs->number = 1; - } - /* - FOURTH ARGUMENT: the number of elements to read or write - */ - if(kns[3] && kns[3]->u.obj) - { - if(!INTEGER(kns[3])) - { - return FALSE; - } - fs->number = toLong(kns[3]); - } - else - fs->number = 1; - } - return TRUE; - } - /* - SECOND ARGUMENT:POSITIONING - fil$(,SET) - fil$(,END) - fil$(,CUR) - fil$(,SET,offset) - fil$(,END,offset) - fil$(,CUR,offset) - */ - else if((whence = someopt(kns[1], whences)) != 0L) - { - LONG offset; - assert(fs->fp != 0); - fs->time = tijdnr++; - /* - THIRD ARGUMENT: an offset - */ - if(kns[2] && kns[2]->u.obj) - { - if(!INTEGER(kns[2])) - { - return FALSE; - } - offset = toLong(kns[2]); - } - else - offset = 0L; - - if((offset < 0L && whence == SEEK_SET) - || (offset > 0L && whence == SEEK_END) - || FSEEK(fs->fp, offset, whence == SET ? SEEK_SET - : whence == END ? SEEK_END - : SEEK_CUR)) - { - deallocateFileStatus(fs); - fs = NULL; - return FALSE; - } - fs->rwstatus = NoPending; - return TRUE; - } - /* - SECOND ARGUMENT:TELL POSITION - fil$(,TEL) - */ - else if(PLOBJ(kns[1]) == TEL) - { - char pos[11]; - sprintf(pos, LONGD, FTELL(fs->fp)); - wipe(*PPnode); - *PPnode = scopy((const char*)pos); - return TRUE; - } - else - { - return FALSE; - } - } - /* - return FALSE if the second argument is not empty but could not be recognised - */ - } - else - { - if(fs) - { - fs = preparefp(fs, name, 0L); - } - else - { - fs = search_fp(name, 0L); - } - } - - if(!fs) - { - return FALSE; - } - /* - READ OR WRITE - Now we are either going to read or to write - */ - - type = fs->type; - mode.l = fs->mode; - fp = fs->fp; - - /* - THIRD ARGUMENT: the number of elements to read or write - OR stop characters, depending on type (20081113) - */ - - if(kns[2] && kns[2]->u.obj) - { - if(type == STRt) - { - setStop(fs, (char*)&kns[2]->u.obj); - } - else - { - if(!INTEGER(kns[2])) - { - return FALSE; - } - fs->number = toLong(kns[2]); - } - } - - /* - We allow 1, 2 or 4 bytes to be read/written in one fil$ operation - These can be distributed over decimal numbers. - */ - - if(type == DEC) - { - switch((int)fs->size) - { - case 1: - if(fs->number > 4) - fs->number = 4; - break; - case 2: - if(fs->number > 2) - fs->number = 2; - break; - default: - fs->size = 4; /*Invalid size declaration adjusted*/ - fs->number = 1; - } - } - fs->time = tijdnr++; - /* - FOURTH ARGUMENT:VALUE TO WRITE - */ - if(kns[3]) - { - if(mode.c[0] != 'r' || mode.c[1] == '+' || mode.c[2] == '+') - /* - WRITE - */ - { - if(fs->rwstatus == Reading) - { - LONG fpos = FTELL(fs->fp); - FSEEK(fs->fp, fpos, SEEK_SET); - } - fs->rwstatus = Writing; - if(type == DEC) - { - numericalvalue = toLong(kns[3]); - for(ind = 0; ind < fs->number; ind++) - switch((int)fs->size) - { - case 1: - fputc((int)numericalvalue & 0xFF, fs->fp); - numericalvalue >>= 8; - break; - case 2: - snum.s = (short)(numericalvalue & 0xFFFF); - fwrite(snum.c, 1, 2, fs->fp); - numericalvalue >>= 16; - break; - case 4: - snum.i = (INT32_T)(numericalvalue & 0xFFFFFFFF); - fwrite(snum.c, 1, 4, fs->fp); - assert(fs->number == 1); - break; - default: - fwrite((char*)&numericalvalue, 1, 4, fs->fp); - break; - } - } - else if(type == CHR) - { - size_t len, len1, minl; - len1 = (size_t)(fs->size * fs->number); - len = strlen((char*)POBJ(kns[3])); - minl = len1 < len ? (len1 > 0 ? len1 : len) : len; - if(fwrite(POBJ(kns[3]), 1, minl, fs->fp) == minl) - for(; len < len1 && putc(' ', fs->fp) != EOF; len++); - } - else /*if(type == STRt)*/ - { - if(fs->stop - && fs->stop[0] - )/* stop string also works when writing. */ - { - char* s = (char*)POBJ(kns[3]); - while(!strchr(fs->stop, *s)) - fputc(*s++, fs->fp); - } - else - { - fputs((char*)POBJ(kns[3]), fs->fp); - } - } - } - else - { - /* - Fail if not in write mode - */ - return FALSE; - } - } - else - { - if(mode.c[0] == 'r' || mode.c[1] == '+' || mode.c[2] == '+') - { - /* - READ - */ -#define INPUTBUFFERSIZE 256 - unsigned char buffer[INPUTBUFFERSIZE]; - unsigned char* bbuffer;/* = buffer;*/ - if(fs->rwstatus == Writing) - { - fflush(fs->fp); - fs->rwstatus = NoPending; - } - if(feof(fp)) - { - return FALSE; - } - fs->rwstatus = Reading; - if(type == STRt) - { - psk lpkn = NULL; - psk rpkn = NULL; - char* conc[2]; - int count = 0; - LONG pos = FTELL(fp); - int kar = 0; - while(count < (INPUTBUFFERSIZE - 1) - && (kar = fgetc(fp)) != EOF - && (!fs->stop - || !strchr(fs->stop, kar) - ) - ) - { - buffer[count++] = (char)kar; - } - if(count < (INPUTBUFFERSIZE - 1)) - { - buffer[count] = '\0'; - bbuffer = buffer; - } - else - { - buffer[(INPUTBUFFERSIZE - 1)] = '\0'; - while((kar = fgetc(fp)) != EOF - && (!fs->stop - || !strchr(fs->stop, kar) - ) - ) - count++; - if(count >= INPUTBUFFERSIZE) - { - bbuffer = (unsigned char*)bmalloc((size_t)count + 1); - strcpy((char*)bbuffer, (char*)buffer); - FSEEK(fp, pos + (INPUTBUFFERSIZE - 1), SEEK_SET); - if(fread((char*)bbuffer + (INPUTBUFFERSIZE - 1), 1, count - (INPUTBUFFERSIZE - 1), fs->fp) == 0) - { - bfree(bbuffer); - return FALSE; - } - if(ferror(fs->fp)) - { - bfree(bbuffer); - perror("fread"); - return FALSE; - } - if(kar != EOF) - fgetc(fp); /* skip stopping character (which is in 'kar') */ - } - else - bbuffer = buffer; - } - source = bbuffer; - lpkn = input(NULL, lpkn, 1, NULL, NULL); - if(kar == EOF) - bbuffer[0] = '\0'; - else - { - bbuffer[0] = (char)kar; - bbuffer[1] = '\0'; - } - source = bbuffer; - rpkn = input(NULL, rpkn, 1, NULL, NULL); - conc[0] = "(\1.\2)"; - addr[1] = lpkn; - addr[2] = rpkn; - conc[1] = NULL; - *PPnode = vbuildup(*PPnode, (const char**)conc); - wipe(addr[1]); - wipe(addr[2]); - } - else - { - size_t readbytes = fs->size * fs->number; - if(readbytes >= INPUTBUFFERSIZE) - bbuffer = (unsigned char*)bmalloc(readbytes + 1); - else - bbuffer = buffer; - if((readbytes = fread((char*)bbuffer, (size_t)fs->size, (size_t)fs->number, fs->fp)) == 0 - && fs->size != 0 - && fs->number != 0 - ) - { - return FALSE; - } - if(ferror(fs->fp)) - { - perror("fread"); - return FALSE; - } - *(bbuffer + (int)readbytes) = 0; - if(type == DEC) - { - numericalvalue = 0L; - sh = 0; - for(ind = 0; ind < fs->number;) - { - switch((int)fs->size) - { - case 1: - numericalvalue += (LONG)bbuffer[ind++] << sh; - sh += 8; - continue; - case 2: - numericalvalue += (LONG)(*(short*)(bbuffer + ind)) << sh; - ind += 2; - sh += 16; - continue; - case 4: - numericalvalue += (LONG)(*(INT32_T*)(bbuffer + ind)) << sh; - ind += 4; - sh += 32; - continue; - default: - numericalvalue += *(LONG*)bbuffer; - break; - } - break; - } - sprintf((char*)bbuffer, LONGD, numericalvalue); - } - source = bbuffer; - *PPnode = input(NULL, *PPnode, 1, NULL, NULL); - } - if(bbuffer != (unsigned char*)&buffer[0]) - bfree(bbuffer); - return TRUE; - } - else - { - return FALSE; - } - } - return TRUE; - } -#endif -#endif - -static int allopts(psk pnode, LONG opt[]) - { - int i; - while(is_op(pnode)) - { - if(!allopts(pnode->LEFT, opt)) - return FALSE; - pnode = pnode->RIGHT; - } - for(i = 0; opt[i]; i++) - if(PLOBJ(pnode) == opt[i]) - return TRUE; - return FALSE; - } - -static int flush(void) - { -#ifdef __GNUC__ - return fflush(global_fpo); -#else -#if _BRACMATEMBEDDED - if(WinFlush) - WinFlush(); - return 1; -#else - return 1; -#endif -#endif - } - -static int output(ppsk PPnode, void(*how)(psk k)) - { - FILE* saveFpo; - psk rightnode, rlnode, rrightnode, rrrightnode; - static LONG opts[] = - { APP,BIN,CON,EXT,MEM,LIN,NEW,RAW,TXT,VAP,WYD,0L }; - if(Op(rightnode = (*PPnode)->RIGHT) == COMMA) - { - int wide; - saveFpo = global_fpo; - rlnode = rightnode->LEFT; - rrightnode = rightnode->RIGHT; - wide = search_opt(rrightnode, WYD); - if(wide) - LineLength = WIDELINELENGTH; - hum = !search_opt(rrightnode, LIN); - listWithName = !search_opt(rrightnode, RAW); - if(allopts(rrightnode, opts)) - { - if(search_opt(rrightnode, MEM)) - { - psk ret; - telling = 1; - process = tel; - global_fpo = NULL; - (*how)(rlnode); - ret = (psk)bmalloc(sizeof(ULONG) + telling); - ret->v.fl = READY | SUCCESS; - process = glue; - source = POBJ(ret); - (*how)(rlnode); - hum = 1; - process = myputc; - wipe(*PPnode); - *PPnode = ret; - global_fpo = saveFpo; - return TRUE; - } - else - { - (*how)(rlnode); - flush(); - addr[2] = rlnode; - } - } - else if(Op(rrightnode) == COMMA - && !is_op(rrightnode->LEFT) - && allopts((rrrightnode = rrightnode->RIGHT), opts)) - { -#if !defined NO_FOPEN - int binmode = ((how == lst) && !search_opt(rrrightnode, TXT)) || search_opt(rrrightnode, BIN); - fileStatus* fs = - myfopen((char*)POBJ(rrightnode->LEFT), - search_opt(rrrightnode, NEW) - ? (binmode - ? WRITEBIN - : WRITETXT - ) - : (binmode - ? APPENDBIN - : APPENDTXT - ) -#if !defined NO_LOW_LEVEL_FILE_HANDLING - , TRUE -#endif - ); - if(fs == NULL) - { - errorprintf("cannot open %s\n", POBJ(rrightnode->LEFT)); - global_fpo = saveFpo; - hum = 1; - return FALSE; - } - else - { - global_fpo = fs->fp; - (*how)(rlnode); - deallocateFileStatus(fs); - global_fpo = saveFpo; - addr[2] = rlnode; - } -#else - hum = 1; - return FALSE; -#endif - } - else - { - (*how)(rightnode); - flush(); - addr[2] = rightnode; - } - *PPnode = dopb(*PPnode, addr[2]); - if(wide) - LineLength = NARROWLINELENGTH; - } - else - { - (*how)(rightnode); - flush(); - *PPnode = rightbranch(*PPnode); - } - hum = 1; - listWithName = 1; - return TRUE; - } - -#if !defined NO_FOPEN -static psk fileget(psk rlnode, int intval_i, psk Pnode, int* err, Boolean* GoOn) - { - FILE* saveFp; - fileStatus* fs; - saveFp = global_fpi; - fs = myfopen((char*)POBJ(rlnode), (intval_i & OPT_TXT) ? READTXT : READBIN -#if !defined NO_LOW_LEVEL_FILE_HANDLING - , TRUE -#endif - ); - if(fs == NULL) - { - global_fpi = saveFp; - return 0L; - } - else - global_fpi = fs->fp; - for(;;) - { - Pnode = input(global_fpi, Pnode, intval_i, err, GoOn); - if(!*GoOn || *err) - break; - Pnode = eval(Pnode); - } - deallocateFileStatus(fs); - global_fpi = saveFp; - return Pnode; - } -#endif -/* End of filestatus.c */ - -/* Begin of simil.c */ - -static LONG simil -(const char* s1 - , const char* s1end - , const char* s2 - , const char* s2end - , int* putf1 - , int* putf2 - , LONG* plen1 - , LONG* plen2 -) - { - const char* ls1; - const char* s1l = NULL; - const char* s1r = NULL; - const char* s2l = NULL; - const char* s2r = NULL; - LONG max; - LONG len1; - LONG len2 = 0; - /* regard each character in s1 as possible starting point for match */ - for(max = 0, ls1 = s1, len1 = 0 - ; ls1 < s1end - ; getCodePoint2(&ls1, putf1), ++len1) - { - const char* ls2; - /* compare with s2 */ - for(ls2 = s2, len2 = 0; ls2 < s2end; getCodePoint2(&ls2, putf2), ++len2) - { - const char* lls1 = ls1; - const char* lls2 = ls2; - /* determine lenght of equal parts */ - LONG len12 = 0; - for(;;) - { - if(lls1 < s1end && lls2 < s2end) - { - const char* ns1 = lls1, * ns2 = lls2; - int K1 = getCodePoint2(&ns1, putf1); - int K2 = getCodePoint2(&ns2, putf2); - if(toLowerUnicode(K1) == toLowerUnicode(K2)) - { - ++len12; - lls1 = ns1; - lls2 = ns2; - } - else - break; - } - else - break; - } - /* adapt score if needed */ - if(len12 > max) - { - max = len12; - /* remember end points of left strings and start points of - right strings */ - s1l = ls1; - s1r = lls1; - s2l = ls2; - s2r = lls2; - } - } - } - if(max) - { - max += simil(s1, s1l, s2, s2l, putf1, putf2, NULL, NULL) + simil(s1r, s1end, s2r, s2end, putf1, putf2, NULL, NULL); - } - if(plen1) - { - *plen1 = len1; - } - if(plen2) - { - if(len1 == 0) - { - for(len2 = 0; *s2; getCodePoint2(&s2, putf2), ++len2) - ; - } - *plen2 = len2; - } - return max; - } - -static void Sim(char* draft, char* str1, char* str2) - { - int utf1 = 1; - int utf2 = 1; - LONG len1 = 0; - LONG len2 = 0; - LONG sim = simil(str1, str1 + strlen((char*)str1), str2, str2 + strlen((char*)str2), &utf1, &utf2, &len1, &len2); - sprintf(draft, LONGD "/" LONGD, (2L * (LONG)sim), len1 + len2); - } -/* End of simil.c */ - -/* Begin of objectdef.c */ - -static classdef classes[] = - { {"hash",hash} - , {"calculation",calculation} - , {"UFP",calculation} /*Next thing after UFO. Unshackled Floating Point?*/ - , {NULL,NULL} - }; /**/ - -static int hasSubObject(psk src) - { - while(is_op(src)) - { - if(Op(src) == EQUALS) - return TRUE; - else - { - if(hasSubObject(src->LEFT)) - return TRUE; - src = src->RIGHT; - } - } - return FALSE; - } - -static psk objectcopysub(psk src); - -static psk objectcopysub2(psk src) /* src is NOT an object */ - { - psk goal; - if(is_op(src) && hasSubObject(src)) - { - goal = (psk)bmalloc(sizeof(knode)); - goal->v.fl = src->v.fl & COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - goal->LEFT = objectcopysub(src->LEFT); - goal->RIGHT = objectcopysub(src->RIGHT); - return goal; - } - else - return same_as_w(src); - } - -static psk objectcopysub(psk src) - { - psk goal; - if(is_object(src)) - { - if(ISBUILTIN((objectnode*)src)) - { - return same_as_w(src); - } - else - { - goal = (psk)bmalloc(sizeof(objectnode)); -#if WORD32 - ((typedObjectnode*)goal)->u.Int = 0; -#else - ((typedObjectnode*)goal)->v.fl &= ~(BUILT_IN | CREATEDWITHNEW); -#endif - } - goal->v.fl = src->v.fl & COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - goal->LEFT = same_as_w(src->LEFT); - goal->RIGHT = same_as_w(src->RIGHT); - return goal; - } - else - return objectcopysub2(src); - } - -static psk objectcopy(psk src) - { - psk goal; - if(is_object(src)) /* Make a copy of this '=' node ... */ - { - if(ISBUILTIN((objectnode*)src)) - { - goal = (psk)bmalloc(sizeof(typedObjectnode)); -#if WORD32 - ((typedObjectnode*)goal)->u.Int = BUILTIN; -#else - ((typedObjectnode*)goal)->v.fl |= BUILT_IN; -#endif - ((typedObjectnode*)goal)->vtab = ((typedObjectnode*)src)->vtab; - ((typedObjectnode*)goal)->voiddata = NULL; - } - else - { - goal = (psk)bmalloc(sizeof(objectnode)); -#if WORD32 - ((typedObjectnode*)goal)->u.Int = 0; -#else - ((typedObjectnode*)goal)->v.fl &= ~(BUILT_IN | CREATEDWITHNEW); -#endif - } - goal->v.fl = src->v.fl & COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - goal->LEFT = same_as_w(src->LEFT); - /*?? This adds an extra level of copying, but ONLY for objects that have a '=' node as the lhs of the main '=' node*/ - /* What is it good for? Bart 20010220 */ - goal->RIGHT = objectcopysub(src->RIGHT); /* and of all '=' child nodes (but not of grandchildren!) */ - return goal; - } - else - return objectcopysub2(src); - } - -static psk getObjectDef(psk src) - { - psk def; - typedObjectnode* dest; - if(!is_op(src)) - { - classdef* df = classes; - for(; df->name && strcmp(df->name, (char*)POBJ(src)); ++df) - ; - if(df->vtab) - { - dest = (typedObjectnode*)bmalloc(sizeof(typedObjectnode)); - dest->v.fl = EQUALS | SUCCESS; - dest->left = same_as_w(&nilNode); - dest->right = same_as_w(src); -#if WORD32 - dest->u.Int = BUILTIN; -#else - dest->v.fl &= ~(BUILT_IN | CREATEDWITHNEW); - dest->v.fl |= BUILT_IN; -#endif - dest->voiddata = NULL; - dest->vtab = df->vtab; - return (psk)dest; - } - } - else if(Op(src) == EQUALS) - { - src->RIGHT = Head(src->RIGHT); - return objectcopy(src); - } - - if((def = SymbolBinding_w(src, src->v.fl & DOUBLY_INDIRECT)) != NULL) - { - dest = (typedObjectnode*)bmalloc(sizeof(typedObjectnode)); - dest->v.fl = EQUALS | SUCCESS; - dest->left = same_as_w(&nilNode); - dest->right = objectcopy(def); /* TODO Head(&def) ? */ - wipe(def); -#if WORD32 - dest->u.Int = 0; -#else - dest->v.fl &= ~(BUILT_IN | CREATEDWITHNEW); -#endif - dest->voiddata = NULL; - dest->vtab = NULL; - return (psk)dest; - } - return NULL; - } -/* End of objectdef.c */ - -/* Begin of functions.c */ - -#define LONGCASE - -#ifdef LONGCASE -#define SWITCH(v) switch(v) -#define FIRSTCASE(a) case a : -#define CASE(a) case a : -#define DEFAULT default : -#else -#define SWITCH(v) LONG lob;lob = v; -#define FIRSTCASE(a) if(lob == a) -#define CASE(a) else if(lob == a) -#define DEFAULT else -#endif - -#ifdef DELAY_DUE_TO_INPUT -static clock_t delayDueToInput = 0; -#endif - -#if !defined NO_C_INTERFACE -static void* strToPointer(const char* str) - { - size_t res = 0; - while(*str) - res = 10 * res + (*str++ - '0'); - return (void*)res; - } - -static void pointerToStr(char* pc, void* p) - { - size_t P = (size_t)p; - char* PC = pc; - while(P) - { - *pc++ = (char)((P % 10) + '0'); - P /= 10; - } - *pc-- = '\0'; - while(PC < pc) - { - char sav = *PC; - *PC = *pc; - *pc = sav; - ++PC; - --pc; - } - } -#endif - -#if O_S -static psk swi(psk Pnode, psk rlnode, psk rrightnode) - { - int i; - union - { - unsigned int i[sizeof(os_regset) + 1]; - struct - { - int swicode; - os_regset regs; - } s; - } u; - char pc[121]; - for(i = 0; i < sizeof(os_regset) / sizeof(int); i++) - u.s.regs.r[i] = 0; - rrightnode = Pnode; - i = 0; - do - { - rrightnode = rrightnode->RIGHT; - rlnode = is_op(rrightnode) ? rrightnode->LEFT : rrightnode; - if(is_op(rlnode) || !INTEGER_NOT_NEG(rlnode)) - return functionFail(Pnode); - u.i[i++] = (unsigned int) - strtoul((char*)POBJ(rlnode), (char**)NULL, 10); - } while(is_op(rrightnode) && i < 10); -#ifdef __TURBOC__ - intr(u.s.swicode, (struct REGPACK*)&u.s.regs); - sprintf(pc, "0.%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", - u.i[1], u.i[2], u.i[3], u.i[4], u.i[5], - u.i[6], u.i[7], u.i[8], u.i[9], u.i[10]); -#else -#if defined ARM - i = (int)os_swix(u.s.swicode, &u.s.regs); - sprintf(pc, "%u.%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", - i, - u.i[1], u.i[2], u.i[3], u.i[4], u.i[5], - u.i[6], u.i[7], u.i[8], u.i[9], u.i[10]); -#endif -#endif - return build_up(Pnode, pc, NULL); - } -#endif - -static void stringreverse(char* a, size_t len) - { - char* b; - b = a + len; - while(a < --b) - { - char c = *a; - *a = *b; - *b = c; - ++a; - } - } - -static void print_clock(char* pjotter) - { - clock_t time = clock(); -#ifdef DELAY_DUE_TO_INPUT - time -= delayDueToInput; -#endif - if(time == (clock_t)-1) - sprintf(pjotter, "-1"); - else -#if defined __TURBOC__ && !defined __BORLANDC__ - sprintf(pjotter, "%0lu/%lu", (ULONG)time, (ULONG)(10.0 * CLOCKS_PER_SEC));/* CLOCKS_PER_SEC == 18.2 */ -#else - sprintf(pjotter, LONG0D "/" LONGD, (LONG)time, (LONG)CLOCKS_PER_SEC); -#endif - } - -static void combiflags(psk pnode) - { - int lflgs; - if((lflgs = pnode->LEFT->v.fl & UNOPS) != 0) - { - pnode->RIGHT = isolated(pnode->RIGHT); - if(NOTHINGF(lflgs)) - { - pnode->RIGHT->v.fl |= lflgs & ~NOT; - pnode->RIGHT->v.fl ^= NOT | SUCCESS; - } - else - pnode->RIGHT->v.fl |= lflgs; - } - } - -static function_return_type execFnc(psk Pnode) - { - psk lnode; - objectStuff Object = { 0,0,0 }; - - lnode = Pnode->LEFT; - if(is_op(lnode)) - { - switch(Op(lnode)) - { - case EQUALS: /* Anonymous function: (=.out$!arg)$HELLO -> lnode == (=.out$!arg) */ - lnode->RIGHT = Head(lnode->RIGHT); - lnode = same_as_w(lnode->RIGHT); - if(lnode) /* lnode is null if either the function wasn't found or it is a built-in member function of an object. */ - { - if(Op(lnode) == DOT) /* The dot separating local variables from the function body. */ - { - psh(&argNode, Pnode->RIGHT, NULL); - Pnode = dopb(Pnode, lnode); - wipe(lnode); - if(Op(Pnode) == DOT) - { - psh(Pnode->LEFT, &zeroNode, NULL); - Pnode = eval(Pnode); - /**** Evaluate anonymous function. - - (=.!arg)$XYZ - ****/ - pop(Pnode->LEFT); - Pnode = dopb(Pnode, Pnode->RIGHT); - } - deleteNode(&argNode); - return functionOk(Pnode); - } - else - { -#if defined NO_EXIT_ON_NON_SEVERE_ERRORS - return functionFail(Pnode); -#else - errorprintf("(Syntax error) The following is not a function:\n\n "); - writeError(Pnode->LEFT); - exit(116); -#endif - } - } - break; - case DOT: /* Method. Dot separating object name (or anonymous definition) from method name */ - lnode = findMethod(lnode, &Object); - if(lnode) - { - if(Op(lnode) == DOT) /* The dot separating local variables from the function body. */ - { - psh(&argNode, Pnode->RIGHT, NULL); - - if(Object.self) - { - psh(&selfNode, Object.self, NULL); /* its */ - Pnode = dopb(Pnode, lnode); - wipe(lnode); - /* - psh(&selfNode,self,NULL); Must precede dopb(...). - Example where this is relevant: - - {?} ((==.lst$its).)' - (its= - =.lst$its); - {!} its - - */ - if(Object.object) - { - psh(&SelfNode, Object.object, NULL); /* Its */ - if(Op(Pnode) == DOT) - { - psh(Pnode->LEFT, &zeroNode, NULL); - Pnode = eval(Pnode); - /**** Evaluate member function of built-in - object from within an enveloping - object. ----------------- - | - ( new$hash:?myhash | - & ( | - = ( myInsert | - = . (Its..insert)$!arg <- - ) - ) - : (=?(myhash.)) - & (myhash..myInsert)$(X.12) - ) - ****/ - pop(Pnode->LEFT); - Pnode = dopb(Pnode, Pnode->RIGHT); - } - deleteNode(&SelfNode); - } - else - { - if(Op(Pnode) == DOT) - { - psh(Pnode->LEFT, &zeroNode, NULL); - Pnode = eval(Pnode); - /**** Evaluate member function from - within an other member function - ( ( Object | - = (do=.out$!arg) | - ( A | - = | - . (its.do)$!arg <----- - ) - ) - & (Object.A)$XYZ - ) - ****/ - pop(Pnode->LEFT); - Pnode = dopb(Pnode, Pnode->RIGHT); - } - } - deleteNode(&selfNode); - deleteNode(&argNode); - return functionOk(Pnode); - } - else - { /* Unreachable? */ - deleteNode(&argNode); - } - } - else if(Object.theMethod) - { - if(Object.theMethod((struct typedObjectnode*)Object.object, &Pnode)) - { - /**** Evaluate a built-in method of an anonymous object. - - (new$hash.insert)$(a.2) - ****/ - wipe(lnode); /* This is the built-in object, which got increased refcount to evade untimely wiping. */ - return functionOk(Pnode); - } - else - { /* method failed. E.g. (new$hash.insert)$(a) */ - wipe(lnode); - } - } - else - { -#if defined NO_EXIT_ON_NON_SEVERE_ERRORS - return functionFail(Pnode); -#else - errorprintf("(Syntax error) The following is not a function:\n\n "); - writeError(Pnode->LEFT); - exit(116); -#endif - } - } - else - { - if(Object.theMethod) - { - if(Object.theMethod((struct typedObjectnode*)Object.object, &Pnode)) - { - /**** Evaluate a built-in method of a named object. - | - new$hash:?H | - & (H..insert)$(XYZ.2) <- - ****/ - return functionOk(Pnode); - } - } - } - break; - default: - { - /* /('(x.$x^2)) when evaluating /('(x.$x^2))$3 */ - if((Op(lnode) == FUU) - && (lnode->v.fl & FRACTION) - && (Op(lnode->RIGHT) == DOT) - && (!is_op(lnode->RIGHT->LEFT)) - ) - { - lnode = lambda(lnode->RIGHT->RIGHT, lnode->RIGHT->LEFT, Pnode->RIGHT); - /**** Evaluate a lambda expression - - /('(x.$x^2))$3 - ****/ - if(lnode) - { - /* - /( - ' ( g - . /('(x.$g'($x'$x))) - $ /('(x.$g'($x'$x))) - ) - ) - $ /( - ' ( r - . /( - ' ( n - . $n:~>0&1 - | $n*($r)$($n+-1) - ) - ) - ) - ) - */ - wipe(Pnode); - Pnode = lnode; - } - else - { - /* - /('(x./('(x.$x ()$x))$aap))$noot - */ - lnode = subtreecopy(Pnode->LEFT->RIGHT->RIGHT); - wipe(Pnode); - Pnode = lnode; - if(!is_op(Pnode) && !(Pnode->v.fl & INDIRECT)) - Pnode->v.fl |= READY; /* /('(x.u))$7 */ - } - return functionOk(Pnode); - } - return functionFail(Pnode);/* completely wrong expression, e.g. (+(x.$x^2))$3 */ - } - } - } - else - { -#if 1 - lnode = getValueByVariableName(lnode); -#else - /* UNSAFE */ - /* The next two variables are used to cache the address of the most recently called user function. - These values must be reset each time stringEval() is called. - (When Bracmat is embedded in a Java program as a JNI, data addresses are not stable, it seems.) */ - static psk oldlnode = 0; - static psk lastEvaluatedFunction = 0; - /* Unsafe, esp. in JNI */ - if(oldlnode == lnode) - lnode = lastEvaluatedFunction; /* Speeding up! Esp. in map, vap, mop. */ - else - { - oldlnode = lnode; - lnode = getValueByVariableName(lnode); - lastEvaluatedFunction = lnode; - } -#endif - - if(lnode) /* lnode is null if either the function wasn't found or it is a built-in member function of an object. */ - { - if(Op(lnode) == DOT) /* The dot separating local variables from the function body. */ - { - psh(&argNode, Pnode->RIGHT, NULL); - Pnode = dopb(Pnode, lnode); - if(Op(Pnode) == DOT) - { - psh(Pnode->LEFT, &zeroNode, NULL); - Pnode = eval(Pnode); - /**** Evaluate a named function - | - ( f=.2*!arg | - & f$6 <----- - ) - ****/ - pop(Pnode->LEFT); - Pnode = dopb(Pnode, Pnode->RIGHT); - } - deleteNode(&argNode); - return functionOk(Pnode); - } - else - { -#if defined NO_EXIT_ON_NON_SEVERE_ERRORS - return functionFail(Pnode); -#else - errorprintf("(Syntax error) The following is not a function:\n\n "); - writeError(Pnode->LEFT); - exit(116); -#endif - } - } - } - DBGSRC(errorprintf("Function not found"); writeError(Pnode); Printf("\n");) - return functionFail(Pnode); - } - -static function_return_type functions(psk Pnode) - { - static char draft[22]; - psk lnode, rightnode, rrightnode, rlnode; - union { - int i; - ULONG ul; - } intVal; - lnode = Pnode->LEFT; - rightnode = Pnode->RIGHT; - { - SWITCH(PLOBJ(lnode)) - { - FIRSTCASE(STR) /* str$(arg arg arg .. ..) */ - { - beNice = FALSE; - hum = 0; - telling = 1; - process = tstr; - result(rightnode); - rlnode = (psk)bmalloc(sizeof(ULONG) + telling); - process = pstr; - source = POBJ(rlnode); - result(rightnode); - rlnode->v.fl = (READY | SUCCESS) | (numbercheck(SPOBJ(rlnode)) & ~DEFINITELYNONUMBER); - beNice = TRUE; - hum = 1; - process = myputc; - wipe(Pnode); - Pnode = rlnode; - return functionOk(Pnode); - } -#if O_S - CASE(SWI) /* swi$(.(input regs)) */ - { - Pnode = swi(Pnode, rlnode, rrightnode); - return functionOk(Pnode); - } -#endif -#if _BRACMATEMBEDDED -#if defined PYTHONINTERFACE - CASE(NI) /* Ni$"Statements to be executed by Python" */ - { - if(Ni && !is_op(rightnode) && !HAS_VISIBLE_FLAGS_OR_MINUS(rightnode)) - { - Ni((const char*)POBJ(rightnode)); - return functionOk(Pnode); - } - else - return functionFail(Pnode); - } - CASE(NII) /* Ni!$"Expression to be evaluated by Python" */ - { - if(Nii && !is_op(rightnode) && !HAS_VISIBLE_FLAGS_OR_MINUS(rightnode)) - { - const char* val; - val = Nii((const char*)POBJ(rightnode)); - wipe(Pnode); - Pnode = scopy((const char*)val); - return functionOk(Pnode); - } - else - return functionFail(Pnode); - } -#endif -#endif - -#ifdef ERR - CASE(ERR) /* err $ */ - { - if(!is_op(rightnode)) - { - if(redirectError((char*)POBJ(rightnode))) - return functionOk(Pnode); - } - return functionFail(Pnode); - } -#endif -#if !defined NO_C_INTERFACE - CASE(ALC) /* alc $ */ - { - void* p; - if(is_op(rightnode) - || !INTEGER_POS(rightnode) - || (p = bmalloc((int)strtoul((char*)POBJ(rightnode), (char**)NULL, 10))) - == NULL) - return functionFail(Pnode); - pointerToStr(draft, p); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - CASE(FRE) /* fre $ */ - { - void* p; - if(is_op(rightnode) || !INTEGER_POS(rightnode)) - return functionFail(Pnode); - p = strToPointer((char*)POBJ(rightnode)); - pskfree((psk)p); - return functionOk(Pnode); - } - CASE(PEE) /* pee $ ([,]) (1,2,4,8)*/ - { - void* p; - intVal.i = 1; - if(is_op(rightnode)) - { - rlnode = rightnode->LEFT; - rrightnode = rightnode->RIGHT; - if(!is_op(rrightnode)) - { - switch(rrightnode->u.obj) - { - case '2': - intVal.i = 2; - break; - case '4': - intVal.i = 4; - break; - } - } - } - else - rlnode = rightnode; - if(is_op(rlnode) || !INTEGER_POS(rlnode)) - return functionFail(Pnode); - p = strToPointer((char*)POBJ(rlnode)); - p = (void*)((char*)p - (ptrdiff_t)((size_t)p % intVal.i)); - switch(intVal.i) - { - case 2: - sprintf(draft, "%hu", *(short unsigned int*)p); - break; - case 4: - sprintf(draft, "%lu", (unsigned long)*(UINT32_T*)p); - break; -#ifndef __BORLANDC__ -#if (!defined ARM || defined __SYMBIAN32__) - case 8: - sprintf(draft, "%llu", *(unsigned long long*)p); - break; -#endif -#endif - case 1: - default: - sprintf(draft, "%u", (unsigned int)*(unsigned char*)p); - break; - } - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - CASE(POK) /* pok $ (,[,]) */ - { - psk rrlnode; - void* p; - LONG val; - intVal.i = 1; - if(!is_op(rightnode)) - return functionFail(Pnode); - rlnode = rightnode->LEFT; - rrightnode = rightnode->RIGHT; - if(is_op(rrightnode)) - { - psk rrrightnode; - rrrightnode = rrightnode->RIGHT; - rrlnode = rrightnode->LEFT; - if(!is_op(rrrightnode)) - { - switch(rrrightnode->u.obj) - { - case '2': - intVal.i = 2; - break; - case '4': - intVal.i = 4; - break; - case '8': - intVal.i = 8; - break; - default: - ; - } - } - } - else - rrlnode = rrightnode; - if(is_op(rlnode) || !INTEGER_POS(rlnode) - || is_op(rrlnode) || !INTEGER(rrlnode)) - return functionFail(Pnode); - p = strToPointer((char*)POBJ(rlnode)); - p = (void*)((char*)p - (ptrdiff_t)((size_t)p % intVal.i)); - val = toLong(rrlnode); - switch(intVal.i) - { - case 2: - *(unsigned short int*)p = (unsigned short int)val; - break; - case 4: - *(UINT32_T*)p = (UINT32_T)val; - break; -#ifndef __BORLANDC__ - case 8: - *(ULONG*)p = (ULONG)val; - break; -#endif - case 1: - default: - *(unsigned char*)p = (unsigned char)val; - break; - } - return functionOk(Pnode); - } - CASE(FNC) /* fnc $ (.) */ - { - typedef Boolean(*fncTp)(void*); - union - { - fncTp pfnc; /* Hoping this works. */ - void* vp; /* Pointers to data and pointers to functions may - have different sizes. */ - } u; - void* argStruct; - if(sizeof(int(*)(void*)) != sizeof(void*) || !is_op(rightnode)) - return functionFail(Pnode); - u.vp = strToPointer((char*)POBJ(rightnode->LEFT)); - if(!u.pfnc) - return functionFail(Pnode); - argStruct = strToPointer((char*)POBJ(rightnode->RIGHT)); - return u.pfnc(argStruct) ? functionOk(Pnode) : functionFail(Pnode); - } -#endif - CASE(X2D) /* x2d $ hexnumber */ - { - char* endptr; - uint64_t val; - if(is_op(rightnode) - || HAS_VISIBLE_FLAGS_OR_MINUS(rightnode) - ) - return functionFail(Pnode); - errno = 0; - val = STRTOUL((char*)POBJ(rightnode), &endptr, 16); - if(errno == ERANGE || (endptr && *endptr)) - return functionFail(Pnode); /*not all characters scanned*/ - sprintf(draft, "%" PRIu64, val); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - CASE(D2X) /* d2x $ decimalnumber */ - { - char* endptr; - int64_t val; - if(is_op(rightnode) || !INTEGER_NOT_NEG(rightnode)) - return functionFail(Pnode); -#ifdef __BORLANDC__ - if(strlen((char*)POBJ(rightnode)) > 10 - || strlen((char*)POBJ(rightnode)) == 10 - && strcmp((char*)POBJ(rightnode), "4294967295") > 0 - ) - return functionFail(Pnode); /*not all characters scanned*/ -#endif - errno = 0; - val = STRTOUL((char*)POBJ(rightnode), &endptr, 10); - if(errno == ERANGE - || (endptr && *endptr) - ) - return functionFail(Pnode); /*not all characters scanned*/ - sprintf(draft, "%" PRIX64, val); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - CASE(Chr) /* chr $ number */ - { - if(is_op(rightnode) || !INTEGER_POS(rightnode)) - return functionFail(Pnode); - intVal.ul = strtoul((char*)POBJ(rightnode), (char**)NULL, 10); - if(intVal.ul > 255) - return functionFail(Pnode); - draft[0] = (char)intVal.ul; - draft[1] = 0; - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - CASE(Chu) /* chu $ number */ - { - unsigned long val; - if(is_op(rightnode) || !INTEGER_POS(rightnode)) - return functionFail(Pnode); - val = strtoul((char*)POBJ(rightnode), (char**)NULL, 10); - if(putCodePoint(val, (unsigned char*)draft) == NULL) - return functionFail(Pnode); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - CASE(ASC) /* asc $ character */ - { - if(is_op(rightnode)) - return functionFail(Pnode); - sprintf(draft, "%d", (int)rightnode->u.obj); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - CASE(UGC) - { - if(is_op(rightnode)) - { - Pnode->v.fl |= FENCE; - return functionFail(Pnode); - } - else - { - const char* s = (const char*)POBJ(rightnode); - if(*s) - { - intVal.i = getCodePoint(&s); - if(intVal.i < 0 || *s) - { - if(intVal.i != -2) - { - Pnode->v.fl |= IMPLIEDFENCE; - } - return functionFail(Pnode); - } - sprintf(draft, "%s", gencat(intVal.i)); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - else - return functionFail(Pnode); - } - } - CASE(UTF) - { - /* - @(abcædef:? (%@>"~" ?:?a & utf$!a) ?) - @(str$(abc chu$200 def):? (%@>"~" ?:?a & utf$!a) ?) - */ - if(is_op(rightnode)) - { - Pnode->v.fl |= FENCE; - return functionFail(Pnode); - } - else - { - const char* s = (const char*)POBJ(rightnode); - intVal.i = getCodePoint(&s); - if(intVal.i < 0 || *s) - { - if(intVal.i != -2) - { - Pnode->v.fl |= IMPLIEDFENCE; - } - return functionFail(Pnode); - } - sprintf(draft, "%d", intVal.i); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - } -#if !defined NO_LOW_LEVEL_FILE_HANDLING -#if !defined NO_FOPEN - CASE(FIL) /* fil $ (,[,[set|cur|end]]) */ - { - return fil(&Pnode) ? functionOk(Pnode) : functionFail(Pnode); - } -#endif -#endif - CASE(FLG) /* flg $ or flg$(=) */ - { - if(is_object(rightnode) && !(rightnode->LEFT->v.fl & VISIBLE_FLAGS)) - rightnode = rightnode->RIGHT; - intVal.ul = rightnode->v.fl; - addr[3] = same_as_w(rightnode); - addr[3] = isolated(addr[3]); - addr[3]->v.fl = addr[3]->v.fl & ~VISIBLE_FLAGS; - addr[2] = same_as_w(&nilNode); - addr[2] = isolated(addr[2]); - addr[2]->v.fl &= ~VISIBLE_FLAGS; - addr[2]->v.fl |= VISIBLE_FLAGS & intVal.ul; - if(addr[2]->v.fl & INDIRECT) - { - addr[2]->v.fl &= ~READY; /* {?} flg$(=!a):(=?X.?)&lst$X */ - addr[3]->v.fl |= READY; /* {?} flg$(=!a):(=?.?Y)&!Y */ - } - if(NOTHINGF(intVal.ul)) - { - addr[2]->v.fl ^= SUCCESS; - addr[3]->v.fl ^= SUCCESS; - } - sprintf(draft, "=\2.\3"); - Pnode = build_up(Pnode, draft, NULL); - wipe(addr[2]); - wipe(addr[3]); - return functionOk(Pnode); - } - CASE(GLF) /* glf $ (=.) : (=?a) a= */ - { - if(is_object(rightnode) - && Op(rightnode->RIGHT) == DOT - ) - { - intVal.ul = rightnode->RIGHT->LEFT->v.fl & VISIBLE_FLAGS; - if(intVal.ul && (rightnode->RIGHT->RIGHT->v.fl & intVal.ul)) - return functionFail(Pnode); - addr[3] = same_as_w(rightnode->RIGHT->RIGHT); - addr[3] = isolated(addr[3]); - addr[3]->v.fl |= intVal.ul; - if(NOTHINGF(intVal.ul)) - { - addr[3]->v.fl ^= SUCCESS; - } - if(intVal.ul & INDIRECT) - { - addr[3]->v.fl &= ~READY;/* ^= --> &= ~ */ - } - sprintf(draft, "=\3"); - Pnode = build_up(Pnode, draft, NULL); - wipe(addr[3]); - return functionOk(Pnode); - } - return functionFail(Pnode); - } -#if SHOWMAXALLOCATED - CASE(BEZ) /* bez $ */ - { - Bez(draft); - Pnode = build_up(Pnode, draft, NULL); -#if SHOWCURRENTLYALLOCATED - bezetting(); -#endif - return functionOk(Pnode); - } -#endif - CASE(MMF) /* mem $ [EXT] */ - { - mmf(&Pnode); - return functionOk(Pnode); - } - CASE(MOD) - { - if(RATIONAL_COMP(rlnode = rightnode->LEFT) && - RATIONAL_COMP_NOT_NUL(rrightnode = rightnode->RIGHT)) - { - psk pnode; - pnode = qModulo(rlnode, rrightnode); - wipe(Pnode); - Pnode = pnode; - return functionOk(Pnode); - } - return functionFail(Pnode); - } - CASE(REV) - { - if(!is_op(rightnode)) - { - size_t len = strlen((char*)POBJ(rightnode)); - psk pnode; - pnode = same_as_w(rightnode); - if(len > 1) - { - pnode = isolated(pnode); - stringreverse((char*)POBJ(pnode), len); - } - wipe(Pnode); - Pnode = pnode; - return functionOk(Pnode); - } - else - return functionFail(Pnode); - } - CASE(LOW) - { - psk pnode; - if(!is_op(rightnode)) - pnode = changeCase(rightnode -#if CODEPAGE850 - , FALSE -#endif - , TRUE); - else if(!is_op(rlnode = rightnode->LEFT)) - pnode = changeCase(rlnode -#if CODEPAGE850 - , search_opt(rightnode->RIGHT, DOS) -#endif - , TRUE); - else - return functionFail(Pnode); - wipe(Pnode); - Pnode = pnode; - return functionOk(Pnode); - } - CASE(UPP) - { - psk pnode; - if(!is_op(rightnode)) - pnode = changeCase(rightnode -#if CODEPAGE850 - , FALSE -#endif - , FALSE); - else if(!is_op(rlnode = rightnode->LEFT)) - pnode = changeCase(rlnode -#if CODEPAGE850 - , search_opt(rightnode->RIGHT, DOS) -#endif - , FALSE); - else - return functionFail(Pnode); - wipe(Pnode); - Pnode = pnode; - return functionOk(Pnode); - } - CASE(DIV) - { - if(is_op(rightnode) - && RATIONAL_COMP(rlnode = rightnode->LEFT) - && RATIONAL_COMP_NOT_NUL(rrightnode = rightnode->RIGHT) - ) - { - psk pnode; - pnode = qIntegerDivision(rlnode, rrightnode); - wipe(Pnode); - Pnode = pnode; - return functionOk(Pnode); - } - return functionFail(Pnode); - } - CASE(DEN) - { - if(RATIONAL_COMP(rightnode)) - { - Pnode = qDenominator(Pnode); - } - return functionOk(Pnode); - } - CASE(LST) - { - return output(&Pnode, lst) ? functionOk(Pnode) : functionFail(Pnode); - } - CASE(MAP) /* map $ (.) */ - { - if(is_op(rightnode)) - {/*XXX*/ - psk nnode; - psk nPnode; - ppsk ppnode = &nPnode; - rrightnode = rightnode->RIGHT; - while(is_op(rrightnode) && Op(rrightnode) == WHITE) - { - nnode = (psk)bmalloc(sizeof(knode)); - nnode->v.fl = Pnode->v.fl; - nnode->v.fl &= COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - nnode->LEFT = same_as_w(rightnode->LEFT); - nnode->RIGHT = same_as_w(rrightnode->LEFT); - rlnode = setIndex(nnode); - if(rlnode) - nnode = rlnode; - else - { - if(not_built_in(nnode->LEFT)) /* Do not use ternary operator! That eats stack! */ - nnode = execFnc(nnode); - else - { - rlnode = functions(nnode); - if(rlnode) - nnode = rlnode; - else - nnode = execFnc(nnode); - } - } - - if(!is_op(nnode) && IS_NIL(nnode)) - { - wipe(nnode); - } - else - { - rlnode = (psk)bmalloc(sizeof(knode)); - rlnode->v.fl = WHITE | SUCCESS; - *ppnode = rlnode; - ppnode = &(rlnode->RIGHT); - rlnode->LEFT = nnode; - } - - rrightnode = rrightnode->RIGHT; - } - if(is_op(rrightnode) || !IS_NIL(rrightnode)) - { - nnode = (psk)bmalloc(sizeof(knode)); - nnode->v.fl = Pnode->v.fl; - nnode->v.fl &= COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - nnode->LEFT = same_as_w(rightnode->LEFT); - nnode->RIGHT = same_as_w(rrightnode); - rlnode = setIndex(nnode); - if(rlnode) - nnode = rlnode; - else - { - if(not_built_in(nnode->LEFT)) /* Do not use ternary operator! That eats stack! */ - nnode = execFnc(nnode); - else - { - rlnode = functions(nnode); - if(rlnode) - nnode = rlnode; - else - nnode = execFnc(nnode); - } - } - *ppnode = nnode; - } - else - { - *ppnode = same_as_w(rrightnode); - } - wipe(Pnode); - Pnode = nPnode; - return functionOk(Pnode); - } - else - return functionFail(Pnode); - } - CASE(MOP)/* mop $ (..(=)) - mop regards tree1 as a right descending 'list' with a backbone - operator that is the same as the heading operator of tree 2. - For example, - mop$((=.!arg).2*a+e\Lb+c^2.(=+)) - generates the list - 2*a e\Lb c^2 - */ - { - if(is_op(rightnode)) - {/*XXX*/ - psk nnode; - psk nPnode; - ppsk ppnode = &nPnode; - rrightnode = rightnode->RIGHT; - if(Op(rightnode) == DOT) - { - if(Op(rrightnode) == DOT) - { - lnode = rrightnode->RIGHT; - rrightnode = rrightnode->LEFT; - if(Op(lnode) == EQUALS) - { - intVal.ul = Op(lnode->RIGHT); - if(intVal.ul) - { - while(is_op(rrightnode) && Op(rrightnode) == intVal.ul) - { - nnode = (psk)bmalloc(sizeof(knode)); - nnode->v.fl = Pnode->v.fl; - nnode->v.fl &= COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - nnode->LEFT = same_as_w(rightnode->LEFT); - nnode->RIGHT = same_as_w(rrightnode->LEFT); - rlnode = setIndex(nnode); - if(rlnode) - nnode = rlnode; - else - { - if(not_built_in(nnode->LEFT)) /* Do not use ternary operator! That eats stack! */ - nnode = execFnc(nnode); - else - { - rlnode = functions(nnode); - if(rlnode) - nnode = rlnode; - else - nnode = execFnc(nnode); - } - } - - if(!is_op(nnode) && IS_NIL(nnode)) - { - wipe(nnode); - } - else - { - rlnode = (psk)bmalloc(sizeof(knode)); - rlnode->v.fl = WHITE | SUCCESS; - *ppnode = rlnode; - ppnode = &(rlnode->RIGHT); - rlnode->LEFT = nnode; - } - rrightnode = rrightnode->RIGHT; - } - } - else - { - /* No operator specified */ - return functionFail(Pnode); - } - } - else - { - /* The last argument must have heading = operator */ - return functionFail(Pnode); - } - } - else - { - /* Expecting a dot */ - return functionFail(Pnode); - } - } - else - { - /* Expecting a dot */ - return functionFail(Pnode); - } - if(is_op(rrightnode) || !IS_NIL(rrightnode)) - { - nnode = (psk)bmalloc(sizeof(knode)); - nnode->v.fl = Pnode->v.fl; - nnode->v.fl &= COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - nnode->LEFT = same_as_w(rightnode->LEFT); - nnode->RIGHT = same_as_w(rrightnode); - rlnode = setIndex(nnode); - if(rlnode) - nnode = rlnode; - else - { - if(not_built_in(nnode->LEFT)) /* Do not use ternary operator! That eats stack! */ - nnode = execFnc(nnode); - else - { - rlnode = functions(nnode); - if(rlnode) - nnode = rlnode; - else - nnode = execFnc(nnode); - } - } - - *ppnode = nnode; - } - else - { - *ppnode = same_as_w(rrightnode); - } - wipe(Pnode); - Pnode = nPnode; - return functionOk(Pnode); - } - else - return functionFail(Pnode); - } - CASE(Vap) /* vap $ (..) - or vap $ (.) - Second form splits in characters. */ - { - if(is_op(rightnode)) - {/*XXX*/ - rrightnode = rightnode->RIGHT; - if(is_op(rrightnode)) - { /* first form */ - psk sepnode = rrightnode->RIGHT; - rrightnode = rrightnode->LEFT; - if(is_op(sepnode) || is_op(rrightnode)) - { - return functionFail(Pnode); - } - else - { - const char* separator = &sepnode->u.sobj; - if(!*separator) - { - return functionFail(Pnode); - } - else - { - char* subject = &rrightnode->u.sobj; - psk nPnode; - ppsk ppnode = &nPnode; - char* oldsubject = subject; - while(subject) - { - psk nnode; - nnode = (psk)bmalloc(sizeof(knode)); - nnode->v.fl = Pnode->v.fl; - nnode->v.fl &= COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - nnode->LEFT = same_as_w(rightnode->LEFT); - subject = strstr(oldsubject, separator); - if(subject) - { - *subject = '\0'; - nnode->RIGHT = scopy(oldsubject); - *subject = separator[0]; - oldsubject = subject + strlen(separator); - } - else - { - nnode->RIGHT = scopy(oldsubject); - } - rlnode = setIndex(nnode); - if(rlnode) - nnode = rlnode; - else - { - if(not_built_in(nnode->LEFT)) /* Do not use ternary operator! That eats stack! */ - nnode = execFnc(nnode); - else - { - rlnode = functions(nnode); - if(rlnode) - nnode = rlnode; - else - nnode = execFnc(nnode); - } - } - - if(subject) - { - rlnode = (psk)bmalloc(sizeof(knode)); - rlnode->v.fl = WHITE | SUCCESS; - *ppnode = rlnode; - ppnode = &(rlnode->RIGHT); - rlnode->LEFT = nnode; - } - else - { - *ppnode = nnode; - } - } - wipe(Pnode); - Pnode = nPnode; - return functionOk(Pnode); - } - } - } - else - { - /* second form */ - const char* subject = &rrightnode->u.sobj; - psk nPnode = 0; - ppsk ppnode = &nPnode; - const char* oldsubject = subject; - int k; - if(hasUTF8MultiByteCharacters(subject)) - { - for(; (k = getCodePoint(&subject)) > 0; oldsubject = subject) - { - psk nnode; - nnode = (psk)bmalloc(sizeof(knode)); - nnode->v.fl = Pnode->v.fl; - nnode->v.fl &= COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - nnode->LEFT = same_as_w(rightnode->LEFT); - nnode->RIGHT = charcopy(oldsubject, subject); - rlnode = setIndex(nnode); - if(rlnode) - nnode = rlnode; - else - { - if(not_built_in(nnode->LEFT)) /* Do not use ternary operator! That eats stack! */ - nnode = execFnc(nnode); - else - { - rlnode = functions(nnode); - if(rlnode) - nnode = rlnode; - else - nnode = execFnc(nnode); - } - } - - if(*subject) - { - rlnode = (psk)bmalloc(sizeof(knode)); - rlnode->v.fl = WHITE | SUCCESS; - *ppnode = rlnode; - ppnode = &(rlnode->RIGHT); - rlnode->LEFT = nnode; - } - else - { - *ppnode = nnode; - } - } - } - else - { - for(; (k = *subject++) != 0; oldsubject = subject) - { - psk nnode; - nnode = (psk)bmalloc(sizeof(knode)); - nnode->v.fl = Pnode->v.fl; - nnode->v.fl &= COPYFILTER;/* ~ALL_REFCOUNT_BITS_SET;*/ - nnode->LEFT = same_as_w(rightnode->LEFT); - nnode->RIGHT = charcopy(oldsubject, subject); - rlnode = setIndex(nnode); - if(rlnode) - nnode = rlnode; - else - { - if(not_built_in(nnode->LEFT)) /* Do not use ternary operator! That eats stack! */ - nnode = execFnc(nnode); - else - { - rlnode = functions(nnode); - if(rlnode) - nnode = rlnode; - else - nnode = execFnc(nnode); - } - } - - if(*subject) - { - rlnode = (psk)bmalloc(sizeof(knode)); - rlnode->v.fl = WHITE | SUCCESS; - *ppnode = rlnode; - ppnode = &(rlnode->RIGHT); - rlnode->LEFT = nnode; - } - else - { - *ppnode = nnode; - } - } - } - wipe(Pnode); - Pnode = nPnode ? nPnode : same_as_w(&nilNode); - return functionOk(Pnode); - } - } - else - return functionFail(Pnode); - } -#if !defined NO_FILE_RENAME - CASE(REN) - { - if(is_op(rightnode) - && !is_op(rlnode = rightnode->LEFT) - && !is_op(rrightnode = rightnode->RIGHT) - ) - { - intVal.i = rename((const char*)POBJ(rlnode), (const char*)POBJ(rrightnode)); - if(intVal.i) - { -#ifndef EACCES - sprintf(draft, "%d", intVal.i); -#else - switch(errno) - { - case EACCES: - /* - File or directory specified by newname already exists or - could not be created (invalid path); or oldname is a directory - and newname specifies a different path. - */ - strcpy(draft, "EACCES"); - break; - case ENOENT: - /* - File or path specified by oldname not found. - */ - strcpy(draft, "ENOENT"); - break; - case EINVAL: - /* - Name contains invalid characters. - */ - strcpy(draft, "EINVAL"); - break; - default: - sprintf(draft, "%d", errno); - break; - } -#endif - } - else - strcpy(draft, "0"); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - else - return functionFail(Pnode); - } -#endif -#if !defined NO_FILE_REMOVE - CASE(RMV) - { - if(!is_op(rightnode)) - { -#if defined __SYMBIAN32__ - intVal.i = unlink((const char*)POBJ(rightnode)); -#else - intVal.i = remove((const char*)POBJ(rightnode)); -#endif - if(intVal.i) - { -#ifndef EACCES - sprintf(draft, "%d", intVal.i); -#else - switch(errno) - { - case EACCES: - /* - File or directory specified by newname already exists or - could not be created (invalid path); or oldname is a directory - and newname specifies a different path. - */ - strcpy(draft, "EACCES"); - break; - case ENOENT: - /* - File or path specified by oldname not found. - */ - strcpy(draft, "ENOENT"); - break; - default: - { -#ifdef __VMS - if(!strcmp("file currently locked by another user", (const char*)strerror(errno))) - { /* OpenVMS */ - strcpy(draft, "EACCES"); - break; - } - else -#endif - { - wipe(Pnode); - Pnode = scopy((const char*)strerror(errno)); - return functionOk(Pnode); - } - /* sprintf(draft,"%d",errno); - break;*/ - } - } -#endif - } - else - strcpy(draft, "0"); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - else - return functionFail(Pnode); - } -#endif - CASE(ARG) /* arg$ or arg$N (N == 0,1,... and N < argc) */ - { - static int argno = 0; - if(is_op(rightnode)) - return functionFail(Pnode); - if(PLOBJ(rightnode) != '\0') - { - unsigned long val; - if(!INTEGER_NOT_NEG(rightnode)) - return functionFail(Pnode); - val = strtoul((char*)POBJ(rightnode), (char**)NULL, 10); - if(val >= (unsigned long)ARGC) - return functionFail(Pnode); - wipe(Pnode); - Pnode = scopy((const char*)ARGV[val]); - return functionOk(Pnode); - } - if(argno < ARGC) - { - wipe(Pnode); - Pnode = scopy((const char*)ARGV[argno++]); - return functionOk(Pnode); - } - else - { - return functionFail(Pnode); - } - } - CASE(GET) /* get$file */ - { - Boolean GoOn; - int err = 0; - if(is_op(rightnode)) - { - if(is_op(rlnode = rightnode->LEFT)) - return functionFail(Pnode); - rrightnode = rightnode->RIGHT; - intVal.i = (search_opt(rrightnode, ECH) << SHIFT_ECH) - + (search_opt(rrightnode, MEM) << SHIFT_MEM) - + (search_opt(rrightnode, VAP) << SHIFT_VAP) - + (search_opt(rrightnode, STG) << SHIFT_STR) - + (search_opt(rrightnode, ML) << SHIFT_ML) - + (search_opt(rrightnode, TRM) << SHIFT_TRM) - + (search_opt(rrightnode, HT) << SHIFT_HT) - + (search_opt(rrightnode, X) << SHIFT_X) - + (search_opt(rrightnode, JSN) << SHIFT_JSN) - + (search_opt(rrightnode, TXT) << SHIFT_TXT) - + (search_opt(rrightnode, BIN) << SHIFT_BIN); - } - else - { - intVal.i = 0; - rlnode = rightnode; - } - if(intVal.i & OPT_MEM) - { - addr[1] = same_as_w(rlnode); - source = POBJ(addr[1]); - for(;;) - { - Pnode = input(NULL, Pnode, intVal.i, &err, &GoOn); - if(!GoOn || err) - break; - Pnode = eval(Pnode); - } - wipe(addr[1]); - } - else - { - if(rlnode->u.obj && strcmp((char*)POBJ(rlnode), "stdin")) - { -#if defined NO_FOPEN - return functionFail(Pnode); -#else - psk pnode = fileget(rlnode, intVal.i, Pnode, &err, &GoOn); - if(pnode) - Pnode = pnode; - else - return functionFail(Pnode); -#endif - } - else - { - intVal.i |= OPT_ECH; -#ifdef DELAY_DUE_TO_INPUT - for(;;) - { - clock_t time0; - time0 = clock(); - Pnode = input(stdin, Pnode, intVal.i, &err, &GoOn); - delayDueToInput += clock() - time0; - if(!GoOn || err) - break; - Pnode = eval(Pnode); - } -#else - for(;;) - { - Pnode = input(stdin, Pnode, intVal.i, &err, &GoOn); - if(!GoOn || err) - break; - Pnode = eval(Pnode); - } -#endif - } - } - return err ? functionFail(Pnode) : functionOk(Pnode); - } - CASE(PUT) /* put$(file,mode,node) of put$node */ - { - return output(&Pnode, result) ? functionOk(Pnode) : functionFail(Pnode); - } -#if !defined __SYMBIAN32__ -#if !defined NO_SYSTEM_CALL - CASE(SYS) - { - if(is_op(rightnode) || (PLOBJ(rightnode) == '\0')) - return functionFail(Pnode); - else - { - intVal.i = system((const char*)POBJ(rightnode)); - if(intVal.i) - { -#ifndef E2BIG - sprintf(draft, "%d", intVal.i); -#else - switch(errno) - { - case E2BIG: - /* - Argument list (which is system-dependent) is too big. - */ - strcpy(draft, "E2BIG"); - break; - case ENOENT: - /* - Command interpreter cannot be found. - */ - strcpy(draft, "ENOENT"); - break; - case ENOEXEC: - /* - Command-interpreter file has invalid format and is not executable. - */ - strcpy(draft, "ENOEXEC"); - break; - case ENOMEM: - /* - Not enough memory is available to execute command; or available - memory has been corrupted; or invalid block exists, indicating - that process making call was not allocated properly. - */ - strcpy(draft, "ENOMEM"); - break; - default: - sprintf(draft, "%d", errno); - break; - } -#endif - } - else - strcpy(draft, "0"); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - } -#endif -#endif - CASE(TBL) /* tbl$(varname,length) */ - { - if(is_op(rightnode)) - return psh(rightnode->LEFT, &zeroNode, rightnode->RIGHT) ? functionOk(Pnode) : functionFail(Pnode); - else - return functionFail(Pnode); - } -#if 0 - /* - The same effect is obtained by :?!(=) - */ - CASE(PRV) /* "?"$ */ - { - if((rightnode->v.fl & SUCCESS) - && (is_op(rightnode) || rightnode->u.obj || HAS_UNOPS(rightnode))) - insert(&nilNode, rightnode); - Pnode = rightbranch(Pnode); - return functionOk(Pnode); - } -#endif - CASE(CLK) /* clk' */ - { - print_clock(draft); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - - CASE(SIM) /* sim$(,) , fuzzy compare (percentage) */ - { - if(is_op(rightnode) - && !is_op(rlnode = rightnode->LEFT) - && !is_op(rrightnode = rightnode->RIGHT)) - { - Sim(draft, (char*)POBJ(rlnode), (char*)POBJ(rrightnode)); - wipe(Pnode); - Pnode = scopy((const char*)draft); - return functionOk(Pnode); - } - else - return functionFail(Pnode); - } -#if DEBUGBRACMAT - CASE(DBG) /* dbg$ */ - { - ++debug; - if(Op(Pnode) != FUU) - { - errorprintf("Use dbg'(expression), not dbg$(expression)!\n"); - writeError(Pnode); - } - Pnode = rightbranch(Pnode); - Pnode = eval(Pnode); - --debug; - return functionOk(Pnode); - } -#endif - CASE(WHL) - { - while(isSUCCESSorFENCE(rightnode = eval(same_as_w(Pnode->RIGHT)))) - { - wipe(rightnode); - } - wipe(rightnode); - return functionOk(Pnode); - } - CASE(New) /* new$*/ - { - if(Op(rightnode) == COMMA) - { - addr[2] = getObjectDef(rightnode->LEFT); - if(!addr[2]) - return functionFail(Pnode); - addr[3] = rightnode->RIGHT; - if(ISBUILTIN((objectnode*)addr[2])) - Pnode = build_up(Pnode, "((\2.New)'\3)&\2", NULL); - /* We might be able to call 'new' if 'New' had attached the argument - (containing the definition of a 'new' method) to the rhs of the '='. - This cannot be done in a general way without introducing new syntax rules for the new$ function. - */ - else - Pnode = build_up(Pnode, "(((\2.new)'\3)|)&\2", NULL); - } - else - { - addr[2] = getObjectDef(rightnode); - if(!addr[2]) - return functionFail(Pnode); - if(ISBUILTIN((objectnode*)addr[2])) - Pnode = build_up(Pnode, "((\2.New)')&\2", NULL); - /* There cannot be a user-defined 'new' method on a built-in object if there is no way to supply it*/ - /* 'die' CAN be user-supplied. The built-in function is 'Die' */ - else - Pnode = build_up(Pnode, "(((\2.new)')|)&\2", NULL); - } - SETCREATEDWITHNEW((objectnode*)addr[2]); - wipe(addr[2]); - return functionOk(Pnode); - } - CASE(0) /* $ ' */ - { - if(Op(Pnode) == FUU) - { - if(!HAS_UNOPS(Pnode->LEFT)) - { - intVal.ul = Pnode->v.fl & UNOPS; - if(intVal.ul == FRACTION - && is_op(Pnode->RIGHT) - && Op(Pnode->RIGHT) == DOT - && !is_op(Pnode->RIGHT->LEFT) - ) - { /* /('(a.a+2))*/ - return functionOk(Pnode); - } - else - { - rightnode = evalmacro(Pnode->RIGHT); - rrightnode = (psk)bmalloc(sizeof(objectnode)); -#if WORD32 - ((typedObjectnode*)rrightnode)->u.Int = 0; -#else - ((typedObjectnode*)rrightnode)->v.fl &= ~(BUILT_IN | CREATEDWITHNEW); -#endif - rrightnode->v.fl = EQUALS | SUCCESS; - rrightnode->LEFT = same_as_w(&nilNode); - if(rightnode) - { - rrightnode->RIGHT = rightnode; - } - else - { - rrightnode->RIGHT = same_as_w(Pnode->RIGHT); - } - wipe(Pnode); - Pnode = rrightnode; - Pnode->v.fl |= intVal.ul; /* (a=b)&!('$a)*/ - } - } - else - { - combiflags(Pnode); - Pnode = rightbranch(Pnode); - } - return functionOk(Pnode); - } - else - { - return functionFail(Pnode); - } - } - DEFAULT - { - return 0; - } - } - } - /*return functionOk(Pnode); 20 Dec 1995, unreachable code in Borland C */ - } -/* End of functions.c */ - -/* Begin of canonization.c */ - -#define MPI 3.14159265358979323846 -#define ME 2.718281828459045090795598298427648842334747314453125 - -static const char -hash5[] = "\5", -hash6[] = "\6"; - -static psk tryq(psk Pnode, psk fun, Boolean* ok) - { - psk anchor; - psh(&argNode, Pnode, NULL); - Pnode->v.fl |= READY; - - anchor = subtreecopy(fun->RIGHT); - - psh(fun->LEFT, &zeroNode, NULL); - anchor = eval(anchor); - pop(fun->LEFT); - if(anchor->v.fl & SUCCESS) - { - *ok = TRUE; - wipe(Pnode); - Pnode = anchor; - } - else - { - *ok = FALSE; - wipe(anchor); - } - deleteNode(&argNode); - return Pnode; - } - -static int absone(psk pnode) - { - char* pstring; - pstring = SPOBJ(pnode); - return(*pstring == '1' && *++pstring == 0); - } - -static psk handleExponents(psk Pnode) - { - psk lnode; - Boolean done = FALSE; - for(; ((lnode = Pnode->LEFT)->v.fl & READY) && Op(lnode) == EXP;) - { - done = TRUE; - Pnode->LEFT = lnode = isolated(lnode); - lnode->v.fl &= ~READY & ~OPERATOR;/* turn off READY flag */ - lnode->v.fl |= TIMES; - addr[1] = lnode->LEFT; - addr[2] = lnode->RIGHT; - addr[3] = Pnode->RIGHT; - Pnode = build_up(Pnode, "(\1^(\2*\3))", NULL); - } - if(done) - { - return Pnode; - } - else - { - static const char* conc_arr[] = { NULL,NULL,NULL,NULL,NULL,NULL }; - - Qnumber iexponent, hiexponent; - - psk rightnode; - if(!is_op(rightnode = Pnode->RIGHT)) - { - if(RAT_NUL(rightnode)) - { - wipe(Pnode); - return copyof(&oneNode); - } - if(IS_ONE(rightnode)) - { - return leftbranch(Pnode); - } - } - lnode = Pnode->LEFT; - if(!is_op(lnode)) - { - if((RAT_NUL(lnode) && !RAT_NEG_COMP(rightnode)) || IS_ONE(lnode)) - { - return leftbranch(Pnode); - } - - if(!is_op(rightnode)) - { - if(RATIONAL_COMP(rightnode)) - { - if(RATIONAL_COMP(lnode)) - { - if(RAT_NEG_COMP(rightnode) && absone(rightnode)) - { - conc_arr[1] = NULL; - conc_arr[2] = hash6; - conc_arr[3] = NULL; - addr[6] = qqDivide(&oneNode, lnode); - assert(lnode == Pnode->LEFT); - Pnode = vbuildup(Pnode, conc_arr + 2); - wipe(addr[6]); - return Pnode; - } - else if(RAT_NEG_COMP(lnode) && RAT_RAT_COMP(rightnode)) - { - return Pnode; /*{?} -3^2/3 => -3^2/3 */ - } - /* Missing here is n^m, with m > 2. - That case is handled in casemacht. */ - } - else if(PLOBJ(lnode) == IM) - { - if(qCompare(rightnode, &zeroNode) & MINUS) - { /* i^-n -> -i^n */ /*{?} i^-7 => i */ - /* -i^-n -> i^n */ /*{?} -i^-7 => -i */ - conc_arr[0] = "(\2^\3)"; - addr[2] = qTimesMinusOne(lnode); - addr[3] = qTimesMinusOne(rightnode); - conc_arr[1] = NULL; - Pnode = vbuildup(Pnode, conc_arr); - wipe(addr[2]); - wipe(addr[3]); - return Pnode; - } - else if(qCompare(&twoNode, rightnode) & (QNUL | MINUS)) - { - iexponent = qModulo(rightnode, &fourNode); - if(iexponent->v.fl & QNUL) - { - wipe(Pnode); /*{?} i^4 => 1 */ - Pnode = copyof(&oneNode); - } - else - { - int Sign; - Sign = qCompare(iexponent, &twoNode); - if(Sign & QNUL) - { - wipe(Pnode); - Pnode = copyof(&minusOneNode); - } - else - { - if(!(Sign & MINUS)) - { - hiexponent = iexponent; - iexponent = qPlus(&fourNode, hiexponent, MINUS); - wipe(hiexponent); - } - addr[2] = lnode; - addr[6] = iexponent; - conc_arr[0] = "(-1*\2)^"; - conc_arr[1] = "(\6)"; - conc_arr[2] = NULL; - Pnode = vbuildup(Pnode, conc_arr); - } - } - wipe(iexponent); - return Pnode; - } - } - } - } - } - - if(Op(lnode) == TIMES) - { - addr[1] = lnode->LEFT; - addr[2] = lnode->RIGHT; - addr[3] = Pnode->RIGHT; - return build_up(Pnode, "\1^\3*\2^\3", NULL); - } - - if(RATIONAL_COMP(lnode)) - { - static const char parenonepow[] = "(\1^"; - if(INTEGER_NOT_NUL_COMP(rightnode) && !absone(rightnode)) - { - addr[1] = lnode; - if(INTEGER_POS_COMP(rightnode)) - { - if(qCompare(&twoNode, rightnode) & MINUS) - { - /* m^n = (m^(n\2))^2*m^(n mod 2) */ /*{?} 9^7 => 4782969 */ - conc_arr[0] = parenonepow; - conc_arr[1] = hash5; - conc_arr[3] = hash6; - conc_arr[4] = NULL; - addr[5] = qIntegerDivision(rightnode, &twoNode); - conc_arr[2] = ")^2*\1^"; - addr[6] = qModulo(rightnode, &twoNode); - Pnode = vbuildup(Pnode, conc_arr); - wipe(addr[5]); - wipe(addr[6]); - } - else - { - /* m^2 = m*m */ - Pnode = build_up(Pnode, "(\1*\1)", NULL); - } - } - else - { - /*{?} 7^-13 => 1/96889010407 */ - conc_arr[0] = parenonepow; - conc_arr[1] = hash6; - addr[6] = qTimesMinusOne(rightnode); - conc_arr[2] = ")^-1"; - conc_arr[3] = 0; - Pnode = vbuildup(Pnode, conc_arr); - wipe(addr[6]); - } - return Pnode; - } - else if(RAT_RAT(rightnode)) - { - char** conc, slash = 0; - int wipe[20], ind; - nnumber numerator = { 0 }, denominator = { 0 }; - for(ind = 0; ind < 20; wipe[ind++] = TRUE); - ind = 0; - conc = (char**)bmalloc(20 * sizeof(char**)); - /* 20 is safe value for ULONGs */ - addr[1] = Pnode->RIGHT; - if(RAT_RAT_COMP(Pnode->LEFT)) - { - split(Pnode->LEFT, &numerator, &denominator); - if(!subroot(&numerator, conc, &ind)) - { - wipe[ind] = FALSE; - conc[ind++] = numerator.number; - slash = numerator.number[numerator.length]; - numerator.number[numerator.length] = 0; - - wipe[ind] = FALSE; - conc[ind++] = "^\1"; - } - wipe[ind] = FALSE; - conc[ind++] = "*("; - if(!subroot(&denominator, conc, &ind)) - { - wipe[ind] = FALSE; - conc[ind++] = denominator.number; - wipe[ind] = FALSE; - conc[ind++] = "^\1"; - } - wipe[ind] = FALSE; - conc[ind++] = ")^-1"; - } - else - { - numerator.number = (char*)POBJ(Pnode->LEFT); - numerator.alloc = NULL; - numerator.length = strlen(numerator.number); - if(!subroot(&numerator, conc, &ind)) - { - bfree(conc); - return Pnode; - } - } - conc[ind--] = NULL; - Pnode = vbuildup(Pnode, (const char**)conc); - if(slash) - numerator.number[numerator.length] = slash; - for(; ind >= 0; ind--) - if(wipe[ind]) - bfree(conc[ind]); - bfree(conc); - return Pnode; - } - } - } - if(is_op(Pnode->RIGHT)) - { - int ok; - Pnode = tryq(Pnode, f4, &ok); - } - return Pnode; - } - -/* -Improvement that DOES evaluate b+(i*c+i*d)+-i*c -It also allows much deeper structures, because the right place for insertion -is found iteratively, not recursively. This also causes some operations to -be tremendously faster. e.g. (1+a+b+c)^30+1&ready evaluates in about -4,5 seconds now, previously in 330 seconds! (AST Bravo MS 5233M 233 MHz MMX Pentium) -*/ -static void splitProduct_number_im_rest(psk pnode, ppsk Nm, ppsk I, ppsk NNNI) - { - psk temp; - if(Op(pnode) == TIMES) - { - if(RATIONAL_COMP(pnode->LEFT)) - {/* 17*x */ - *Nm = pnode->LEFT; - temp = pnode->RIGHT; - }/* Nm*temp */ - else - { - *Nm = NULL; - temp = pnode; - }/* temp */ - if(Op(temp) == TIMES) - { - if(!is_op(temp->LEFT) && PLOBJ(temp->LEFT) == IM) - {/* Nm*i*x */ - *I = temp->LEFT; - *NNNI = temp->RIGHT; - }/* Nm*I*NNNI */ - else - { - *I = NULL; - *NNNI = temp; - }/* Nm*NNNI */ - } - else - { - if(!is_op(temp) && PLOBJ(temp) == IM) - {/* Nm*i */ - *I = temp; - *NNNI = NULL; - }/* Nm*I */ - else - { - *I = NULL; - *NNNI = temp; - }/* Nm*NNNI */ - } - } - else if(!is_op(pnode) && PLOBJ(pnode) == IM) - {/* i */ - *Nm = NULL; - *I = pnode; - *NNNI = NULL; - }/* I */ - else - {/* x */ - *Nm = NULL; - *I = NULL; - *NNNI = pnode; - }/* NNNI */ - } - -#if EXPAND -static psk expandDummy(psk Pnode, int* ok) - { - *ok = FALSE; - return Pnode; - } -#endif - -static psk expandProduct(psk Pnode, int* ok) - { - switch(Op(Pnode)) - { - case TIMES: - case EXP: - { - if(((match(0, Pnode, m0, NULL, 0, Pnode, 3333) & TRUE) - && ((Pnode = tryq(Pnode, f0, ok)), *ok) - ) - || ((match(0, Pnode, m1, NULL, 0, Pnode, 4444) & TRUE) - && ((Pnode = tryq(Pnode, f1, ok)), *ok) - ) - ) - { - if(is_op(Pnode)) /*{?} (1+i)*(1+-i)+Z => 2+Z */ - Pnode->v.fl &= ~READY; - return Pnode; - } - break; - } - } - *ok = FALSE; - return Pnode; - } - -static psk mergeOrSortTerms(psk Pnode) - { - /* - Split Pnode in left L and right R argument - - If L is zero, - return R - - If R is zero, - return L - - If L is a product containing a sum, - expand it - - If R is a product containing a sum, - expand it - - Find the proper place split of R into Rhead , RtermS, RtermGE and Rtail for L to insert into: - L + R -> Rhead + RtermS + L + RtermGE + Rtail: - Start with Rhead = NIL, RtermS = NIL RtermGE is first term of R and Rtail is remainder of R - Split L into Lterm and Ltail - If Lterm is a number - if RtermGE is a number - return sum(Lterm,RtermGE) + Ltail + Rtail - else - return Lterm + Ltail + R - Else if Rterm is a number - return Rterm + L + Rtail - Else - get the non-numerical factor LtermNN of Lterm - if LtermNN is imaginary - get the nonimaginary factors of LtermNN (these may also include 'e' and 'pi') LtermNNNI - find Rhead, RtermS, RtermGE and Rtail - such that Rhead does contain all non-imaginary terms - and such that RtermGE and Rtail - either are NIL - or RtermGE is imaginary - and (RtermS is NIL or RtermSNNNI < LtermNNNI) and LtermNNNI <= RtermGENNNI - if RtermGE is NIL - return R + L - else - if LtermNNNI < RtermGENNNI - return Rhead + RtermS + L + RtermGE + Rtail - else - return Rhead + RtermS + sum(L,RtermGE) + Rtail - else - find Rhead, RtermS, RtermGE and Rtail - such that RtermGE and Rtail - either are NIL - or (RtermS is NIL or RtermSNN < LtermNN) and LtermNN <= RtermGENN - if RtermGE is NIL - return R + L - else - if LtermNN < RtermGENN - return Rhead + RtermS + L + RtermGE + Rtail - else - return Rhead + RtermS + sum(L,RtermGE) + Rtail - - */ - static const char* conc[] = { NULL,NULL,NULL,NULL }; - int res = FALSE; - psk top = Pnode; - - psk L = top->LEFT; - psk Lterm, Ltail; - psk LtermN, LtermI, LtermNNNI; - - psk R; - psk Rterm, Rtail; - psk RtermN, RtermI, RtermNNNI; - - int ok; - if(!is_op(L) && RAT_NUL_COMP(L)) - { - /* 0+x -> x */ - return rightbranch(top); - } - - R = top->RIGHT; - if(!is_op(R) && RAT_NUL_COMP(R)) - { - /*{?} x+0 => x */ - return leftbranch(top); - } - - if(is_op(L) - && ((top->LEFT = expandProduct(top->LEFT, &ok)), ok) - ) - { - res = TRUE; - } - if(is_op(R) - && ((top->RIGHT = expandProduct(top->RIGHT, &ok)), ok) - ) - { /* - {?} a*b+u*(x+y) => a*b+u*x+u*y - */ - res = TRUE; - } - if(res) - { - Pnode->v.fl &= ~READY; - return Pnode; - } - rightoperand_and_tail(top, &Rterm, &Rtail); - leftoperand_and_tail(top, &Lterm, &Ltail); - assert(Ltail == NULL); - - if(RATIONAL_COMP(Lterm)) - { - if(RATIONAL_COMP(Rterm)) - { - conc[0] = hash6; - if(Lterm == Rterm) - { - /* 7+7 -> 2*7 */ /*{?} 7+7 => 14 */ - addr[6] = qTimes(&twoNode, Rterm); - } - else - { - /* 4+7 -> 11 */ /*{?} 4+7 => 11 */ - addr[6] = qPlus(Lterm, Rterm, 0); - } - conc[1] = NULL; - conc[2] = NULL; - if(Rtail != NULL) - { - addr[4] = Rtail; - conc[1] = "+\4"; - } - Pnode = vbuildup(top, conc); - wipe(addr[6]); - } - return Pnode; - } - else if(RATIONAL_COMP(Rterm)) - { - addr[1] = Rterm; - addr[2] = L; - if(Rtail) - { - /* How to get here? - (1+a)*(1+b)+c+(1+d)*(1+f) - The lhs (1+a)*(1+b) is not expanded before the merge starts - Comparing (1+a)*(1+b) with 1, c, d, f and d*f, this product lands - after d*f. Thereafter (1+a)*(1+b) is expanded, giving a - numeral 1 in the middle of the expression: - 1+c+d+f+d*f+(1+a)*(1+b) - 1+c+d+f+d*f+1+a+b+a*b - Rterm is 1+a+b+a*b - Rtail is a+b+a*b - */ - addr[3] = Rtail; - return build_up(top, "\1+\2+\3", NULL); - } - else - { - /* 4*(x+7)+p+-4*x */ - return build_up(top, "\1+\2", NULL); - } - } - - if(Op(Lterm) == LOG - && Op(Rterm) == LOG - && !equal(Lterm->LEFT, Rterm->LEFT) - ) - { - addr[1] = Lterm->LEFT; - addr[2] = Lterm->RIGHT; - addr[3] = Rterm->RIGHT; - if(Rtail == NULL) - return build_up(top, "\1\016(\2*\3)", NULL); /*{?} 2\L3+2\L9 => 4+2\L27/16 */ - else - { - addr[4] = Rtail; - return build_up(top, "\1\016(\2*\3)+\4", NULL); /*{?} 2\L3+2\L9+3\L123 => 8+2\L27/16+3\L41/27 */ - } - } - - splitProduct_number_im_rest(Lterm, &LtermN, &LtermI, &LtermNNNI); - - if(LtermI) - { - ppsk runner = &Pnode; - splitProduct_number_im_rest(Rterm, &RtermN, &RtermI, &RtermNNNI); - while(RtermI == NULL - && Op((*runner)->RIGHT) == PLUS - ) - { - runner = &(*runner)->RIGHT; - *runner = isolated(*runner); - rightoperand_and_tail((*runner), &Rterm, &Rtail); - splitProduct_number_im_rest(Rterm, &RtermN, &RtermI, &RtermNNNI);/*{?} i*x+-i*x+a => a */ - } - if(RtermI != NULL) - { /*{?} i*x+-i*x => 0 */ - int indx; - int dif; - if(LtermNNNI == NULL) - { - dif = RtermNNNI == NULL ? 0 : -1;/*{?} i+-i*x => i+-i*x */ - /*{?} i+-i => 0 */ - } - else - { - assert(RtermNNNI != NULL); - dif = equal(LtermNNNI, RtermNNNI); - } - if(dif == 0) - { /*{?} i*x+-i*x => 0 */ - if(RtermN) - { - addr[2] = RtermN; /*{?} i*x+3*i*x => 4*i*x */ - if(LtermN == NULL) - { - /* a+n*a */ /*{?} i*x+3*i*x => 4*i*x */ - if(HAS_MINUS_SIGN(LtermI)) - { /*{?} -i*x+3*i*x => 2*i*x */ - if(HAS_MINUS_SIGN(RtermI)) - { - conc[0] = "(1+\2)*-i";/*{?} -i*x+3*-i*x => 4*-i*x */ - } - else - { - conc[0] = "(-1+\2)*i";/*{?} -i*x+3*i*x => 2*i*x */ - } - } - else if(HAS_MINUS_SIGN(RtermI)) - { - conc[0] = "(-1+\2)*-i"; /*{?} i*x+3*-i*x => 2*-i*x */ - } - else - { - conc[0] = "(1+\2)*i";/*{?} i*x+3*i*x => 4*i*x */ - } - } - /* (1+n)*a */ - else - { - /* n*a+m*a */ /*{?} 3*-i*x+-3*i*x => 6*-i*x */ - addr[3] = LtermN; - if(HAS_MINUS_SIGN(LtermI)) - { - if(HAS_MINUS_SIGN(RtermI)) - { - conc[0] = "(\3+\2)*-i";/*{?} 3*-i*x+-3*i*x => 6*-i*x */ - } - else - { - conc[0] = "(-1*\3+\2)*i";/*{?} 3*-i*x+-3*-i*x => 0 */ - } - } - else if(HAS_MINUS_SIGN(RtermI)) - { - conc[0] = "(\3+-1*\2)*i"; /*{?} 3*i*x+-3*i*x => 0 */ - } - else - { - conc[0] = "(\3+\2)*i"; /*{?} 3*i*x+4*i*x => 7*i*x */ - } - /* (n+m)*a */ - } - } - else - { /*{?} i*x+-i*x => 0 */ - addr[1] = LtermNNNI; - if(LtermN != NULL) - { - /* m*a+a */ - addr[2] = LtermN; /*{?} 3*i*x+i*x => 4*i*x */ - if(HAS_MINUS_SIGN(LtermI)) - - if(HAS_MINUS_SIGN(RtermI)) - { - conc[0] = "(1+\2)*-i";/*{?} 3*-i*x+-i*x => 4*-i*x */ - } - else - { - conc[0] = "(-1+\2)*-i";/*{?} 3*-i*x+i*x => 2*-i*x */ - } - - else if(HAS_MINUS_SIGN(RtermI)) - { - conc[0] = "(-1+\2)*i"; /*{?} 3*i*x+-i*x => 2*i*x */ - } - else - { - conc[0] = "(1+\2)*i"; /*{?} 3*i*x+i*x => 4*i*x */ - } - /* (1+m)*a */ - } - else - { - /* a+a */ /*{?} i*x+-i*x => 0 */ - if(HAS_MINUS_SIGN(LtermI)) - - if(HAS_MINUS_SIGN(RtermI)) - { - conc[0] = "2*-i"; /*{?} -i+-i => 2*-i */ - } - else - { - conc[0] = "0"; /*{?} -i+i => 0 */ - } - - else if(HAS_MINUS_SIGN(RtermI)) - { - conc[0] = "0"; /*{?} i*x+-i*x => 0 */ - } - else - { - conc[0] = "2*i"; /*{?} i+i => 2*i */ - } - } - /* 2*a */ - } - if(LtermNNNI != NULL) - { /*{?} i*x+-i*x => 0 */ - addr[1] = RtermNNNI; - conc[1] = "*\1"; - indx = 2; - } - else - indx = 1; /*{?} i+-i => 0 */ - if(Rtail != NULL) - { - addr[4] = Rtail; /*{?} -i+-i+i*y => 2*-i+i*y */ - conc[indx++] = "+\4"; - } - conc[indx] = NULL; /*{?} i*x+-i*x => 0 */ - (*runner)->RIGHT = vbuildup((*runner)->RIGHT, conc); - if(runner != &Pnode) - { - (*runner)->v.fl &= ~READY;/*{?} i*x+-i*x+a => a */ - *runner = eval(*runner); - } - return rightbranch(top); /*{?} i*x+-i*x => 0 */ - } - assert(Ltail == NULL); - } - else /* LtermI != NULL && RtermI == NULL */ - { - addr[1] = Rterm; /*{?} i*x+-i*x+a => a */ - addr[2] = L; - (*runner)->RIGHT = build_up((*runner)->RIGHT, "\1+\2", NULL); - (*runner)->RIGHT->v.fl |= READY; - return rightbranch(top); - } - } - else /* LtermI == NULL */ - { - ppsk runner = &Pnode; - int dif = 1; - assert(LtermNNNI != NULL); - splitProduct_number_im_rest(Rterm, &RtermN, &RtermI, &RtermNNNI); - while(RtermNNNI != NULL - && RtermI == NULL - && (dif = cmp(LtermNNNI, RtermNNNI)) > 0 - && Op((*runner)->RIGHT) == PLUS - ) - { - /* - x^(y*(a+b))+z^(y*(a+b))+-1*x^(a*y+b*y) => z^(y*(a+b)) - cos$(a+b)+-1*(cos$a*cos$b+-1*sin$a*sin$b) => 0 - x^(y*(a+b))+x^(a*y+b*y) => 2*x^(y*(a+b)) - x^(y*(a+b))+-1*x^(a*y+b*y) => 0 - fct$(a^((b+c)*(d+e))+a^((b+c)*(d+f))) => a^(b*d+c*d) * (a^(b*f+c*f)+a^(e*b+e*c)) - (a^((b+c)*(d+e))+a^((b+c)*(d+f))) + -1 * a^(b*d+c*d) * (a^(b*f+c*f)+a^(e*b+e*c)) => 0 - -1*(a^((b+c)*(d+e))+a^((b+c)*(d+f))) + a^(b*d+c*d) * (a^(b*f+c*f)+a^(e*b+e*c)) => 0 - a^(b*d+c*d) * (a^(b*f+c*f)+a^(e*b+e*c)) + -1*(a^((b+c)*(d+e))+a^((b+c)*(d+f))) => 0 - -1 * a^(b*d+c*d) * (a^(b*f+c*f)+a^(e*b+e*c)) + a^((b+c)*(d+e)) + a^((b+c)*(d+f)) => 0 - */ - runner = &(*runner)->RIGHT; /*{?} (b^3+c^3)+b^3+c+b^3 => c+3*b^3+c^3 */ - *runner = isolated(*runner); - rightoperand_and_tail((*runner), &Rterm, &Rtail); - splitProduct_number_im_rest(Rterm, &RtermN, &RtermI, &RtermNNNI); - } - if(RtermI != NULL) - dif = -1; /*{?} (-i+a)+-i => a+2*-i */ - if(dif == 0) - { - if(RtermN) - { - addr[1] = RtermNNNI; - addr[2] = RtermN; - if(LtermN == NULL) - /*{?} a+n*a => a+a*n */ - conc[0] = "(1+\2)*\1"; - /* (1+n)*a */ - else - { - /*{?} n*a+m*a => a*m+a*n */ /*{?} 7*a+9*a => 16*a */ - addr[3] = LtermN; - conc[0] = "(\3+\2)*\1"; - /* (n+m)*a */ - } - } - else - { - addr[1] = LtermNNNI; - if(LtermN != NULL) - { - /* m*a+a */ - addr[2] = LtermN; - conc[0] = "(1+\2)*\1"; /*{?} 3*a+a => 4*a */ - /* (1+m)*a */ - } - else - { - /*{?} a+a => 2*a */ - conc[0] = "2*\1"; - } - /* 2*a */ - } - assert(Ltail == NULL); - conc[1] = NULL; - conc[2] = NULL; - if(Rtail != NULL) - { - addr[4] = Rtail; - conc[1] = "+\4"; - } - (*runner)->RIGHT = vbuildup((*runner)->RIGHT, conc); - if(runner != &Pnode) - { - (*runner)->v.fl &= ~READY; - /*{?} (b^3+c^3)+b^3+c+b^3 => c+3*b^3+c^3 */ - /* This would evaluate to c+(1+2)*b^3+c^3 if READY flag wasn't turned off */ - /* Correct evaluation: c+3*b^3+c^3 */ - *runner = eval(*runner); - } - return rightbranch(top); - } - else if(dif > 0) /*{?} b+a => a+b */ - { - addr[1] = Rterm; - addr[2] = L; - (*runner)->RIGHT = build_up((*runner)->RIGHT, "\1+\2", NULL); - (*runner)->RIGHT->v.fl |= READY; - return rightbranch(top); - } - else if((*runner) != top) /* b + a + c */ - { - addr[1] = L; - addr[2] = (*runner)->RIGHT; - (*runner)->RIGHT = build_up((*runner)->RIGHT, "\1+\2", NULL); - (*runner)->RIGHT = eval((*runner)->RIGHT); - return rightbranch(top); /* (1+a+b+c)^30+1 */ - } - assert(Ltail == NULL); - } - return Pnode; - } - -static psk substtimes(psk Pnode) - { - static const char* conc[] = { NULL,NULL,NULL,NULL }; - psk rkn, lkn; - psk rvar, lvar; - psk temp, llnode, rlnode; - int nodedifference; - rkn = rightoperand(Pnode); - - if(is_op(rkn)) - rvar = NULL; /* (f.e)*(y.s) */ - else - { - if(IS_ONE(rkn)) - { - return leftbranch(Pnode); /*{?} (a=7)&!(a*1) => 7 */ - } - else if(RAT_NUL(rkn))/*{?} -1*140/1000 => -7/50 */ - { - wipe(Pnode); /*{?} x*0 => 0 */ - return copyof(&zeroNode); - } - rvar = rkn; /*{?} a*a => a^2 */ - } - - lkn = Pnode->LEFT; - if(!is_op(lkn)) - { - if(RAT_NUL(lkn)) /*{?} -1*140/1000 => -7/50 */ - { - wipe(Pnode); /*{?} 0*x => 0 */ - return copyof(&zeroNode); - } - lvar = lkn; - - if(IS_ONE(lkn)) - { - return rightbranch(Pnode); /*{?} 1*-1 => -1 */ - } - else if(RATIONAL_COMP(lkn) && rvar) - { - if(RATIONAL_COMP(rkn)) - { - if(rkn == lkn) - lvar = (Pnode->LEFT = isolated(lkn)); /*{?} 1/10*1/10 => 1/100 */ - conc[0] = hash6; - addr[6] = qTimes(rvar, lvar); - if(rkn == Pnode->RIGHT) - conc[1] = NULL; /*{?} -1*140/1000 => -7/50 */ - else - { - addr[1] = Pnode->RIGHT->RIGHT; /*{?} -1*1/4*e^(2*i*x) => -1/4*e^(2*i*x) */ - conc[1] = "*\1"; - } - Pnode = vbuildup(Pnode, conc); - wipe(addr[6]); - return Pnode; - } - else - { - if(PLOBJ(rkn) == IM && RAT_NEG_COMP(lkn)) - { - conc[0] = "(\2*\3)"; - addr[2] = qTimesMinusOne(lkn); - addr[3] = qTimesMinusOne(rkn); - if(rkn == Pnode->RIGHT) - conc[1] = NULL; /*{?} -1*i => -i */ - else - { - addr[1] = Pnode->RIGHT->RIGHT; /*{?} -3*i*x => 3*-i*x */ - conc[1] = "*\1"; - } - Pnode = vbuildup(Pnode, conc); - wipe(addr[2]); - wipe(addr[3]); - return Pnode; - } - } - } - } - - rlnode = Op(rkn) == EXP ? rkn->LEFT : rkn; /*{?} (f.e)*(y.s) => (f.e)*(y.s) */ - llnode = Op(lkn) == EXP ? lkn->LEFT : lkn; - if((nodedifference = equal(llnode, rlnode)) == 0) - { - /* a^n*a^m */ - if(rlnode != rkn) - { - addr[1] = rlnode; /*{?} e^(i*x)*e^(-i*x) => 1 */ - addr[2] = rkn->RIGHT; - if(llnode == lkn) - { - conc[0] = "\1^(1+\2)"; /*{?} a*a^n => a^(1+n) */ - }/* a^(1+n) */ - else - { - /* a^n*a^m */ - addr[3] = lkn->RIGHT; /*{?} e^(i*x)*e^(-i*x) => 1 */ - conc[0] = "\1^(\3+\2)"; - /* a^(n+m) */ - } - } - else - { - if(llnode != lkn) - { - addr[1] = llnode; /*{?} a^m*a => a^(1+m) */ - addr[2] = lkn->RIGHT; - conc[0] = "\1^(1+\2)"; - /* a^(m+1) */ - } - else - { - /*{?} a*a => a^2 */ - addr[1] = llnode; /*{?} i*i*(-1/2*e^(i*a)+1/2*e^(-i*a))*(-1/2*e^(i*b)+1/2*e^(-i*b)) => -1*(-1/2*e^(i*a)+1/2*e^(-i*a))*(-1/2*e^(i*b)+1/2*e^(-i*b)) */ - conc[0] = "\1^2"; - /* a^2 */ - } - } - if(rkn != (temp = Pnode->RIGHT)) - { - addr[4] = temp->RIGHT; /*{?} i*i*(-1/2*e^(i*a)+1/2*e^(-i*a))*(-1/2*e^(i*b)+1/2*e^(-i*b)) => -1*(-1/2*e^(i*a)+1/2*e^(-i*a))*(-1/2*e^(i*b)+1/2*e^(-i*b)) */ - conc[1] = "*\4"; - } - else - conc[1] = NULL; /*{?} e^(i*x)*e^(-i*x) => 1 */ - return vbuildup(Pnode, (const char**)conc); - } - else - { - int degree; - degree = number_degree(rlnode) - number_degree(llnode); /*{?} (f.e)*(y.s) => (f.e)*(y.s) */ - if(degree > 0 - || (degree == 0 && (nodedifference > 0))) - { - /* b^n*a^m */ - /* l^n*a^m */ - if((temp = Pnode->RIGHT) == rkn) - { - Pnode->RIGHT = lkn; /*{?} x*2 => 2*x */ - Pnode->LEFT = rkn; - Pnode->v.fl &= ~READY; - } - else - { - addr[1] = lkn; /*{?} i*2*x => 2*i*x */ - addr[2] = temp->LEFT; - addr[3] = temp->RIGHT; - Pnode = build_up(Pnode, "\2*\1*\3", NULL); - } - return Pnode; - /* a^m*b^n */ - /* a^m*l^n */ - } - else if(PLOBJ(rlnode) == IM) - { - if(PLOBJ(llnode) == IM) /*{?} -1*i^1/3 => -i^5/3 */ - { - /*{?} i^n*-i^m => i^(-1*m+n) */ - if(rlnode != rkn) - { - addr[1] = llnode; - addr[2] = rkn->RIGHT; - if(llnode == lkn) - /*{?} i*-i^n => i^(1+-1*n) */ - conc[0] = "\1^(1+-1*\2)"; - /* i^(1-n) */ - else - { - addr[3] = lkn->RIGHT; /*{?} i^n*-i^m => i^(-1*m+n) */ - conc[0] = "\1^(\3+-1*\2)"; - /* i^(n-m) */ - } - } - else - { - if(llnode != lkn) - { - /*{?} i^m*-i => i^(-1+m) */ - addr[1] = llnode; - addr[2] = lkn->RIGHT; - conc[0] = "\1^(-1+\2)"; - /* i^(m-1) */ - } - else - { - /*{?} i*-i => 1 */ - conc[0] = "1"; - /* 1 */ - } - } - } - else if(RAT_NEG_COMP(llnode) - /* -n*i^m -> n*-i^(2+m) */ - /*{?} -7*i^9 => 7*i */ /*{!} 7*-i^11 */ - /* -n*-i^m -> n*i^(2+m) */ - /*{?} -7*-i^9 => 7*-i */ /*{!}-> 7*i^11 */ - && rlnode != rkn - && llnode == lkn - ) - { /*{?} -1*i^1/3 => -i^5/3 */ - addr[1] = llnode; - addr[2] = rkn->LEFT; - addr[3] = rkn->RIGHT; - addr[4] = &twoNode; - conc[0] = "(-1*\1)*\2^(\3+\4)"; - } - else - return Pnode; /*{?} 2*i*x => 2*i*x */ - if(rkn != (temp = Pnode->RIGHT)) - { - addr[4] = temp->RIGHT; /*{?} i^n*-i^m*z => i^(-1*m+n)*z */ - conc[1] = "*\4"; - } - else - conc[1] = NULL; /*{?} -1*i^1/3 => -i^5/3 */ /*{?} i^n*-i^m => i^(-1*m+n) */ - return vbuildup(Pnode, (const char**)conc); - } - else - return Pnode; /*{?} (f.e)*(y.s) => (f.e)*(y.s) */ - } - } - -static int bringright(psk pnode) - { - /* (a*b*c*d)*a*b*c*d -> a*b*c*d*a*b*c*d */ - psk lnode; - int done; - done = FALSE; - for(; Op(lnode = pnode->LEFT) == Op(pnode);) - { - lnode = isolated(lnode); - lnode->v.fl &= ~READY; - pnode->LEFT = lnode->LEFT; - lnode->LEFT = lnode->RIGHT; - lnode->RIGHT = pnode->RIGHT; - pnode->v.fl &= ~READY; - pnode->RIGHT = lnode; - pnode = lnode; - done = TRUE; - } - return done; - } -/* - 1* - / \ - / \ - / \ - 2* 3* - / \ / \ - a x b c - -lhead = a -ltail = x -rhead = b -rtail = c - -rennur = NIL -runner = (a * x) * b * c -lloper = a * x - - 2* - / \ - a - rennur = a*NIL - - 1* - / \ - x 3* - / \ - b c -*/ -static int cmpplus(psk kn1, psk kn2) - { - if(RATIONAL_COMP(kn2)) - { - if(RATIONAL_COMP(kn1)) - return 0; - return 1; /* switch places */ - } - else if(RATIONAL_COMP(kn1)) - return -1; - else - { - psk N1; - psk I1; - psk NNNI1; - psk N2; - psk I2; - psk NNNI2; - splitProduct_number_im_rest(kn1, &N1, &I1, &NNNI1); - splitProduct_number_im_rest(kn2, &N2, &I2, &NNNI2); - if(I1 != NULL && I2 == NULL) - return 1; /* switch places: imaginary terms after real terms */ - if(NNNI2 == NULL) - { - if(NNNI1 != NULL) - return 1; - return 0; - } - else if(NNNI1 == NULL) - return -1; - else - { - int diff; - diff = equal(NNNI1, NNNI2); - if(diff > 0) - { - return 1; /* switch places */ - } - else if(diff < 0) - { - return -1; - } - else - { - return 0; - } - } - } - } - -static int cmptimes(psk kn1, psk kn2) - { - int diff; - if(Op(kn1) == EXP) - kn1 = kn1->LEFT; - if(Op(kn2) == EXP) - kn2 = kn2->LEFT; - - diff = number_degree(kn2); - if(diff != 5) - diff -= number_degree(kn1); - else - { - diff = -number_degree(kn1); - if(!diff) - return 0; /* two numbers */ - } - if(diff > 0) - return 1; /* switch places */ - else if(diff == 0) - { - diff = equal(kn1, kn2); - if(diff > 0) - { - return 1; /* switch places */ - } - else if(diff < 0) - { - return -1; - } - else - { - return 0; - } - } - else - { - return -1; - } - } - -static psk merge -(psk Pnode - , int(*comp)(psk, psk) - , psk(*combine)(psk) -#if EXPAND - , psk(*expand)(psk, int*) -#endif -) - { - psk lhead, ltail, rhead, rtail; - psk Rennur = &nilNode; /* Will contain all evaluated nodes in inverse order.*/ - psk tmp; - for(;;) - {/* traverse from left to right to evaluate left side branches */ -#if EXPAND - Boolean ok; -#endif - Pnode = isolated(Pnode); - assert(!shared(Pnode)); - Pnode->v.fl |= READY; -#if EXPAND - do - { - Pnode->LEFT = eval(Pnode->LEFT); - Pnode->LEFT = expand(Pnode->LEFT, &ok); - } while(ok); -#else - Pnode->LEFT = eval(Pnode->LEFT); -#endif - tmp = Pnode->RIGHT; - if(tmp->v.fl & READY) - { - break; - } - if(!is_op(tmp) - || Op(Pnode) != Op(tmp) - ) - { -#if EXPAND - do - { - tmp = eval(tmp); - tmp = expand(tmp, &ok); - } while(ok); - Pnode->RIGHT = tmp; -#else - Pnode->RIGHT = eval(tmp); -#endif - break; - } - Pnode->RIGHT = Rennur; - Rennur = Pnode; - Pnode = tmp; - } - for(;;) - { /* From right to left, prepend sorted elements to result */ - psk rennur = &nilNode; /*Will contain branches in inverse sorted order*/ - psk L = leftoperand_and_tail(Pnode, &lhead, <ail); - psk R = rightoperand_and_tail(Pnode, &rhead, &rtail); - for(;;) - { /* From right to left, prepend smallest of lhs and rhs - to rennur - */ - assert(rhead->v.fl & READY); - assert((L == lhead && ltail == NULL) || L->RIGHT == ltail); - assert((L == lhead && ltail == NULL) || L->LEFT == lhead); - assert(Pnode->LEFT == L); - assert((R == rhead && rtail == NULL) || R->RIGHT == rtail); - assert((R == rhead && rtail == NULL) || R->LEFT == rhead); - assert(Pnode->RIGHT == R); - assert(L->v.fl & READY); - assert(Pnode->RIGHT->v.fl & READY); - if(comp(lhead, rhead) <= 0) /* a * b */ - { - if(ltail == NULL) /* a * (b*c) */ - { - assert(Pnode->RIGHT->v.fl & READY); - break; - } - else /* (a*d) * (b*c) */ - { - L = isolated(L); - assert(!shared(L)); - if(ltail != L->RIGHT) - { - wipe(L->RIGHT); /* rare, set REFCOUNTSTRESSTEST 1 */ - ltail = same_as_w(ltail); - } - L->RIGHT = rennur; - rennur = L; - assert(!shared(Pnode)); - Pnode = isolated(Pnode); - assert(!shared(Pnode)); - Pnode->LEFT = ltail; - L = leftoperand_and_tail(Pnode, &lhead, <ail); - } /* rennur := a*rennur */ - /* d * (b*c) */ - } - else /* Wrong order */ - { - Pnode = isolated(Pnode); - assert(!shared(Pnode)); - assert(L->v.fl & READY); - if(rtail == NULL) /* (b*c) * a */ - { - Pnode->LEFT = R; - assert(L->v.fl & READY); - Pnode->RIGHT = L; - break; - } /* a * (b*c) */ - else /* (b*c) * (a*d) c * (b*a) */ - { - R = isolated(R); - assert(!shared(R)); - if(R->RIGHT != rtail) - { - wipe(R->RIGHT); /* rare, set REFCOUNTSTRESSTEST 1 */ - rtail = same_as_w(rtail); - } - R->RIGHT = rennur; - rennur = R; - assert(!shared(Pnode)); - Pnode->RIGHT = rtail; - R = rightoperand_and_tail(Pnode, &rhead, &rtail); - } /* rennur := a*rennur rennur := b*rennur */ - /* (b*c) * d */ - } - } - for(;;) - { /*Combine combinable elements and prepend to result*/ - Pnode->v.fl |= READY; - - Pnode = combine(Pnode); - if(!(Pnode->v.fl & READY)) - { /*This may results in recursive call to merge - if the result of the evaluation is not in same - sorting position as unevaluated expression. */ - assert(!shared(Pnode)); - Pnode = eval(Pnode); - } -#if DATAMATCHESITSELF - if(is_op(Pnode)) - { - if((Pnode->LEFT->v.fl & SELFMATCHING) && (Pnode->RIGHT->v.fl & SELFMATCHING)) - Pnode->v.fl |= SELFMATCHING; - else - Pnode->v.fl &= ~SELFMATCHING; - } -#endif - if(rennur != &nilNode) - { - psk n = rennur->RIGHT; - assert(!shared(rennur)); - rennur->RIGHT = Pnode; - Pnode = rennur; - rennur = n; - } - else - break; - } - if(Rennur == &nilNode) - break; - tmp = Rennur->RIGHT; - assert(!shared(Rennur)); - Rennur->RIGHT = Pnode; - Pnode = Rennur; - assert(!shared(Pnode)); - Pnode->v.fl |= READY; -#if DATAMATCHESITSELF - if(is_op(Pnode)) - { - if((Pnode->LEFT->v.fl & SELFMATCHING) && (Pnode->RIGHT->v.fl & SELFMATCHING)) - Pnode->v.fl |= SELFMATCHING; - else - Pnode->v.fl &= ~SELFMATCHING; - } -#endif - Rennur = tmp; - } - return Pnode; - } - -static psk substlog(psk Pnode) - { - static const char* conc[] = { NULL,NULL,NULL,NULL }; - psk lnode = Pnode->LEFT, rightnode = Pnode->RIGHT; - if(!equal(lnode, rightnode)) - { - wipe(Pnode); - return copyof(&oneNode); - } - else if(is_op(rightnode)) /*{?} x\L(2+y) => x\L(2+y) */ - { - int ok; - return tryq(Pnode, f5, &ok); /*{?} x\L(a*x^n*z) => n+x\L(a*z) */ - } - else if(IS_ONE(rightnode)) /*{?} x\L1 => 0 */ /*{!} 0 */ - { - wipe(Pnode); - return copyof(&zeroNode); - } - else if(RAT_NUL(rightnode)) /*{?} z\L0 => z\L0 */ - return Pnode; - else if(is_op(lnode)) /*{?} (x+y)\Lz => (x+y)\Lz */ - return Pnode; - else if(RAT_NUL(lnode)) /*{?} 0\Lx => 0\Lx */ - return Pnode; - else if(IS_ONE(lnode)) /*{?} 1\Lx => 1\Lx */ - return Pnode; - else if(RAT_NEG(lnode)) /*{?} -7\Lx => -7\Lx */ - return Pnode; - else if(RATIONAL_COMP(rightnode)) /*{?} x\L7 => x\L7 */ - { - if(qCompare(rightnode, &zeroNode) & MINUS) - { - /* (nL-m = i*pi/eLn+nLm) */ /*{?} 7\L-9 => 1+7\L9/7+i*pi*e\L7^-1 */ /*{!} i*pi/e\L7+7\L9) */ - addr[1] = lnode; - addr[2] = rightnode; - return build_up(Pnode, "(i*pi*e\016\1^-1+\1\016(-1*\2))", NULL); - } - else if(RATIONAL_COMP(lnode)) /* m\Ln */ /*{?} 7\L9 => 1+7\L9/7 */ - { - if(qCompare(lnode, &oneNode) & MINUS) - { - /* (1/n)Lm = -1*nLm */ /*{?} 1/7\L9 => -1*(1+7\L9/7) */ /*{!} -1*nLm */ - addr[1] = rightnode; - conc[0] = "(-1*"; - conc[1] = hash6; - addr[6] = qqDivide(&oneNode, lnode); - conc[2] = "\016\1)"; - Pnode = vbuildup(Pnode, conc); - wipe(addr[6]); - return Pnode; - } - else if(qCompare(lnode, rightnode) & MINUS) - { - /* nL(n+m) = 1+nL((n+m)/n) */ /*{?} 7\L(7+9) => 1+7\L16/7 */ /*{!} 1+nL((n+m)/n) */ - conc[0] = "(1+\1\016"; - assert(lnode != rightnode); - addr[1] = lnode; - conc[1] = hash6; - addr[6] = qqDivide(rightnode, lnode); - conc[2] = ")"; - Pnode = vbuildup(Pnode, conc); - wipe(addr[6]); - return Pnode; - } - else if(qCompare(rightnode, &oneNode) & MINUS) - { - /* nL(1/m) = -1+nL(n/m) */ /*{?} 7\L1/9 => -2+7\L49/9 */ /*{!} -1+nL(n/m) */ - conc[0] = "(-1+\1\016"; - assert(lnode != rightnode); - addr[1] = lnode; - conc[1] = hash6; - addr[6] = qTimes(rightnode, lnode); - conc[2] = ")"; - Pnode = vbuildup(Pnode, conc); - wipe(addr[6]); - return Pnode; - } - } - } - return Pnode; - } - -static int is_dependent_of(psk el, psk input_buffer) - { - int ret; - psk pnode; - assert(!is_op(input_buffer)); - pnode = NULL; - addr[1] = input_buffer; - addr[2] = el; - pnode = build_up(pnode, "(!dep:(? (\1.? \2 ?) ?)", NULL); - pnode = eval(pnode); - ret = isSUCCESS(pnode); - wipe(pnode); - return ret; - } - -static psk substdiff(psk Pnode) - { - psk lnode, rightnode; - lnode = Pnode->LEFT; - rightnode = Pnode->RIGHT; - if(is_constant(lnode) || is_constant(rightnode)) - { - wipe(Pnode); - Pnode = copyof(&zeroNode); - } - else if(!equal(lnode, rightnode)) - { - wipe(Pnode); - Pnode = copyof(&oneNode); - } - else if(!is_op(rightnode) - && is_dependent_of(lnode, rightnode) - ) - { - ; - } - else if(!is_op(rightnode)) - { - wipe(Pnode); - Pnode = copyof(&zeroNode); - } - else if(Op(rightnode) == PLUS) - { - addr[1] = lnode; - addr[2] = rightnode->LEFT; - addr[3] = rightnode->RIGHT; - Pnode = build_up(Pnode, "((\1\017\2)+(\1\017\3))", NULL); - } - else if(is_op(rightnode)) - { - addr[2] = rightnode->LEFT; - addr[1] = lnode; - addr[3] = rightnode->RIGHT; - switch(Op(rightnode)) - { - case TIMES: - Pnode = build_up(Pnode, "(\001\017\2*\3+\2*\001\017\3)", NULL); - break; - case EXP: - Pnode = build_up(Pnode, - "(\2^(-1+\3)*\3*\001\017\2+\2^\3*e\016\2*\001\017\3)", NULL); - break; - case LOG: - Pnode = build_up(Pnode, - "(\2^-1*e\016\2^-2*e\016\3*\001\017\2+\3^-1*e\016\2^-1*\001\017\3)", NULL); - break; - } - } - return Pnode; - } - -#if JMP /* Often no need for polling in multithreaded apps.*/ -#include -#include -static void PeekMsg(void) - { - static MSG msg; - while(PeekMessage(&msg, NULL, WM_PAINT, WM_DDE_LAST, PM_REMOVE)) - { - if(msg.message == WM_QUIT) - { - PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0L); - longjmp(jumper, 1); - } - TranslateMessage(&msg); /* Translates virtual key codes */ - DispatchMessage(&msg); /* Dispatches message to window*/ - } - } -#endif - -/* -Iterative handling of WHITE operator in evaluate. -Can now handle very deep structures without stack overflow -*/ - -static psk handleWhitespace(psk Pnode) - { /* assumption: (Op(*Pnode) == WHITE) && !((*Pnode)->v.fl & READY) */ - static psk apnode; - psk whitespacenode; - psk next; - ppsk pwhitespacenode = &Pnode; - ppsk prevpwhitespacenode = NULL; - for(;;) - { - whitespacenode = *pwhitespacenode; - whitespacenode->LEFT = eval(whitespacenode->LEFT); - if(!is_op(apnode = whitespacenode->LEFT) - && !(apnode->u.obj) - && !HAS_UNOPS(apnode) - ) - { - *pwhitespacenode = rightbranch(whitespacenode); - } - else - { - prevpwhitespacenode = pwhitespacenode; - pwhitespacenode = &(whitespacenode->RIGHT); - } - if(Op(whitespacenode = *pwhitespacenode) == WHITE && !(whitespacenode->v.fl & READY)) - { - if(shared(*pwhitespacenode)) - *pwhitespacenode = copyop(*pwhitespacenode); - } - else - { - *pwhitespacenode = eval(*pwhitespacenode); - if(prevpwhitespacenode - && !is_op(whitespacenode = *pwhitespacenode) - && !((whitespacenode)->u.obj) - && !HAS_UNOPS(whitespacenode) - ) - *prevpwhitespacenode = leftbranch(*prevpwhitespacenode); - break; - } - } - - whitespacenode = Pnode; - while(Op(whitespacenode) == WHITE) - { - next = whitespacenode->RIGHT; - bringright(whitespacenode); - if(next->v.fl & READY) - break; - whitespacenode = next; - whitespacenode->v.fl |= READY; - } - return Pnode; - } -/* -Iterative handling of COMMA operator in evaluate. -Can now handle very deep structures without stack overflow -*/ -static psk handleComma(psk Pnode) - { /* assumption: (Op(*Pnode) == COMMA) && !((*Pnode)->v.fl & READY) */ - psk commanode = Pnode; - psk next; - ppsk pcommanode; - while(Op(commanode->RIGHT) == COMMA && !(commanode->RIGHT->v.fl & READY)) - { - commanode->LEFT = eval(commanode->LEFT); - pcommanode = &(commanode->RIGHT); - commanode = commanode->RIGHT; - if(shared(commanode)) - { - *pcommanode = commanode = copyop(commanode); - } - } - commanode->LEFT = eval(commanode->LEFT); - commanode->RIGHT = eval(commanode->RIGHT); - commanode = Pnode; - while(Op(commanode) == COMMA) - { - next = commanode->RIGHT; - bringright(commanode); - if(next->v.fl & READY) - break; - commanode = next; - commanode->v.fl |= READY; - } - return Pnode; - } - -static psk evalvar(psk Pnode) - { - psk loc_adr = SymbolBinding_w(Pnode, Pnode->v.fl & DOUBLY_INDIRECT); - if(loc_adr != NULL) - { - wipe(Pnode); - Pnode = loc_adr; - } - else - { - if(shared(Pnode)) - { - /*You can get here if a !variable is unitialized*/ - dec_refcount(Pnode); - Pnode = iCopyOf(Pnode); - } - assert(!shared(Pnode)); - Pnode->v.fl |= READY; - Pnode->v.fl ^= SUCCESS; - } - return Pnode; - } -/* End of canonization.c */ - -/* Begin of evaluate.c */ - -#if MAXSTACK -static int maxstack = 0; -static int theStack = 0; -#define ASTACK {++theStack;if(theStack > maxstack) maxstack = theStack;}{ -#define ZSTACK }{--theStack;} -#else -#define ASTACK -#define ZSTACK -#endif -static psk eval(psk Pnode) - { - ASTACK - /* - Notice that there are only few local variables on the stack. This ensures - maximal utilisation of stack-depth for recursion. - */ - DBGSRC(Printf("evaluate :"); result(Pnode); Printf("\n");) - while(!(Pnode->v.fl & READY)) - { - if(is_op(Pnode)) - { - sk lkn = *Pnode; - psk auxkn; - /* The operators MATCH, AND and OR are treated in another way than - the other operators. These three operators are the only 'volatile' - operators: they cannot occur in a fully evaluated tree. For that reason - there is no need to allocate space for an evaluated version of such - operators on the stack. Instead the local variable lkn is used. - */ - switch(Op(Pnode)) - { - case MATCH: - { - privatized(Pnode, &lkn); - lkn.LEFT = eval(lkn.LEFT); - if(isSUCCESSorFENCE(lkn.LEFT)) - /* - `~a:?b will assign `~a to b - */ - { -#if STRINGMATCH_CAN_BE_NEGATED - if(lkn.v.fl & ATOM) /* should other flags be - excluded, including ~ ?*/ -#else - if((lkn.v.fl & ATOM) && !NEGATION(lkn.v.fl, ATOM)) -#endif - { -#if CUTOFFSUGGEST - if(!is_op(lkn.LEFT) && stringmatch(0, "V", SPOBJ(lkn.LEFT), NULL, lkn.RIGHT, lkn.LEFT, 0, strlen((char*)POBJ(lkn.LEFT)), NULL, 0) & TRUE) -#else - if(!is_op(lkn.LEFT) && stringmatch(0, "V", POBJ(lkn.LEFT), NULL, lkn.RIGHT, lkn.LEFT, 0, strlen((char*)POBJ(lkn.LEFT))) & TRUE) -#endif - Pnode = _leftbranch(&lkn); /* ~@(a:a) is now treated like ~(a:a)*/ - else - { - if(is_op(lkn.LEFT)) - { -#if !defined NO_EXIT_ON_NON_SEVERE_ERRORS - errorprintf("Error in stringmatch: left operand is not atomic "); writeError(&lkn); - exit(117); -#endif - } - Pnode = _fleftbranch(&lkn);/* ~@(a:b) is now treated like ~(a:b)*/ - } - } - else - { - if(match(0, lkn.LEFT, lkn.RIGHT, NULL, 0, lkn.LEFT, 5555) & TRUE) - Pnode = _leftbranch(&lkn); - else - Pnode = _fleftbranch(&lkn); - } - } - else - { - Pnode = _leftbranch(&lkn); - } - DBGSRC(Printf("after match:"); result(Pnode); Printf("\n"); \ - if(Pnode->v.fl & SUCCESS) Printf(" SUCCESS\n"); \ - else Printf(" FENCE\n");) - break; - } - /* The operators AND and OR are tail-recursion optimised. */ - case AND: - { - privatized(Pnode, &lkn); - lkn.LEFT = eval(lkn.LEFT); - if(isSUCCESSorFENCE(lkn.LEFT)) - { - Pnode = _rightbranch(&lkn);/* TRUE or FENCE */ - if(lkn.v.fl & INDIRECT) - { - lkn.RIGHT = eval(Pnode); - if(isSUCCESS(lkn.RIGHT)) - { - Pnode = evalvar(lkn.RIGHT); - } - else - Pnode->v.fl ^= SUCCESS; - } - } - else - Pnode = _leftbranch(&lkn);/* FAIL */ - break; - } - case OR: - { - privatized(Pnode, &lkn); - lkn.LEFT = eval(lkn.LEFT); - if(isSUCCESSorFENCE(lkn.LEFT)) - { - Pnode = _fenceleftbranch(&lkn);/* FENCE or TRUE */ - if((lkn.v.fl & INDIRECT) && isSUCCESS(Pnode)) - { - lkn.RIGHT = eval(Pnode); - if(isSUCCESS(lkn.RIGHT)) - Pnode = evalvar(lkn.RIGHT); - else - Pnode->v.fl ^= SUCCESS; - } - } - else - { - Pnode = _rightbranch(&lkn);/* FAIL */ - if((lkn.v.fl & INDIRECT) && isSUCCESS(Pnode)) - { - lkn.RIGHT = eval(Pnode); - if(isSUCCESS(lkn.RIGHT)) - Pnode = evalvar(lkn.RIGHT); - else - Pnode->v.fl ^= SUCCESS; - } - } - break; - } - /* Operators that can occur in evaluated expressions: */ - case EQUALS: - if(ISBUILTIN((objectnode*)Pnode)) - { - Pnode->v.fl |= READY; - break; - } - - if(!is_op(Pnode->LEFT) - && !Pnode->LEFT->u.obj - && (Pnode->v.fl & INDIRECT) - && !(Pnode->v.fl & DOUBLY_INDIRECT) - ) - { - static int fl; - fl = Pnode->v.fl & (UNOPS & ~INDIRECT); - Pnode = __rightbranch(Pnode); - if(fl) - { - Pnode = isolated(Pnode); - Pnode->v.fl |= fl; /* {?} <>#@`/%?!(=b) => /#<>%@?`b */ - } - break; - - /* Pnode = Pnode->RIGHT;*/ - } - else - { - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode->v.fl |= READY; - Pnode->LEFT = eval(Pnode->LEFT); - if(is_op(Pnode->LEFT)) - { - if(update(Pnode->LEFT, Pnode->RIGHT)) - Pnode = leftbranch(Pnode); - else - Pnode = fleftbranch(Pnode); - } - else if(Pnode->LEFT->u.obj) - { - insert(Pnode->LEFT, Pnode->RIGHT); - Pnode = leftbranch(Pnode); - } - else if(Pnode->v.fl & INDIRECT) - /* !(=a) -> a */ - { - Pnode = evalvar(Pnode); - } - } - break; - case DOT: - { - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode->v.fl |= READY; - Pnode->LEFT = eval(Pnode->LEFT); - Pnode->RIGHT = eval(Pnode->RIGHT); - if(Pnode->v.fl & INDIRECT) - { - Pnode = evalvar(Pnode); - } - break; - } - case COMMA: - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode->v.fl |= READY; - Pnode = handleComma(Pnode);/* do not recurse, iterate! */ - if(lkn.v.fl & INDIRECT) - { - Pnode = evalvar(Pnode); - } - break; - case WHITE: - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode->v.fl |= READY; - Pnode = handleWhitespace(Pnode);/* do not recurse, iterate! */ - if(lkn.v.fl & INDIRECT) - { - Pnode = evalvar(Pnode); - } - break; - case PLUS: - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode = merge(Pnode, cmpplus, mergeOrSortTerms -#if EXPAND - , expandProduct -#endif - ); - if(lkn.v.fl & INDIRECT) - { - Pnode = evalvar(Pnode); - } - break; - case TIMES: - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode->v.fl |= READY; - { - Pnode = merge(Pnode, cmptimes, substtimes -#if EXPAND - , expandDummy -#endif - ); - } - if(lkn.v.fl & INDIRECT) - { - Pnode = evalvar(Pnode); /* {?} a=7 & !(a*1) */ - } - break; - case EXP: - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode->v.fl |= READY; - if(evaluate((Pnode->LEFT)) == TRUE - && evaluate((Pnode->RIGHT)) == TRUE - ) - { - Pnode = handleExponents(Pnode); - } - else - Pnode->v.fl ^= SUCCESS; - if(lkn.v.fl & INDIRECT) - { - Pnode = evalvar(Pnode); - } - break; - case LOG: - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode->v.fl |= READY; - if(evaluate((Pnode->LEFT)) == TRUE - && evaluate((Pnode->RIGHT)) == TRUE - ) - { - Pnode = substlog(Pnode); - } - else - { - Pnode->v.fl ^= SUCCESS; - } - if(lkn.v.fl & INDIRECT) - { - Pnode = evalvar(Pnode); - } - break; - case DIF: - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode->v.fl |= READY; - if(!(lkn.v.fl & INDIRECT) - && evaluate((Pnode->LEFT)) == TRUE - && evaluate((Pnode->RIGHT)) == TRUE - ) - { - Pnode = substdiff(Pnode); - break; - } - Pnode->v.fl ^= SUCCESS; - break; - case FUN: - case FUU: - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode->v.fl |= READY; - Pnode->LEFT = eval(Pnode->LEFT); - if(Op(Pnode) == FUN) - { - Pnode->RIGHT = eval(Pnode->RIGHT); - } - - auxkn = setIndex(Pnode); - if(auxkn) - Pnode = auxkn; - else - { - if(not_built_in(Pnode->LEFT)) /* Do not use ternary operator! That eats stack! */ - Pnode = execFnc(Pnode); - else - { - auxkn = functions(Pnode); - if(auxkn) - Pnode = auxkn; - else - Pnode = execFnc(Pnode); - } - } - - if(lkn.v.fl & INDIRECT) - { - Pnode = evalvar(Pnode); - } - break; - case UNDERSCORE: - if(shared(Pnode)) - { - Pnode = copyop(Pnode); - } - Pnode->v.fl |= READY; - if(dummy_op == EQUALS) - { - auxkn = Pnode; - Pnode = (psk)bmalloc(sizeof(objectnode)); -#if WORD32 - ((typedObjectnode*)(Pnode))->u.Int = 0; -#else - ((typedObjectnode*)(Pnode))->v.fl &= ~(BUILT_IN | CREATEDWITHNEW); -#endif - Pnode->LEFT = subtreecopy(auxkn->LEFT); - auxkn->RIGHT = Head(auxkn->RIGHT); - Pnode->RIGHT = subtreecopy(auxkn->RIGHT); - wipe(auxkn); - } - Pnode->v.fl &= (~OPERATOR & ~READY); - Pnode->v.fl |= dummy_op; - Pnode->v.fl |= SUCCESS; - if(dummy_op == UNDERSCORE) - Pnode->v.fl |= READY; /* stop iterating */ - if(lkn.v.fl & INDIRECT) - {/* (a=b=127)&(.):(_)&!(a_b) */ - Pnode = evalvar(Pnode); - } - break; - } - } - else - { - /* An unevaluated leaf can only be an atom with ! or !!, - so we don't need to test for this condition.*/ - Pnode = evalvar(Pnode); - /* After evaluation of a variable, the loop continues. - Together with how & and | (AND and OR) are treated, this ensures that - a loop can run indefinitely, without using stack space. */ - } - } -#if JMP - PeekMsg(); -#endif - ZSTACK - return Pnode; - } -/* End of evaluate.c */ - -#else /*#if defined SINGLESOURCE*/ - -#endif /*#if defined SINGLESOURCE*/ - -#if SHOWCURRENTLYALLOCATED -#if SHOWMAXALLOCATED == 0 -#undef SHOWMAXALLOCATED -#define SHOWMAXALLOCATED 1 -#endif -#ifndef SHOWMAXALLOCATED -#define SHOWMAXALLOCATED 1 -#endif -#endif - -/*#define reslt parenthesised_result */ /* to show ALL parentheses (one pair for each operator)*/ - -#define LOGWORDLENGTH 2 - -#include - -/* -0:?n&whl'(1+!n:<100000:?n&57265978465924376578234566767834625978465923745729775787627876873875436743934786450097*53645235643259824350824580457283955438957043287250857432895703498700987123454567897656:?T)&!T -NEWMULT -{!} 3072046909146355923036506564192345471346475055611123765430367260576556764424411699428134904701221896786418686608674094452972067252677279867454597742488128986716908647272632 - S 3,41 sec (1437.1457.2) -!NEWMULT -{!} 3072046909146355923036506564192345471346475055611123765430367260576556764424411699428134904701221896786418686608674094452972067252677279867454597742488128986716908647272632 - S 26,60 sec (1437.1453.2) - -0:?n&whl'(1+!n:<1000000:?n&57265978465627876873875436743934786450097*53645235643259824350824987123454567897656:?T)&!T -NEWMULT -{!} 3072046909130450126528027450054726559442406960607487886384944156986716908647272632 - S 18,53 sec (1437.1457.2)!NEWMULT -{!} 3072046909130450126528027450054726559442406960607487886384944156986716908647272632 - S 67,78 sec (1437.1456.2) - -0:?n&whl'(1+!n:<1000000:?n&75436743934786450097*53645235643259824350:?T)&!T -NEWMULT -{!} 4046821904541870443295997539156260461950 - S 10,52 sec (1437.1457.2) -!NEWMULT -{!} 4046821904541870443295997539156260461950 - S 17,06 sec (1437.1453.2) - -0:?n&whl'(1+!n:<1000000:?n&4350*2073384975284367439375369802:?T)&!T -NEWMULT -{!} 9019224642486998361282858638700 - S 8,93 sec (1437.1456.2) -!NEWMULT -{!} 9019224642486998361282858638700 - S 5,59 sec (1437.1456.2) - -0:?n&whl'(1+!n:<1000000:?n&43500273*384975284367439375369802:?T)&!T -NEWMULT -{!} 16746529968236245139535862955946 - S 9,51 sec (1437.1456.2) -!NEWMULT -{!} 16746529968236245139535862955946 - S 8,53 sec (1437.1456.2) - -0:?n&whl'(1+!n:<1000000:?n&384975284367439375369802*43500273:?T)&!T -NEWMULT -{!} 16746529968236245139535862955946 - S 9,12 sec (1437.1456.2) -!NEWMULT -{!} 16746529968236245139535862955946 - S 8,10 sec (1437.1456.2) - -0:?n&whl'(1+!n:<1000000:?n&38497528436743937536*980243500273:?T)&!T -NEWMULT -{!} 37736952026693231197301110947328 - S 9,38 sec (1437.1456.2) -!NEWMULT -{!} 37736952026693231197301110947328 - S 8,80 sec (1437.1454.2) - S 9,95 sec (1437.1456.2) - S 9,58 sec (1437.1453.2) - -0:?n&whl'(1+!n:<1000000:?n&3849752843674393*7536980243500273:?T)&!T -NEWMULT -{!} 29015511125132894970381018609289 - S 9,60 sec (1437.1454.2) -!NEWMULT -{!} 29015511125132894970381018609289 - S 10,86 sec (1437.1453.2) - -0:?n&whl'(1+!n:<10000000:?n&752843674393*753698024350:?T)&!T -NEWMULT -{!} 567416790034398785469550 - S 71,22 sec (1437.1457.2) -!NEWMULT -{!} 567416790034398785469550 - S 66,63 sec (1437.1453.2) - -0:?n&whl'(1+!n:<10000000:?n&7543674393*5369824350:?T)&!T -NEWMULT -{!} 40508206444002869550 - S 62,38 sec (1437.1456.2) -!NEWMULT -{!} 40508206444002869550 - S 51,77 sec (1437.1463.2) - -*/ - -#if DEBUGBRACMAT -#ifndef NDEBUG -static void printMatchState(const char* msg, matchstate s, int pos, int len) - { - Printf("\n%s pos %d len %d once %d", msg, pos, len, s.b.bonce); - Printf("\n t o p m f i"); - Printf("\n lmr %d %d %d %d %d %d", - s.b.blmr_true, s.b.blmr_once, s.b.blmr_position_once, s.b.blmr_position_max_reached, s.b.blmr_fence, s.b.blmr_pristine); - Printf("\n rmr %d %d %d %d %d %d\n", - s.b.brmr_true, s.b.brmr_once, s.b.brmr_position_once, s.b.brmr_position_max_reached, s.b.brmr_fence, s.b.brmr_pristine); - } -#endif -#endif - -static const char -fct[] = "(fct=f G T P C V I B W H J O.(T=m Z a p r R Q.!arg:(?m.?Z)&0:?R:?Q&" -"whl'(!Z:?a+?p*!m*?r+?Z&!R+!a:?R&!Q+!p*!r:?Q)&(!Q.!R+!Z))&(P=M E.!arg:(?M.?E)&" -"whl'(!E:?*(!M|!M^((#%:~<1)+?))*?+?E)&!E:0)&(G=f e r a.!arg:(?e.?f)&0:?r&whl'(" -"!e:%?a+?e&!a*!f:?a&!a+!r:?r)&!r)&(C=f r A Z M.!arg:%+%:(?+?*(?M^((#<%0:?f)+?r" -")&!M^!f:?M)*?+?|?+?*(?M^(#>%1+?)&P$(!M.!arg))*?+?|%?f+?r&!f:?A*~#%?`M*(?Z&P$(" -"!M.!r)))&!M*C$(G$(!arg.!M^-1))|!arg)&(W=n A Z M s.C$!arg:?arg:?A*((~-1:#%?n)*" -"?+?:?M)*?Z&(!n:<0&-1|1):?s&!s*!n*!A*(1+!s*!n^-1*!M+-1)*!Z|!arg)&(V=n A Z M.C$" -"!arg:?arg:?A*(#%?n*?+?:?M)*?Z&!n*!A*(1+!n^-1*!M+-1)*!Z|!arg)&(I=f v l r.!arg:" -"(?f.?v)&!v:?l_?r&I$(!f.!l)&I$(!f.!r)|!v:#|!v\017!f:0)&(O=a f e.!arg:?a*?f^(%*" -"%:?e)*?arg&!a*!f^J$(1+!e+-1)*O$!arg|!arg)&(J=t.!arg:%?t+%?arg&O$!t+(!arg:%+%&" -"J|O)$!arg|!arg)&(f=L R A Z a m z S Q r q t F h N D.(D=R Q S t x r X ax zx M." -"!arg:(?R.?Q)&!Q:?+%`(?*(~#%?`M&T$(!M.!Q):(?x.?r)&I$(!r.!M))*?)+?&N$!x:?x&sub$" -"(!R.!M.(VAR+-1*!r)*!x^-1):?S&(!x:?ax*(%+%:?X)*?zx&T$(!X^-1.!S):(?t.?S)&1+!ax*" -"!zx*(!S*!X+!t)+-1:?S|1:?x)&T$(VAR.!S):(?t.0)&N$!t*!x^-1)&!arg:(?arg.(=?N))&N$" -"!arg:?arg&(!arg:%?L*%?R&f$(!L.'$N)*f$(!R.'$N)|!arg:%?L^%?R&f$(!L.!R:~/#&'$V|'" -"$W)^J$(1+!R+-1)|J$!arg:?arg:#?+~#%?A+%?Z&!A:?a*~#%?`m*?z&T$(!m.!Z):(~0:?Q.?)&" -"!a*!z+!Q:?t:?r&!arg:?S&1:?Q&1:?F&whl'(!r:%?q*?r&N$!q:?h*(%+%:?q)&D$(!S.!q):?S" -"&!h*!F:?F&!Q*!q:?Q)&!Q+-1*!F^-1*!t:0&f$(!Q.'$N)*f$(!S.'$N)|!arg))&(B=A E M Z " -"a b e m n y z.!arg:?A*%?`M^?E*(?Z&!A*!Z:?a*%?`m^?e*(?z&!a*!z:?b*?n^!e*?y&!M+" -"!m:0))&B$(!b*(1+-1*!n+-1)^!e*!y*!M^(!E+!e))|!arg)&(H=A Z a b e z w x n m o." -"!arg:?A*(%?b+%?z:?m)*(?Z&!b:?*?a^%?e*(?&!z:?w&whl'(!w:?*!a^?*?+?w)&!w:0&!e:?+" -"#?n*(~#%@*?:?x)+(?&!z:?w&whl'(!w:?*!a^(?+#?o*(!x&(!o:WinIn) - { - WinIn = init->WinIn; - } - if(init->WinOut) - { - WinOut = init->WinOut; - } - if(init->WinFlush) - { - WinFlush = init->WinFlush; - } -#if defined PYTHONINTERFACE - if(init->Ni) - { - Ni = init->Ni; - } - if(init->Nii) - { - Nii = init->Nii; - } -#endif - } -#endif - initVariables(); - if(!init_memoryspace()) - return 0; - init_opcode(); - global_anchor = NULL; - - global_fpi = stdin; - global_fpo = stdout; - - argNode.v.fl = READY | SUCCESS; - argNode.u.lobj = O('a', 'r', 'g'); - - sjtNode.v.fl = READY | SUCCESS; - sjtNode.u.lobj = O('s', 'j', 't'); - - selfNode.v.fl = READY | SUCCESS; - selfNode.u.lobj = O('i', 't', 's'); - - SelfNode.v.fl = READY | SUCCESS; - SelfNode.u.lobj = O('I', 't', 's'); - - nilNode.v.fl = READY | SUCCESS | IDENT; - nilNode.u.lobj = 0L; - - nilNodeNotNeutral.v.fl = READY | SUCCESS; - nilNodeNotNeutral.u.lobj = 0L; - - zeroNode.v.fl = READY | SUCCESS | IDENT | QNUMBER | QNUL BITWISE_OR_SELFMATCHING; - zeroNode.u.lobj = 0L; - zeroNode.u.obj = '0'; - - zeroNodeNotNeutral.v.fl = READY | SUCCESS | QNUMBER | QNUL BITWISE_OR_SELFMATCHING; - zeroNodeNotNeutral.u.lobj = 0L; - zeroNodeNotNeutral.u.obj = '0'; - - oneNode.u.lobj = 0L; - oneNode.u.obj = '1'; - oneNode.v.fl = READY | SUCCESS | IDENT | QNUMBER BITWISE_OR_SELFMATCHING; - *(&(oneNode.u.obj) + 1) = 0; - - oneNodeNotNeutral.u.lobj = 0L; - oneNodeNotNeutral.u.obj = '1'; - oneNodeNotNeutral.v.fl = READY | SUCCESS | QNUMBER BITWISE_OR_SELFMATCHING; - *(&(oneNode.u.obj) + 1) = 0; - - minusOneNode.u.lobj = 0L; - minusOneNode.u.obj = '1'; - minusOneNode.v.fl = READY | SUCCESS | QNUMBER | MINUS BITWISE_OR_SELFMATCHING; - *(&(minusOneNode.u.obj) + 1) = 0; - - twoNode.u.lobj = 0L; - twoNode.u.obj = '2'; - twoNode.v.fl = READY | SUCCESS | QNUMBER BITWISE_OR_SELFMATCHING; - *(&(twoNode.u.obj) + 1) = 0; - - fourNode.u.lobj = 0L; - fourNode.u.obj = '4'; - fourNode.v.fl = READY | SUCCESS | QNUMBER BITWISE_OR_SELFMATCHING; - *(&(fourNode.u.obj) + 1) = 0; - - m0 = build_up(m0, "?*(%+%)^~/#>1*?", NULL); - m1 = build_up(m1, "?*(%+%)*?", NULL); - f0 = build_up(f0, "(g,k,pow" - ".(pow" - "=b,c,d,l,s,f" - ".!arg:(%?b+%?c)^?d" - "&1:?f" - "&(s" - "=!d:1&0" - "|(!f*!d*(1+!l:?l)^-1:?f)" - "*!b^!l" - "*pow$(!c^(-1+!d:?d))" - "+!s" - ")" - "&!b^!d+!c^!d+!s" - "|!arg" - ")" - "&!arg:?g*((%+%)^~/#>1:?arg)*?k" - "&!g*pow$!arg*!k)", NULL); - f1 = build_up(f1, - "((\177g,\177h,\177i).!arg:?\177g*(%?\177h+%?\177i)*", - "?arg&!\177g*!\177h*!arg+!\177g*!\177i*!arg)", NULL); - f4 = build_up(f4, "l,a,b,c,e,f" - ".(a" - "=j,g,h,i" - ".!arg:?l^(?j+?g*!l\016?h*?i+?arg)" - "&!l^(!j+!arg)*!h^(!g*!i)" - ")" - "&(e" - "=j,g,I" - ".!arg:?j+#?g*((i|-i):?I)*pi+?arg" - "&1:?l" - "&!j+(mod$(1+!g,2)+-1)*!I*pi+!arg" - ")" - "&(f" - "=j,i" - ".!arg:?j+#?l*((i|-i):?I)*pi+?arg" - "&!I^(2*!l):?l" - "&!j+!arg" - ")" - "&(b" - "=" - "(!l:(<-1|>1)&e" - "|(-1|1/2|-1/2)&f" - ")" - ":?l" - ")" - "&(c" - "=" - ".1+!arg:?arg" - "&1:?l" - "&-1+!arg" - ")" - "&(!arg:?l^(?+?*!l\016?*?+?)&a$!arg" - "|!arg" - ":e^((?+#?l*(i|-i)*pi+?&`!b" - "|?" - "*(pi|i|-i)" - "*?" - "*(?+?*(pi|i|-i)*?+?:%+%)" - "*?" - "&c:?l" - ")" - ":?arg" - ")" - "&e^!l$!arg*!l" - ")", NULL); - f5 = build_up(f5, - "l,d" - ".(d" - "=j,g,h" - ".!arg:(~1:?l)\016(?j*!l^?g*?h)&!g+!l\016(!j*!h)" - ")" - "&!arg:?l\016(?*!l^?*?)" - "&d$!arg", NULL); - - global_anchor = starttree_w(global_anchor, - "(cat=flt,sin,tay,fct,cos,out,sgn.!arg:((?flt,(?sin,?tay)|?sin&:?tay)|?flt&:?sin:" - "?tay)&(fct=.!arg:%?cos ?arg&!cos:((?out.?)|?out)&'(? ($out|($out.?)" - ") ?):(=?sgn)&(!flt:!sgn&!(glf$(=~.!sin:!sgn))&!cos|) fct$!arg|)&(:!flt:!sin&mem$!tay|(:!flt&mem$:?flt" - "|)&fct$(mem$!tay))),", - "(let=.@(ugc$!arg:(L|M) ?)&!arg),", - "(out=(.put$!arg:?arg&put$\212&!arg))," - "(flt=((e,d,m,s,f).!arg:(?arg,~<0:?d)&!arg:0|(-1*!arg:>0:?arg&-1|1):?s&" - "10\016!arg:?e+(10\016?m|0&1:?m)&(!m+1/2*1/10^!d:~<10&1+!e:?e&!m*1/10" - ":?m|)&@(div$(!m+1/2*(1/10^!d:?d),!d):" - "`%?f ?m)&str$(!s*!f (!d:~1&\256|) !m \305 !e))),", - - "(tay=((f,tot,x,fac,cnt,res,R).", - "(R=!cnt:!tot&!res|!res+(sub$(!x\017!f:?f.!x.0))*((!fac*(!cnt+1:?cnt))" - ":?fac)^-1*!x^!cnt:?res&!R)&", - "!arg:(?f,?x,?tot)&(fac=1)&(cnt=0)&((sub$(!f.!x.0)):?res)&!R)),", - - /*"(ego=(r.sub$(sub$(!arg.(sin.?r).'sin$!r).(cos.?r).'cos$!r))),", - - "(goe=((h,s).sub$(!arg.'(e^?h).", - "'(-1*(sgn$(-1+i*!h+1:?h):?s)*i*(sin.-1+!s*!h+1:?s)+(cos.!s))))),",*/ - - "(sin=(.i*(-1/2*e^(i*!arg)+1/2*e^(-i*!arg)))),", - - "(cos=(.1/2*(e^(i*!arg)+e^(-i*!arg)))),", - - "(jsn=Q R O C T H I X Y.(Q=.!arg:(,?arg)&R$!arg|!arg:(.@?arg)&I$!arg|" - "!arg:(0|(?.?)+?,)&O$!arg|!arg:(true|false|null)|!arg:/&(X$!arg|Y$(" - "!arg,20))|!arg)&(R=J S L.\333:?S&whl'(!arg:%?J ?arg&\254 Q$!J !S:?S)&" - "(!S:\254 ?S|)&\335 !S:?S&:?L&whl'(!S:%?a ?S&!a !L:?L)&str$!L)&(O=J V " - "S.!arg:(?arg,)&:?S&whl'(!arg:(@?J.?V)+?arg&!S \254 I$!J \272 Q$!V:?S)" - "&(!S:\254 ?S|)&str$(\373 !S \375))&(C=a c z.@(!arg:?a (%@:<\240:?c) " - "?z)&str$(!a (!c:\210&\334\342|!c:\212&\334\356|!c:\215&\334\362|!c:" - "\214&\334\346|!c:\211&\334\364|\334\365\260\260 d2x$(asc$!c)) C$!z)|" - "!arg)&(T=a z.@(!arg:?a \" ?z)&str$(C$!a \334\242 T$!z)|C$!arg)&(H=a z" - ".@(!arg:?a \334 ?z)&str$(T$!a \334\334 H$!z)|T$!arg)&(I=.str$(\" H$" - "!arg \"))&(X=a z d n A B D F G L x.den$!arg:?d&!d*(!arg:~<0|-1*!arg):" - "?n&(5\016!d:#%?A+?B&`(!B:0&2^!A|!B:5\016?B&2\016(!B*(den$!B:?B)):#?D&" - "!A+-1*5\016!B+-1*!D:?A&(!A:>0&2|1/5)^!A)|2\016!d:#%?A&5^!A):?F&-1+-1*" - "10\016(!d*!F):?x&!n*!F:?G&@(!G:? [?L)&whl'(!L+!x:<0&str$(0 !G):?G&1+" - "!L:?L)&@(!G:?a [!x ?z)&whl'@(!z:?z 0)&str$((!arg:<0&\255|) !a (!z:|" - "\256 !z)))&(Y=e,d,m,s,f.!arg:(?arg,~<0:?d)&!arg:0|(-1*!arg:>0:?arg&-1" - "|1):?s&10\016!arg:?e+(10\016?m|0&1:?m)&(!m+1/2*1/10^!d:~<10&1+!e:?e&" - "!m*1/10:?m|)&@(div$(!m+1/2*(1/10^!d:?d),!d):%?`f ?m)&str$(!s*!f (!d:" - "~1&\256 (@(rev$!m:? #?m)&rev$!m)|!m) E !e))&str$(Q$!arg)),", - "(sgn=(.!arg:?#%arg*%+?&sgn$!arg|!arg:<0&-1|1)),", - "(abs=(.sgn$!arg*!arg)),", - "(sub=\177e,\177x,\177v,\177F.(\177F=\177l,\177r.!arg:!\177x&!\177v|" - "!arg:%?\177l_%?\177r&(\177F$!\177l)_(\177F$!\177r)|!arg)&!arg:((" - "?\177e.?\177x.?\177v)|out$(str$((=sub$(expr.var.rep)) !arg))&get'&~`)" - "&\177F$!\177e),", - - "(MLencoding=D N M J h m R.:?N:?D&(R=? (charset.?N) ?|? (content.@(?:? " - "charset ? \275 ?N)) ?)&(M=? (~<>meta.(!R,?)|!R) ?)&(J=? (~<>head.(?," - "!M)|?&~`) ?|? (~<>head:?h.?) ?m (.!h.) ?&!m:!M)&(!arg:(@ (\277.@(?:" - "~<>XML (? encoding ? \275 ? (\242 ?N \242|\247 ?N \247) ?|?&" - "utf\255\270:?D))) ?&!D:|? (~<>html.(?,!J)|?&~`) ?|? (~<>html.?) !J)|)&(!N" - ":~|!arg:? (\241DOCTYPE.@(?:? html ?)) ?&utf\255\270|!D)),", - "(nestML=a L B s e x.:?L&whl'(!arg:%?a ?arg&!a !L:?L)&!L:?arg&:?L:?B:" - "?s&whl'(!arg:%?a ?arg&(!a:(.?e.)&(!L.) !B:?B&:?L&!e !s:?s|(!a:(?e.?,?" - ")&!a|!a:(?e.?x)&(!s:!e ?s&(!e.!x,!L) (!B:(%?L.) ?B&)|!a)|!a) !L:?L))&" - "!L),", - "(toML=O d t g l \246 w \242 \247 H G S D E F I U x.:?O&0:?x&chr$\261\262\267" - ":?D&(d=a.whl'(!arg:%?a ?arg&!a !O:?O))&'(a c n.@(!arg:?a (>%@($D) ?:" - "?arg))&(@(!arg:(%?c&utf$!c:?n) ?arg)|@(!arg:(%?c&asc$!c:?n) ?arg))&!a" - " \246\243 !n \273 S$!arg|!arg):(=?S)&'(a c n.@(!arg:?a (>%@($D) ?:" - "?arg))&(@(!arg:(%?c&utf$!c:?n) ?arg)&(!n:>\262\265\265&!a \246\243 !n" - " \273 I$!arg|!a chr$!n I$!arg)|!a !arg)|!arg):(=?I)&'(a c n.@(!arg:?a" - " (>%@($D) ?:?arg))&(@(!arg:(%?c&utf$!c:?n) ?)&!a !arg|@(!arg:(%?c&asc" - "$!c:?n) ?arg)&!a chu$!n U$!arg)|!arg):(=?U)&MLencoding$!arg:(" - "~<>utf\255\270&U:?F|~<>iso\255\270\270\265\271\255\261&I:?F|?&S:?F)&'" - "($F)$!a:(=?H)&'($F)$!arg:(=?G)&'(a b.@(!arg:?a \246 ?arg)&$H " - "\246amp\273 \246$!arg|$G):(=?\246)&'(a b.@(!arg:?a ()$D ?arg)&\246$!a" - " (@(!arg:%?b ?arg)&!b) E$!arg|\246$!arg):(=?E)&'(a.@(!arg:?a \274 " - "?arg)&E$!a \246lt\273 l$!arg|E$!arg):(=?l)&(g=a.@(!arg:?a \276 ?arg)&" - "l$!a \246gt\273 g$!arg|l$!arg)&(\242=a.@(!arg:?a \242 ?arg)&g$!a " - "\246quot\273 \242$!arg|g$!arg)&(\247=a.@(!arg:?a \247 ?arg)&\242$!a " - "\246apos\273 \247$!arg|\242$!arg)&(t=a v.!arg:(?a.?v) ?arg&\240 g$!a " - "\275\242 \247$!v \242 t$!arg|)&(!arg:? (html|HTML.?) ?&(Q=!C:&low$!A:" - "(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|" - "source|track|wbr))|(Q=!C:))&'(r A B C T.whl'(!arg:%?r ?arg&(!r:(?A." - "?B)&(!B:(?T,?C)&($Q&d$(\274 !A t$!T \240\257\276)|d$(\274 !A t$!T " - "\276)&(!A:(~<>script|~<>style)&d$!C|w$!C)&d$(\274\257 !A \276))|!A:(&" - "!B:(?B.)&d$(\274\257 g$!B \276)|\241&d$(\274\241 !F$!B \276)|" - "\241\255\255&d$(\274\241\255\255 !F$!B \255\255\276)|\277&d$(\274\277" - " (=.@(!arg:(?arg \277|xml ?:?arg))&1:?x&!arg \277|!arg (!x:1&\277|))$" - "(!F$!B) \276)|\241\333CDATA\333&d$(\274\241\333CDATA\333 !F$!B " - "\335\335\276)|\241DOCTYPE&d$(\274\241DOCTYPE !F$!B \276)|?&d$(\274 !A" - " t$!B \276)))|d$(g$!r)))):(=?w)&w$!arg&str$((=a L.:?L&whl'(!arg:%?a " - "?arg&!a !L:?L)&!L)$!O)),", - fct, - NULL); - -#if JMP - if(setjmp(jumper) != 0) - return; -#endif - global_anchor = eval(global_anchor); - stringEval("(v=\"Bracmat version " VERSION ", build " BUILD " (" DATUM ")\")", NULL, &err); - return 1; - } - -void endProc(void) - { - int err; - static int called = 0; - if(called) - return; - called = 1; - stringEval("cat$:? CloseDown ? & CloseDown$ | ", NULL, &err); - if(err) - errorprintf("Error executing CloseDown\n"); - } - -/* main - the text-mode front end for bracmat */ - -#if !_BRACMATEMBEDDED - -#if defined __EMSCRIPTEN__ -int oneShot(char* inp) - { - int err; - char* mainLoopExpression; - const char* ret; - char* argv[1] = { NULL }; - argv[0] = inp; - ARGV = argv; - ARGC = 1; - mainLoopExpression = "out$get$(arg$0,MEM)"; - stringEval(mainLoopExpression, &ret, &err); - return (int)STRTOL(ret, 0, 10); - } -#endif - -int mainLoop(int argc, char* argv[]) - { - int err; - char* mainLoopExpression; - const char* ret = 0; -#if defined __EMSCRIPTEN__ - if(argc == 2) - { /* to get here, e.g.: ./bracmat out$hello */ - return oneShot(argv[1]); - } - else -#endif - if(argc > 1) - { /* to get here, e.g.: ./bracmat "you:?a" "out$(hello !a)" */ - ARGC = argc; - ARGV = argv; - mainLoopExpression = "arg$&whl'(get$(arg$,MEM):?\"?...@#$*~%!\")&!\"?...@#$*~%!\""; - stringEval(mainLoopExpression, &ret, &err); - return ret ? (int)STRTOL(ret, 0, 10) : -1; - } - else - { - mainLoopExpression = - "(w=\"11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\\n" - "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\\n" - "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\\n" - "PROVIDE THE PROGRAM \\\"AS IS\\\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\\n" - "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\\n" - "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\\n" - "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\\n" - "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\\n" - "REPAIR OR CORRECTION.\\n\")&" - "(c=\"12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\\n" - "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\\n" - "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\\n" - "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\\n" - "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\\n" - "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\\n" - "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\\n" - "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BONE ADVISED OF THE\\n" - "POSSIBILITY OF SUCH DAMAGES.\\n\")&" - "out$!v&" - "out$\"Copyright (C) 2002 Bart Jongejan\\n" - "Bracmat comes with ABSOLUTELY NO WARRANTY; for details type `!w'.\\n" - "This is free software, and you are welcome to redistribute it\\n" - "under certain conditions; type `!c' for details.\\n\\n" - "\\n\\n{?} get$help { tutorial }\\n{?} ) { stop }\"&" - "(main=put$\"{?} \"&clk$():?SEC&((get':?!(=):(|?&clk$+-1*!SEC:?SEC&" - "put$\"{!} \"&put$!&put$(\"\\n S \" str$(div$(!SEC,1) \",\" (div$(mod$(" - "!SEC*100,100),1):?SEC&!SEC:<10&0|) !SEC) sec))|put$\"\\n F\")|" - "put$\"\\n I\")&" - -#if SHOWMAXALLOCATED - - "out$str$(\" \" bez')&" -#else - "out$&" -#endif - - "!main)&!main"; - stringEval(mainLoopExpression, NULL, &err); - } - return 0; - } - -#if EMSCRIPTEN_HTML -int main() - { - int ret = 0; - errorStream = stderr; - if(!startProc()) - return -1; - return ret; - } -#else -int main(int argc, char* argv[]) - { - int ret; /* numerical result of mainLoop becomes exit code. - If out of integer range or not numerical: 0*/ - char* p = argv[0] + strlen(argv[0]); -#if 0 - char s1[] = { 160,0 }; - char s2[] = { 32,0 }; -#ifdef _WIN64 /* Microsoft 64 bit */ - printf("_WIN64\n"); -#else /* 32 bit and gcc 64 bit */ - printf("!_WIN64\n"); -#endif - printf("sizeof(char *) " LONGU "\n", (ULONG)sizeof(char*)); - printf("sizeof(LONG) " LONGU "\n", (ULONG)sizeof(LONG)); - printf("sizeof(ULONG) " LONGU "\n", (ULONG)sizeof(ULONG)); - printf("sizeof(size_t) " LONGU "\n", (ULONG)sizeof(size_t)); - printf("sizeof(sk) " LONGU "\n", (ULONG)sizeof(sk)); - printf("sizeof(tFlags) " LONGU "\n", (ULONG)sizeof(tFlags)); - printf("WORD32 %d\n", WORD32); - printf("RADIX " LONGD "\n", (LONG)RADIX); - printf("RADIX2 " LONGD "\n", (LONG)RADIX2); - printf("TEN_LOG_RADIX " LONGD "\n", (LONG)TEN_LOG_RADIX); - printf("HEADROOM " LONGD "\n", (LONG)HEADROOM); - printf("strcmp:%d\n", strcmp(s1, s2)); - return 0; -#endif -#ifndef NDEBUG - { - LONG radix, ten_log_radix; -#if defined _WIN64 - assert(HEADROOM * RADIX2 < LLONG_MAX); -#else - assert(HEADROOM * RADIX2 < LONG_MAX); -#endif - for(radix = 1, ten_log_radix = 1; ten_log_radix <= TEN_LOG_RADIX; radix *= 10, ++ten_log_radix) - ; - assert(RADIX == radix); - } -#endif - assert(sizeof(tFlags) == sizeof(ULONG)); -#if !defined __EMSCRIPTEN__ - while(--p >= argv[0]) - if(*p == '\\' || *p == '/') - { - ++p; -#if !defined NO_FOPEN - targetPath = (char*)malloc(p - argv[0] + 1); - if(targetPath) - { - strncpy(targetPath, argv[0], p - argv[0]); - targetPath[p - argv[0]] = '\0'; - } -#endif - break; - } -#endif - - errorStream = stderr; - if(!startProc()) - return -1; - ret = mainLoop(argc, argv); - endProc();/* to get here, eg: {?} main=out$bye! */ -#if !defined NO_FOPEN - if(targetPath) - free(targetPath); -#endif - return ret; - } -#endif -#endif /*#if !_BRACMATEMBEDDED*/ - -/* End of potu.c */