OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 | 6 |
7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 }; | 254 }; |
255 | 255 |
256 | 256 |
257 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { | 257 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { |
258 inlined_finally_nodes_.Add(node); | 258 inlined_finally_nodes_.Add(node); |
259 } | 259 } |
260 | 260 |
261 | 261 |
262 // For parsing a compilation unit. | 262 // For parsing a compilation unit. |
263 Parser::Parser(const Script& script, const Library& library) | 263 Parser::Parser(const Script& script, const Library& library) |
264 : script_(script), | 264 : script_(Script::Handle(script.raw())), |
265 tokens_iterator_(TokenStream::Handle(script.tokens()), 0), | 265 tokens_iterator_(TokenStream::Handle(script.tokens()), 0), |
266 token_kind_(Token::kILLEGAL), | 266 token_kind_(Token::kILLEGAL), |
267 current_block_(NULL), | 267 current_block_(NULL), |
268 is_top_level_(false), | 268 is_top_level_(false), |
269 current_member_(NULL), | 269 current_member_(NULL), |
270 allow_function_literals_(true), | 270 allow_function_literals_(true), |
271 parsed_function_(NULL), | 271 parsed_function_(NULL), |
272 innermost_function_(Function::Handle()), | 272 innermost_function_(Function::Handle()), |
273 current_class_(Class::Handle()), | 273 current_class_(Class::Handle()), |
274 library_(library), | 274 library_(Library::Handle(library.raw())), |
275 try_blocks_list_(NULL) { | 275 try_blocks_list_(NULL) { |
276 ASSERT(tokens_iterator_.IsValid()); | 276 ASSERT(tokens_iterator_.IsValid()); |
277 ASSERT(!library.IsNull()); | 277 ASSERT(!library.IsNull()); |
278 } | 278 } |
279 | 279 |
280 | 280 |
281 // For parsing a function. | 281 // For parsing a function. |
282 Parser::Parser(const Script& script, | 282 Parser::Parser(const Script& script, |
283 ParsedFunction* parsed_function, | 283 ParsedFunction* parsed_function, |
284 intptr_t token_position) | 284 intptr_t token_position) |
285 : script_(script), | 285 : script_(Script::Handle(script.raw())), |
286 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), | 286 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), |
287 token_kind_(Token::kILLEGAL), | 287 token_kind_(Token::kILLEGAL), |
288 current_block_(NULL), | 288 current_block_(NULL), |
289 is_top_level_(false), | 289 is_top_level_(false), |
290 current_member_(NULL), | 290 current_member_(NULL), |
291 allow_function_literals_(true), | 291 allow_function_literals_(true), |
292 parsed_function_(parsed_function), | 292 parsed_function_(parsed_function), |
293 innermost_function_(Function::Handle(parsed_function->function().raw())), | 293 innermost_function_(Function::Handle(parsed_function->function().raw())), |
294 current_class_(Class::Handle(parsed_function->function().Owner())), | 294 current_class_(Class::Handle(parsed_function->function().Owner())), |
295 library_(Library::Handle(Class::Handle( | 295 library_(Library::Handle(Class::Handle( |
296 parsed_function->function().origin()).library())), | 296 parsed_function->function().origin()).library())), |
297 try_blocks_list_(NULL) { | 297 try_blocks_list_(NULL) { |
298 ASSERT(tokens_iterator_.IsValid()); | 298 ASSERT(tokens_iterator_.IsValid()); |
299 ASSERT(!current_function().IsNull()); | 299 ASSERT(!current_function().IsNull()); |
300 if (FLAG_enable_type_checks) { | 300 if (FLAG_enable_type_checks) { |
301 EnsureExpressionTemp(); | 301 EnsureExpressionTemp(); |
302 } | 302 } |
303 } | 303 } |
304 | 304 |
305 | 305 |
| 306 void Parser::SetScript(const Script & script, intptr_t token_pos) { |
| 307 script_ = script.raw(); |
| 308 tokens_iterator_.SetStream(TokenStream::Handle(script.tokens()), token_pos); |
| 309 token_kind_ = Token::kILLEGAL; |
| 310 } |
| 311 |
| 312 |
306 bool Parser::SetAllowFunctionLiterals(bool value) { | 313 bool Parser::SetAllowFunctionLiterals(bool value) { |
307 bool current_value = allow_function_literals_; | 314 bool current_value = allow_function_literals_; |
308 allow_function_literals_ = value; | 315 allow_function_literals_ = value; |
309 return current_value; | 316 return current_value; |
310 } | 317 } |
311 | 318 |
312 | 319 |
313 const Function& Parser::current_function() const { | 320 const Function& Parser::current_function() const { |
314 ASSERT(parsed_function() != NULL); | 321 ASSERT(parsed_function() != NULL); |
315 return parsed_function()->function(); | 322 return parsed_function()->function(); |
(...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1824 if (field.is_final()) { | 1831 if (field.is_final()) { |
1825 ErrorMsg("final field '%s' not initialized", | 1832 ErrorMsg("final field '%s' not initialized", |
1826 String::Handle(field.name()).ToCString()); | 1833 String::Handle(field.name()).ToCString()); |
1827 } else { | 1834 } else { |
1828 field.UpdateCid(kNullCid); | 1835 field.UpdateCid(kNullCid); |
1829 } | 1836 } |
1830 } | 1837 } |
1831 } | 1838 } |
1832 | 1839 |
1833 | 1840 |
| 1841 AstNode* Parser::ParseExternalInitializedField(const Field& field) { |
| 1842 // Only use this function if the initialized field originates |
| 1843 // from a different class. We need to save and restore current |
| 1844 // class, library, and token stream (script). |
| 1845 ASSERT(current_class().raw() != field.origin()); |
| 1846 const Class& saved_class = Class::Handle(current_class().raw()); |
| 1847 const Library& saved_library = Library::Handle(library().raw()); |
| 1848 const Script& saved_script = Script::Handle(script().raw()); |
| 1849 const intptr_t saved_token_pos = TokenPos(); |
| 1850 |
| 1851 set_current_class(Class::Handle(field.origin())); |
| 1852 set_library(Library::Handle(current_class().library())); |
| 1853 SetScript(Script::Handle(current_class().script()), field.token_pos()); |
| 1854 |
| 1855 ASSERT(IsIdentifier()); |
| 1856 ConsumeToken(); |
| 1857 ExpectToken(Token::kASSIGN); |
| 1858 AstNode* init_expr = NULL; |
| 1859 if (field.is_const()) { |
| 1860 init_expr = ParseConstExpr(); |
| 1861 } else { |
| 1862 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1863 if (init_expr->EvalConstExpr() != NULL) { |
| 1864 init_expr = |
| 1865 new LiteralNode(field.token_pos(), EvaluateConstExpr(init_expr)); |
| 1866 } |
| 1867 } |
| 1868 set_current_class(saved_class); |
| 1869 set_library(saved_library); |
| 1870 SetScript(saved_script, saved_token_pos); |
| 1871 return init_expr; |
| 1872 } |
| 1873 |
| 1874 |
1834 void Parser::ParseInitializedInstanceFields(const Class& cls, | 1875 void Parser::ParseInitializedInstanceFields(const Class& cls, |
1835 LocalVariable* receiver, | 1876 LocalVariable* receiver, |
1836 GrowableArray<Field*>* initialized_fields) { | 1877 GrowableArray<Field*>* initialized_fields) { |
1837 TRACE_PARSER("ParseInitializedInstanceFields"); | 1878 TRACE_PARSER("ParseInitializedInstanceFields"); |
1838 const Array& fields = Array::Handle(cls.fields()); | 1879 const Array& fields = Array::Handle(cls.fields()); |
1839 Field& f = Field::Handle(); | 1880 Field& f = Field::Handle(); |
1840 const intptr_t saved_pos = TokenPos(); | 1881 const intptr_t saved_pos = TokenPos(); |
1841 for (int i = 0; i < fields.Length(); i++) { | 1882 for (int i = 0; i < fields.Length(); i++) { |
1842 f ^= fields.At(i); | 1883 f ^= fields.At(i); |
1843 if (!f.is_static() && f.has_initializer()) { | 1884 if (!f.is_static() && f.has_initializer()) { |
1844 Field& field = Field::ZoneHandle(); | 1885 Field& field = Field::ZoneHandle(); |
1845 field ^= fields.At(i); | 1886 field ^= fields.At(i); |
1846 if (field.is_final()) { | 1887 if (field.is_final()) { |
1847 // Final fields with initializer expression may not be initialized | 1888 // Final fields with initializer expression may not be initialized |
1848 // again by constructors. Remember that this field is already | 1889 // again by constructors. Remember that this field is already |
1849 // initialized. | 1890 // initialized. |
1850 initialized_fields->Add(&field); | 1891 initialized_fields->Add(&field); |
1851 } | 1892 } |
1852 intptr_t field_pos = field.token_pos(); | 1893 AstNode* init_expr = NULL; |
1853 if (current_class().raw() != field.origin()) { | 1894 if (current_class().raw() != field.origin()) { |
1854 const Class& origin_class = Class::Handle(field.origin()); | 1895 init_expr = ParseExternalInitializedField(field); |
1855 if (origin_class.library() != library_.raw()) { | |
1856 ErrorMsg("Cannot handle initialized mixin field '%s'" | |
1857 "from imported library\n", field.ToCString()); | |
1858 } | |
1859 } | |
1860 SetPosition(field_pos); | |
1861 ASSERT(IsIdentifier()); | |
1862 ConsumeToken(); | |
1863 ExpectToken(Token::kASSIGN); | |
1864 | |
1865 AstNode* init_expr = NULL; | |
1866 if (field.is_const()) { | |
1867 init_expr = ParseConstExpr(); | |
1868 } else { | 1896 } else { |
1869 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 1897 SetPosition(field.token_pos()); |
1870 if (init_expr->EvalConstExpr() != NULL) { | 1898 ASSERT(IsIdentifier()); |
1871 init_expr = new LiteralNode(field_pos, EvaluateConstExpr(init_expr)); | 1899 ConsumeToken(); |
| 1900 ExpectToken(Token::kASSIGN); |
| 1901 if (field.is_const()) { |
| 1902 init_expr = ParseConstExpr(); |
| 1903 } else { |
| 1904 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1905 if (init_expr->EvalConstExpr() != NULL) { |
| 1906 init_expr = new LiteralNode(field.token_pos(), |
| 1907 EvaluateConstExpr(init_expr)); |
| 1908 } |
1872 } | 1909 } |
1873 } | 1910 } |
1874 ASSERT(init_expr != NULL); | 1911 ASSERT(init_expr != NULL); |
1875 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); | 1912 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); |
1876 EnsureExpressionTemp(); | 1913 EnsureExpressionTemp(); |
1877 AstNode* field_init = | 1914 AstNode* field_init = |
1878 new StoreInstanceFieldNode(field.token_pos(), | 1915 new StoreInstanceFieldNode(field.token_pos(), |
1879 instance, | 1916 instance, |
1880 field, | 1917 field, |
1881 init_expr); | 1918 init_expr); |
(...skipping 8110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9992 void Parser::SkipQualIdent() { | 10029 void Parser::SkipQualIdent() { |
9993 ASSERT(IsIdentifier()); | 10030 ASSERT(IsIdentifier()); |
9994 ConsumeToken(); | 10031 ConsumeToken(); |
9995 if (CurrentToken() == Token::kPERIOD) { | 10032 if (CurrentToken() == Token::kPERIOD) { |
9996 ConsumeToken(); // Consume the kPERIOD token. | 10033 ConsumeToken(); // Consume the kPERIOD token. |
9997 ExpectIdentifier("identifier expected after '.'"); | 10034 ExpectIdentifier("identifier expected after '.'"); |
9998 } | 10035 } |
9999 } | 10036 } |
10000 | 10037 |
10001 } // namespace dart | 10038 } // namespace dart |
OLD | NEW |