| 1831 | } |
| 1832 | |
| 1833 | GDScriptParser::SuiteNode *GDScriptParser::parse_suite(const String &p_context, SuiteNode *p_suite, bool p_for_lambda) { |
| 1834 | SuiteNode *suite = p_suite != nullptr ? p_suite : alloc_node<SuiteNode>(); |
| 1835 | suite->parent_block = current_suite; |
| 1836 | suite->parent_function = current_function; |
| 1837 | current_suite = suite; |
| 1838 | |
| 1839 | if (!p_for_lambda && suite->parent_block != nullptr && suite->parent_block->is_in_loop) { |
| 1840 | // Do not reset to false if true is set before calling parse_suite(). |
| 1841 | suite->is_in_loop = true; |
| 1842 | } |
| 1843 | |
| 1844 | bool multiline = false; |
| 1845 | |
| 1846 | if (match(GDScriptTokenizer::Token::NEWLINE)) { |
| 1847 | multiline = true; |
| 1848 | } |
| 1849 | |
| 1850 | if (multiline) { |
| 1851 | if (!consume(GDScriptTokenizer::Token::INDENT, vformat(R"(Expected indented block after %s.)", p_context))) { |
| 1852 | current_suite = suite->parent_block; |
| 1853 | complete_extents(suite); |
| 1854 | return suite; |
| 1855 | } |
| 1856 | } |
| 1857 | reset_extents(suite, current); |
| 1858 | |
| 1859 | int error_count = 0; |
| 1860 | |
| 1861 | do { |
| 1862 | if (is_at_end() || (!multiline && previous.type == GDScriptTokenizer::Token::SEMICOLON && check(GDScriptTokenizer::Token::NEWLINE))) { |
| 1863 | break; |
| 1864 | } |
| 1865 | Node *statement = parse_statement(); |
| 1866 | if (statement == nullptr) { |
| 1867 | if (error_count++ > 100) { |
| 1868 | push_error("Too many statement errors.", suite); |
| 1869 | break; |
| 1870 | } |
| 1871 | continue; |
| 1872 | } |
| 1873 | suite->statements.push_back(statement); |
| 1874 | |
| 1875 | // Register locals. |
| 1876 | switch (statement->type) { |
| 1877 | case Node::VARIABLE: { |
| 1878 | VariableNode *variable = static_cast<VariableNode *>(statement); |
| 1879 | const SuiteNode::Local &local = current_suite->get_local(variable->identifier->name); |
| 1880 | if (local.type != SuiteNode::Local::UNDEFINED) { |
| 1881 | push_error(vformat(R"(There is already a %s named "%s" declared in this scope.)", local.get_name(), variable->identifier->name), variable->identifier); |
| 1882 | } |
| 1883 | current_suite->add_local(variable, current_function); |
| 1884 | break; |
| 1885 | } |
| 1886 | case Node::CONSTANT: { |
| 1887 | ConstantNode *constant = static_cast<ConstantNode *>(statement); |
| 1888 | const SuiteNode::Local &local = current_suite->get_local(constant->identifier->name); |
| 1889 | if (local.type != SuiteNode::Local::UNDEFINED) { |
| 1890 | String name; |