Decl& Parser::on_concept_declaration(Token, Name& n, Decl_list& ps) { Decl& decl = build.make_concept(n, ps); declare(cxt, current_scope(), decl); return decl; }
// Build and declare the class. Decl& Parser::start_class_declaration(Name& n) { Decl& d = cxt.make_class_declaration(n); declare(cxt, current_scope(), d); return d; }
Decl& Parser::on_type_template_parameter(Name& n, Type& t) { Decl& parm = build.make_type_parameter(n, t); declare(cxt, current_scope(), parm); return parm; }
// -------------------------------------------------------------------------- // // Coroutine Decl& Parser::on_coroutine_declaration(Name& n,Decl_list& p, Type& t, Stmt& s) { Decl& d = build.make_coroutine_declaration(n,p,t,s); declare(cxt, current_scope(), d); return d; }
Decl& Parser::on_class_declaration(Name& n, Type& t, Stmt& s) { Decl& d = build.make_class_declaration(n, t, s); declare(cxt, current_scope(), d); return d; }
// Declare the given definiton in the enclosing scope of current scope. Expr* declare_outside(Expr* t) { Scope* s = current_scope(); s=s->parent; if (Def* d = as<Def>(t)) { s->insert({d->name(),d}); return d; } }
Type& Parser::on_type_name(Token tok) { Simple_id& id = build.get_id(tok); Decl& decl = simple_lookup(cxt, current_scope(), id); if (Type* type = get_type_for_decl(cxt, decl)) return *type; throw Lookup_error("'{}' does not name a type", id); }
// FIXME: What if the identifier refers to a set of declarations? Decl& Parser::on_concept_name(Token tok) { Simple_id& id = build.get_id(tok); Decl& decl = simple_lookup(cxt, current_scope(), id); if (is<Concept_decl>(&decl)) return decl; throw Lookup_error("'{}' does not name a concept", id); }
// Associate the term t with the name n in the current scope. Expr* declare(Name* n, Expr* e) { Scope* s = current_scope(); if (s->count(n) != 0) { error(e->loc) << format("name '{}' already bound in this scope", pretty(n)); return nullptr; } s->insert({n, e}); return e; }
// Return the declaration associated with the name n, // or nullptr if no such name exists. Expr* lookup(Name* n) { Scope* s = current_scope(); while (s) { auto iter = s->find(n); if (iter != s->end()) return iter->second; s = s->parent; } return nullptr; }
Type& Parser::on_type_alias(Token tok) { Simple_id& id = build.get_id(tok); Decl& decl = simple_lookup(cxt, current_scope(), id); if (Type_parm* d = as<Type_parm>(&decl)) return build.get_typename_type(*d); // TODO: Actually support type aliases. throw Lookup_error("'{}' does not name a type", id); }
std::string SemState::define_var(Variable::VarType type, const std::string& name, int line) { // 检查符号名是否被重定义 std::vector<RoughSymbol>& scoped_symbols = current_scope()->scoped_symbols; for (size_t i = 0, sz = scoped_symbols.size(); i < sz; ++i) { const RoughSymbol& sym = scoped_symbols.at(i); if (sym.name == name) throw GrammarException("Symbol '" + name + "' redefined", line); } // 注册符号表 RoughSymbol sym(type, name); for (ssize_t i = _scope_stack.size() - 1; i >= 0; --i) { ScopeState *ss = _scope_stack.at(i); assert(NULL != ss); switch (ss->type) { case ScopeState::TYPE_ANNOYMOUS_SCOPE: continue; case ScopeState::TYPE_PROC_SCOPE: case ScopeState::TYPE_MODULE_SCOPE: { ProcScopeState *pss = (ProcScopeState*) ss; assert(NULL != pss); sym.uniq_name = pss->mk_uniq_name(name); scoped_symbols.push_back(sym); pss->proc_symbols.push_back(sym); return sym.uniq_name; } default: assert(false); break; } } assert(false); return sym.uniq_name; }
tree current_nonlambda_scope (void) { tree scope = current_scope (); for (;;) { if (TREE_CODE (scope) == FUNCTION_DECL && LAMBDA_FUNCTION_P (scope)) { scope = CP_TYPE_CONTEXT (DECL_CONTEXT (scope)); continue; } else if (LAMBDA_TYPE_P (scope)) { scope = CP_TYPE_CONTEXT (scope); continue; } break; } return scope; }
// Returns true if the system is currently in function scope. bool in_func_scope() { return current_scope()->kind == func_scope; }
// Returns true if the system is currently in lambda scope. bool in_lambda_scope() { return current_scope()->kind == lambda_scope; }
// Returns true if the system is currently in global scope. bool in_global_scope() { return current_scope()->kind == global_scope; }
// Create a fresh name for this scope. Name* fresh_name() { std::stringstream ss; ss << 'a' << ++current_scope()->counter; return new Id(ss.str()); }