Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Rework TclGetIndexFromToken to make use of TclGetEndOffsetFromObj, and to lay out the index value encoding cases. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | bug-db36fa5122 |
Files: | files | file ages | folders |
SHA3-256: |
8cadbda624ef9b7ac006bda76841f724 |
User & Date: | dgp 2018-03-07 17:02:50.201 |
Context
2018-03-07
| ||
18:39 | Establish 4 symbols for categories of parsed index values: TCL_INDEX_START = 0 The start index.... check-in: 3f026007bd user: dgp tags: bug-db36fa5122 | |
17:02 | Rework TclGetIndexFromToken to make use of TclGetEndOffsetFromObj, and to lay out the index value en... check-in: 8cadbda624 user: dgp tags: bug-db36fa5122 | |
13:40 | Tests of [assemble] use of compiled index values. check-in: d6534fb386 user: dgp tags: bug-db36fa5122 | |
Changes
Changes to generic/tclCompCmdsGR.c.
︙ | ︙ | |||
30 31 32 33 34 35 36 | /* *---------------------------------------------------------------------- * * TclGetIndexFromToken -- * | | | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < > | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | /* *---------------------------------------------------------------------- * * TclGetIndexFromToken -- * * Parse a token to determine if an index value is known at * compile time. Two cases are possible. The compile time value * of the token might be parsed as an absolute index value * in the C signed int range. Note that this includes index * values that are integers as presented as well as index * arithmetic expressions that can be fully computed at compile * time. The absolute index values that can be directly meaningful * as an index into either a list or a string are those integer * values >= 0 and < INT_MAX. The largest string supported in Tcl 8 * has bytelength INT_MAX. This means the largest character supported * length is also INT_MAX, and the index of the last character in a * string of length INT_MAX is INT_MAX-1. * * Any absolute index value parsed outside that range is encoded * using the minBoundary and maxBounday values passed in by the * caller as the encoding to use for indices that are either * less than or greater than the usable index range. INT_MAX * is available as a good choice for most callers to use for * maxBoundary. Likewise, the value -1 is good for most callers * to use for minBoundary. * * A token can also be parsed as an end-relative index expression. * All end-relative expressions that indicate an index larger * than end (end+2, end--5) point beyond the end of the indexed * collection, and can be encoded as maxBoundary. The end-relative * expressions that indicate an index less than or equal to end * are encoded relative to the value TCL_INDEX_END (-2). The * index "end" is encoded as -2, down to the index "end-0x7ffffffe" * which is encoded as INT_MIN. Since the largest index into a * string possible in Tcl 8 is 0x7ffffffe, the interpretation of * "end-0x7ffffffe" for that largest string would be 0. Thus, * if the tokens "end-0x7fffffff" or "end+-0x80000000" are parsed, * they can be encoded with the minBoundary value. * * These details will require re-examination whenever string and * list length limits are increased, but that will likely also * mean a revised routine capable of returning Tcl_WideInt values. * * Returns: * TCL_OK if parsing succeeded, and TCL_ERROR if it failed. * * Side effects: * When TCL_OK is returned, the encoded index value is written * to *index. * *---------------------------------------------------------------------- */ int TclGetIndexFromToken( Tcl_Token *tokenPtr, |
︙ | ︙ | |||
65 66 67 68 69 70 71 | if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) { Tcl_DecrRefCount(tmpObj); return TCL_ERROR; } result = TclGetIntFromObj(NULL, tmpObj, &idx); if (result == TCL_OK) { | > | | > > > | > | < | | < > | > > | > | | | > > > > > > > > > > > > > > | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) { Tcl_DecrRefCount(tmpObj); return TCL_ERROR; } result = TclGetIntFromObj(NULL, tmpObj, &idx); if (result == TCL_OK) { /* We parsed a value in the range INT_MIN...INT_MAX */ integerEncode: if (idx < 0) { /* All negative absolute indices are "before the beginning" */ idx = minBoundary; } else if (idx == INT_MAX) { /* This index value is always "after the end" */ idx = maxBoundary; } /* usual case, the absolute index value encodes itself */ } else { result = TclGetEndOffsetFromObj(NULL, tmpObj, 0, &idx); if (result == TCL_OK) { /* * We parsed an end+offset index value. * idx holds the offset value in the range INT_MIN...INT_MAX. */ if (idx > 0) { /* * All end+postive or end-negative expressions * always indicate "after the end". */ idx = maxBoundary; } else if (idx < INT_MIN - TCL_INDEX_END) { /* These indices alwasy indicate "before the beginning */ idx = minBoundary; } else { /* Encoded end-positive (or end+negative) are offset */ idx += TCL_INDEX_END; } } else { result = TclGetIntForIndexM(NULL, tmpObj, 0, &idx); if (result == TCL_OK) { /* * Only reach this case when the index value is a * constant index arithmetic expression, and idx * holds the result. Treat it the same as if it were * parsed as an absolute integer value. */ goto integerEncode; } } } Tcl_DecrRefCount(tmpObj); if (result == TCL_OK) { *index = idx; |
︙ | ︙ |