blob: d62b6a5d537d9e13fa1ae54d23e307bd50ed6f7d [file] [log] [blame]
Steve Blockd0582a62009-12-15 09:54:21 +00001// Copyright 2006-2009 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <stdlib.h>
29
30#include "v8.h"
31
32#include "token.h"
33#include "scanner.h"
34#include "utils.h"
35
36#include "cctest.h"
37
38namespace i = ::v8::internal;
39
40TEST(KeywordMatcher) {
41 struct KeywordToken {
42 const char* keyword;
43 i::Token::Value token;
44 };
45
46 static const KeywordToken keywords[] = {
47#define KEYWORD(t, s, d) { s, i::Token::t },
48#define IGNORE(t, s, d) /* */
49 TOKEN_LIST(IGNORE, KEYWORD, IGNORE)
50#undef KEYWORD
51 { NULL, i::Token::IDENTIFIER }
52 };
53
54 static const char* future_keywords[] = {
55#define FUTURE(t, s, d) s,
56 TOKEN_LIST(IGNORE, IGNORE, FUTURE)
57#undef FUTURE
58#undef IGNORE
59 NULL
60 };
61
62 KeywordToken key_token;
63 for (int i = 0; (key_token = keywords[i]).keyword != NULL; i++) {
64 i::KeywordMatcher matcher;
65 const char* keyword = key_token.keyword;
66 int length = i::StrLength(keyword);
67 for (int j = 0; j < length; j++) {
68 if (key_token.token == i::Token::INSTANCEOF && j == 2) {
69 // "in" is a prefix of "instanceof". It's the only keyword
70 // that is a prefix of another.
71 CHECK_EQ(i::Token::IN, matcher.token());
72 } else {
73 CHECK_EQ(i::Token::IDENTIFIER, matcher.token());
74 }
75 matcher.AddChar(keyword[j]);
76 }
77 CHECK_EQ(key_token.token, matcher.token());
78 // Adding more characters will make keyword matching fail.
79 matcher.AddChar('z');
80 CHECK_EQ(i::Token::IDENTIFIER, matcher.token());
81 // Adding a keyword later will not make it match again.
82 matcher.AddChar('i');
83 matcher.AddChar('f');
84 CHECK_EQ(i::Token::IDENTIFIER, matcher.token());
85 }
86
87 // Future keywords are not recognized.
88 const char* future_keyword;
89 for (int i = 0; (future_keyword = future_keywords[i]) != NULL; i++) {
90 i::KeywordMatcher matcher;
91 int length = i::StrLength(future_keyword);
92 for (int j = 0; j < length; j++) {
93 matcher.AddChar(future_keyword[j]);
94 }
95 CHECK_EQ(i::Token::IDENTIFIER, matcher.token());
96 }
97
98 // Zero isn't ignored at first.
99 i::KeywordMatcher bad_start;
100 bad_start.AddChar(0);
101 CHECK_EQ(i::Token::IDENTIFIER, bad_start.token());
102 bad_start.AddChar('i');
103 bad_start.AddChar('f');
104 CHECK_EQ(i::Token::IDENTIFIER, bad_start.token());
105
106 // Zero isn't ignored at end.
107 i::KeywordMatcher bad_end;
108 bad_end.AddChar('i');
109 bad_end.AddChar('f');
110 CHECK_EQ(i::Token::IF, bad_end.token());
111 bad_end.AddChar(0);
112 CHECK_EQ(i::Token::IDENTIFIER, bad_end.token());
113
114 // Case isn't ignored.
115 i::KeywordMatcher bad_case;
116 bad_case.AddChar('i');
117 bad_case.AddChar('F');
118 CHECK_EQ(i::Token::IDENTIFIER, bad_case.token());
119
120 // If we mark it as failure, continuing won't help.
121 i::KeywordMatcher full_stop;
122 full_stop.AddChar('i');
123 CHECK_EQ(i::Token::IDENTIFIER, full_stop.token());
124 full_stop.Fail();
125 CHECK_EQ(i::Token::IDENTIFIER, full_stop.token());
126 full_stop.AddChar('f');
127 CHECK_EQ(i::Token::IDENTIFIER, full_stop.token());
128}
129