// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- // // The contents of this file are subject to the Netscape Public // License Version 1.1 (the "License"); you may not use this file // except in compliance with the License. You may obtain a copy of // the License at http://www.mozilla.org/NPL/ // // Software distributed under the License is distributed on an "AS // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr // implied. See the License for the specific language governing // rights and limitations under the License. // // The Original Code is the JavaScript 2 Prototype. // // The Initial Developer of the Original Code is Netscape // Communications Corporation. Portions created by Netscape are // Copyright (C) 1998 Netscape Communications Corporation. All // Rights Reserved. #include #include #include "utilities.h" #ifdef WIN32 #include #endif #ifdef XP_MAC #include #include #endif namespace JS = JavaScript; // // Assertions // #ifdef DEBUG #ifdef XP_MAC // PStrFromCStr converts the source C string to a destination // pascal string as it copies. The dest string will // be truncated to fit into an Str255 if necessary. // If the C String pointer is NULL, the pascal string's length is // set to zero. static void PStrFromCStr(const char* src, Str255 &dst) { int length = 0; if (src) { char *p = reinterpret_cast(&dst[1]); int spaceLeft = 255; char ch; while ((ch = *src++) != 0) { *p++ = ch; if (--spaceLeft == 0) break; } length = 255 - spaceLeft; } dst[0] = (uchar)length; } static void jsdebugstr(const char *debuggerMsg) { Str255 pStr; PStrFromCStr(debuggerMsg, pStr); DebugStr(pStr); } static void dprintf(const char *format, ...) { std::va_list ap; char buffer[4096]; va_start(ap, format); std::vsprintf(buffer, format, ap); va_end(ap); jsdebugstr(buffer); } #endif /* XP_MAC */ void JS::Assert(const char *s, const char *file, int line) { #if defined(XP_UNIX) || defined(XP_OS2) fprintf(std::stderr, "Assertion failure: %s, at %s:%d\n", s, file, line); #endif #ifdef XP_MAC dprintf("Assertion failure: %s, at %s:%d\n", s, file, line); #endif #ifdef WIN32 DebugBreak(); #endif #ifndef XP_MAC abort(); #endif } #endif /* DEBUG */ // // Bit manipulation // // Return lg2 of the least power of 2 greater than or equal to n. // Return 0 if n is 0 or 1. uint JS::ceilingLog2(uint32 n) { uint log2 = 0; if (n & (n-1)) log2++; if (n >> 16) log2 += 16, n >>= 16; if (n >> 8) log2 += 8, n >>= 8; if (n >> 4) log2 += 4, n >>= 4; if (n >> 2) log2 += 2, n >>= 2; if (n >> 1) log2++; return log2; } // Return lg2 of the greatest power of 2 less than or equal to n. // This really just finds the highest set bit in the word. // Return 0 if n is 0 or 1. uint JS::floorLog2(uint32 n) { uint log2 = 0; if (n >> 16) log2 += 16, n >>= 16; if (n >> 8) log2 += 8, n >>= 8; if (n >> 4) log2 += 4, n >>= 4; if (n >> 2) log2 += 2, n >>= 2; if (n >> 1) log2++; return log2; } // // Unicode UTF-16 characters and strings // #ifdef _WIN32 // Microsoft VC6 bug: String constructor and append limited to char16 iterators // Return a String containing the characters of the null-terminated C string cstr // (without the trailing null). JS::String JS::widenCString(const char *cstr) { size_t len = strlen(cstr); String s(len, uni::null); std::transform(cstr, cstr+len, s.begin(), widen); return s; } // Widen and append length characters starting at chars to the end of str. void JS::appendChars(String &str, const char *chars, size_t length) { String::size_type strLen = str.size(); str.append(length, uni::null); std::transform(chars, chars+length, str.begin()+strLen, widen); } // Widen and insert length characters starting at chars into the given position of str. void JS::insertChars(String &str, String::size_type pos, const char *chars, size_t length) { str.insert(pos, length, uni::null); std::transform(chars, chars+length, str.begin()+pos, widen); } #endif // Widen and insert the null-terminated string cstr into the given position of str. void JS::insertChars(String &str, String::size_type pos, const char *cstr) { insertChars(str, pos, cstr, strlen(cstr)); } // Widen and append the null-terminated string cstr to the end of str. // Return str. JS::String &JS::operator+=(String &str, const char *cstr) { appendChars(str, cstr, strlen(cstr)); return str; } // Return the concatenation of str and the null-terminated string cstr. JS::String JS::operator+(const String &str, const char *cstr) { return str + widenCString(cstr); } // Return the concatenation of the null-terminated string cstr and str. JS::String JS::operator+(const char *cstr, const String &str) { String s = widenCString(cstr); s += str; return s; } // From java.lang.Character: // // The character properties are currently encoded into 32 bits in the // following manner: // // 10 bits signed offset used for converting case // 1 bit if 1, adding the signed offset converts the character to // lowercase // 1 bit if 1, subtracting the signed offset converts the character to // uppercase // 1 bit if 1, character has a titlecase equivalent (possibly itself) // 3 bits 0 May not be part of an identifier // 1 Format control // 2 May start or continue a JS identifier (includes $ and _) // 3 May continue a JS identifier // 4 Behaves like a white space character (but not line break) // 5 Behaves like a line break character // 2 bits 0 this character has no numeric property // 1 adding the digit offset to the character code and then // masking with 0x1F will produce the desired numeric value // 2 this character has a "strange" numeric value // 3 a JS supradecimal digit: adding the digit offset to the // character code, then masking with 0x1F, then adding 10 // will produce the desired numeric value // 5 bits digit offset // 4 bits reserved for future use // 5 bits character type // The X table has 1024 entries for a total of 1024 bytes. const uint8 JS::CharInfo::x[] = { 0, 1, 2, 3, 4, 5, 6, 7, // 0x0000 8, 9, 10, 11, 12, 13, 14, 15, // 0x0200 16, 17, 18, 19, 20, 21, 22, 23, // 0x0400 24, 25, 26, 27, 28, 28, 28, 28, // 0x0600 28, 28, 28, 28, 29, 30, 31, 32, // 0x0800 33, 34, 35, 36, 37, 38, 39, 40, // 0x0A00 41, 42, 43, 44, 45, 46, 28, 28, // 0x0C00 47, 48, 49, 50, 51, 52, 53, 28, // 0x0E00 28, 28, 54, 55, 56, 57, 58, 59, // 0x1000 28, 28, 28, 28, 28, 28, 28, 28, // 0x1200 28, 28, 28, 28, 28, 28, 28, 28, // 0x1400 28, 28, 28, 28, 28, 28, 28, 28, // 0x1600 28, 28, 28, 28, 28, 28, 28, 28, // 0x1800 28, 28, 28, 28, 28, 28, 28, 28, // 0x1A00 28, 28, 28, 28, 28, 28, 28, 28, // 0x1C00 60, 60, 61, 62, 63, 64, 65, 66, // 0x1E00 67, 68, 69, 70, 71, 72, 73, 74, // 0x2000 75, 75, 75, 76, 77, 78, 28, 28, // 0x2200 79, 80, 81, 82, 83, 83, 84, 85, // 0x2400 86, 85, 28, 28, 87, 88, 89, 28, // 0x2600 28, 28, 28, 28, 28, 28, 28, 28, // 0x2800 28, 28, 28, 28, 28, 28, 28, 28, // 0x2A00 28, 28, 28, 28, 28, 28, 28, 28, // 0x2C00 28, 28, 28, 28, 28, 28, 28, 28, // 0x2E00 90, 91, 92, 93, 94, 56, 95, 28, // 0x3000 96, 97, 98, 99, 83, 100, 83, 101, // 0x3200 28, 28, 28, 28, 28, 28, 28, 28, // 0x3400 28, 28, 28, 28, 28, 28, 28, 28, // 0x3600 28, 28, 28, 28, 28, 28, 28, 28, // 0x3800 28, 28, 28, 28, 28, 28, 28, 28, // 0x3A00 28, 28, 28, 28, 28, 28, 28, 28, // 0x3C00 28, 28, 28, 28, 28, 28, 28, 28, // 0x3E00 28, 28, 28, 28, 28, 28, 28, 28, // 0x4000 28, 28, 28, 28, 28, 28, 28, 28, // 0x4200 28, 28, 28, 28, 28, 28, 28, 28, // 0x4400 28, 28, 28, 28, 28, 28, 28, 28, // 0x4600 28, 28, 28, 28, 28, 28, 28, 28, // 0x4800 28, 28, 28, 28, 28, 28, 28, 28, // 0x4A00 28, 28, 28, 28, 28, 28, 28, 28, // 0x4C00 56, 56, 56, 56, 56, 56, 56, 56, // 0x4E00 56, 56, 56, 56, 56, 56, 56, 56, // 0x5000 56, 56, 56, 56, 56, 56, 56, 56, // 0x5200 56, 56, 56, 56, 56, 56, 56, 56, // 0x5400 56, 56, 56, 56, 56, 56, 56, 56, // 0x5600 56, 56, 56, 56, 56, 56, 56, 56, // 0x5800 56, 56, 56, 56, 56, 56, 56, 56, // 0x5A00 56, 56, 56, 56, 56, 56, 56, 56, // 0x5C00 56, 56, 56, 56, 56, 56, 56, 56, // 0x5E00 56, 56, 56, 56, 56, 56, 56, 56, // 0x6000 56, 56, 56, 56, 56, 56, 56, 56, // 0x6200 56, 56, 56, 56, 56, 56, 56, 56, // 0x6400 56, 56, 56, 56, 56, 56, 56, 56, // 0x6600 56, 56, 56, 56, 56, 56, 56, 56, // 0x6800 56, 56, 56, 56, 56, 56, 56, 56, // 0x6A00 56, 56, 56, 56, 56, 56, 56, 56, // 0x6C00 56, 56, 56, 56, 56, 56, 56, 56, // 0x6E00 56, 56, 56, 56, 56, 56, 56, 56, // 0x7000 56, 56, 56, 56, 56, 56, 56, 56, // 0x7200 56, 56, 56, 56, 56, 56, 56, 56, // 0x7400 56, 56, 56, 56, 56, 56, 56, 56, // 0x7600 56, 56, 56, 56, 56, 56, 56, 56, // 0x7800 56, 56, 56, 56, 56, 56, 56, 56, // 0x7A00 56, 56, 56, 56, 56, 56, 56, 56, // 0x7C00 56, 56, 56, 56, 56, 56, 56, 56, // 0x7E00 56, 56, 56, 56, 56, 56, 56, 56, // 0x8000 56, 56, 56, 56, 56, 56, 56, 56, // 0x8200 56, 56, 56, 56, 56, 56, 56, 56, // 0x8400 56, 56, 56, 56, 56, 56, 56, 56, // 0x8600 56, 56, 56, 56, 56, 56, 56, 56, // 0x8800 56, 56, 56, 56, 56, 56, 56, 56, // 0x8A00 56, 56, 56, 56, 56, 56, 56, 56, // 0x8C00 56, 56, 56, 56, 56, 56, 56, 56, // 0x8E00 56, 56, 56, 56, 56, 56, 56, 56, // 0x9000 56, 56, 56, 56, 56, 56, 56, 56, // 0x9200 56, 56, 56, 56, 56, 56, 56, 56, // 0x9400 56, 56, 56, 56, 56, 56, 56, 56, // 0x9600 56, 56, 56, 56, 56, 56, 56, 56, // 0x9800 56, 56, 56, 56, 56, 56, 56, 56, // 0x9A00 56, 56, 56, 56, 56, 56, 56, 56, // 0x9C00 56, 56, 56, 56, 56, 56, 102, 28, // 0x9E00 28, 28, 28, 28, 28, 28, 28, 28, // 0xA000 28, 28, 28, 28, 28, 28, 28, 28, // 0xA200 28, 28, 28, 28, 28, 28, 28, 28, // 0xA400 28, 28, 28, 28, 28, 28, 28, 28, // 0xA600 28, 28, 28, 28, 28, 28, 28, 28, // 0xA800 28, 28, 28, 28, 28, 28, 28, 28, // 0xAA00 56, 56, 56, 56, 56, 56, 56, 56, // 0xAC00 56, 56, 56, 56, 56, 56, 56, 56, // 0xAE00 56, 56, 56, 56, 56, 56, 56, 56, // 0xB000 56, 56, 56, 56, 56, 56, 56, 56, // 0xB200 56, 56, 56, 56, 56, 56, 56, 56, // 0xB400 56, 56, 56, 56, 56, 56, 56, 56, // 0xB600 56, 56, 56, 56, 56, 56, 56, 56, // 0xB800 56, 56, 56, 56, 56, 56, 56, 56, // 0xBA00 56, 56, 56, 56, 56, 56, 56, 56, // 0xBC00 56, 56, 56, 56, 56, 56, 56, 56, // 0xBE00 56, 56, 56, 56, 56, 56, 56, 56, // 0xC000 56, 56, 56, 56, 56, 56, 56, 56, // 0xC200 56, 56, 56, 56, 56, 56, 56, 56, // 0xC400 56, 56, 56, 56, 56, 56, 56, 56, // 0xC600 56, 56, 56, 56, 56, 56, 56, 56, // 0xC800 56, 56, 56, 56, 56, 56, 56, 56, // 0xCA00 56, 56, 56, 56, 56, 56, 56, 56, // 0xCC00 56, 56, 56, 56, 56, 56, 56, 56, // 0xCE00 56, 56, 56, 56, 56, 56, 56, 56, // 0xD000 56, 56, 56, 56, 56, 56, 56, 56, // 0xD200 56, 56, 56, 56, 56, 56, 56, 56, // 0xD400 56, 56, 56, 56, 56, 56, 103, 28, // 0xD600 104, 104, 104, 104, 104, 104, 104, 104, // 0xD800 104, 104, 104, 104, 104, 104, 104, 104, // 0xDA00 104, 104, 104, 104, 104, 104, 104, 104, // 0xDC00 104, 104, 104, 104, 104, 104, 104, 104, // 0xDE00 105, 105, 105, 105, 105, 105, 105, 105, // 0xE000 105, 105, 105, 105, 105, 105, 105, 105, // 0xE200 105, 105, 105, 105, 105, 105, 105, 105, // 0xE400 105, 105, 105, 105, 105, 105, 105, 105, // 0xE600 105, 105, 105, 105, 105, 105, 105, 105, // 0xE800 105, 105, 105, 105, 105, 105, 105, 105, // 0xEA00 105, 105, 105, 105, 105, 105, 105, 105, // 0xEC00 105, 105, 105, 105, 105, 105, 105, 105, // 0xEE00 105, 105, 105, 105, 105, 105, 105, 105, // 0xF000 105, 105, 105, 105, 105, 105, 105, 105, // 0xF200 105, 105, 105, 105, 105, 105, 105, 105, // 0xF400 105, 105, 105, 105, 105, 105, 105, 105, // 0xF600 105, 105, 105, 105, 56, 56, 56, 56, // 0xF800 106, 28, 28, 28, 107, 108, 109, 110, // 0xFA00 56, 56, 56, 56, 111, 112, 113, 114, // 0xFC00 115, 116, 56, 117, 118, 119, 120, 121 // 0xFE00 }; // The Y table has 7808 entries for a total of 7808 bytes. const uint8 JS::CharInfo::y[] = { 0, 0, 0, 0, 0, 0, 0, 0, // 0 0, 1, 14, 1, 1, 14, 0, 0, // 0 0, 0, 0, 0, 0, 0, 0, 0, // 0 0, 0, 0, 0, 0, 0, 0, 0, // 0 2, 3, 3, 3, 4, 3, 3, 3, // 0 5, 6, 3, 7, 3, 8, 3, 3, // 0 9, 9, 9, 9, 9, 9, 9, 9, // 0 9, 9, 3, 3, 7, 7, 7, 3, // 0 3, 10, 10, 10, 10, 10, 10, 10, // 1 10, 10, 10, 10, 10, 10, 10, 10, // 1 10, 10, 10, 10, 10, 10, 10, 10, // 1 10, 10, 10, 5, 3, 6, 11, 12, // 1 11, 13, 13, 13, 13, 13, 13, 13, // 1 13, 13, 13, 13, 13, 13, 13, 13, // 1 13, 13, 13, 13, 13, 13, 13, 13, // 1 13, 13, 13, 5, 7, 6, 7, 0, // 1 0, 0, 0, 0, 0, 0, 0, 0, // 2 0, 0, 0, 0, 0, 0, 0, 0, // 2 0, 0, 0, 0, 0, 0, 0, 0, // 2 0, 0, 0, 0, 0, 0, 0, 0, // 2 2, 3, 4, 4, 4, 4, 15, 15, // 2 11, 15, 16, 5, 7, 8, 15, 11, // 2 15, 7, 17, 17, 11, 16, 15, 3, // 2 11, 18, 16, 6, 19, 19, 19, 3, // 2 20, 20, 20, 20, 20, 20, 20, 20, // 3 20, 20, 20, 20, 20, 20, 20, 20, // 3 20, 20, 20, 20, 20, 20, 20, 7, // 3 20, 20, 20, 20, 20, 20, 20, 16, // 3 21, 21, 21, 21, 21, 21, 21, 21, // 3 21, 21, 21, 21, 21, 21, 21, 21, // 3 21, 21, 21, 21, 21, 21, 21, 7, // 3 21, 21, 21, 21, 21, 21, 21, 22, // 3 23, 24, 23, 24, 23, 24, 23, 24, // 4 23, 24, 23, 24, 23, 24, 23, 24, // 4 23, 24, 23, 24, 23, 24, 23, 24, // 4 23, 24, 23, 24, 23, 24, 23, 24, // 4 23, 24, 23, 24, 23, 24, 23, 24, // 4 23, 24, 23, 24, 23, 24, 23, 24, // 4 25, 26, 23, 24, 23, 24, 23, 24, // 4 16, 23, 24, 23, 24, 23, 24, 23, // 4 24, 23, 24, 23, 24, 23, 24, 23, // 5 24, 16, 23, 24, 23, 24, 23, 24, // 5 23, 24, 23, 24, 23, 24, 23, 24, // 5 23, 24, 23, 24, 23, 24, 23, 24, // 5 23, 24, 23, 24, 23, 24, 23, 24, // 5 23, 24, 23, 24, 23, 24, 23, 24, // 5 23, 24, 23, 24, 23, 24, 23, 24, // 5 27, 23, 24, 23, 24, 23, 24, 28, // 5 16, 29, 23, 24, 23, 24, 30, 23, // 6 24, 31, 31, 23, 24, 16, 32, 32, // 6 33, 23, 24, 31, 34, 16, 35, 36, // 6 23, 24, 16, 16, 35, 37, 16, 38, // 6 23, 24, 23, 24, 23, 24, 38, 23, // 6 24, 39, 40, 16, 23, 24, 39, 23, // 6 24, 41, 41, 23, 24, 23, 24, 42, // 6 23, 24, 16, 40, 23, 24, 40, 40, // 6 40, 40, 40, 40, 43, 44, 45, 43, // 7 44, 45, 43, 44, 45, 23, 24, 23, // 7 24, 23, 24, 23, 24, 23, 24, 23, // 7 24, 23, 24, 23, 24, 16, 23, 24, // 7 23, 24, 23, 24, 23, 24, 23, 24, // 7 23, 24, 23, 24, 23, 24, 23, 24, // 7 16, 43, 44, 45, 23, 24, 46, 46, // 7 46, 46, 23, 24, 23, 24, 23, 24, // 7 23, 24, 23, 24, 23, 24, 23, 24, // 8 23, 24, 23, 24, 23, 24, 23, 24, // 8 23, 24, 23, 24, 23, 24, 23, 24, // 8 46, 46, 46, 46, 46, 46, 46, 46, // 8 46, 46, 46, 46, 46, 46, 46, 46, // 8 46, 46, 46, 46, 46, 46, 46, 46, // 8 46, 46, 46, 46, 46, 46, 46, 46, // 8 46, 46, 46, 46, 46, 46, 46, 46, // 8 46, 46, 46, 46, 46, 46, 46, 46, // 9 46, 46, 46, 46, 46, 46, 46, 46, // 9 16, 16, 16, 47, 48, 16, 49, 49, // 9 50, 50, 16, 51, 16, 16, 16, 16, // 9 49, 16, 16, 52, 16, 16, 16, 16, // 9 53, 54, 16, 16, 16, 16, 16, 54, // 9 16, 16, 55, 16, 16, 16, 16, 16, // 9 16, 16, 16, 16, 16, 16, 16, 16, // 9 16, 16, 16, 56, 16, 16, 16, 16, // 10 56, 16, 57, 57, 16, 16, 16, 16, // 10 16, 16, 58, 16, 16, 16, 16, 16, // 10 16, 16, 16, 16, 16, 16, 16, 16, // 10 16, 16, 16, 16, 16, 16, 16, 16, // 10 16, 46, 46, 46, 46, 46, 46, 46, // 10 59, 59, 59, 59, 59, 59, 59, 59, // 10 59, 11, 11, 59, 59, 59, 59, 59, // 10 59, 59, 11, 11, 11, 11, 11, 11, // 11 11, 11, 11, 11, 11, 11, 11, 11, // 11 59, 59, 11, 11, 11, 11, 11, 11, // 11 11, 11, 11, 11, 11, 11, 11, 46, // 11 59, 59, 59, 59, 59, 11, 11, 11, // 11 11, 11, 46, 46, 46, 46, 46, 46, // 11 46, 46, 46, 46, 46, 46, 46, 46, // 11 46, 46, 46, 46, 46, 46, 46, 46, // 11 60, 60, 60, 60, 60, 60, 60, 60, // 12 60, 60, 60, 60, 60, 60, 60, 60, // 12 60, 60, 60, 60, 60, 60, 60, 60, // 12 60, 60, 60, 60, 60, 60, 60, 60, // 12 60, 60, 60, 60, 60, 60, 60, 60, // 12 60, 60, 60, 60, 60, 60, 60, 60, // 12 60, 60, 60, 60, 60, 60, 60, 60, // 12 60, 60, 60, 60, 60, 60, 60, 60, // 12 60, 60, 60, 60, 60, 60, 46, 46, // 13 46, 46, 46, 46, 46, 46, 46, 46, // 13 46, 46, 46, 46, 46, 46, 46, 46, // 13 46, 46, 46, 46, 46, 46, 46, 46, // 13 60, 60, 46, 46, 46, 46, 46, 46, // 13 46, 46, 46, 46, 46, 46, 46, 46, // 13 46, 46, 46, 46, 3, 3, 46, 46, // 13 46, 46, 59, 46, 46, 46, 3, 46, // 13 46, 46, 46, 46, 11, 11, 61, 3, // 14 62, 62, 62, 46, 63, 46, 64, 64, // 14 16, 20, 20, 20, 20, 20, 20, 20, // 14 20, 20, 20, 20, 20, 20, 20, 20, // 14 20, 20, 46, 20, 20, 20, 20, 20, // 14 20, 20, 20, 20, 65, 66, 66, 66, // 14 16, 21, 21, 21, 21, 21, 21, 21, // 14 21, 21, 21, 21, 21, 21, 21, 21, // 14 21, 21, 16, 21, 21, 21, 21, 21, // 15 21, 21, 21, 21, 67, 68, 68, 46, // 15 69, 70, 38, 38, 38, 71, 72, 46, // 15 46, 46, 38, 46, 38, 46, 38, 46, // 15 38, 46, 23, 24, 23, 24, 23, 24, // 15 23, 24, 23, 24, 23, 24, 23, 24, // 15 73, 74, 16, 40, 46, 46, 46, 46, // 15 46, 46, 46, 46, 46, 46, 46, 46, // 15 46, 75, 75, 75, 75, 75, 75, 75, // 16 75, 75, 75, 75, 75, 46, 75, 75, // 16 20, 20, 20, 20, 20, 20, 20, 20, // 16 20, 20, 20, 20, 20, 20, 20, 20, // 16 20, 20, 20, 20, 20, 20, 20, 20, // 16 20, 20, 20, 20, 20, 20, 20, 20, // 16 21, 21, 21, 21, 21, 21, 21, 21, // 16 21, 21, 21, 21, 21, 21, 21, 21, // 16 21, 21, 21, 21, 21, 21, 21, 21, // 17 21, 21, 21, 21, 21, 21, 21, 21, // 17 46, 74, 74, 74, 74, 74, 74, 74, // 17 74, 74, 74, 74, 74, 46, 74, 74, // 17 23, 24, 23, 24, 23, 24, 23, 24, // 17 23, 24, 23, 24, 23, 24, 23, 24, // 17 23, 24, 23, 24, 23, 24, 23, 24, // 17 23, 24, 23, 24, 23, 24, 23, 24, // 17 23, 24, 15, 60, 60, 60, 60, 46, // 18 46, 46, 46, 46, 46, 46, 46, 46, // 18 23, 24, 23, 24, 23, 24, 23, 24, // 18 23, 24, 23, 24, 23, 24, 23, 24, // 18 23, 24, 23, 24, 23, 24, 23, 24, // 18 23, 24, 23, 24, 23, 24, 23, 24, // 18 23, 24, 23, 24, 23, 24, 23, 24, // 18 23, 24, 23, 24, 23, 24, 23, 24, // 18 40, 23, 24, 23, 24, 46, 46, 23, // 19 24, 46, 46, 23, 24, 46, 46, 46, // 19 23, 24, 23, 24, 23, 24, 23, 24, // 19 23, 24, 23, 24, 23, 24, 23, 24, // 19 23, 24, 23, 24, 23, 24, 23, 24, // 19 23, 24, 23, 24, 46, 46, 23, 24, // 19 23, 24, 23, 24, 23, 24, 46, 46, // 19 23, 24, 46, 46, 46, 46, 46, 46, // 19 46, 46, 46, 46, 46, 46, 46, 46, // 20 46, 46, 46, 46, 46, 46, 46, 46, // 20 46, 46, 46, 46, 46, 46, 46, 46, // 20 46, 46, 46, 46, 46, 46, 46, 46, // 20 46, 46, 46, 46, 46, 46, 46, 46, // 20 46, 46, 46, 46, 46, 46, 46, 46, // 20 46, 76, 76, 76, 76, 76, 76, 76, // 20 76, 76, 76, 76, 76, 76, 76, 76, // 20 76, 76, 76, 76, 76, 76, 76, 76, // 21 76, 76, 76, 76, 76, 76, 76, 76, // 21 76, 76, 76, 76, 76, 76, 76, 46, // 21 46, 59, 3, 3, 3, 3, 3, 3, // 21 46, 77, 77, 77, 77, 77, 77, 77, // 21 77, 77, 77, 77, 77, 77, 77, 77, // 21 77, 77, 77, 77, 77, 77, 77, 77, // 21 77, 77, 77, 77, 77, 77, 77, 77, // 21 77, 77, 77, 77, 77, 77, 77, 16, // 22 46, 3, 46, 46, 46, 46, 46, 46, // 22 46, 60, 60, 60, 60, 60, 60, 60, // 22 60, 60, 60, 60, 60, 60, 60, 60, // 22 60, 60, 46, 60, 60, 60, 60, 60, // 22 60, 60, 60, 60, 60, 60, 60, 60, // 22 60, 60, 60, 60, 60, 60, 60, 60, // 22 60, 60, 46, 60, 60, 60, 3, 60, // 22 3, 60, 60, 3, 60, 46, 46, 46, // 23 46, 46, 46, 46, 46, 46, 46, 46, // 23 40, 40, 40, 40, 40, 40, 40, 40, // 23 40, 40, 40, 40, 40, 40, 40, 40, // 23 40, 40, 40, 40, 40, 40, 40, 40, // 23 40, 40, 40, 46, 46, 46, 46, 46, // 23 40, 40, 40, 3, 3, 46, 46, 46, // 23 46, 46, 46, 46, 46, 46, 46, 46, // 23 46, 46, 46, 46, 46, 46, 46, 46, // 24 46, 46, 46, 46, 3, 46, 46, 46, // 24 46, 46, 46, 46, 46, 46, 46, 46, // 24 46, 46, 46, 3, 46, 46, 46, 3, // 24 46, 40, 40, 40, 40, 40, 40, 40, // 24 40, 40, 40, 40, 40, 40, 40, 40, // 24 40, 40, 40, 40, 40, 40, 40, 40, // 24 40, 40, 40, 46, 46, 46, 46, 46, // 24 59, 40, 40, 40, 40, 40, 40, 40, // 25 40, 40, 40, 60, 60, 60, 60, 60, // 25 60, 60, 60, 46, 46, 46, 46, 46, // 25 46, 46, 46, 46, 46, 46, 46, 46, // 25 78, 78, 78, 78, 78, 78, 78, 78, // 25 78, 78, 3, 3, 3, 3, 46, 46, // 25 60, 40, 40, 40, 40, 40, 40, 40, // 25 40, 40, 40, 40, 40, 40, 40, 40, // 25 40, 40, 40, 40, 40, 40, 40, 40, // 26 40, 40, 40, 40, 40, 40, 40, 40, // 26 40, 40, 40, 40, 40, 40, 40, 40, // 26 40, 40, 40, 40, 40, 40, 40, 40, // 26 40, 40, 40, 40, 40, 40, 40, 40, // 26 40, 40, 40, 40, 40, 40, 40, 40, // 26 40, 40, 40, 40, 40, 40, 40, 40, // 26 46, 46, 40, 40, 40, 40, 40, 46, // 26 40, 40, 40, 40, 40, 40, 40, 40, // 27 40, 40, 40, 40, 40, 40, 40, 46, // 27 40, 40, 40, 40, 3, 40, 60, 60, // 27 60, 60, 60, 60, 60, 79, 79, 60, // 27 60, 60, 60, 60, 60, 59, 59, 60, // 27 60, 15, 60, 60, 60, 60, 46, 46, // 27 9, 9, 9, 9, 9, 9, 9, 9, // 27 9, 9, 46, 46, 46, 46, 46, 46, // 27 46, 46, 46, 46, 46, 46, 46, 46, // 28 46, 46, 46, 46, 46, 46, 46, 46, // 28 46, 46, 46, 46, 46, 46, 46, 46, // 28 46, 46, 46, 46, 46, 46, 46, 46, // 28 46, 46, 46, 46, 46, 46, 46, 46, // 28 46, 46, 46, 46, 46, 46, 46, 46, // 28 46, 46, 46, 46, 46, 46, 46, 46, // 28 46, 46, 46, 46, 46, 46, 46, 46, // 28 46, 60, 60, 80, 46, 40, 40, 40, // 29 40, 40, 40, 40, 40, 40, 40, 40, // 29 40, 40, 40, 40, 40, 40, 40, 40, // 29 40, 40, 40, 40, 40, 40, 40, 40, // 29 40, 40, 40, 40, 40, 40, 40, 40, // 29 40, 40, 40, 40, 40, 40, 40, 40, // 29 40, 40, 40, 40, 40, 40, 40, 40, // 29 40, 40, 46, 46, 60, 40, 80, 80, // 29 80, 60, 60, 60, 60, 60, 60, 60, // 30 60, 80, 80, 80, 80, 60, 46, 46, // 30 15, 60, 60, 60, 60, 46, 46, 46, // 30 40, 40, 40, 40, 40, 40, 40, 40, // 30 40, 40, 60, 60, 3, 3, 81, 81, // 30 81, 81, 81, 81, 81, 81, 81, 81, // 30 3, 46, 46, 46, 46, 46, 46, 46, // 30 46, 46, 46, 46, 46, 46, 46, 46, // 30 46, 60, 80, 80, 46, 40, 40, 40, // 31 40, 40, 40, 40, 40, 46, 46, 40, // 31 40, 46, 46, 40, 40, 40, 40, 40, // 31 40, 40, 40, 40, 40, 40, 40, 40, // 31 40, 40, 40, 40, 40, 40, 40, 40, // 31 40, 46, 40, 40, 40, 40, 40, 40, // 31 40, 46, 40, 46, 46, 46, 40, 40, // 31 40, 40, 46, 46, 60, 46, 80, 80, // 31 80, 60, 60, 60, 60, 46, 46, 80, // 32 80, 46, 46, 80, 80, 60, 46, 46, // 32 46, 46, 46, 46, 46, 46, 46, 80, // 32 46, 46, 46, 46, 40, 40, 46, 40, // 32 40, 40, 60, 60, 46, 46, 81, 81, // 32 81, 81, 81, 81, 81, 81, 81, 81, // 32 40, 40, 4, 4, 82, 82, 82, 82, // 32 19, 83, 15, 46, 46, 46, 46, 46, // 32 46, 46, 60, 46, 46, 40, 40, 40, // 33 40, 40, 40, 46, 46, 46, 46, 40, // 33 40, 46, 46, 40, 40, 40, 40, 40, // 33 40, 40, 40, 40, 40, 40, 40, 40, // 33 40, 40, 40, 40, 40, 40, 40, 40, // 33 40, 46, 40, 40, 40, 40, 40, 40, // 33 40, 46, 40, 40, 46, 40, 40, 46, // 33 40, 40, 46, 46, 60, 46, 80, 80, // 33 80, 60, 60, 46, 46, 46, 46, 60, // 34 60, 46, 46, 60, 60, 60, 46, 46, // 34 46, 46, 46, 46, 46, 46, 46, 46, // 34 46, 40, 40, 40, 40, 46, 40, 46, // 34 46, 46, 46, 46, 46, 46, 81, 81, // 34 81, 81, 81, 81, 81, 81, 81, 81, // 34 60, 60, 40, 40, 40, 46, 46, 46, // 34 46, 46, 46, 46, 46, 46, 46, 46, // 34 46, 60, 60, 80, 46, 40, 40, 40, // 35 40, 40, 40, 40, 46, 40, 46, 40, // 35 40, 40, 46, 40, 40, 40, 40, 40, // 35 40, 40, 40, 40, 40, 40, 40, 40, // 35 40, 40, 40, 40, 40, 40, 40, 40, // 35 40, 46, 40, 40, 40, 40, 40, 40, // 35 40, 46, 40, 40, 46, 40, 40, 40, // 35 40, 40, 46, 46, 60, 40, 80, 80, // 35 80, 60, 60, 60, 60, 60, 46, 60, // 36 60, 80, 46, 80, 80, 60, 46, 46, // 36 15, 46, 46, 46, 46, 46, 46, 46, // 36 46, 46, 46, 46, 46, 46, 46, 46, // 36 40, 46, 46, 46, 46, 46, 81, 81, // 36 81, 81, 81, 81, 81, 81, 81, 81, // 36 46, 46, 46, 46, 46, 46, 46, 46, // 36 46, 46, 46, 46, 46, 46, 46, 46, // 36 46, 60, 80, 80, 46, 40, 40, 40, // 37 40, 40, 40, 40, 40, 46, 46, 40, // 37 40, 46, 46, 40, 40, 40, 40, 40, // 37 40, 40, 40, 40, 40, 40, 40, 40, // 37 40, 40, 40, 40, 40, 40, 40, 40, // 37 40, 46, 40, 40, 40, 40, 40, 40, // 37 40, 46, 40, 40, 46, 46, 40, 40, // 37 40, 40, 46, 46, 60, 40, 80, 60, // 37 80, 60, 60, 60, 46, 46, 46, 80, // 38 80, 46, 46, 80, 80, 60, 46, 46, // 38 46, 46, 46, 46, 46, 46, 60, 80, // 38 46, 46, 46, 46, 40, 40, 46, 40, // 38 40, 40, 46, 46, 46, 46, 81, 81, // 38 81, 81, 81, 81, 81, 81, 81, 81, // 38 15, 46, 46, 46, 46, 46, 46, 46, // 38 46, 46, 46, 46, 46, 46, 46, 46, // 38 46, 46, 60, 80, 46, 40, 40, 40, // 39 40, 40, 40, 46, 46, 46, 40, 40, // 39 40, 46, 40, 40, 40, 40, 46, 46, // 39 46, 40, 40, 46, 40, 46, 40, 40, // 39 46, 46, 46, 40, 40, 46, 46, 46, // 39 40, 40, 40, 46, 46, 46, 40, 40, // 39 40, 40, 40, 40, 40, 40, 46, 40, // 39 40, 40, 46, 46, 46, 46, 80, 80, // 39 60, 80, 80, 46, 46, 46, 80, 80, // 40 80, 46, 80, 80, 80, 60, 46, 46, // 40 46, 46, 46, 46, 46, 46, 46, 80, // 40 46, 46, 46, 46, 46, 46, 46, 46, // 40 46, 46, 46, 46, 46, 46, 46, 81, // 40 81, 81, 81, 81, 81, 81, 81, 81, // 40 84, 19, 19, 46, 46, 46, 46, 46, // 40 46, 46, 46, 46, 46, 46, 46, 46, // 40 46, 80, 80, 80, 46, 40, 40, 40, // 41 40, 40, 40, 40, 40, 46, 40, 40, // 41 40, 46, 40, 40, 40, 40, 40, 40, // 41 40, 40, 40, 40, 40, 40, 40, 40, // 41 40, 40, 40, 40, 40, 40, 40, 40, // 41 40, 46, 40, 40, 40, 40, 40, 40, // 41 40, 40, 40, 40, 46, 40, 40, 40, // 41 40, 40, 46, 46, 46, 46, 60, 60, // 41 60, 80, 80, 80, 80, 46, 60, 60, // 42 60, 46, 60, 60, 60, 60, 46, 46, // 42 46, 46, 46, 46, 46, 60, 60, 46, // 42 46, 46, 46, 46, 46, 46, 46, 46, // 42 40, 40, 46, 46, 46, 46, 81, 81, // 42 81, 81, 81, 81, 81, 81, 81, 81, // 42 46, 46, 46, 46, 46, 46, 46, 46, // 42 46, 46, 46, 46, 46, 46, 46, 46, // 42 46, 46, 80, 80, 46, 40, 40, 40, // 43 40, 40, 40, 40, 40, 46, 40, 40, // 43 40, 46, 40, 40, 40, 40, 40, 40, // 43 40, 40, 40, 40, 40, 40, 40, 40, // 43 40, 40, 40, 40, 40, 40, 40, 40, // 43 40, 46, 40, 40, 40, 40, 40, 40, // 43 40, 40, 40, 40, 46, 40, 40, 40, // 43 40, 40, 46, 46, 46, 46, 80, 60, // 43 80, 80, 80, 80, 80, 46, 60, 80, // 44 80, 46, 80, 80, 60, 60, 46, 46, // 44 46, 46, 46, 46, 46, 80, 80, 46, // 44 46, 46, 46, 46, 46, 46, 40, 46, // 44 40, 40, 46, 46, 46, 46, 81, 81, // 44 81, 81, 81, 81, 81, 81, 81, 81, // 44 46, 46, 46, 46, 46, 46, 46, 46, // 44 46, 46, 46, 46, 46, 46, 46, 46, // 44 46, 46, 80, 80, 46, 40, 40, 40, // 45 40, 40, 40, 40, 40, 46, 40, 40, // 45 40, 46, 40, 40, 40, 40, 40, 40, // 45 40, 40, 40, 40, 40, 40, 40, 40, // 45 40, 40, 40, 40, 40, 40, 40, 40, // 45 40, 46, 40, 40, 40, 40, 40, 40, // 45 40, 40, 40, 40, 40, 40, 40, 40, // 45 40, 40, 46, 46, 46, 46, 80, 80, // 45 80, 60, 60, 60, 46, 46, 80, 80, // 46 80, 46, 80, 80, 80, 60, 46, 46, // 46 46, 46, 46, 46, 46, 46, 46, 80, // 46 46, 46, 46, 46, 46, 46, 46, 46, // 46 40, 40, 46, 46, 46, 46, 81, 81, // 46 81, 81, 81, 81, 81, 81, 81, 81, // 46 46, 46, 46, 46, 46, 46, 46, 46, // 46 46, 46, 46, 46, 46, 46, 46, 46, // 46 46, 40, 40, 40, 40, 40, 40, 40, // 47 40, 40, 40, 40, 40, 40, 40, 40, // 47 40, 40, 40, 40, 40, 40, 40, 40, // 47 40, 40, 40, 40, 40, 40, 40, 40, // 47 40, 40, 40, 40, 40, 40, 40, 40, // 47 40, 40, 40, 40, 40, 40, 40, 3, // 47 40, 60, 40, 40, 60, 60, 60, 60, // 47 60, 60, 60, 46, 46, 46, 46, 4, // 47 40, 40, 40, 40, 40, 40, 59, 60, // 48 60, 60, 60, 60, 60, 60, 60, 15, // 48 9, 9, 9, 9, 9, 9, 9, 9, // 48 9, 9, 3, 3, 46, 46, 46, 46, // 48 46, 46, 46, 46, 46, 46, 46, 46, // 48 46, 46, 46, 46, 46, 46, 46, 46, // 48 46, 46, 46, 46, 46, 46, 46, 46, // 48 46, 46, 46, 46, 46, 46, 46, 46, // 48 46, 40, 40, 46, 40, 46, 46, 40, // 49 40, 46, 40, 46, 46, 40, 46, 46, // 49 46, 46, 46, 46, 40, 40, 40, 40, // 49 46, 40, 40, 40, 40, 40, 40, 40, // 49 46, 40, 40, 40, 46, 40, 46, 40, // 49 46, 46, 40, 40, 46, 40, 40, 3, // 49 40, 60, 40, 40, 60, 60, 60, 60, // 49 60, 60, 46, 60, 60, 40, 46, 46, // 49 40, 40, 40, 40, 40, 46, 59, 46, // 50 60, 60, 60, 60, 60, 60, 46, 46, // 50 9, 9, 9, 9, 9, 9, 9, 9, // 50 9, 9, 46, 46, 40, 40, 46, 46, // 50 46, 46, 46, 46, 46, 46, 46, 46, // 50 46, 46, 46, 46, 46, 46, 46, 46, // 50 46, 46, 46, 46, 46, 46, 46, 46, // 50 46, 46, 46, 46, 46, 46, 46, 46, // 50 15, 15, 15, 15, 3, 3, 3, 3, // 51 3, 3, 3, 3, 3, 3, 3, 3, // 51 3, 3, 3, 15, 15, 15, 15, 15, // 51 60, 60, 15, 15, 15, 15, 15, 15, // 51 78, 78, 78, 78, 78, 78, 78, 78, // 51 78, 78, 85, 85, 85, 85, 85, 85, // 51 85, 85, 85, 85, 15, 60, 15, 60, // 51 15, 60, 5, 6, 5, 6, 80, 80, // 51 40, 40, 40, 40, 40, 40, 40, 40, // 52 46, 40, 40, 40, 40, 40, 40, 40, // 52 40, 40, 40, 40, 40, 40, 40, 40, // 52 40, 40, 40, 40, 40, 40, 40, 40, // 52 40, 40, 40, 40, 40, 40, 40, 40, // 52 40, 40, 46, 46, 46, 46, 46, 46, // 52 46, 60, 60, 60, 60, 60, 60, 60, // 52 60, 60, 60, 60, 60, 60, 60, 80, // 52 60, 60, 60, 60, 60, 3, 60, 60, // 53 60, 60, 60, 60, 46, 46, 46, 46, // 53 60, 60, 60, 60, 60, 60, 46, 60, // 53 46, 60, 60, 60, 60, 60, 60, 60, // 53 60, 60, 60, 60, 60, 60, 60, 60, // 53 60, 60, 60, 60, 60, 60, 46, 46, // 53 46, 60, 60, 60, 60, 60, 60, 60, // 53 46, 60, 46, 46, 46, 46, 46, 46, // 53 46, 46, 46, 46, 46, 46, 46, 46, // 54 46, 46, 46, 46, 46, 46, 46, 46, // 54 46, 46, 46, 46, 46, 46, 46, 46, // 54 46, 46, 46, 46, 46, 46, 46, 46, // 54 76, 76, 76, 76, 76, 76, 76, 76, // 54 76, 76, 76, 76, 76, 76, 76, 76, // 54 76, 76, 76, 76, 76, 76, 76, 76, // 54 76, 76, 76, 76, 76, 76, 76, 76, // 54 76, 76, 76, 76, 76, 76, 46, 46, // 55 46, 46, 46, 46, 46, 46, 46, 46, // 55 16, 16, 16, 16, 16, 16, 16, 16, // 55 16, 16, 16, 16, 16, 16, 16, 16, // 55 16, 16, 16, 16, 16, 16, 16, 16, // 55 16, 16, 16, 16, 16, 16, 16, 16, // 55 16, 16, 16, 16, 16, 16, 16, 46, // 55 46, 46, 46, 3, 46, 46, 46, 46, // 55 40, 40, 40, 40, 40, 40, 40, 40, // 56 40, 40, 40, 40, 40, 40, 40, 40, // 56 40, 40, 40, 40, 40, 40, 40, 40, // 56 40, 40, 40, 40, 40, 40, 40, 40, // 56 40, 40, 40, 40, 40, 40, 40, 40, // 56 40, 40, 40, 40, 40, 40, 40, 40, // 56 40, 40, 40, 40, 40, 40, 40, 40, // 56 40, 40, 40, 40, 40, 40, 40, 40, // 56 40, 40, 40, 40, 40, 40, 40, 40, // 57 40, 40, 40, 40, 40, 40, 40, 40, // 57 40, 40, 40, 40, 40, 40, 40, 40, // 57 40, 40, 46, 46, 46, 46, 46, 40, // 57 40, 40, 40, 40, 40, 40, 40, 40, // 57 40, 40, 40, 40, 40, 40, 40, 40, // 57 40, 40, 40, 40, 40, 40, 40, 40, // 57 40, 40, 40, 40, 40, 40, 40, 40, // 57 40, 40, 40, 40, 40, 40, 40, 40, // 58 40, 40, 40, 40, 40, 40, 40, 40, // 58 40, 40, 40, 40, 40, 40, 40, 40, // 58 40, 40, 40, 40, 40, 40, 40, 40, // 58 40, 40, 40, 46, 46, 46, 46, 46, // 58 40, 40, 40, 40, 40, 40, 40, 40, // 58 40, 40, 40, 40, 40, 40, 40, 40, // 58 40, 40, 40, 40, 40, 40, 40, 40, // 58 40, 40, 40, 40, 40, 40, 40, 40, // 59 40, 40, 40, 40, 40, 40, 40, 40, // 59 40, 40, 40, 40, 40, 40, 40, 40, // 59 40, 40, 40, 40, 40, 40, 40, 40, // 59 40, 40, 40, 40, 40, 40, 40, 40, // 59 40, 40, 40, 40, 40, 40, 40, 40, // 59 40, 40, 40, 40, 40, 40, 40, 40, // 59 40, 40, 46, 46, 46, 46, 46, 46, // 59 23, 24, 23, 24, 23, 24, 23, 24, // 60 23, 24, 23, 24, 23, 24, 23, 24, // 60 23, 24, 23, 24, 23, 24, 23, 24, // 60 23, 24, 23, 24, 23, 24, 23, 24, // 60 23, 24, 23, 24, 23, 24, 23, 24, // 60 23, 24, 23, 24, 23, 24, 23, 24, // 60 23, 24, 23, 24, 23, 24, 23, 24, // 60 23, 24, 23, 24, 23, 24, 23, 24, // 60 23, 24, 23, 24, 23, 24, 23, 24, // 61 23, 24, 23, 24, 23, 24, 23, 24, // 61 23, 24, 23, 24, 23, 24, 16, 16, // 61 16, 16, 16, 16, 46, 46, 46, 46, // 61 23, 24, 23, 24, 23, 24, 23, 24, // 61 23, 24, 23, 24, 23, 24, 23, 24, // 61 23, 24, 23, 24, 23, 24, 23, 24, // 61 23, 24, 23, 24, 23, 24, 23, 24, // 61 23, 24, 23, 24, 23, 24, 23, 24, // 62 23, 24, 23, 24, 23, 24, 23, 24, // 62 23, 24, 23, 24, 23, 24, 23, 24, // 62 23, 24, 23, 24, 23, 24, 23, 24, // 62 23, 24, 23, 24, 23, 24, 23, 24, // 62 23, 24, 23, 24, 23, 24, 23, 24, // 62 23, 24, 23, 24, 23, 24, 23, 24, // 62 23, 24, 46, 46, 46, 46, 46, 46, // 62 86, 86, 86, 86, 86, 86, 86, 86, // 63 87, 87, 87, 87, 87, 87, 87, 87, // 63 86, 86, 86, 86, 86, 86, 46, 46, // 63 87, 87, 87, 87, 87, 87, 46, 46, // 63 86, 86, 86, 86, 86, 86, 86, 86, // 63 87, 87, 87, 87, 87, 87, 87, 87, // 63 86, 86, 86, 86, 86, 86, 86, 86, // 63 87, 87, 87, 87, 87, 87, 87, 87, // 63 86, 86, 86, 86, 86, 86, 46, 46, // 64 87, 87, 87, 87, 87, 87, 46, 46, // 64 16, 86, 16, 86, 16, 86, 16, 86, // 64 46, 87, 46, 87, 46, 87, 46, 87, // 64 86, 86, 86, 86, 86, 86, 86, 86, // 64 87, 87, 87, 87, 87, 87, 87, 87, // 64 88, 88, 89, 89, 89, 89, 90, 90, // 64 91, 91, 92, 92, 93, 93, 46, 46, // 64 86, 86, 86, 86, 86, 86, 86, 86, // 65 87, 87, 87, 87, 87, 87, 87, 87, // 65 86, 86, 86, 86, 86, 86, 86, 86, // 65 87, 87, 87, 87, 87, 87, 87, 87, // 65 86, 86, 86, 86, 86, 86, 86, 86, // 65 87, 87, 87, 87, 87, 87, 87, 87, // 65 86, 86, 16, 94, 16, 46, 16, 16, // 65 87, 87, 95, 95, 96, 11, 38, 11, // 65 11, 11, 16, 94, 16, 46, 16, 16, // 66 97, 97, 97, 97, 96, 11, 11, 11, // 66 86, 86, 16, 16, 46, 46, 16, 16, // 66 87, 87, 98, 98, 46, 11, 11, 11, // 66 86, 86, 16, 16, 16, 99, 16, 16, // 66 87, 87, 100, 100, 101, 11, 11, 11, // 66 46, 46, 16, 94, 16, 46, 16, 16, // 66 102, 102, 103, 103, 96, 11, 11, 46, // 66 2, 2, 2, 2, 2, 2, 2, 2, // 67 2, 2, 2, 2, 104, 104, 104, 104, // 67 8, 8, 8, 8, 8, 8, 3, 3, // 67 5, 6, 5, 5, 5, 6, 5, 5, // 67 3, 3, 3, 3, 3, 3, 3, 3, // 67 105, 106, 104, 104, 104, 104, 104, 46, // 67 3, 3, 3, 3, 3, 3, 3, 3, // 67 3, 5, 6, 3, 3, 3, 3, 12, // 67 12, 3, 3, 3, 7, 5, 6, 46, // 68 46, 46, 46, 46, 46, 46, 46, 46, // 68 46, 46, 46, 46, 46, 46, 46, 46, // 68 46, 46, 46, 46, 46, 46, 46, 46, // 68 46, 46, 46, 46, 46, 46, 46, 46, // 68 46, 46, 104, 104, 104, 104, 104, 104, // 68 17, 46, 46, 46, 17, 17, 17, 17, // 68 17, 17, 7, 7, 7, 5, 6, 16, // 68 107, 107, 107, 107, 107, 107, 107, 107, // 69 107, 107, 7, 7, 7, 5, 6, 46, // 69 46, 46, 46, 46, 46, 46, 46, 46, // 69 46, 46, 46, 46, 46, 46, 46, 46, // 69 4, 4, 4, 4, 4, 4, 4, 4, // 69 4, 4, 4, 4, 46, 46, 46, 46, // 69 46, 46, 46, 46, 46, 46, 46, 46, // 69 46, 46, 46, 46, 46, 46, 46, 46, // 69 46, 46, 46, 46, 46, 46, 46, 46, // 70 46, 46, 46, 46, 46, 46, 46, 46, // 70 60, 60, 60, 60, 60, 60, 60, 60, // 70 60, 60, 60, 60, 60, 79, 79, 79, // 70 79, 60, 46, 46, 46, 46, 46, 46, // 70 46, 46, 46, 46, 46, 46, 46, 46, // 70 46, 46, 46, 46, 46, 46, 46, 46, // 70 46, 46, 46, 46, 46, 46, 46, 46, // 70 15, 15, 38, 15, 15, 15, 15, 38, // 71 15, 15, 16, 38, 38, 38, 16, 16, // 71 38, 38, 38, 16, 15, 38, 15, 15, // 71 38, 38, 38, 38, 38, 38, 15, 15, // 71 15, 15, 15, 15, 38, 15, 38, 15, // 71 38, 15, 38, 38, 38, 38, 16, 16, // 71 38, 38, 15, 38, 16, 40, 40, 40, // 71 40, 46, 46, 46, 46, 46, 46, 46, // 71 46, 46, 46, 46, 46, 46, 46, 46, // 72 46, 46, 46, 46, 46, 46, 46, 46, // 72 46, 46, 46, 19, 19, 19, 19, 19, // 72 19, 19, 19, 19, 19, 19, 19, 108, // 72 109, 109, 109, 109, 109, 109, 109, 109, // 72 109, 109, 109, 109, 110, 110, 110, 110, // 72 111, 111, 111, 111, 111, 111, 111, 111, // 72 111, 111, 111, 111, 112, 112, 112, 112, // 72 113, 113, 113, 46, 46, 46, 46, 46, // 73 46, 46, 46, 46, 46, 46, 46, 46, // 73 7, 7, 7, 7, 7, 15, 15, 15, // 73 15, 15, 15, 15, 15, 15, 15, 15, // 73 15, 15, 15, 15, 15, 15, 15, 15, // 73 15, 15, 15, 15, 15, 15, 15, 15, // 73 15, 15, 15, 15, 15, 15, 15, 15, // 73 15, 15, 15, 15, 15, 15, 15, 15, // 73 15, 15, 15, 15, 15, 15, 15, 15, // 74 15, 15, 15, 15, 15, 15, 15, 15, // 74 15, 15, 7, 15, 7, 15, 15, 15, // 74 15, 15, 15, 15, 15, 15, 15, 15, // 74 15, 15, 15, 15, 15, 15, 15, 15, // 74 15, 15, 15, 46, 46, 46, 46, 46, // 74 46, 46, 46, 46, 46, 46, 46, 46, // 74 46, 46, 46, 46, 46, 46, 46, 46, // 74 7, 7, 7, 7, 7, 7, 7, 7, // 75 7, 7, 7, 7, 7, 7, 7, 7, // 75 7, 7, 7, 7, 7, 7, 7, 7, // 75 7, 7, 7, 7, 7, 7, 7, 7, // 75 7, 7, 7, 7, 7, 7, 7, 7, // 75 7, 7, 7, 7, 7, 7, 7, 7, // 75 7, 7, 7, 7, 7, 7, 7, 7, // 75 7, 7, 7, 7, 7, 7, 7, 7, // 75 7, 7, 7, 7, 7, 7, 7, 7, // 76 7, 7, 7, 7, 7, 7, 7, 7, // 76 7, 7, 7, 7, 7, 7, 7, 7, // 76 7, 7, 7, 7, 7, 7, 7, 7, // 76 7, 7, 7, 7, 7, 7, 7, 7, // 76 7, 7, 7, 7, 7, 7, 7, 7, // 76 7, 7, 46, 46, 46, 46, 46, 46, // 76 46, 46, 46, 46, 46, 46, 46, 46, // 76 15, 46, 15, 15, 15, 15, 15, 15, // 77 7, 7, 7, 7, 15, 15, 15, 15, // 77 15, 15, 15, 15, 15, 15, 15, 15, // 77 15, 15, 15, 15, 15, 15, 15, 15, // 77 7, 7, 15, 15, 15, 15, 15, 15, // 77 15, 5, 6, 15, 15, 15, 15, 15, // 77 15, 15, 15, 15, 15, 15, 15, 15, // 77 15, 15, 15, 15, 15, 15, 15, 15, // 77 15, 15, 15, 15, 15, 15, 15, 15, // 78 15, 15, 15, 15, 15, 15, 15, 15, // 78 15, 15, 15, 15, 15, 15, 15, 15, // 78 15, 15, 15, 15, 15, 15, 15, 15, // 78 15, 15, 15, 15, 15, 15, 15, 15, // 78 15, 15, 15, 15, 15, 15, 15, 15, // 78 15, 15, 15, 15, 15, 15, 15, 15, // 78 15, 15, 15, 46, 46, 46, 46, 46, // 78 15, 15, 15, 15, 15, 15, 15, 15, // 79 15, 15, 15, 15, 15, 15, 15, 15, // 79 15, 15, 15, 15, 15, 15, 15, 15, // 79 15, 15, 15, 15, 15, 15, 15, 15, // 79 15, 15, 15, 15, 15, 46, 46, 46, // 79 46, 46, 46, 46, 46, 46, 46, 46, // 79 46, 46, 46, 46, 46, 46, 46, 46, // 79 46, 46, 46, 46, 46, 46, 46, 46, // 79 15, 15, 15, 15, 15, 15, 15, 15, // 80 15, 15, 15, 46, 46, 46, 46, 46, // 80 46, 46, 46, 46, 46, 46, 46, 46, // 80 46, 46, 46, 46, 46, 46, 46, 46, // 80 114, 114, 114, 114, 114, 114, 114, 114, // 80 114, 114, 114, 114, 114, 114, 114, 114, // 80 114, 114, 114, 114, 82, 82, 82, 82, // 80 82, 82, 82, 82, 82, 82, 82, 82, // 80 82, 82, 82, 82, 82, 82, 82, 82, // 81 115, 115, 115, 115, 115, 115, 115, 115, // 81 115, 115, 115, 115, 115, 115, 115, 115, // 81 115, 115, 115, 115, 15, 15, 15, 15, // 81 15, 15, 15, 15, 15, 15, 15, 15, // 81 15, 15, 15, 15, 15, 15, 15, 15, // 81 15, 15, 15, 15, 15, 15, 116, 116, // 81 116, 116, 116, 116, 116, 116, 116, 116, // 81 116, 116, 116, 116, 116, 116, 116, 116, // 82 116, 116, 116, 116, 116, 116, 116, 116, // 82 117, 117, 117, 117, 117, 117, 117, 117, // 82 117, 117, 117, 117, 117, 117, 117, 117, // 82 117, 117, 117, 117, 117, 117, 117, 117, // 82 117, 117, 118, 46, 46, 46, 46, 46, // 82 46, 46, 46, 46, 46, 46, 46, 46, // 82 46, 46, 46, 46, 46, 46, 46, 46, // 82 15, 15, 15, 15, 15, 15, 15, 15, // 83 15, 15, 15, 15, 15, 15, 15, 15, // 83 15, 15, 15, 15, 15, 15, 15, 15, // 83 15, 15, 15, 15, 15, 15, 15, 15, // 83 15, 15, 15, 15, 15, 15, 15, 15, // 83 15, 15, 15, 15, 15, 15, 15, 15, // 83 15, 15, 15, 15, 15, 15, 15, 15, // 83 15, 15, 15, 15, 15, 15, 15, 15, // 83 15, 15, 15, 15, 15, 15, 15, 15, // 84 15, 15, 15, 15, 15, 15, 15, 15, // 84 15, 15, 15, 15, 15, 15, 46, 46, // 84 46, 46, 46, 46, 46, 46, 46, 46, // 84 15, 15, 15, 15, 15, 15, 15, 15, // 84 15, 15, 15, 15, 15, 15, 15, 15, // 84 15, 15, 15, 15, 15, 15, 15, 15, // 84 15, 15, 15, 15, 15, 15, 15, 15, // 84 15, 15, 15, 15, 15, 15, 15, 15, // 85 15, 15, 15, 15, 15, 15, 15, 15, // 85 15, 15, 15, 15, 15, 15, 15, 15, // 85 15, 15, 15, 15, 15, 15, 15, 15, // 85 15, 15, 15, 15, 15, 15, 15, 15, // 85 15, 15, 15, 15, 15, 15, 15, 15, // 85 46, 46, 46, 46, 46, 46, 46, 46, // 85 46, 46, 46, 46, 46, 46, 46, 46, // 85 15, 15, 15, 15, 15, 15, 15, 15, // 86 15, 15, 15, 15, 15, 15, 15, 15, // 86 15, 15, 15, 15, 46, 46, 46, 46, // 86 46, 46, 15, 15, 15, 15, 15, 15, // 86 15, 15, 15, 15, 15, 15, 15, 15, // 86 15, 15, 15, 15, 15, 15, 15, 15, // 86 15, 15, 15, 15, 15, 15, 15, 15, // 86 15, 15, 15, 15, 15, 15, 15, 15, // 86 46, 15, 15, 15, 15, 46, 15, 15, // 87 15, 15, 46, 46, 15, 15, 15, 15, // 87 15, 15, 15, 15, 15, 15, 15, 15, // 87 15, 15, 15, 15, 15, 15, 15, 15, // 87 15, 15, 15, 15, 15, 15, 15, 15, // 87 46, 15, 15, 15, 15, 15, 15, 15, // 87 15, 15, 15, 15, 15, 15, 15, 15, // 87 15, 15, 15, 15, 15, 15, 15, 15, // 87 15, 15, 15, 15, 15, 15, 15, 15, // 88 15, 15, 15, 15, 46, 15, 46, 15, // 88 15, 15, 15, 46, 46, 46, 15, 46, // 88 15, 15, 15, 15, 15, 15, 15, 46, // 88 46, 15, 15, 15, 15, 15, 15, 15, // 88 46, 46, 46, 46, 46, 46, 46, 46, // 88 46, 46, 46, 46, 46, 46, 119, 119, // 88 119, 119, 119, 119, 119, 119, 119, 119, // 88 114, 114, 114, 114, 114, 114, 114, 114, // 89 114, 114, 83, 83, 83, 83, 83, 83, // 89 83, 83, 83, 83, 15, 46, 46, 46, // 89 15, 15, 15, 15, 15, 15, 15, 15, // 89 15, 15, 15, 15, 15, 15, 15, 15, // 89 15, 15, 15, 15, 15, 15, 15, 15, // 89 46, 15, 15, 15, 15, 15, 15, 15, // 89 15, 15, 15, 15, 15, 15, 15, 46, // 89 2, 3, 3, 3, 15, 59, 3, 120, // 90 5, 6, 5, 6, 5, 6, 5, 6, // 90 5, 6, 15, 15, 5, 6, 5, 6, // 90 5, 6, 5, 6, 8, 5, 6, 5, // 90 15, 121, 121, 121, 121, 121, 121, 121, // 90 121, 121, 60, 60, 60, 60, 60, 60, // 90 8, 59, 59, 59, 59, 59, 15, 15, // 90 46, 46, 46, 46, 46, 46, 46, 15, // 90 46, 40, 40, 40, 40, 40, 40, 40, // 91 40, 40, 40, 40, 40, 40, 40, 40, // 91 40, 40, 40, 40, 40, 40, 40, 40, // 91 40, 40, 40, 40, 40, 40, 40, 40, // 91 40, 40, 40, 40, 40, 40, 40, 40, // 91 40, 40, 40, 40, 40, 40, 40, 40, // 91 40, 40, 40, 40, 40, 40, 40, 40, // 91 40, 40, 40, 40, 40, 40, 40, 40, // 91 40, 40, 40, 40, 40, 40, 40, 40, // 92 40, 40, 40, 40, 40, 40, 40, 40, // 92 40, 40, 40, 40, 40, 46, 46, 46, // 92 46, 60, 60, 59, 59, 59, 59, 46, // 92 46, 40, 40, 40, 40, 40, 40, 40, // 92 40, 40, 40, 40, 40, 40, 40, 40, // 92 40, 40, 40, 40, 40, 40, 40, 40, // 92 40, 40, 40, 40, 40, 40, 40, 40, // 92 40, 40, 40, 40, 40, 40, 40, 40, // 93 40, 40, 40, 40, 40, 40, 40, 40, // 93 40, 40, 40, 40, 40, 40, 40, 40, // 93 40, 40, 40, 40, 40, 40, 40, 40, // 93 40, 40, 40, 40, 40, 40, 40, 40, // 93 40, 40, 40, 40, 40, 40, 40, 40, // 93 40, 40, 40, 40, 40, 40, 40, 40, // 93 40, 40, 40, 3, 59, 59, 59, 46, // 93 46, 46, 46, 46, 46, 40, 40, 40, // 94 40, 40, 40, 40, 40, 40, 40, 40, // 94 40, 40, 40, 40, 40, 40, 40, 40, // 94 40, 40, 40, 40, 40, 40, 40, 40, // 94 40, 40, 40, 40, 40, 40, 40, 40, // 94 40, 40, 40, 40, 40, 46, 46, 46, // 94 46, 40, 40, 40, 40, 40, 40, 40, // 94 40, 40, 40, 40, 40, 40, 40, 40, // 94 40, 40, 40, 40, 40, 40, 40, 40, // 95 40, 40, 40, 40, 40, 40, 40, 46, // 95 15, 15, 85, 85, 85, 85, 15, 15, // 95 15, 15, 15, 15, 15, 15, 15, 15, // 95 46, 46, 46, 46, 46, 46, 46, 46, // 95 46, 46, 46, 46, 46, 46, 46, 46, // 95 46, 46, 46, 46, 46, 46, 46, 46, // 95 46, 46, 46, 46, 46, 46, 46, 46, // 95 15, 15, 15, 15, 15, 15, 15, 15, // 96 15, 15, 15, 15, 15, 15, 15, 15, // 96 15, 15, 15, 15, 15, 15, 15, 15, // 96 15, 15, 15, 15, 15, 46, 46, 46, // 96 85, 85, 85, 85, 85, 85, 85, 85, // 96 85, 85, 15, 15, 15, 15, 15, 15, // 96 15, 15, 15, 15, 15, 15, 15, 15, // 96 15, 15, 15, 15, 15, 15, 15, 15, // 96 15, 15, 15, 15, 46, 46, 46, 46, // 97 46, 46, 46, 46, 46, 46, 46, 46, // 97 46, 46, 46, 46, 46, 46, 46, 46, // 97 46, 46, 46, 46, 46, 46, 46, 46, // 97 15, 15, 15, 15, 15, 15, 15, 15, // 97 15, 15, 15, 15, 15, 15, 15, 15, // 97 15, 15, 15, 15, 15, 15, 15, 15, // 97 15, 15, 15, 15, 46, 46, 46, 15, // 97 114, 114, 114, 114, 114, 114, 114, 114, // 98 114, 114, 15, 15, 15, 15, 15, 15, // 98 15, 15, 15, 15, 15, 15, 15, 15, // 98 15, 15, 15, 15, 15, 15, 15, 15, // 98 15, 15, 15, 15, 15, 15, 15, 15, // 98 15, 15, 15, 15, 15, 15, 15, 15, // 98 15, 46, 46, 46, 46, 46, 46, 46, // 98 46, 46, 46, 46, 46, 46, 46, 46, // 98 15, 15, 15, 15, 15, 15, 15, 15, // 99 15, 15, 15, 15, 46, 46, 46, 46, // 99 15, 15, 15, 15, 15, 15, 15, 15, // 99 15, 15, 15, 15, 15, 15, 15, 15, // 99 15, 15, 15, 15, 15, 15, 15, 15, // 99 15, 15, 15, 15, 15, 15, 15, 15, // 99 15, 15, 15, 15, 15, 15, 15, 15, // 99 15, 15, 15, 15, 15, 15, 15, 46, // 99 15, 15, 15, 15, 15, 15, 15, 15, // 100 15, 15, 15, 15, 15, 15, 15, 15, // 100 15, 15, 15, 15, 15, 15, 15, 15, // 100 15, 15, 15, 15, 15, 15, 15, 15, // 100 15, 15, 15, 15, 15, 15, 15, 15, // 100 15, 15, 15, 15, 15, 15, 15, 15, // 100 15, 15, 15, 15, 15, 15, 15, 46, // 100 46, 46, 46, 15, 15, 15, 15, 15, // 100 15, 15, 15, 15, 15, 15, 15, 15, // 101 15, 15, 15, 15, 15, 15, 15, 15, // 101 15, 15, 15, 15, 15, 15, 15, 15, // 101 15, 15, 15, 15, 15, 15, 46, 46, // 101 15, 15, 15, 15, 15, 15, 15, 15, // 101 15, 15, 15, 15, 15, 15, 15, 15, // 101 15, 15, 15, 15, 15, 15, 15, 15, // 101 15, 15, 15, 15, 15, 15, 15, 46, // 101 40, 40, 40, 40, 40, 40, 40, 40, // 102 40, 40, 40, 40, 40, 40, 40, 40, // 102 40, 40, 40, 40, 40, 40, 40, 40, // 102 40, 40, 40, 40, 40, 40, 40, 40, // 102 40, 40, 40, 40, 40, 40, 46, 46, // 102 46, 46, 46, 46, 46, 46, 46, 46, // 102 46, 46, 46, 46, 46, 46, 46, 46, // 102 46, 46, 46, 46, 46, 46, 46, 46, // 102 40, 40, 40, 40, 40, 40, 40, 40, // 103 40, 40, 40, 40, 40, 40, 40, 40, // 103 40, 40, 40, 40, 40, 40, 40, 40, // 103 40, 40, 40, 40, 40, 40, 40, 40, // 103 40, 40, 40, 40, 46, 46, 46, 46, // 103 46, 46, 46, 46, 46, 46, 46, 46, // 103 46, 46, 46, 46, 46, 46, 46, 46, // 103 46, 46, 46, 46, 46, 46, 46, 46, // 103 122, 122, 122, 122, 122, 122, 122, 122, // 104 122, 122, 122, 122, 122, 122, 122, 122, // 104 122, 122, 122, 122, 122, 122, 122, 122, // 104 122, 122, 122, 122, 122, 122, 122, 122, // 104 122, 122, 122, 122, 122, 122, 122, 122, // 104 122, 122, 122, 122, 122, 122, 122, 122, // 104 122, 122, 122, 122, 122, 122, 122, 122, // 104 122, 122, 122, 122, 122, 122, 122, 122, // 104 123, 123, 123, 123, 123, 123, 123, 123, // 105 123, 123, 123, 123, 123, 123, 123, 123, // 105 123, 123, 123, 123, 123, 123, 123, 123, // 105 123, 123, 123, 123, 123, 123, 123, 123, // 105 123, 123, 123, 123, 123, 123, 123, 123, // 105 123, 123, 123, 123, 123, 123, 123, 123, // 105 123, 123, 123, 123, 123, 123, 123, 123, // 105 123, 123, 123, 123, 123, 123, 123, 123, // 105 40, 40, 40, 40, 40, 40, 40, 40, // 106 40, 40, 40, 40, 40, 40, 40, 40, // 106 40, 40, 40, 40, 40, 40, 40, 40, // 106 40, 40, 40, 40, 40, 40, 40, 40, // 106 40, 40, 40, 40, 40, 40, 40, 40, // 106 40, 40, 40, 40, 40, 40, 46, 46, // 106 46, 46, 46, 46, 46, 46, 46, 46, // 106 46, 46, 46, 46, 46, 46, 46, 46, // 106 16, 16, 16, 16, 16, 16, 16, 46, // 107 46, 46, 46, 46, 46, 46, 46, 46, // 107 46, 46, 46, 16, 16, 16, 16, 16, // 107 46, 46, 46, 46, 46, 46, 60, 40, // 107 40, 40, 40, 40, 40, 40, 40, 40, // 107 40, 7, 40, 40, 40, 40, 40, 40, // 107 40, 40, 40, 40, 40, 40, 40, 46, // 107 40, 40, 40, 40, 40, 46, 40, 46, // 107 40, 40, 46, 40, 40, 46, 40, 40, // 108 40, 40, 40, 40, 40, 40, 40, 40, // 108 40, 40, 40, 40, 40, 40, 40, 40, // 108 40, 40, 40, 40, 40, 40, 40, 40, // 108 40, 40, 40, 40, 40, 40, 40, 40, // 108 40, 40, 40, 40, 40, 40, 40, 40, // 108 40, 40, 40, 40, 40, 40, 40, 40, // 108 40, 40, 40, 40, 40, 40, 40, 40, // 108 40, 40, 40, 40, 40, 40, 40, 40, // 109 40, 40, 40, 40, 40, 40, 40, 40, // 109 40, 40, 40, 40, 40, 40, 40, 40, // 109 40, 40, 40, 40, 40, 40, 40, 40, // 109 40, 40, 40, 40, 40, 40, 40, 40, // 109 40, 40, 40, 40, 40, 40, 40, 40, // 109 40, 40, 46, 46, 46, 46, 46, 46, // 109 46, 46, 46, 46, 46, 46, 46, 46, // 109 46, 46, 46, 46, 46, 46, 46, 46, // 110 46, 46, 46, 46, 46, 46, 46, 46, // 110 46, 46, 46, 40, 40, 40, 40, 40, // 110 40, 40, 40, 40, 40, 40, 40, 40, // 110 40, 40, 40, 40, 40, 40, 40, 40, // 110 40, 40, 40, 40, 40, 40, 40, 40, // 110 40, 40, 40, 40, 40, 40, 40, 40, // 110 40, 40, 40, 40, 40, 40, 40, 40, // 110 40, 40, 40, 40, 40, 40, 40, 40, // 111 40, 40, 40, 40, 40, 40, 40, 40, // 111 40, 40, 40, 40, 40, 40, 40, 40, // 111 40, 40, 40, 40, 40, 40, 40, 40, // 111 40, 40, 40, 40, 40, 40, 40, 40, // 111 40, 40, 40, 40, 40, 40, 40, 40, // 111 40, 40, 40, 40, 40, 40, 40, 40, // 111 40, 40, 40, 40, 40, 40, 5, 6, // 111 46, 46, 46, 46, 46, 46, 46, 46, // 112 46, 46, 46, 46, 46, 46, 46, 46, // 112 40, 40, 40, 40, 40, 40, 40, 40, // 112 40, 40, 40, 40, 40, 40, 40, 40, // 112 40, 40, 40, 40, 40, 40, 40, 40, // 112 40, 40, 40, 40, 40, 40, 40, 40, // 112 40, 40, 40, 40, 40, 40, 40, 40, // 112 40, 40, 40, 40, 40, 40, 40, 40, // 112 40, 40, 40, 40, 40, 40, 40, 40, // 113 40, 40, 40, 40, 40, 40, 40, 40, // 113 46, 46, 40, 40, 40, 40, 40, 40, // 113 40, 40, 40, 40, 40, 40, 40, 40, // 113 40, 40, 40, 40, 40, 40, 40, 40, // 113 40, 40, 40, 40, 40, 40, 40, 40, // 113 40, 40, 40, 40, 40, 40, 40, 40, // 113 40, 40, 40, 40, 40, 40, 40, 40, // 113 40, 40, 40, 40, 40, 40, 40, 40, // 114 46, 46, 46, 46, 46, 46, 46, 46, // 114 46, 46, 46, 46, 46, 46, 46, 46, // 114 46, 46, 46, 46, 46, 46, 46, 46, // 114 46, 46, 46, 46, 46, 46, 46, 46, // 114 46, 46, 46, 46, 46, 46, 46, 46, // 114 40, 40, 40, 40, 40, 40, 40, 40, // 114 40, 40, 40, 40, 46, 46, 46, 46, // 114 46, 46, 46, 46, 46, 46, 46, 46, // 115 46, 46, 46, 46, 46, 46, 46, 46, // 115 46, 46, 46, 46, 46, 46, 46, 46, // 115 46, 46, 46, 46, 46, 46, 46, 46, // 115 60, 60, 60, 60, 46, 46, 46, 46, // 115 46, 46, 46, 46, 46, 46, 46, 46, // 115 3, 8, 8, 12, 12, 5, 6, 5, // 115 6, 5, 6, 5, 6, 5, 6, 5, // 115 6, 5, 6, 5, 6, 46, 46, 46, // 116 46, 3, 3, 3, 3, 12, 12, 12, // 116 3, 3, 3, 46, 3, 3, 3, 3, // 116 8, 5, 6, 5, 6, 5, 6, 3, // 116 3, 3, 7, 8, 7, 7, 7, 46, // 116 3, 4, 3, 3, 46, 46, 46, 46, // 116 40, 40, 40, 46, 40, 46, 40, 40, // 116 40, 40, 40, 40, 40, 40, 40, 40, // 116 40, 40, 40, 40, 40, 40, 40, 40, // 117 40, 40, 40, 40, 40, 40, 40, 40, // 117 40, 40, 40, 40, 40, 40, 40, 40, // 117 40, 40, 40, 40, 40, 40, 40, 40, // 117 40, 40, 40, 40, 40, 40, 40, 40, // 117 40, 40, 40, 40, 40, 40, 40, 40, // 117 40, 40, 40, 40, 40, 40, 40, 40, // 117 40, 40, 40, 40, 40, 46, 46, 104, // 117 46, 3, 3, 3, 4, 3, 3, 3, // 118 5, 6, 3, 7, 3, 8, 3, 3, // 118 9, 9, 9, 9, 9, 9, 9, 9, // 118 9, 9, 3, 3, 7, 7, 7, 3, // 118 3, 10, 10, 10, 10, 10, 10, 10, // 118 10, 10, 10, 10, 10, 10, 10, 10, // 118 10, 10, 10, 10, 10, 10, 10, 10, // 118 10, 10, 10, 5, 3, 6, 11, 12, // 118 11, 13, 13, 13, 13, 13, 13, 13, // 119 13, 13, 13, 13, 13, 13, 13, 13, // 119 13, 13, 13, 13, 13, 13, 13, 13, // 119 13, 13, 13, 5, 7, 6, 7, 46, // 119 46, 3, 5, 6, 3, 3, 40, 40, // 119 40, 40, 40, 40, 40, 40, 40, 40, // 119 59, 40, 40, 40, 40, 40, 40, 40, // 119 40, 40, 40, 40, 40, 40, 40, 40, // 119 40, 40, 40, 40, 40, 40, 40, 40, // 120 40, 40, 40, 40, 40, 40, 40, 40, // 120 40, 40, 40, 40, 40, 40, 40, 40, // 120 40, 40, 40, 40, 40, 40, 59, 59, // 120 40, 40, 40, 40, 40, 40, 40, 40, // 120 40, 40, 40, 40, 40, 40, 40, 40, // 120 40, 40, 40, 40, 40, 40, 40, 40, // 120 40, 40, 40, 40, 40, 40, 40, 46, // 120 46, 46, 40, 40, 40, 40, 40, 40, // 121 46, 46, 40, 40, 40, 40, 40, 40, // 121 46, 46, 40, 40, 40, 40, 40, 40, // 121 46, 46, 40, 40, 40, 46, 46, 46, // 121 4, 4, 7, 11, 15, 4, 4, 46, // 121 7, 7, 7, 7, 7, 15, 15, 46, // 121 46, 46, 46, 46, 46, 46, 46, 46, // 121 46, 46, 46, 46, 46, 15, 46, 46 // 121 }; // The A table has 124 entries for a total of 496 bytes. const uint32 JS::CharInfo::a[] = { 0x0000000F, // 0 Cc 0x0004000F, // 1 Cc, whitespace 0x0004000C, // 2 Zs, whitespace 0x00000018, // 3 Po 0x0002001A, // 4 Sc, currency 0x00000015, // 5 Ps 0x00000016, // 6 Pe 0x00000019, // 7 Sm 0x00000014, // 8 Pd 0x00036009, // 9 Nd, identifier part, decimal 16 0x0822FE01, // 10 Lu, hasLower (add 32), identifier start, supradecimal 31 0x0000001B, // 11 Sk 0x00020017, // 12 Pc, underscore 0x0812FE02, // 13 Ll, hasUpper (subtract 32), identifier start, supradecimal 31 0x0005000F, // 14 Cc, break 0x0000001C, // 15 So 0x00020002, // 16 Ll, identifier start 0x0000600B, // 17 No, decimal 16 0x0000500B, // 18 No, decimal 8 0x0000800B, // 19 No, strange 0x08220001, // 20 Lu, hasLower (add 32), identifier start 0x08120002, // 21 Ll, hasUpper (subtract 32), identifier start 0xE1D20002, // 22 Ll, hasUpper (subtract -121), identifier start 0x00620001, // 23 Lu, hasLower (add 1), identifier start 0x00520002, // 24 Ll, hasUpper (subtract 1), identifier start 0xCE620001, // 25 Lu, hasLower (add -199), identifier start 0x3A120002, // 26 Ll, hasUpper (subtract 232), identifier start 0xE1E20001, // 27 Lu, hasLower (add -121), identifier start 0x4B120002, // 28 Ll, hasUpper (subtract 300), identifier start 0x34A20001, // 29 Lu, hasLower (add 210), identifier start 0x33A20001, // 30 Lu, hasLower (add 206), identifier start 0x33620001, // 31 Lu, hasLower (add 205), identifier start 0x32A20001, // 32 Lu, hasLower (add 202), identifier start 0x32E20001, // 33 Lu, hasLower (add 203), identifier start 0x33E20001, // 34 Lu, hasLower (add 207), identifier start 0x34E20001, // 35 Lu, hasLower (add 211), identifier start 0x34620001, // 36 Lu, hasLower (add 209), identifier start 0x35620001, // 37 Lu, hasLower (add 213), identifier start 0x00020001, // 38 Lu, identifier start 0x36A20001, // 39 Lu, hasLower (add 218), identifier start 0x00020005, // 40 Lo, identifier start 0x36620001, // 41 Lu, hasLower (add 217), identifier start 0x36E20001, // 42 Lu, hasLower (add 219), identifier start 0x00AA0001, // 43 Lu, hasLower (add 2), hasTitle, identifier start 0x007A0003, // 44 Lt, hasUpper (subtract 1), hasLower (add 1), hasTitle, identifier start 0x009A0002, // 45 Ll, hasUpper (subtract 2), hasTitle, identifier start 0x00000000, // 46 unassigned 0x34920002, // 47 Ll, hasUpper (subtract 210), identifier start 0x33920002, // 48 Ll, hasUpper (subtract 206), identifier start 0x33520002, // 49 Ll, hasUpper (subtract 205), identifier start 0x32920002, // 50 Ll, hasUpper (subtract 202), identifier start 0x32D20002, // 51 Ll, hasUpper (subtract 203), identifier start 0x33D20002, // 52 Ll, hasUpper (subtract 207), identifier start 0x34520002, // 53 Ll, hasUpper (subtract 209), identifier start 0x34D20002, // 54 Ll, hasUpper (subtract 211), identifier start 0x35520002, // 55 Ll, hasUpper (subtract 213), identifier start 0x36920002, // 56 Ll, hasUpper (subtract 218), identifier start 0x36520002, // 57 Ll, hasUpper (subtract 217), identifier start 0x36D20002, // 58 Ll, hasUpper (subtract 219), identifier start 0x00020004, // 59 Lm, identifier start 0x00030006, // 60 Mn, identifier part 0x09A20001, // 61 Lu, hasLower (add 38), identifier start 0x09620001, // 62 Lu, hasLower (add 37), identifier start 0x10220001, // 63 Lu, hasLower (add 64), identifier start 0x0FE20001, // 64 Lu, hasLower (add 63), identifier start 0x09920002, // 65 Ll, hasUpper (subtract 38), identifier start 0x09520002, // 66 Ll, hasUpper (subtract 37), identifier start 0x10120002, // 67 Ll, hasUpper (subtract 64), identifier start 0x0FD20002, // 68 Ll, hasUpper (subtract 63), identifier start 0x0F920002, // 69 Ll, hasUpper (subtract 62), identifier start 0x0E520002, // 70 Ll, hasUpper (subtract 57), identifier start 0x0BD20002, // 71 Ll, hasUpper (subtract 47), identifier start 0x0D920002, // 72 Ll, hasUpper (subtract 54), identifier start 0x15920002, // 73 Ll, hasUpper (subtract 86), identifier start 0x14120002, // 74 Ll, hasUpper (subtract 80), identifier start 0x14220001, // 75 Lu, hasLower (add 80), identifier start 0x0C220001, // 76 Lu, hasLower (add 48), identifier start 0x0C120002, // 77 Ll, hasUpper (subtract 48), identifier start 0x00034009, // 78 Nd, identifier part, decimal 0 0x00000007, // 79 Me 0x00030008, // 80 Mc, identifier part 0x00037409, // 81 Nd, identifier part, decimal 26 0x00005A0B, // 82 No, decimal 13 0x00006E0B, // 83 No, decimal 23 0x0000740B, // 84 No, decimal 26 0x0000000B, // 85 No 0xFE120002, // 86 Ll, hasUpper (subtract -8), identifier start 0xFE220001, // 87 Lu, hasLower (add -8), identifier start 0xED920002, // 88 Ll, hasUpper (subtract -74), identifier start 0xEA920002, // 89 Ll, hasUpper (subtract -86), identifier start 0xE7120002, // 90 Ll, hasUpper (subtract -100), identifier start 0xE0120002, // 91 Ll, hasUpper (subtract -128), identifier start 0xE4120002, // 92 Ll, hasUpper (subtract -112), identifier start 0xE0920002, // 93 Ll, hasUpper (subtract -126), identifier start 0xFDD20002, // 94 Ll, hasUpper (subtract -9), identifier start 0xEDA20001, // 95 Lu, hasLower (add -74), identifier start 0xFDE20001, // 96 Lu, hasLower (add -9), identifier start 0xEAA20001, // 97 Lu, hasLower (add -86), identifier start 0xE7220001, // 98 Lu, hasLower (add -100), identifier start 0xFE520002, // 99 Ll, hasUpper (subtract -7), identifier start 0xE4220001, // 100 Lu, hasLower (add -112), identifier start 0xFE620001, // 101 Lu, hasLower (add -7), identifier start 0xE0220001, // 102 Lu, hasLower (add -128), identifier start 0xE0A20001, // 103 Lu, hasLower (add -126), identifier start 0x00010010, // 104 Cf, ignorable 0x0005000D, // 105 Zl, break 0x0005000E, // 106 Zp, break 0x0000400B, // 107 No, decimal 0 0x0000440B, // 108 No, decimal 2 0x0422420A, // 109 Nl, hasLower (add 16), identifier start, decimal 1 0x0422800A, // 110 Nl, hasLower (add 16), identifier start, strange 0x0412620A, // 111 Nl, hasUpper (subtract 16), identifier start, decimal 17 0x0412800A, // 112 Nl, hasUpper (subtract 16), identifier start, strange 0x0002800A, // 113 Nl, identifier start, strange 0x0000420B, // 114 No, decimal 1 0x0000720B, // 115 No, decimal 25 0x06A0001C, // 116 So, hasLower (add 26) 0x0690001C, // 117 So, hasUpper (subtract 26) 0x00006C0B, // 118 No, decimal 22 0x0000560B, // 119 No, decimal 11 0x0002720A, // 120 Nl, identifier start, decimal 25 0x0002400A, // 121 Nl, identifier start, decimal 0 0x00000013, // 122 Cs 0x00000012 // 123 Co }; // Return c converted to upper case. If c cannot be converted to upper case, // return c unchanged. char16 JS::toUpper(char16 c) { CharInfo ci(c); if (ci.info & 0x00100000) c = static_cast(static_cast(c) - (static_cast(ci.info) >> 22)); return c; } // Return c converted to lower case. If c cannot be converted to lower case, // return c unchanged. char16 JS::toLower(char16 c) { CharInfo ci(c); if (ci.info & 0x00200000) c = static_cast(static_cast(c) + (static_cast(ci.info) >> 22)); return c; } // Return true if c is an ASCII hexadecimal digit, in which case store the digit's numeric value in d. bool JS::isASCIIHexDigit(char16 c, uint &digit) { uint cv = c; if (cv < '0') return false; if (cv <= '9') { digit = cv - '0'; return true; } cv |= 0x20; if (cv >= 'a' && cv <= 'f') { digit = cv - 'a' + 10; return true; } return false; } // Return str advanced past white space characters, but no further than strEnd. const char16 *JS::skipWhiteSpace(const char16 *str, const char16 *strEnd) { while (str != strEnd && isSpace(*str)) str++; return str; } // // Zones // // #define DEBUG_ZONE to allocate each object in its own malloc block. // This allows tools such as Purify to do bounds checking on all blocks. // Construct a Zone that allocates memory in chunks of the given size. JS::Zone::Zone(size_t blockSize): headers(0), freeBegin(0), freeEnd(0), blockSize(blockSize) { ASSERT(blockSize && !(blockSize & basicAlignment-1)); } // Deallocate the Zone's blocks. void JS::Zone::clear() { Header *h = headers; while (h) { Header *next = h->next; STD::free(h); h = next; } headers = 0; } // Allocate a fully aligned block of the given size. // Throw bad_alloc if out of memory, without corrupting any of the Zone data structures. void *JS::Zone::newBlock(size_t size) { Header *h = static_cast
(STD::malloc(sizeof(Header) + size)); h->next = headers; headers = h; return h+1; } // Allocate a naturally-aligned object of the given size (in bytes). Throw // bad_alloc if out of memory, without corrupting any of the Zone data structures. void *JS::Zone::allocate(size_t size) { ASSERT(size); // Can't allocate zero-size blocks. #ifdef DEBUG_ZONE return newBlock(size); #else size = size + (basicAlignment-1) & -basicAlignment; // Round up to natural alignment if necessary char *p = freeBegin; size_t freeBytes = static_cast(freeEnd - p); if (size > freeBytes) { // If freeBytes is at least a quarter of blockSize, allocate a separate block. if (freeBytes<<2 >= blockSize || size >= blockSize) return newBlock(size); p = static_cast(newBlock(blockSize)); freeEnd = p + blockSize; } freeBegin = p + size; return p; #endif } // Same as allocate but does not align size up to basicAlignment. Thus, the next // object allocated in the zone will immediately follow this one if it falls in the same zone block. // Use this when all objects in the zone have the same size. void *JS::Zone::allocateUnaligned(size_t size) { ASSERT(size); // Can't allocate zero-size blocks. #ifdef DEBUG_ZONE return newBlock(size); #else char *p = freeBegin; size_t freeBytes = static_cast(freeEnd - p); if (size > freeBytes) { // If freeBytes is at least a quarter of blockSize, allocate a separate block. if (freeBytes<<2 >= blockSize || size >= blockSize) return newBlock(size); p = static_cast(newBlock(blockSize)); freeEnd = p + blockSize; } freeBegin = p + size; return p; #endif } // // Arenas // struct JS::Arena::DestructorEntry: JS::ArenaObject { DestructorEntry *next; // Next destructor registration in linked list void (*destructor)(void *); // Destructor function void *object; // Object on which to call the destructor DestructorEntry(void (*destructor)(void *), void *object): destructor(destructor), object(object) {} }; // Call the Arena's registered destructors. void JS::Arena::runDestructors() { DestructorEntry *e = destructorEntries; while (e) { e->destructor(e->object); e = e->next; } destructorEntries = 0; } // Ensure that object's destructor is called at the time the arena is deallocated or cleared. // The destructors will be called in reverse order of being registered. // registerDestructor might itself runs out of memory, in which case it immediately // calls object's destructor before throwing bad_alloc. void JS::Arena::newDestructorEntry(void (*destructor)(void *), void *object) { try { DestructorEntry *e = new(*this) DestructorEntry(destructor, object); e->next = destructorEntries; destructorEntries = e; } catch (...) { destructor(object); throw; } } // Allocate a String in the Arena and register that String so that it is deallocated at // the same time as the Arena. // DO NOT CALL DELETE ON THE RESULT! JS::String &JS::newArenaString(Arena &arena) { String *s = new(arena) String(); arena.registerDestructor(s); return *s; } JS::String &JS::newArenaString(Arena &arena, const String &str) { String *s = new(arena) String(str); arena.registerDestructor(s); return *s; } // // Input // // Read a line from the input file, including the trailing line break character. // Return the total number of characters read, which is str's length. // Translate and sequences to characters; a sequence // only counts as one character. size_t JS::LineReader::readLine(string &str) { int ch; bool oldCRWasLast = crWasLast; crWasLast = false; str.resize(0); while ((ch = getc(in)) != EOF) { if (ch == '\n') { if (!str.size() && oldCRWasLast) continue; str += '\n'; break; } if (ch == '\r') { crWasLast = true; str += '\n'; break; } str += static_cast(ch); } return str.size(); } size_t JS::LineReader::readLine(String &wstr) { string str; size_t n = readLine(str); wstr.resize(n); std::transform(str.begin(), str.end(), wstr.begin(), widen); return n; } // // Output // #ifdef XP_MAC_MPW // Macintosh MPW replacements for the ANSI routines. These translate LF's to CR's because // the MPW libraries supplied by Metrowerks don't do that for some reason. static void translateLFtoCR(char *begin, char *end) { while (begin != end) { if (*begin == '\n') *begin = '\r'; ++begin; } } size_t JS::printChars(FILE *file, const char *begin, const char *end) { ASSERT(end >= begin); size_t n = static_cast(end - begin); size_t extra = 0; char buffer[1024]; while (n > sizeof buffer) { std::memcpy(buffer, begin, sizeof buffer); translateLFtoCR(buffer, buffer + sizeof buffer); extra += fwrite(buffer, 1, sizeof buffer, file); n -= sizeof buffer; begin += sizeof buffer; } std::memcpy(buffer, begin, n); translateLFtoCR(buffer, buffer + n); return extra + fwrite(buffer, 1, n, file); } int std::fputc(int c, FILE *file) { char buffer = static_cast(c); if (buffer == '\n') buffer = '\r'; return static_cast(fwrite(&buffer, 1, 1, file)); } int std::fputs(const char *s, FILE *file) { return static_cast(JS::printChars(file, s, s + strlen(s))); } int std::fprintf(FILE* file, const char *format, ...) { JS::Buffer b; while (true) { va_list args; va_start(args, format); int n = vsnprintf(b.buffer, b.size, format, args); va_end(args); if (n >= 0 && n < b.size) { translateLFtoCR(b.buffer, b.buffer + n); return static_cast(fwrite(b.buffer, 1, static_cast(n), file)); } b.expand(b.size*2); } } #endif // XP_MAC_MPW // Write ch. void JS::Formatter::printChar8(char ch) { printStr8(&ch, &ch + 1); } // Write ch. void JS::Formatter::printChar16(char16 ch) { printStr16(&ch, &ch + 1); } // Write the null-terminated string str. void JS::Formatter::printZStr8(const char *str) { printStr8(str, str + strlen(str)); } // Write the String s. void JS::Formatter::printString16(const String &s) { const char16 *begin = s.data(); printStr16(begin, begin + s.size()); } // Write the printf format using the supplied args. void JS::Formatter::printVFormat8(const char *format, va_list args) { Buffer b; while (true) { int n = vsnprintf(b.buffer, b.size, format, args); if (n >= 0 && static_cast(n) < b.size) { printStr8(b.buffer, b.buffer + n); return; } b.expand(b.size*2); } } static const int printCharBufferSize = 64; // Print ch count times. void JS::printChar(Formatter &f, char ch, int count) { char str[printCharBufferSize]; while (count > 0) { int c = count; if (c > printCharBufferSize) c = printCharBufferSize; count -= c; STD::memset(str, ch, static_cast(c)); printString(f, str, str+c); } } // Print ch count times. void JS::printChar(Formatter &f, char16 ch, int count) { char16 str[printCharBufferSize]; while (count > 0) { int c = count; if (c > printCharBufferSize) c = printCharBufferSize; count -= c; char16 *strEnd = str + c; std::fill(str, strEnd, ch); printString(f, str, strEnd); } } // Print i using the given formatting string, padding on the left with pad characters // to use at least nDigits characters. void JS::printNum(Formatter &f, uint32 i, int nDigits, char pad, const char *format) { char str[20]; int n = sprintf(str, format, i); if (n < nDigits) printChar(f, pad, nDigits - n); printString(f, str, str+n); } // Print p as a pointer. void JS::printPtr(Formatter &f, void *p) { char str[20]; int n = sprintf(str, "%p", p); printString(f, str, str+n); } // printf formats for printing non-ASCII characters on an ASCII stream #ifdef XP_MAC static const char unprintableFormat[] = "\xC7%.4X\xC8"; // Use angle quotes #elif defined _WIN32 static const char unprintableFormat[] = "\xAB%.4X\xBB"; // Use angle quotes #else static const char unprintableFormat[] = "<%.4X>"; #endif static const uint16 defaultFilterRanges[] = { 0x00, 0x09, // Filter all control characters except \t and \n 0x0B, 0x20, 0x7F, 0x100, // Filter all non-ASCII characters 0, 0 }; JS::BitSet<256> JS::AsciiFileFormatter::defaultFilter(defaultFilterRanges); // Construct an AsciiFileFormatter using the given file and filter f. // If f is nil, use the default filter. JS::AsciiFileFormatter::AsciiFileFormatter(FILE *file, BitSet<256> *f): file(file) { if (f) filter = *f; else filter = defaultFilter; filterEmpty = filter.none(); } // Write ch, escaping non-ASCII characters. void JS::AsciiFileFormatter::printChar8(char ch) { if (filterChar(ch)) fprintf(file, unprintableFormat, static_cast(ch)); else fputc(ch, file); } // Write ch, escaping non-ASCII characters. void JS::AsciiFileFormatter::printChar16(char16 ch) { if (filterChar(ch)) fprintf(file, unprintableFormat, char16Value(ch)); else fputc(static_cast(ch), file); } // Write the null-terminated string str, escaping non-ASCII characters. void JS::AsciiFileFormatter::printZStr8(const char *str) { if (filterEmpty) fputs(str, file); else printStr8(str, str + strlen(str)); } // Write the string between strBegin and strEnd, escaping non-ASCII characters. void JS::AsciiFileFormatter::printStr8(const char *strBegin, const char *strEnd) { if (filterEmpty) printChars(file, strBegin, strEnd); else { ASSERT(strEnd >= strBegin); const char *p = strBegin; while (strBegin != strEnd) { char ch = *strBegin; if (filterChar(ch)) { if (p != strBegin) { printChars(file, p, strBegin); p = strBegin; } fprintf(file, unprintableFormat, static_cast(ch)); } ++strBegin; } if (p != strBegin) printChars(file, p, strBegin); } } // Write the string between strBegin and strEnd, escaping non-ASCII characters. void JS::AsciiFileFormatter::printStr16(const char16 *strBegin, const char16 *strEnd) { char buffer[512]; ASSERT(strEnd >= strBegin); char *q = buffer; while (strBegin != strEnd) { char16 ch = *strBegin++; if (filterChar(ch)) { if (q != buffer) { printChars(file, buffer, q); q = buffer; } fprintf(file, unprintableFormat, char16Value(ch)); } else { *q++ = static_cast(ch); if (q == buffer + sizeof buffer) { printChars(file, buffer, buffer + sizeof buffer); q = buffer; } } } if (q != buffer) printChars(file, buffer, q); } JS::AsciiFileFormatter JS::stdOut(stdout); JS::AsciiFileFormatter JS::stdErr(stderr); // Write ch. void JS::StringFormatter::printChar8(char ch) { s += ch; } // Write ch. void JS::StringFormatter::printChar16(char16 ch) { s += ch; } // Write the null-terminated string str. void JS::StringFormatter::printZStr8(const char *str) { s += str; } // Write the string between strBegin and strEnd. void JS::StringFormatter::printStr8(const char *strBegin, const char *strEnd) { appendChars(s, strBegin, strEnd); } // Write the string between strBegin and strEnd. void JS::StringFormatter::printStr16(const char16 *strBegin, const char16 *strEnd) { s.append(strBegin, strEnd); } // Write the String str. void JS::StringFormatter::printString16(const String &str) { s += str; } // // Formatted Output // // See "Prettyprinting" by Derek Oppen in ACM Transactions on Programming Languages and Systems 2:4, // October 1980, pages 477-482 for the algorithm. // The default line width for pretty printing uint32 JS::PrettyPrinter::defaultLineWidth = 20; // Create a PrettyPrinter that outputs to Formatter f. The PrettyPrinter breaks lines at // optional breaks so as to try not to exceed lines of width lineWidth, although it may not // always be able to do so. Formatter f should be at the beginning of a line. // Call end before destroying the Formatter; otherwise the last line may not be output to f. JS::PrettyPrinter::PrettyPrinter(Formatter &f, uint32 lineWidth): lineWidth(min(lineWidth, unlimitedLineWidth)), outputFormatter(f), outputPos(0), lineNum(0), lastBreak(0), margin(0), nNestedBlocks(0), leftSerialPos(0), rightSerialPos(0), itemPool(20) { #ifdef DEBUG topRegion = 0; #endif } // Destroy the PrettyPrinter. Because it's a very bad idea for a destructor to throw // exceptions, this destructor does not flush any buffered output. Call end just before // destroying the PrettyPrinter to do that. JS::PrettyPrinter::~PrettyPrinter() { ASSERT(!topRegion && !nNestedBlocks); } // Output either a line break (if sameLine is false) or length spaces (if sameLine is true). // Also advance leftSerialPos by length. // // If this method throws an exception, it is guaranteed to already have updated all of the // PrettyPrinter state; all that might be missing would be some output to outputFormatter. void JS::PrettyPrinter::outputBreak(bool sameLine, uint32 length) { leftSerialPos += length; if (sameLine) { outputPos += length; // Exceptions may be thrown below. printChar(outputFormatter, ' ', static_cast(length)); } else { lastBreak = ++lineNum; outputPos = margin; // Exceptions may be thrown below. outputFormatter << '\n'; printChar(outputFormatter, ' ', static_cast(margin)); } } // Check to see whether (rightSerialPos+rightOffset)-leftSerialPos has gotten so large that we may pop items // off the left end of activeItems because their totalLengths are known to be larger than the // amount of space left on the current line. // Return true if there are any items left on activeItems. // // If this method throws an exception, it leaves the PrettyPrinter in a consistent state, having // atomically popped off one or more items from the left end of activeItems. bool JS::PrettyPrinter::reduceLeftActiveItems(uint32 rightOffset) { uint32 newRightSerialPos = rightSerialPos + rightOffset; while (activeItems) { Item *leftItem = &activeItems.front(); if (itemStack && leftItem == itemStack.front()) { if (outputPos + newRightSerialPos - leftSerialPos > lineWidth) { itemStack.pop_front(); leftItem->lengthKnown = true; leftItem->totalLength = infiniteLength; } else if (leftItem->lengthKnown) itemStack.pop_front(); } if (!leftItem->lengthKnown) return true; activeItems.pop_front(); try { uint32 length = leftItem->length; switch (leftItem->kind) { case Item::text: { outputPos += length; leftSerialPos += length; // Exceptions may be thrown below. char16 *textBegin; char16 *textEnd; do { length -= itemText.pop_front(length, textBegin, textEnd); printString(outputFormatter, textBegin, textEnd); } while (length); } break; case Item::blockBegin: case Item::indentBlockBegin: { BlockInfo *b = savedBlocks.advance_back(); b->margin = margin; b->lastBreak = lastBreak; b->fits = outputPos + leftItem->totalLength <= lineWidth; if (leftItem->hasKind(Item::blockBegin)) margin = outputPos; else margin += length; } break; case Item::blockEnd: { BlockInfo &b = savedBlocks.pop_back(); margin = b.margin; lastBreak = b.lastBreak; } break; case Item::indent: margin += length; ASSERT(static_cast(margin) >= 0); break; case Item::linearBreak: // Exceptions may be thrown below, but only after updating the PrettyPrinter. outputBreak(savedBlocks.back().fits, length); break; case Item::fillBreak: // Exceptions may be thrown below, but only after updating the PrettyPrinter. outputBreak(lastBreak == lineNum && outputPos + leftItem->totalLength <= lineWidth, length); break; } } catch (...) { itemPool.destroy(leftItem); throw; } itemPool.destroy(leftItem); } return false; } // A break or end of input is about to be processed. Check whether there are any complete // blocks or clumps on the itemStack whose lengths we can now compute; if so, compute these // and pop them off the itemStack. // The current rightSerialPos must be the beginning of the break or end of input. // // This method can't throw exceptions. void JS::PrettyPrinter::reduceRightActiveItems() { uint32 nUnmatchedBlockEnds = 0; while (itemStack) { Item *rightItem = itemStack.pop_back(); switch (rightItem->kind) { case Item::blockBegin: case Item::indentBlockBegin: if (!nUnmatchedBlockEnds) { itemStack.fast_push_back(rightItem); return; } rightItem->computeTotalLength(rightSerialPos); --nUnmatchedBlockEnds; break; case Item::blockEnd: ++nUnmatchedBlockEnds; break; case Item::linearBreak: case Item::fillBreak: rightItem->computeTotalLength(rightSerialPos); if (!nUnmatchedBlockEnds) return; // There can be at most one consecutive break posted on the itemStack. break; default: ASSERT(false); // Other kinds can't be pushed onto the itemStack. } } } // Indent the beginning of every new line after this one by offset until the corresponding endIndent // call. Return an Item to pass to endIndent that will end this indentation. // This method may throw an exception, in which case the PrettyPrinter is left unchanged. JS::PrettyPrinter::Item &JS::PrettyPrinter::beginIndent(int32 offset) { Item *unindent = new(itemPool) Item(Item::indent, static_cast(-offset)); if (activeItems) { try { activeItems.push_back(*new(itemPool) Item(Item::indent, static_cast(offset))); } catch (...) { itemPool.destroy(unindent); throw; } } else { margin += offset; ASSERT(static_cast(margin) >= 0); } return *unindent; } // End an indent began by beginIndent. i should be the result of a beginIndent. // This method can't throw exceptions (it's called by the Indent destructor). void JS::PrettyPrinter::endIndent(Item &i) { if (activeItems) activeItems.push_back(i); else { margin += i.length; ASSERT(static_cast(margin) >= 0); itemPool.destroy(&i); } } // Begin a logical block. If kind is Item::indentBlockBegin, offset is the indent to use for // the second and subsequent lines of this block. // Return an Item to pass to endBlock that will end this block. // This method may throw an exception, in which case the PrettyPrinter is left unchanged. JS::PrettyPrinter::Item &JS::PrettyPrinter::beginBlock(Item::Kind kind, int32 offset) { uint32 newNNestedBlocks = nNestedBlocks + 1; savedBlocks.reserve(newNNestedBlocks); itemStack.reserve_back(1 + newNNestedBlocks); Item *endItem = new(itemPool) Item(Item::blockEnd); Item *beginItem; try { beginItem = new(itemPool) Item(kind, static_cast(offset), rightSerialPos); } catch (...) { itemPool.destroy(endItem); throw; } // No state modifications before this point. // No exceptions after this point. activeItems.push_back(*beginItem); itemStack.fast_push_back(beginItem); nNestedBlocks = newNNestedBlocks; return *endItem; } // End a logical block began by beginBlock. i should be the result of a beginBlock. // This method can't throw exceptions (it's called by the Block destructor). void JS::PrettyPrinter::endBlock(Item &i) { activeItems.push_back(i); itemStack.fast_push_back(&i); --nNestedBlocks; } // Write a conditional line break. This kind of a line break can only be emitted inside a block. // // A linear line break starts a new line if the containing block cannot be put all one one line; // otherwise the line break is replaced by nSpaces spaces. // Typically a block contains several linear breaks; either they all start new lines or none of them do. // Moreover, if a block directly contains a required break then linear breaks become required breaks. // // A fill line break starts a new line if either the preceding clump or the following clump cannot // be placed entirely on one line or if the following clump would not fit on the current line. A // clump is a consecutive sequence of strings and nested blocks delimited by either a break or the // beginning or end of the currently enclosing block. // // If this method throws an exception, it leaves the PrettyPrinter in a consistent state. void JS::PrettyPrinter::conditionalBreak(uint32 nSpaces, Item::Kind kind) { ASSERT(nSpaces <= unlimitedLineWidth && nNestedBlocks); reduceRightActiveItems(); itemStack.reserve_back(1 + nNestedBlocks); // Begin of exception-atomic stack update. Only new(itemPool) can throw an exception here, // in which case nothing is updated. Item *i = new(itemPool) Item(kind, nSpaces, rightSerialPos); activeItems.push_back(*i); itemStack.fast_push_back(i); rightSerialPos += nSpaces; // End of exception-atomic stack update. reduceLeftActiveItems(0); } // Write the string between strBegin and strEnd. Any embedded newlines ('\n' only) // become required line breaks. // // If this method throws an exception, it may have partially formatted the string but // leaves the PrettyPrinter in a consistent state. void JS::PrettyPrinter::printStr8(const char *strBegin, const char *strEnd) { while (strBegin != strEnd) { const char *sectionEnd = findValue(strBegin, strEnd, '\n'); uint32 sectionLength = static_cast(sectionEnd - strBegin); if (sectionLength) { if (reduceLeftActiveItems(sectionLength)) { itemText.reserve_back(sectionLength); Item &backItem = activeItems.back(); // Begin of exception-atomic update. Only new(itemPool) // can throw an exception here, in which case nothing is updated. if (backItem.hasKind(Item::text)) backItem.length += sectionLength; else activeItems.push_back(*new(itemPool) Item(Item::text, sectionLength)); rightSerialPos += sectionLength; itemText.fast_append(reinterpret_cast(strBegin), reinterpret_cast(sectionEnd)); // End of exception-atomic update. } else { ASSERT(!itemStack && !activeItems && !itemText && leftSerialPos == rightSerialPos); outputPos += sectionLength; printString(outputFormatter, strBegin, sectionEnd); } strBegin = sectionEnd; if (strBegin == strEnd) break; } requiredBreak(); ++strBegin; } } // Write the string between strBegin and strEnd. Any embedded newlines ('\n' only) // become required line breaks. // // If this method throws an exception, it may have partially formatted the string but // leaves the PrettyPrinter in a consistent state. void JS::PrettyPrinter::printStr16(const char16 *strBegin, const char16 *strEnd) { while (strBegin != strEnd) { const char16 *sectionEnd = findValue(strBegin, strEnd, uni::lf); uint32 sectionLength = static_cast(sectionEnd - strBegin); if (sectionLength) { if (reduceLeftActiveItems(sectionLength)) { itemText.reserve_back(sectionLength); Item &backItem = activeItems.back(); // Begin of exception-atomic update. Only new(itemPool) // can throw an exception here, in which case nothing is updated. if (backItem.hasKind(Item::text)) backItem.length += sectionLength; else activeItems.push_back(*new(itemPool) Item(Item::text, sectionLength)); rightSerialPos += sectionLength; itemText.fast_append(strBegin, sectionEnd); // End of exception-atomic update. } else { ASSERT(!itemStack && !activeItems && !itemText && leftSerialPos == rightSerialPos); outputPos += sectionLength; printString(outputFormatter, strBegin, sectionEnd); } strBegin = sectionEnd; if (strBegin == strEnd) break; } requiredBreak(); ++strBegin; } } // Write a required line break. // // If this method throws an exception, it may have emitted partial output but // leaves the PrettyPrinter in a consistent state. void JS::PrettyPrinter::requiredBreak() { reduceRightActiveItems(); reduceLeftActiveItems(infiniteLength); ASSERT(!itemStack && !activeItems && !itemText && leftSerialPos == rightSerialPos); outputBreak(false, 0); } // If required is true, write a required line break; otherwise write a linear line break // of the given width. // // If this method throws an exception, it may have emitted partial output but // leaves the PrettyPrinter in a consistent state. void JS::PrettyPrinter::linearBreak(uint32 nSpaces, bool required) { if (required) requiredBreak(); else linearBreak(nSpaces); } // Flush any saved output in the PrettyPrinter to the output. Call this just before // destroying the PrettyPrinter. All Indent and Block objects must have been exited already. // // If this method throws an exception, it may have emitted partial output but // leaves the PrettyPrinter in a consistent state. void JS::PrettyPrinter::end() { ASSERT(!topRegion); reduceRightActiveItems(); reduceLeftActiveItems(infiniteLength); ASSERT(!savedBlocks && !itemStack && !activeItems && !itemText && rightSerialPos == leftSerialPos && !margin); } // // Exceptions // static const char *const kindStrings[] = { "Syntax error", // syntaxError "Stack overflow" // stackOverflow }; // Return a null-terminated string describing the exception's kind. const char *JS::Exception::kindString() const { return kindStrings[kind]; } // Return the full error message. JS::String JS::Exception::fullMessage() const { String m(widenCString("In ")); m += sourceFile; if (lineNum) { char b[32]; sprintf(b, ", line %d:\n", lineNum); m += b; m += sourceLine; m += '\n'; String sourceLine2(sourceLine); insertChars(sourceLine2, charNum, "[ERROR]"); m += sourceLine2; m += '\n'; } else m += ":\n"; m += kindString(); m += ": "; m += message; m += '\n'; return m; } // // Static Initializers // #ifndef _WIN32 static void jsNewHandler() { std::bad_alloc outOfMemory; throw outOfMemory; } struct InitUtilities { InitUtilities() {std::set_new_handler(&jsNewHandler);} }; #else #include static int jsNewHandler(size_t) { std::bad_alloc outOfMemory; throw outOfMemory; } struct InitUtilities { InitUtilities() {_set_new_handler(&jsNewHandler);} }; #endif InitUtilities initUtilities;