iv-phonic 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,78 +3,54 @@
3
3
  #include <cassert>
4
4
  #include <tr1/cstdint>
5
5
  #include "uchar.h"
6
- #include "ucdata.h"
6
+ #include "character.h"
7
7
 
8
8
  namespace iv {
9
9
  namespace core {
10
10
 
11
11
  class Chars {
12
12
  public:
13
- enum CharCategory {
14
- UPPERCASE_LETTER = 1 << UC16::kUpperCaseLetter,
15
- LOWERCASE_LETTER = 1 << UC16::kLowerCaseLetter,
16
- TITLECASE_LETTER = 1 << UC16::kTitleCaseLetter,
17
- MODIFIER_LETTER = 1 << UC16::kModifierLetter,
18
- OTHER_LETTER = 1 << UC16::kOtherLetter,
19
- NON_SPACING_MARK = 1 << UC16::kNonSpacingMark,
20
- COMBINING_SPACING_MARK = 1 << UC16::kCombiningSpacingMark,
21
- DECIMAL_DIGIT_NUMBER = 1 << UC16::kDecimalDigitNumber,
22
- SPACE_SEPARATOR = 1 << UC16::kSpaceSeparator,
23
- CONNECTOR_PUNCTUATION = 1 << UC16::kConnectorPunctuation
24
- };
25
13
  static inline uint32_t Category(const int c) {
26
- assert(c <= 0xffff+1);
27
- return (c < 0) ? 1 : (1 << UnicodeData::kCategory[c]);
14
+ return (c < 0) ? 0 : character::GetCategory(c);
28
15
  }
29
16
  static inline bool IsASCII(const int c) {
30
- return !(c & ~0x7F);
17
+ return (c >= 0) && character::IsASCII(c);
31
18
  }
32
19
  static inline bool IsASCIIAlpha(const int c) {
33
- return (c | 0x20) >= 'a' && (c | 0x20) <= 'z';
20
+ return (c >= 0) && character::IsASCIIAlpha(c);
34
21
  }
35
22
  static inline bool IsASCIIAlphanumeric(const int c) {
36
- return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z');
23
+ return (c >= 0) && character::IsASCIIAlphanumeric(c);
37
24
  }
38
25
  static inline bool IsNonASCIIIdentifierStart(const int c) {
39
- return Category(c) & (UPPERCASE_LETTER | LOWERCASE_LETTER |
40
- TITLECASE_LETTER | MODIFIER_LETTER | OTHER_LETTER);
26
+ return (c >= 0) && character::IsNonASCIIIdentifierStart(c);
41
27
  }
42
28
  static inline bool IsNonASCIIIdentifierPart(const int c) {
43
- return Category(c) & (UPPERCASE_LETTER | LOWERCASE_LETTER |
44
- TITLECASE_LETTER | MODIFIER_LETTER |
45
- OTHER_LETTER | NON_SPACING_MARK |
46
- COMBINING_SPACING_MARK |
47
- DECIMAL_DIGIT_NUMBER |
48
- CONNECTOR_PUNCTUATION);
29
+ return (c >= 0) && character::IsNonASCIIIdentifierPart(c);
49
30
  }
50
31
  static inline bool IsSeparatorSpace(const int c) {
51
- return UnicodeData::kCategory[c] == UC16::kSpaceSeparator;
32
+ return (c >= 0) && character::IsSeparatorSpace(c);
52
33
  }
53
34
  static inline bool IsWhiteSpace(const int c) {
54
- return IsASCII(c) ?
55
- (c == ' ' || c == '\t' || c == 0xB || c == 0xC) : IsSeparatorSpace(c);
35
+ return (c >= 0) && character::IsWhiteSpace(c);
56
36
  }
57
37
  static inline bool IsLineTerminator(const int c) {
58
- return c == '\r' || c == '\n' || (c & ~1) == 0x2028;
38
+ return (c >= 0) && character::IsLineTerminator(c);
59
39
  }
60
40
  static inline bool IsHexDigit(const int c) {
61
- return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f');
41
+ return (c >= 0) && character::IsHexDigit(c);
62
42
  }
63
43
  static inline bool IsDecimalDigit(const int c) {
64
- return c >= '0' && c <= '9';
44
+ return (c >= 0) && character::IsDecimalDigit(c);
65
45
  }
66
46
  static inline bool IsOctalDigit(const int c) {
67
- return c >= '0' && c <= '7';
47
+ return (c >= 0) && character::IsOctalDigit(c);
68
48
  }
69
49
  static inline bool IsIdentifierStart(const int c) {
70
- return IsASCII(c) ? c == '$' || c == '_' ||
71
- c == '\\' || IsASCIIAlpha(c) :
72
- IsNonASCIIIdentifierStart(c);
50
+ return (c >= 0) && character::IsIdentifierStart(c);
73
51
  }
74
52
  static inline bool IsIdentifierPart(const int c) {
75
- return IsASCII(c) ? c == '$' || c == '_' ||
76
- c == '\\' || IsASCIIAlphanumeric(c) :
77
- IsNonASCIIIdentifierPart(c);
53
+ return (c >= 0) && character::IsIdentifierPart(c);
78
54
  }
79
55
  };
80
56
 
@@ -1,12 +1,13 @@
1
- #ifndef IV_CONVERSIONS_H_
2
- #define IV_CONVERSIONS_H_
1
+ #ifndef _IV_CONVERSIONS_H_
2
+ #define _IV_CONVERSIONS_H_
3
3
  #include <cstdio>
4
4
  #include <cmath>
5
5
  #include <string>
6
6
  #include <limits>
7
7
  #include <tr1/array>
8
8
  #include <tr1/cstdint>
9
- #include "chars.h"
9
+ #include <tr1/cmath>
10
+ #include "character.h"
10
11
  #include "dtoa.h"
11
12
  #include "ustringpiece.h"
12
13
  #include "none.h"
@@ -60,7 +61,7 @@ inline double StringToDouble(Iter it, Iter last, bool parse_float) {
60
61
  }
61
62
 
62
63
  while (it != last &&
63
- (Chars::IsWhiteSpace(*it) || Chars::IsLineTerminator(*it))) {
64
+ (character::IsWhiteSpace(*it) || character::IsLineTerminator(*it))) {
64
65
  ++it;
65
66
  }
66
67
 
@@ -83,7 +84,7 @@ inline double StringToDouble(Iter it, Iter last, bool parse_float) {
83
84
  return Conversions::kNaN;
84
85
  }
85
86
 
86
- if (Chars::IsDecimalDigit(*it)) {
87
+ if (character::IsDecimalDigit(*it)) {
87
88
  if (*it == '0') {
88
89
  is_found_zero = true;
89
90
  ++it;
@@ -99,14 +100,14 @@ inline double StringToDouble(Iter it, Iter last, bool parse_float) {
99
100
  buffer[pos++] = *it;
100
101
  ++it;
101
102
  ++significant_digits;
102
- if (it == last || !Chars::IsHexDigit(*it)) {
103
+ if (it == last || !character::IsHexDigit(*it)) {
103
104
  return Conversions::kNaN;
104
105
  }
105
106
  // waste leading zero
106
107
  while (it != last && *it == '0') {
107
108
  ++it;
108
109
  }
109
- while (it != last && Chars::IsHexDigit(*it)) {
110
+ while (it != last && character::IsHexDigit(*it)) {
110
111
  if (significant_digits < Conversions::kMaxSignificantDigits) {
111
112
  buffer[pos++] = *it;
112
113
  ++it;
@@ -124,7 +125,7 @@ inline double StringToDouble(Iter it, Iter last, bool parse_float) {
124
125
  }
125
126
  if (is_decimal) {
126
127
  while (it != last &&
127
- Chars::IsDecimalDigit(*it)) {
128
+ character::IsDecimalDigit(*it)) {
128
129
  if (significant_digits < Conversions::kMaxSignificantDigits) {
129
130
  buffer[pos++] = *it;
130
131
  ++significant_digits;
@@ -137,7 +138,7 @@ inline double StringToDouble(Iter it, Iter last, bool parse_float) {
137
138
  buffer[pos++] = '.';
138
139
  ++it;
139
140
  while (it != last &&
140
- Chars::IsDecimalDigit(*it)) {
141
+ character::IsDecimalDigit(*it)) {
141
142
  if (significant_digits < Conversions::kMaxSignificantDigits) {
142
143
  buffer[pos++] = *it;
143
144
  ++significant_digits;
@@ -152,7 +153,7 @@ inline double StringToDouble(Iter it, Iter last, bool parse_float) {
152
153
  ++it;
153
154
  const Iter start = it;
154
155
  while (it != last &&
155
- Chars::IsDecimalDigit(*it)) {
156
+ character::IsDecimalDigit(*it)) {
156
157
  if (significant_digits < Conversions::kMaxSignificantDigits) {
157
158
  buffer[pos++] = *it;
158
159
  ++significant_digits;
@@ -173,7 +174,8 @@ inline double StringToDouble(Iter it, Iter last, bool parse_float) {
173
174
  }
174
175
  // infinity
175
176
  while (it != last &&
176
- (Chars::IsWhiteSpace(*it) || Chars::IsLineTerminator(*it))) {
177
+ (character::IsWhiteSpace(*it) ||
178
+ character::IsLineTerminator(*it))) {
177
179
  ++it;
178
180
  }
179
181
  if (it == last || parse_float) {
@@ -209,7 +211,7 @@ inline double StringToDouble(Iter it, Iter last, bool parse_float) {
209
211
  ++it;
210
212
  is_signed_exp = true;
211
213
  }
212
- if (it == last || !Chars::IsDecimalDigit(*it)) {
214
+ if (it == last || !character::IsDecimalDigit(*it)) {
213
215
  if (parse_float) {
214
216
  --it;
215
217
  --pos;
@@ -229,7 +231,7 @@ inline double StringToDouble(Iter it, Iter last, bool parse_float) {
229
231
  exponent = exponent * 10 + (*it - '0');
230
232
  }
231
233
  ++it;
232
- } while (it != last && Chars::IsDecimalDigit(*it));
234
+ } while (it != last && character::IsDecimalDigit(*it));
233
235
  exponent+=insignificant_digits;
234
236
  if (exponent > 9999) {
235
237
  exponent = 9999;
@@ -242,7 +244,7 @@ inline double StringToDouble(Iter it, Iter last, bool parse_float) {
242
244
  exponent_pasing_done:
243
245
 
244
246
  while (it != last &&
245
- (Chars::IsWhiteSpace(*it) || Chars::IsLineTerminator(*it))) {
247
+ (character::IsWhiteSpace(*it) || character::IsLineTerminator(*it))) {
246
248
  ++it;
247
249
  }
248
250
 
@@ -305,7 +307,7 @@ inline double StringToIntegerWithRadix(Iter it, Iter last,
305
307
  int radix, bool strip_prefix) {
306
308
  // remove leading white space
307
309
  while (it != last &&
308
- (Chars::IsWhiteSpace(*it) || Chars::IsLineTerminator(*it))) {
310
+ (character::IsWhiteSpace(*it) || character::IsLineTerminator(*it))) {
309
311
  ++it;
310
312
  }
311
313
 
@@ -411,6 +413,27 @@ inline uint32_t DoubleToUInt32(double d) {
411
413
  return static_cast<uint32_t>(DoubleToInt32(d));
412
414
  }
413
415
 
416
+ inline int64_t DoubleToInt64(double d) {
417
+ int64_t i = static_cast<int64_t>(d);
418
+ if (static_cast<double>(i) == d) {
419
+ return i;
420
+ }
421
+ if (!std::isfinite(d) || d == 0) {
422
+ return 0;
423
+ }
424
+ if (Conversions::DoubleToInt32_Two32 >= d) {
425
+ return static_cast<int64_t>(DoubleToInt32(d));
426
+ }
427
+ const int32_t lo = DoubleToInt32(
428
+ std::fmod(d, Conversions::DoubleToInt32_Two32));
429
+ const int32_t hi = DoubleToInt32(d / Conversions::DoubleToInt32_Two32);
430
+ return hi * 4294967296ULL + lo;
431
+ }
432
+
433
+ inline uint64_t DoubleToUInt64(double d) {
434
+ return static_cast<uint64_t>(DoubleToInt64(d));
435
+ }
436
+
414
437
  inline double DoubleToInteger(double d) {
415
438
  if (std::isnan(d)) {
416
439
  return 0;
@@ -434,7 +457,7 @@ inline bool ConvertToUInt32(Iter it, const Iter last, uint32_t* value) {
434
457
  return true;
435
458
  }
436
459
  }
437
- if (it != last && Chars::IsDecimalDigit(*it)) {
460
+ if (it != last && character::IsDecimalDigit(*it)) {
438
461
  ch = *it - '0';
439
462
  *value = ch;
440
463
  } else {
@@ -444,7 +467,7 @@ inline bool ConvertToUInt32(Iter it, const Iter last, uint32_t* value) {
444
467
  uint32_t prev = *value;
445
468
  for (;it != last; ++it) {
446
469
  prev = *value;
447
- if (Chars::IsDecimalDigit(*it)) {
470
+ if (character::IsDecimalDigit(*it)) {
448
471
  ch = *it - '0';
449
472
  *value = ch + (prev * 10);
450
473
  } else {
@@ -512,4 +535,4 @@ inline std::string DoubleToStringWithRadix(double v, int radix) {
512
535
  }
513
536
 
514
537
  } } // namespace iv::core
515
- #endif // IV_CONVERSIONS_H_
538
+ #endif // _IV_CONVERSIONS_H_
@@ -1,5 +1,5 @@
1
- #ifndef IV_LV5_DTOA_H_
2
- #define IV_LV5_DTOA_H_
1
+ #ifndef _IV_DTOA_H_
2
+ #define _IV_DTOA_H_
3
3
  // Double to String
4
4
 
5
5
  // David M Gay's algorithm and V8 fast-dtoa
@@ -16,5 +16,5 @@ namespace core {
16
16
 
17
17
  using v8::internal::DoubleToCString;
18
18
 
19
- } } // namespace iv::lv5
20
- #endif // IV_LV5_DTOA_H_
19
+ } } // namespace iv::core
20
+ #endif // _IV_DTOA_H_
@@ -364,7 +364,7 @@ class Lexer: private Noncopyable<Lexer<Source> >::type {
364
364
  return buffer16_;
365
365
  }
366
366
 
367
- inline const std::string& Buffer8() const {
367
+ inline const std::vector<char>& Buffer8() const {
368
368
  return buffer8_;
369
369
  }
370
370
 
@@ -482,6 +482,17 @@ class Lexer: private Noncopyable<Lexer<Source> >::type {
482
482
  Advance();
483
483
  }
484
484
 
485
+ void Initialize(const Source* src) {
486
+ using std::swap;
487
+ source_ = src;
488
+ pos_ = 0;
489
+ end_ = source_->size();
490
+ has_line_terminator_before_next_ = false;
491
+ has_shebang_ = false;
492
+ line_number_ = 1;
493
+ swap(location_, Location());
494
+ }
495
+
485
496
  inline void Advance() {
486
497
  if (pos_ == end_) {
487
498
  c_ = -1;
@@ -795,13 +806,14 @@ class Lexer: private Noncopyable<Lexer<Source> >::type {
795
806
 
796
807
  if (type == OCTAL) {
797
808
  double val = 0;
798
- for (std::string::const_iterator it = buffer8_.begin(),
809
+ for (typename std::vector<char>::const_iterator it = buffer8_.begin(),
799
810
  last = buffer8_.end(); it != last; ++it) {
800
811
  val = val * 8 + (*it - '0');
801
812
  }
802
813
  numeric_ = val;
803
814
  } else {
804
- numeric_ = std::atof(buffer8_.c_str());
815
+ const std::string buf(buffer8_.begin(), buffer8_.end());
816
+ numeric_ = std::atof(buf.c_str());
805
817
  }
806
818
  type_ = type;
807
819
  return Token::NUMBER;
@@ -857,7 +869,7 @@ class Lexer: private Noncopyable<Lexer<Source> >::type {
857
869
  }
858
870
 
859
871
  const Source* source_;
860
- std::string buffer8_;
872
+ std::vector<char> buffer8_;
861
873
  std::vector<uc16> buffer16_;
862
874
  double numeric_;
863
875
  State type_;
@@ -23,7 +23,9 @@ struct Location {
23
23
  }
24
24
  };
25
25
 
26
+ #if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3)
26
27
  IV_STATIC_ASSERT(std::tr1::is_pod<Location>::value);
28
+ #endif
27
29
 
28
30
  } } // namespace iv::core
29
31
  #endif // _IV_LOCATION_H_
@@ -13,6 +13,7 @@
13
13
  #include "noncopyable.h"
14
14
  #include "utils.h"
15
15
  #include "ustring.h"
16
+ #include "enable_if.h"
16
17
  #include "none.h"
17
18
 
18
19
  #define IS(token)\
@@ -134,11 +135,12 @@ const UString ParserData<T>::kSet(
134
135
 
135
136
  typedef detail::ParserData<None> ParserData;
136
137
 
137
- template<typename Factory, typename Source>
138
- class Parser : private Noncopyable<Parser<Factory, Source> >::type {
138
+ template<typename Factory, typename Source, bool UseFunctionStatement>
139
+ class Parser
140
+ : private Noncopyable<Parser<Factory, Source, UseFunctionStatement> >::type {
139
141
  public:
140
- typedef Parser<Factory, Source> this_type;
141
- typedef Parser<Factory, Source> parser_type;
142
+ typedef Parser<Factory, Source, UseFunctionStatement> this_type;
143
+ typedef this_type parser_type;
142
144
  typedef Lexer<Source> lexer_type;
143
145
  #define V(AST) typedef typename ast::AST<Factory> AST;
144
146
  AST_NODE_LIST(V)
@@ -213,7 +215,7 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
213
215
 
214
216
  class TargetScope : private Noncopyable<Target>::type {
215
217
  public:
216
- TargetScope(parser_type* parser)
218
+ explicit TargetScope(parser_type* parser)
217
219
  : parser_(parser),
218
220
  target_(parser->target()),
219
221
  labels_(parser->labels()) {
@@ -266,33 +268,39 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
266
268
  // : Statements
267
269
  // | FunctionDeclaration
268
270
  bool ParseSourceElements(Token::Type end,
269
- FunctionLiteral* function, bool *res) {
271
+ FunctionLiteral* function,
272
+ bool *res) {
270
273
  Statement* stmt;
271
- bool recognize_use_strict_directive = true;
274
+ bool recognize_directive = true;
272
275
  const StrictSwitcher switcher(this);
273
276
  while (token_ != end) {
274
277
  if (token_ == Token::FUNCTION) {
275
278
  // FunctionDeclaration
276
279
  stmt = ParseFunctionDeclaration(CHECK);
277
280
  function->AddStatement(stmt);
281
+ recognize_directive = false;
278
282
  } else {
279
283
  stmt = ParseStatement(CHECK);
280
- // use strict directive check
281
- if (recognize_use_strict_directive &&
282
- !strict_ &&
283
- stmt->AsExpressionStatement()) {
284
- Expression* const expr = stmt->AsExpressionStatement()->expr();
285
- if (expr->AsDirectivable()) {
286
- if (expr->AsStringLiteral()->value().compare(
287
- ParserData::kUseStrict.data()) == 0) {
288
- switcher.SwitchStrictMode();
289
- function->set_strict(true);
284
+ // directive prologue
285
+ if (recognize_directive) {
286
+ if (stmt->AsExpressionStatement()) {
287
+ Expression* const expr = stmt->AsExpressionStatement()->expr();
288
+ if (expr->AsDirectivable()) {
289
+ // expression is directive
290
+ if (expr->AsStringLiteral()->value().compare(
291
+ ParserData::kUseStrict.data()) == 0) {
292
+ switcher.SwitchStrictMode();
293
+ function->set_strict(true);
294
+ }
295
+ } else {
296
+ recognize_directive = false;
290
297
  }
298
+ } else {
299
+ recognize_directive = false;
291
300
  }
292
301
  }
293
302
  function->AddStatement(stmt);
294
303
  }
295
- recognize_use_strict_directive = false;
296
304
  }
297
305
  return true;
298
306
  }
@@ -402,7 +410,7 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
402
410
  case Token::FUNCTION:
403
411
  // FunctionStatement (not in ECMA-262 5th)
404
412
  // FunctionExpression
405
- result = ParseFunctionStatement(CHECK);
413
+ result = ParseFunctionStatement<UseFunctionStatement>(CHECK);
406
414
  break;
407
415
 
408
416
  case Token::IDENTIFIER:
@@ -784,6 +792,13 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
784
792
  Statement* ParseReturnStatement(bool *res) {
785
793
  assert(token_ == Token::RETURN);
786
794
  Next();
795
+
796
+ if (scope_->IsGlobal()) {
797
+ // return statement found in global
798
+ // SyntaxError
799
+ RAISE("\"return\" not in function");
800
+ }
801
+
787
802
  if (lexer_.has_line_terminator_before_next() ||
788
803
  token_ == Token::SEMICOLON ||
789
804
  token_ == Token::RBRACE ||
@@ -839,8 +854,21 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
839
854
 
840
855
  EXPECT(Token::LBRACE);
841
856
 
857
+ bool default_found = false;
842
858
  while (token_ != Token::RBRACE) {
843
- case_clause = ParseCaseClause(CHECK);
859
+ if (token_ == Token::CASE ||
860
+ token_ == Token::DEFAULT) {
861
+ case_clause = ParseCaseClause(CHECK);
862
+ } else {
863
+ UNEXPECT(token_);
864
+ }
865
+ if (case_clause->IsDefault()) {
866
+ if (default_found) {
867
+ RAISE("duplicate default clause in switch");
868
+ } else {
869
+ default_found = true;
870
+ }
871
+ }
844
872
  switch_stmt->AddCaseClause(case_clause);
845
873
  }
846
874
  Next();
@@ -918,6 +946,7 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
918
946
 
919
947
  Next();
920
948
 
949
+ IS(Token::LBRACE);
921
950
  Block* const try_block = ParseBlock(CHECK);
922
951
 
923
952
  if (token_ == Token::CATCH) {
@@ -942,6 +971,7 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
942
971
  }
943
972
  }
944
973
  EXPECT(Token::RPAREN);
974
+ IS(Token::LBRACE);
945
975
  catch_block = ParseBlock(CHECK);
946
976
  }
947
977
 
@@ -949,6 +979,7 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
949
979
  // Finally
950
980
  has_catch_or_finally= true;
951
981
  Next();
982
+ IS(Token::LBRACE);
952
983
  finally_block = ParseBlock(CHECK);
953
984
  }
954
985
 
@@ -1008,7 +1039,9 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
1008
1039
  return factory_->NewExpressionStatement(expr);
1009
1040
  }
1010
1041
 
1011
- Statement* ParseFunctionStatement(bool *res) {
1042
+ template<bool Use>
1043
+ Statement* ParseFunctionStatement(bool *res,
1044
+ typename enable_if_c<Use>::type* = 0) {
1012
1045
  assert(token_ == Token::FUNCTION);
1013
1046
  if (strict_) {
1014
1047
  RAISE("function statement not allowed in strict code");
@@ -1022,6 +1055,15 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
1022
1055
  return factory_->NewFunctionStatement(expr);
1023
1056
  }
1024
1057
 
1058
+ template<bool Use>
1059
+ Statement* ParseFunctionStatement(bool *res,
1060
+ typename enable_if_c<!Use>::type* = 0) {
1061
+ // FunctionStatement is not Standard
1062
+ // so, if template parameter UseFunctionStatement is false,
1063
+ // this parser reject FunctionStatement
1064
+ RAISE("function statement is not Standard");
1065
+ }
1066
+
1025
1067
  // Expression
1026
1068
  // : AssignmentExpression
1027
1069
  // | Expression ',' AssignmentExpression
@@ -1614,14 +1656,16 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
1614
1656
  template<typename Callable>
1615
1657
  Callable* ParseArguments(Callable* func, bool *res) {
1616
1658
  Next();
1617
- while (token_ != Token::RPAREN) {
1618
- Expression* const expr = ParseAssignmentExpression(true, CHECK);
1619
- func->AddArgument(expr);
1620
- if (token_ != Token::RPAREN) {
1621
- EXPECT(Token::COMMA);
1659
+ if (token_ != Token::RPAREN) {
1660
+ Expression* const first = ParseAssignmentExpression(true, CHECK);
1661
+ func->AddArgument(first);
1662
+ while (token_ == Token::COMMA) {
1663
+ Next();
1664
+ Expression* const expr = ParseAssignmentExpression(true, CHECK);
1665
+ func->AddArgument(expr);
1622
1666
  }
1623
1667
  }
1624
- Next();
1668
+ EXPECT(Token::RPAREN);
1625
1669
  return func;
1626
1670
  }
1627
1671
 
@@ -1871,29 +1915,33 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
1871
1915
  literal->AddParameter(ident);
1872
1916
  EXPECT(Token::RPAREN);
1873
1917
  } else {
1874
- while (token_ != Token::RPAREN) {
1875
- IS(Token::IDENTIFIER);
1876
- Identifier* const ident = ParseIdentifier(lexer_.Buffer());
1877
- if (!throw_error_if_strict_code) {
1878
- const EvalOrArguments val = IsEvalOrArguments(ident);
1879
- if (val) {
1880
- throw_error_if_strict_code = (val == kEval) ?
1881
- kDetectEvalParameter : kDetectArgumentsParameter;
1882
- throw_error_if_strict_code_line = lexer_.line_number();
1918
+ if (token_ != Token::RPAREN) {
1919
+ do {
1920
+ IS(Token::IDENTIFIER);
1921
+ Identifier* const ident = ParseIdentifier(lexer_.Buffer());
1922
+ if (!throw_error_if_strict_code) {
1923
+ const EvalOrArguments val = IsEvalOrArguments(ident);
1924
+ if (val) {
1925
+ throw_error_if_strict_code = (val == kEval) ?
1926
+ kDetectEvalParameter : kDetectArgumentsParameter;
1927
+ throw_error_if_strict_code_line = lexer_.line_number();
1928
+ }
1929
+ if ((!throw_error_if_strict_code) &&
1930
+ (param_set.find(ident) != param_set.end())) {
1931
+ throw_error_if_strict_code = kDetectDuplicateParameter;
1932
+ throw_error_if_strict_code_line = lexer_.line_number();
1933
+ }
1883
1934
  }
1884
- if ((!throw_error_if_strict_code) &&
1885
- (param_set.find(ident) != param_set.end())) {
1886
- throw_error_if_strict_code = kDetectDuplicateParameter;
1887
- throw_error_if_strict_code_line = lexer_.line_number();
1935
+ literal->AddParameter(ident);
1936
+ param_set.insert(ident);
1937
+ if (token_ == Token::COMMA) {
1938
+ Next();
1939
+ } else {
1940
+ break;
1888
1941
  }
1889
- }
1890
- literal->AddParameter(ident);
1891
- param_set.insert(ident);
1892
- if (token_ != Token::RPAREN) {
1893
- EXPECT(Token::COMMA);
1894
- }
1942
+ } while (true);
1895
1943
  }
1896
- Next();
1944
+ EXPECT(Token::RPAREN);
1897
1945
  }
1898
1946
 
1899
1947
  // '{' FunctionBody '}'
@@ -2032,9 +2080,9 @@ class Parser : private Noncopyable<Parser<Factory, Source> >::type {
2032
2080
  void SetErrorHeader(std::size_t line) {
2033
2081
  std::tr1::array<char, 40> buf;
2034
2082
  error_.append(lexer_.filename());
2035
- int num = std::snprintf(buf.data(), buf.size(),
2036
- ":%lu: SyntaxError: ",
2037
- static_cast<unsigned long>(line)); // NOLINT
2083
+ const int num = std::snprintf(buf.data(), buf.size(),
2084
+ ":%lu: SyntaxError: ",
2085
+ static_cast<unsigned long>(line)); // NOLINT
2038
2086
  error_.append(buf.data(), num);
2039
2087
  }
2040
2088