/* * Rust is very liberal with nesting, so this function is used pretty much for any block */ static void parseBlock (lexerState *lexer, boolean delim, int kind, vString *scope) { int level = 1; if (delim) { if (lexer->cur_token != '{') return; advanceToken(lexer, TRUE); } while (lexer->cur_token != TOKEN_EOF) { if (lexer->cur_token == TOKEN_IDENT) { size_t old_scope_len = vStringLength(scope); if (strcmp(lexer->token_str->buffer, "fn") == 0) { parseFn(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "mod") == 0) { parseMod(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "static") == 0) { parseStatic(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "trait") == 0) { parseTrait(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "type") == 0) { parseType(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "impl") == 0) { parseImpl(lexer, scope, kind); } else if(strcmp(lexer->token_str->buffer, "struct") == 0) { parseStructOrEnum(lexer, scope, kind, TRUE); } else if(strcmp(lexer->token_str->buffer, "enum") == 0) { parseStructOrEnum(lexer, scope, kind, FALSE); } else if(strcmp(lexer->token_str->buffer, "macro_rules") == 0) { parseMacroRules(lexer, scope, kind); } else { advanceToken(lexer, TRUE); if (lexer->cur_token == '!') { skipMacro(lexer); } } resetScope(scope, old_scope_len); } else if (lexer->cur_token == '{') { level++; advanceToken(lexer, TRUE); } else if (lexer->cur_token == '}') { level--; advanceToken(lexer, TRUE); } else if (lexer->cur_token == '\'') { /* Skip over the 'static lifetime, as it confuses the static parser above */ advanceToken(lexer, TRUE); if (lexer->cur_token == TOKEN_IDENT && strcmp(lexer->token_str->buffer, "static") == 0) advanceToken(lexer, TRUE); } else { advanceToken(lexer, TRUE); } if (delim && level <= 0) break; } }
static void enterScope (tokenInfo *const parentToken, const vString *const extraScope, const int parentKind) { tokenInfo *token = newToken (); int origParentKind = parentToken->parentKind; copyToken (token, parentToken, TRUE); if (extraScope) { token->parentKind = parentKind; addToScope (token, extraScope, origParentKind); } readToken (token); while (token->type != TOKEN_EOF && token->type != TOKEN_CLOSE_CURLY) { boolean readNext = TRUE; switch (token->type) { case TOKEN_OPEN_CURLY: enterScope (token, NULL, -1); break; case TOKEN_KEYWORD: switch (token->keyword) { /* handle anonymous classes */ case KEYWORD_new: readToken (token); if (token->keyword != KEYWORD_class) readNext = FALSE; else { char buf[32]; tokenInfo *name = newToken (); copyToken (name, token, TRUE); snprintf (buf, sizeof buf, "AnonymousClass%u", ++AnonymousID); vStringCopyS (name->string, buf); readNext = parseClassOrIface (token, K_CLASS, name); deleteToken (name); } break; case KEYWORD_class: readNext = parseClassOrIface (token, K_CLASS, NULL); break; case KEYWORD_interface: readNext = parseClassOrIface (token, K_INTERFACE, NULL); break; case KEYWORD_trait: readNext = parseTrait (token); break; case KEYWORD_function: readNext = parseFunction (token, NULL); break; case KEYWORD_const: readNext = parseConstant (token); break; case KEYWORD_define: readNext = parseDefine (token); break; case KEYWORD_namespace: readNext = parseNamespace (token); break; case KEYWORD_private: CurrentStatement.access = ACCESS_PRIVATE; break; case KEYWORD_protected: CurrentStatement.access = ACCESS_PROTECTED; break; case KEYWORD_public: CurrentStatement.access = ACCESS_PUBLIC; break; case KEYWORD_var: CurrentStatement.access = ACCESS_PUBLIC; break; case KEYWORD_abstract: CurrentStatement.impl = IMPL_ABSTRACT; break; default: break; } break; case TOKEN_VARIABLE: readNext = parseVariable (token); break; default: break; } if (readNext) readToken (token); } copyToken (parentToken, token, FALSE); parentToken->parentKind = origParentKind; deleteToken (token); }