Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Keywords "true", "false", and "null" are now lower-case. ("NULL" can also optionally be all upper-case.) Use && and || instead of AND and OR. |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
340cf0441f074c039d1180f822bbfe52 |
User & Date: | drh 2011-07-15 18:22:48 |
Context
2011-07-15
| ||
18:36 | Change the NOT operator into !. check-in: 59096a3d9c user: drh tags: trunk | |
18:22 | Keywords "true", "false", and "null" are now lower-case. ("NULL" can also optionally be all upper-case.) Use && and || instead of AND and OR. check-in: 340cf0441f user: drh tags: trunk | |
18:14 | Add the bitwise expression operators (&, |, <<, >> and ~). Also fix the unary minus operator. check-in: d06f20c02a user: dan tags: trunk | |
Changes
Changes to src/tokenize.c.
82
83
84
85
86
87
88
89
90
91
92
93
94
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */ }; /********************************************************************** ** The following code is automatically generated ** by ../tool/mkkeywordhash.c */ /* Hash score: 57 */ static int keywordCode(const char *z, int n){ /* zText[] encodes 295 bytes of keywords in 204 bytes */ /* BEGINSERTRUELSELECTFALSEACHAVINGROUPDATESCAPEXCEPTALLIKEXISTS */ /* ANDELETEASCENDINGLOBETWEENOTCOLLATECOLLECTIONULLIMITCOMMIT */ /* CREATEDESCENDINGDROPRAGMAFLATTENIFROMINTERSECTINTOFFSETORDER */ /* OLLBACKUNIONVALUEWHEREBY */ static const char zText[203] = { 'B','E','G','I','N','S','E','R','T','R','U','E','L','S','E','L','E','C', 'T','F','A','L','S','E','A','C','H','A','V','I','N','G','R','O','U','P', 'D','A','T','E','S','C','A','P','E','X','C','E','P','T','A','L','L','I', 'K','E','X','I','S','T','S','A','N','D','E','L','E','T','E','A','S','C', 'E','N','D','I','N','G','L','O','B','E','T','W','E','E','N','O','T','C', 'O','L','L','A','T','E','C','O','L','L','E','C','T','I','O','N','U','L', 'L','I','M','I','T','C','O','M','M','I','T','C','R','E','A','T','E','D', 'E','S','C','E','N','D','I','N','G','D','R','O','P','R','A','G','M','A', 'F','L','A','T','T','E','N','I','F','R','O','M','I','N','T','E','R','S', 'E','C','T','I','N','T','O','F','F','S','E','T','O','R','D','E','R','O', 'L','L','B','A','C','K','U','N','I','O','N','V','A','L','U','E','W','H', 'E','R','E','B','Y', }; static const unsigned char aHash[80] = { 0, 49, 47, 13, 34, 23, 48, 1, 0, 9, 0, 15, 26, 10, 12, 0, 0, 45, 0, 8, 37, 36, 29, 0, 0, 0, 0, 38, 0, 0, 0, 19, 0, 0, 0, 42, 0, 0, 5, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 25, 30, 41, 24, 43, 28, 0, 17, 33, 40, 20, 44, 0, 39, 6, 0, 0, 35, 0, 0, 27, 18, 0, 0, 0, 31, 22, 16, }; static const unsigned char aNext[49] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 21, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 7, 32, 0, 0, 0, 0, 0, }; static const unsigned char aLen[49] = { 5, 6, 4, 4, 6, 5, 4, 6, 5, 6, 6, 6, 3, 4, 6, 2, 3, 6, 2, 3, 9, 4, 7, 3, 7, 10, 4, 5, 6, 6, 4, 10, 2, 4, 6, 7, 2, 4, 9, 4, 6, 3, 2, 5, 8, 5, 5, 5, 2, }; static const unsigned short int aOffset[49] = { 0, 3, 8, 11, 13, 19, 23, 26, 31, 34, 39, 44, 50, 52, 55, 57, 61, 63, 69, 69, 69, 77, 80, 86, 89, 96, 105, 108, 113, 119, 125, 125, 132, 135, 138, 144, 151, 152, 156, 165, 168, 171, 174, 174, 178, 186, 191, 196, 201, }; static const unsigned char aCode[49] = { TK_BEGIN, TK_INSERT, TK_TRUE, TK_ELSE, TK_SELECT, TK_FALSE, TK_FLATTENOP, TK_HAVING, TK_GROUP, TK_UPDATE, TK_ESCAPE, TK_EXCEPT, TK_ALL, TK_LIKEOP, TK_EXISTS, TK_IS, TK_AND, TK_DELETE, TK_AS, TK_ASCENDING, TK_ASCENDING, TK_LIKEOP, TK_BETWEEN, TK_NOT, TK_COLLATE, TK_COLLECTION, TK_NULL, TK_LIMIT, TK_COMMIT, TK_CREATE, TK_DESCENDING, TK_DESCENDING, TK_IN, TK_DROP, TK_PRAGMA, TK_FLATTENOP, TK_IF, TK_FROM, TK_INTERSECT, TK_INTO, TK_OFFSET, TK_SET, TK_OR, TK_ORDER, TK_ROLLBACK, TK_UNION, TK_VALUE, TK_WHERE, TK_BY, }; int h, i; if( n<2 || z[0]<'A' || z[0]>'Z' ) return TK_ID; h = (z[0]*4 ^ z[n-1]*3 ^ n) % 80; for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){ if( aLen[i]==n && memcmp(&zText[aOffset[i]],z,n)==0 ){ return aCode[i]; } } return TK_ID; } #define XJD1_N_KEYWORD 49 /* End of the automatically generated hash code *********************************************************************/ /* ** Return the length of the token that begins at z[0]. ** Store the token type in *tokenType before returning. ................................................................................ } } case '|': { if( z[1]!='|' ){ *tokenType = TK_BITOR; return 1; }else{ *tokenType = TK_CONCAT; return 2; } } case ',': { *tokenType = TK_COMMA; return 1; } case ':': { *tokenType = TK_COLON; return 1; } case '&': { *tokenType = TK_BITAND; return 1; } case '~': { *tokenType = TK_BITNOT; return 1; } case '"': { int delim = z[0]; |
|
|
|
|
|
|
|
>
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
<
|
|
>
|
<
|
|
|
>
>
>
>
|
|
>
|
82
83
84
85
86
87
88
89
90
91
92
93
94
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
|
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */ }; /********************************************************************** ** The following code is automatically generated ** by ../tool/mkkeywordhash.c */ /* Hash score: 58 */ static int keywordCode(const char *z, int n){ /* zText[] encodes 300 bytes of keywords in 211 bytes */ /* BEGINTORDEROLLBACKELSELECTGROUPDATEACHAVINGLOBETWEENULLIKE */ /* SCAPEXISTSALLIMITANDELETEXCEPTASCENDINGCOLLATECOLLECTIONOT */ /* CREATEDESCENDINGDROPRAGMAFLATTENIFROMUNIONVALUEWHEREBYCOMMIT */ /* INSERTINTERSECTOFFSETfalsenulltrue */ static const char zText[210] = { 'B','E','G','I','N','T','O','R','D','E','R','O','L','L','B','A','C','K', 'E','L','S','E','L','E','C','T','G','R','O','U','P','D','A','T','E','A', 'C','H','A','V','I','N','G','L','O','B','E','T','W','E','E','N','U','L', 'L','I','K','E','S','C','A','P','E','X','I','S','T','S','A','L','L','I', 'M','I','T','A','N','D','E','L','E','T','E','X','C','E','P','T','A','S', 'C','E','N','D','I','N','G','C','O','L','L','A','T','E','C','O','L','L', 'E','C','T','I','O','N','O','T','C','R','E','A','T','E','D','E','S','C', 'E','N','D','I','N','G','D','R','O','P','R','A','G','M','A','F','L','A', 'T','T','E','N','I','F','R','O','M','U','N','I','O','N','V','A','L','U', 'E','W','H','E','R','E','B','Y','C','O','M','M','I','T','I','N','S','E', 'R','T','I','N','T','E','R','S','E','C','T','O','F','F','S','E','T','f', 'a','l','s','e','n','u','l','l','t','r','u','e', }; static const unsigned char aHash[80] = { 0, 42, 40, 19, 34, 13, 41, 1, 49, 8, 0, 50, 28, 9, 23, 0, 0, 5, 48, 11, 37, 36, 43, 0, 0, 0, 0, 38, 0, 0, 0, 24, 0, 0, 0, 47, 0, 0, 7, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 27, 30, 46, 29, 10, 20, 0, 21, 33, 2, 25, 32, 0, 45, 0, 0, 0, 35, 0, 0, 26, 22, 0, 0, 0, 31, 44, 18, }; static const unsigned char aNext[50] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 16, 4, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 17, }; static const unsigned char aLen[50] = { 5, 4, 2, 5, 8, 4, 6, 5, 6, 4, 6, 4, 7, 4, 4, 6, 6, 2, 3, 5, 3, 6, 6, 2, 3, 9, 7, 10, 3, 6, 4, 10, 2, 4, 6, 7, 2, 4, 5, 5, 5, 2, 6, 6, 9, 6, 3, 5, 4, 4, }; static const unsigned short int aOffset[50] = { 0, 3, 6, 6, 10, 18, 20, 26, 29, 34, 37, 42, 45, 51, 54, 57, 62, 64, 68, 70, 75, 77, 82, 88, 88, 88, 97, 104, 113, 116, 122, 122, 129, 132, 135, 141, 148, 149, 153, 158, 163, 168, 170, 176, 182, 191, 194, 197, 202, 206, }; static const unsigned char aCode[50] = { TK_BEGIN, TK_INTO, TK_OR, TK_ORDER, TK_ROLLBACK, TK_ELSE, TK_SELECT, TK_GROUP, TK_UPDATE, TK_FLATTENOP, TK_HAVING, TK_LIKEOP, TK_BETWEEN, TK_NULL, TK_LIKEOP, TK_ESCAPE, TK_EXISTS, TK_IS, TK_ALL, TK_LIMIT, TK_AND, TK_DELETE, TK_EXCEPT, TK_AS, TK_ASCENDING, TK_ASCENDING, TK_COLLATE, TK_COLLECTION, TK_NOT, TK_CREATE, TK_DESCENDING, TK_DESCENDING, TK_IN, TK_DROP, TK_PRAGMA, TK_FLATTENOP, TK_IF, TK_FROM, TK_UNION, TK_VALUE, TK_WHERE, TK_BY, TK_COMMIT, TK_INSERT, TK_INTERSECT, TK_OFFSET, TK_SET, TK_FALSE, TK_NULL, TK_TRUE, }; int h, i; if( n<2 ) return TK_ID; h = (z[0]*4 ^ z[n-1]*3 ^ n) % 80; for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){ if( aLen[i]==n && memcmp(&zText[aOffset[i]],z,n)==0 ){ return aCode[i]; } } return TK_ID; } #define XJD1_N_KEYWORD 50 /* End of the automatically generated hash code *********************************************************************/ /* ** Return the length of the token that begins at z[0]. ** Store the token type in *tokenType before returning. ................................................................................ } } case '|': { if( z[1]!='|' ){ *tokenType = TK_BITOR; return 1; }else{ *tokenType = TK_OR; return 2; } } case ',': { *tokenType = TK_COMMA; return 1; } case ':': { *tokenType = TK_COLON; return 1; } case '&': { if( z[1]=='&' ){ *tokenType = TK_AND; return 2; }else{ *tokenType = TK_BITAND; return 1; } } case '~': { *tokenType = TK_BITNOT; return 1; } case '"': { int delim = z[0]; |
Changes to test/base02.test.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
..
99
100
101
102
103
104
105
106
|
-- Basic sanity checking. -- .new t1.db CREATE COLLECTION c1; INSERT INTO c1 VALUE { x:true }; .testcase 1 SELECT 1 FROM c1 WHERE TRUE; SELECT 2 FROM c1 WHERE 1.0; SELECT 3 FROM c1 WHERE 0.1; SELECT 4 FROM c1 WHERE -0.1; SELECT 5 FROM c1 WHERE {a:1}; SELECT 6 FROM c1 WHERE [1]; SELECT 7 FROM c1 WHERE "x"; SELECT 8 FROM c1 WHERE "1"; SELECT 9 FROM c1 WHERE "0"; SELECT 10 FROM c1 WHERE "false"; .result 1 2 3 4 5 6 7 8 9 10 .testcase 2 SELECT 1 FROM c1 WHERE FALSE; SELECT 2 FROM c1 WHERE NULL; SELECT 3 FROM c1 WHERE 0.0; SELECT 4 FROM c1 WHERE ""; .result .testcase 3 SELECT TRUE AND TRUE FROM c1; SELECT TRUE AND FALSE FROM c1; SELECT FALSE AND TRUE FROM c1; SELECT FALSE AND FALSE FROM c1; SELECT "cat" AND "dog" FROM c1; SELECT "" AND "dog" FROM c1; .result true false false false "dog" "" .testcase 4 SELECT TRUE OR TRUE FROM c1; SELECT TRUE OR FALSE FROM c1; SELECT FALSE OR TRUE FROM c1; SELECT FALSE OR FALSE FROM c1; SELECT "cat" OR "dog" FROM c1; SELECT "" OR "dog" FROM c1; .result true true true false "cat" "dog" .testcase 5 SELECT NOT TRUE FROM c1; SELECT NOT FALSE FROM c1; SELECT NOT "cat" FROM c1; SELECT NOT "" FROM c1; .result false true false true .testcase 6 SELECT 1 & 2 FROM c1; SELECT "5" & 4 FROM c1; ................................................................................ .result 8 49 69 .testcase 15 SELECT 1 - 7 FROM c1; SELECT 45 - 4 FROM c1; SELECT 67 - 2 FROM c1; .result -6 41 65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
..
99
100
101
102
103
104
105
|
-- Basic sanity checking. -- .new t1.db CREATE COLLECTION c1; INSERT INTO c1 VALUE { x:true }; .testcase 1 SELECT 1 FROM c1 WHERE true; SELECT 2 FROM c1 WHERE 1.0; SELECT 3 FROM c1 WHERE 0.1; SELECT 4 FROM c1 WHERE -0.1; SELECT 5 FROM c1 WHERE {a:1}; SELECT 6 FROM c1 WHERE [1]; SELECT 7 FROM c1 WHERE "x"; SELECT 8 FROM c1 WHERE "1"; SELECT 9 FROM c1 WHERE "0"; SELECT 10 FROM c1 WHERE "false"; .result 1 2 3 4 5 6 7 8 9 10 .testcase 2 SELECT 1 FROM c1 WHERE false; SELECT 2 FROM c1 WHERE NULL; SELECT 3 FROM c1 WHERE 0.0; SELECT 4 FROM c1 WHERE ""; .result .testcase 3 SELECT true && true FROM c1; SELECT true && false FROM c1; SELECT false && true FROM c1; SELECT false && false FROM c1; SELECT "cat" && "dog" FROM c1; SELECT "" && "dog" FROM c1; .result true false false false "dog" "" .testcase 4 SELECT true || true FROM c1; SELECT true || false FROM c1; SELECT false || true FROM c1; SELECT false || false FROM c1; SELECT "cat" || "dog" FROM c1; SELECT "" || "dog" FROM c1; .result true true true false "cat" "dog" .testcase 5 SELECT NOT true FROM c1; SELECT NOT false FROM c1; SELECT NOT "cat" FROM c1; SELECT NOT "" FROM c1; .result false true false true .testcase 6 SELECT 1 & 2 FROM c1; SELECT "5" & 4 FROM c1; ................................................................................ .result 8 49 69 .testcase 15 SELECT 1 - 7 FROM c1; SELECT 45 - 4 FROM c1; SELECT 67 - 2 FROM c1; .result -6 41 65 |
Changes to tool/mkkeywordhash.c.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 .. 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 ... 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
{ "DESC", "TK_DESCENDING", }, { "DROP", "TK_DROP", }, { "EACH", "TK_FLATTENOP", }, { "ELSE", "TK_ELSE", }, { "ESCAPE", "TK_ESCAPE", }, { "EXCEPT", "TK_EXCEPT", }, { "EXISTS", "TK_EXISTS", }, { "FALSE", "TK_FALSE", }, { "FLATTEN", "TK_FLATTENOP", }, { "FROM", "TK_FROM", }, { "GLOB", "TK_LIKEOP", }, { "GROUP", "TK_GROUP", }, { "HAVING", "TK_HAVING", }, { "IF", "TK_IF", }, { "INSERT", "TK_INSERT", }, ................................................................................ { "IN", "TK_IN", }, { "INTO", "TK_INTO", }, { "IS", "TK_IS", }, { "LIKE", "TK_LIKEOP", }, { "LIMIT", "TK_LIMIT", }, { "NOT", "TK_NOT", }, { "NULL", "TK_NULL", }, { "OFFSET", "TK_OFFSET", }, { "ORDER", "TK_ORDER", }, { "OR", "TK_OR", }, { "PRAGMA", "TK_PRAGMA", }, { "ROLLBACK", "TK_ROLLBACK", }, { "SELECT", "TK_SELECT", }, { "SET", "TK_SET", }, { "TRUE", "TK_TRUE", }, { "UNION", "TK_UNION", }, { "UPDATE", "TK_UPDATE", }, { "VALUE", "TK_VALUE", }, { "WHERE", "TK_WHERE", }, }; /* Number of keywords */ ................................................................................ printf("\n"); j = 0; } } printf("%s };\n", j==0 ? "" : "\n"); printf(" int h, i;\n"); printf(" if( n<2 || z[0]<'A' || z[0]>'Z' ) return TK_ID;\n"); printf(" h = (z[0]*4 ^ z[n-1]*3 ^ n) %% %d;\n", bestSize); printf(" for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){\n"); printf(" if( aLen[i]==n && memcmp(&zText[aOffset[i]],z,n)==0 ){\n"); printf(" return aCode[i];\n"); printf(" }\n"); printf(" }\n"); printf(" return TK_ID;\n"); |
| > | | |
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 .. 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 ... 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
{ "DESC", "TK_DESCENDING", }, { "DROP", "TK_DROP", }, { "EACH", "TK_FLATTENOP", }, { "ELSE", "TK_ELSE", }, { "ESCAPE", "TK_ESCAPE", }, { "EXCEPT", "TK_EXCEPT", }, { "EXISTS", "TK_EXISTS", }, { "false", "TK_FALSE", }, { "FLATTEN", "TK_FLATTENOP", }, { "FROM", "TK_FROM", }, { "GLOB", "TK_LIKEOP", }, { "GROUP", "TK_GROUP", }, { "HAVING", "TK_HAVING", }, { "IF", "TK_IF", }, { "INSERT", "TK_INSERT", }, ................................................................................ { "IN", "TK_IN", }, { "INTO", "TK_INTO", }, { "IS", "TK_IS", }, { "LIKE", "TK_LIKEOP", }, { "LIMIT", "TK_LIMIT", }, { "NOT", "TK_NOT", }, { "NULL", "TK_NULL", }, { "null", "TK_NULL", }, { "OFFSET", "TK_OFFSET", }, { "ORDER", "TK_ORDER", }, { "OR", "TK_OR", }, { "PRAGMA", "TK_PRAGMA", }, { "ROLLBACK", "TK_ROLLBACK", }, { "SELECT", "TK_SELECT", }, { "SET", "TK_SET", }, { "true", "TK_TRUE", }, { "UNION", "TK_UNION", }, { "UPDATE", "TK_UPDATE", }, { "VALUE", "TK_VALUE", }, { "WHERE", "TK_WHERE", }, }; /* Number of keywords */ ................................................................................ printf("\n"); j = 0; } } printf("%s };\n", j==0 ? "" : "\n"); printf(" int h, i;\n"); printf(" if( n<2 ) return TK_ID;\n"); printf(" h = (z[0]*4 ^ z[n-1]*3 ^ n) %% %d;\n", bestSize); printf(" for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){\n"); printf(" if( aLen[i]==n && memcmp(&zText[aOffset[i]],z,n)==0 ){\n"); printf(" return aCode[i];\n"); printf(" }\n"); printf(" }\n"); printf(" return TK_ID;\n"); |