iv-phonic 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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