feat(*): make sections 'permanent', and add 'transient' contexts, closes #88
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
b13851ba13
commit
2f699fa53a
17 changed files with 117 additions and 88 deletions
|
@ -64,7 +64,7 @@
|
||||||
(define-generic-mode
|
(define-generic-mode
|
||||||
'lean-mode ;; name of the mode to create
|
'lean-mode ;; name of the mode to create
|
||||||
'("--") ;; comments start with
|
'("--") ;; comments start with
|
||||||
'("import" "abbreviation" "opaque_hint" "tactic_hint" "definition" "renaming" "inline" "hiding" "exposing" "parameter" "parameters" "proof" "qed" "conjecture" "hypothesis" "lemma" "corollary" "variable" "variables" "print" "theorem" "axiom" "inductive" "with" "structure" "universe" "alias" "help" "environment" "options" "precedence" "postfix" "prefix" "calc_trans" "calc_subst" "calc_refl" "infix" "infixl" "infixr" "notation" "eval" "check" "exit" "coercion" "end" "private" "using" "namespace" "builtin" "including" "instance" "section" "set_option" "add_rewrite" "extends") ;; some keywords
|
'("import" "abbreviation" "opaque_hint" "tactic_hint" "definition" "renaming" "inline" "hiding" "exposing" "parameter" "parameters" "proof" "qed" "conjecture" "hypothesis" "lemma" "corollary" "variable" "variables" "print" "theorem" "axiom" "inductive" "with" "structure" "universe" "alias" "help" "environment" "options" "precedence" "postfix" "prefix" "calc_trans" "calc_subst" "calc_refl" "infix" "infixl" "infixr" "notation" "eval" "check" "exit" "coercion" "end" "private" "using" "namespace" "builtin" "including" "instance" "section" "context" "set_option" "add_rewrite" "extends") ;; some keywords
|
||||||
'(("\\_<\\(bool\\|int\\|nat\\|real\\|Prop\\|Type\\|ℕ\\|ℤ\\)\\_>" . 'font-lock-type-face)
|
'(("\\_<\\(bool\\|int\\|nat\\|real\\|Prop\\|Type\\|ℕ\\|ℤ\\)\\_>" . 'font-lock-type-face)
|
||||||
("\\_<\\(calc\\|have\\|obtains\\|show\\|by\\|in\\|let\\|forall\\|fun\\|exists\\|if\\|then\\|else\\|assume\\|take\\|obtain\\|from\\)\\_>" . font-lock-keyword-face)
|
("\\_<\\(calc\\|have\\|obtains\\|show\\|by\\|in\\|let\\|forall\\|fun\\|exists\\|if\\|then\\|else\\|assume\\|take\\|obtain\\|from\\)\\_>" . font-lock-keyword-face)
|
||||||
("\"[^\"]*\"" . 'font-lock-string-face)
|
("\"[^\"]*\"" . 'font-lock-string-face)
|
||||||
|
|
|
@ -67,7 +67,15 @@ environment section_cmd(parser & p) {
|
||||||
if (p.curr_is_identifier())
|
if (p.curr_is_identifier())
|
||||||
n = p.check_atomic_id_next("invalid section, atomic identifier expected");
|
n = p.check_atomic_id_next("invalid section, atomic identifier expected");
|
||||||
p.push_local_scope();
|
p.push_local_scope();
|
||||||
return push_scope(p.env(), p.ios(), true, n);
|
return push_scope(p.env(), p.ios(), scope_kind::Section, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
environment context_cmd(parser & p) {
|
||||||
|
name n;
|
||||||
|
if (p.curr_is_identifier())
|
||||||
|
n = p.check_atomic_id_next("invalid context, atomic identifier expected");
|
||||||
|
p.push_local_scope();
|
||||||
|
return push_scope(p.env(), p.ios(), scope_kind::Context, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
environment namespace_cmd(parser & p) {
|
environment namespace_cmd(parser & p) {
|
||||||
|
@ -75,11 +83,11 @@ environment namespace_cmd(parser & p) {
|
||||||
name n = p.check_atomic_id_next("invalid namespace declaration, atomic identifier expected");
|
name n = p.check_atomic_id_next("invalid namespace declaration, atomic identifier expected");
|
||||||
if (is_root_namespace(n))
|
if (is_root_namespace(n))
|
||||||
throw parser_error(sstream() << "invalid namespace name, '" << n << "' is reserved", pos);
|
throw parser_error(sstream() << "invalid namespace name, '" << n << "' is reserved", pos);
|
||||||
return push_scope(p.env(), p.ios(), false, n);
|
return push_scope(p.env(), p.ios(), scope_kind::Namespace, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
environment end_scoped_cmd(parser & p) {
|
environment end_scoped_cmd(parser & p) {
|
||||||
if (in_section(p.env()))
|
if (in_section_or_context(p.env()))
|
||||||
p.pop_local_scope();
|
p.pop_local_scope();
|
||||||
if (p.curr_is_identifier()) {
|
if (p.curr_is_identifier()) {
|
||||||
name n = p.check_atomic_id_next("invalid end of scope, atomic identifier expected");
|
name n = p.check_atomic_id_next("invalid end of scope, atomic identifier expected");
|
||||||
|
@ -300,6 +308,7 @@ cmd_table init_cmd_table() {
|
||||||
add_cmd(r, cmd_info("exit", "exit", exit_cmd));
|
add_cmd(r, cmd_info("exit", "exit", exit_cmd));
|
||||||
add_cmd(r, cmd_info("print", "print a string", print_cmd));
|
add_cmd(r, cmd_info("print", "print a string", print_cmd));
|
||||||
add_cmd(r, cmd_info("section", "open a new section", section_cmd));
|
add_cmd(r, cmd_info("section", "open a new section", section_cmd));
|
||||||
|
add_cmd(r, cmd_info("context", "open a new context", context_cmd));
|
||||||
add_cmd(r, cmd_info("namespace", "open a new namespace", namespace_cmd));
|
add_cmd(r, cmd_info("namespace", "open a new namespace", namespace_cmd));
|
||||||
add_cmd(r, cmd_info("end", "close the current namespace/section", end_scoped_cmd));
|
add_cmd(r, cmd_info("end", "close the current namespace/section", end_scoped_cmd));
|
||||||
add_cmd(r, cmd_info("check", "type check given expression, and display its type", check_cmd));
|
add_cmd(r, cmd_info("check", "type check given expression, and display its type", check_cmd));
|
||||||
|
|
|
@ -33,7 +33,7 @@ environment universe_cmd(parser & p) {
|
||||||
name n = p.check_id_next("invalid universe declaration, identifier expected");
|
name n = p.check_id_next("invalid universe declaration, identifier expected");
|
||||||
check_atomic(n);
|
check_atomic(n);
|
||||||
environment env = p.env();
|
environment env = p.env();
|
||||||
if (in_section(env)) {
|
if (in_section_or_context(env)) {
|
||||||
p.add_local_level(n, mk_param_univ(n));
|
p.add_local_level(n, mk_param_univ(n));
|
||||||
} else {
|
} else {
|
||||||
name const & ns = get_namespace(env);
|
name const & ns = get_namespace(env);
|
||||||
|
@ -79,7 +79,7 @@ static environment declare_var(parser & p, environment env,
|
||||||
bool is_axiom, optional<binder_info> const & _bi, pos_info const & pos) {
|
bool is_axiom, optional<binder_info> const & _bi, pos_info const & pos) {
|
||||||
binder_info bi;
|
binder_info bi;
|
||||||
if (_bi) bi = *_bi;
|
if (_bi) bi = *_bi;
|
||||||
if (in_section(p.env())) {
|
if (in_section_or_context(p.env())) {
|
||||||
p.add_local(p.save_pos(mk_local(n, type, bi), pos));
|
p.add_local(p.save_pos(mk_local(n, type, bi), pos));
|
||||||
return env;
|
return env;
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,7 +100,7 @@ static environment declare_var(parser & p, environment env,
|
||||||
|
|
||||||
/** \brief If we are in a section, then add the new local levels to it. */
|
/** \brief If we are in a section, then add the new local levels to it. */
|
||||||
static void update_section_local_levels(parser & p, level_param_names const & new_ls) {
|
static void update_section_local_levels(parser & p, level_param_names const & new_ls) {
|
||||||
if (in_section(p.env())) {
|
if (in_section_or_context(p.env())) {
|
||||||
for (auto const & l : new_ls)
|
for (auto const & l : new_ls)
|
||||||
p.add_local_level(l, mk_param_univ(l));
|
p.add_local_level(l, mk_param_univ(l));
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ static void update_section_local_levels(parser & p, level_param_names const & ne
|
||||||
optional<binder_info> parse_binder_info(parser & p) {
|
optional<binder_info> parse_binder_info(parser & p) {
|
||||||
optional<binder_info> bi = p.parse_optional_binder_info();
|
optional<binder_info> bi = p.parse_optional_binder_info();
|
||||||
if (bi)
|
if (bi)
|
||||||
check_in_section(p);
|
check_in_section_or_context(p);
|
||||||
return bi;
|
return bi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,10 +119,10 @@ environment variable_cmd_core(parser & p, bool is_axiom) {
|
||||||
name n = p.check_id_next("invalid declaration, identifier expected");
|
name n = p.check_id_next("invalid declaration, identifier expected");
|
||||||
check_atomic(n);
|
check_atomic(n);
|
||||||
buffer<name> ls_buffer;
|
buffer<name> ls_buffer;
|
||||||
if (p.curr_is_token(g_llevel_curly) && in_section(p.env()))
|
if (p.curr_is_token(g_llevel_curly) && in_section_or_context(p.env()))
|
||||||
throw parser_error("invalid declaration, axioms/parameters occurring in sections cannot be universe polymorphic", p.pos());
|
throw parser_error("invalid declaration, axioms/parameters occurring in sections cannot be universe polymorphic", p.pos());
|
||||||
optional<parser::local_scope> scope1;
|
optional<parser::local_scope> scope1;
|
||||||
if (!in_section(p.env()))
|
if (!in_section_or_context(p.env()))
|
||||||
scope1.emplace(p);
|
scope1.emplace(p);
|
||||||
parse_univ_params(p, ls_buffer);
|
parse_univ_params(p, ls_buffer);
|
||||||
expr type;
|
expr type;
|
||||||
|
@ -138,7 +138,7 @@ environment variable_cmd_core(parser & p, bool is_axiom) {
|
||||||
}
|
}
|
||||||
p.parse_close_binder_info(bi);
|
p.parse_close_binder_info(bi);
|
||||||
level_param_names ls;
|
level_param_names ls;
|
||||||
if (in_section(p.env())) {
|
if (in_section_or_context(p.env())) {
|
||||||
ls = to_level_param_names(collect_univ_params(type));
|
ls = to_level_param_names(collect_univ_params(type));
|
||||||
} else {
|
} else {
|
||||||
update_univ_parameters(ls_buffer, collect_univ_params(type), p);
|
update_univ_parameters(ls_buffer, collect_univ_params(type), p);
|
||||||
|
@ -274,7 +274,7 @@ environment definition_cmd_core(parser & p, bool is_theorem, bool _is_opaque) {
|
||||||
real_n = ns + n;
|
real_n = ns + n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_section(env)) {
|
if (in_section_or_context(env)) {
|
||||||
buffer<expr> section_ps;
|
buffer<expr> section_ps;
|
||||||
collect_section_locals(type, value, p, section_ps);
|
collect_section_locals(type, value, p, section_ps);
|
||||||
type = Pi_as_is(section_ps, type, p);
|
type = Pi_as_is(section_ps, type, p);
|
||||||
|
@ -364,7 +364,7 @@ static environment variables_cmd(parser & p) {
|
||||||
}
|
}
|
||||||
p.next();
|
p.next();
|
||||||
optional<parser::local_scope> scope1;
|
optional<parser::local_scope> scope1;
|
||||||
if (!in_section(p.env()))
|
if (!in_section_or_context(p.env()))
|
||||||
scope1.emplace(p);
|
scope1.emplace(p);
|
||||||
expr type = p.parse_expr();
|
expr type = p.parse_expr();
|
||||||
p.parse_close_binder_info(bi);
|
p.parse_close_binder_info(bi);
|
||||||
|
|
|
@ -329,7 +329,7 @@ struct inductive_cmd_fn {
|
||||||
|
|
||||||
/** \brief Include in m_levels any section level referenced by decls. */
|
/** \brief Include in m_levels any section level referenced by decls. */
|
||||||
void include_section_levels(buffer<inductive_decl> const & decls) {
|
void include_section_levels(buffer<inductive_decl> const & decls) {
|
||||||
if (!in_section(m_env))
|
if (!in_section_or_context(m_env))
|
||||||
return;
|
return;
|
||||||
name_set all_lvl_params;
|
name_set all_lvl_params;
|
||||||
for (auto const & d : decls) {
|
for (auto const & d : decls) {
|
||||||
|
@ -382,7 +382,7 @@ struct inductive_cmd_fn {
|
||||||
The section parameters are stored in section_params
|
The section parameters are stored in section_params
|
||||||
*/
|
*/
|
||||||
void abstract_section_locals(buffer<inductive_decl> & decls, buffer<expr> & section_params) {
|
void abstract_section_locals(buffer<inductive_decl> & decls, buffer<expr> & section_params) {
|
||||||
if (!in_section(m_env))
|
if (!in_section_or_context(m_env))
|
||||||
return;
|
return;
|
||||||
expr_struct_set section_locals;
|
expr_struct_set section_locals;
|
||||||
collect_section_locals(decls, section_locals);
|
collect_section_locals(decls, section_locals);
|
||||||
|
@ -508,7 +508,7 @@ struct inductive_cmd_fn {
|
||||||
/** \brief Create an alias for the fully qualified name \c full_id. */
|
/** \brief Create an alias for the fully qualified name \c full_id. */
|
||||||
environment create_alias(environment env, name const & full_id, levels const & section_leves, buffer<expr> const & section_params) {
|
environment create_alias(environment env, name const & full_id, levels const & section_leves, buffer<expr> const & section_params) {
|
||||||
name id(full_id.get_string());
|
name id(full_id.get_string());
|
||||||
if (in_section(env)) {
|
if (in_section_or_context(env)) {
|
||||||
expr r = mk_explicit(mk_constant(full_id, section_leves));
|
expr r = mk_explicit(mk_constant(full_id, section_leves));
|
||||||
r = mk_app(r, section_params);
|
r = mk_app(r, section_params);
|
||||||
m_p.add_local_expr(id, r);
|
m_p.add_local_expr(id, r);
|
||||||
|
|
|
@ -999,7 +999,7 @@ name parser::check_constant_next(char const * msg) {
|
||||||
name id = check_id_next(msg);
|
name id = check_id_next(msg);
|
||||||
expr e = id_to_expr(id, p);
|
expr e = id_to_expr(id, p);
|
||||||
|
|
||||||
if (in_section(m_env) && is_implicit(e)) {
|
if (in_section_or_context(m_env) && is_implicit(e)) {
|
||||||
e = get_app_fn(get_implicit_arg(e));
|
e = get_app_fn(get_implicit_arg(e));
|
||||||
if (is_explicit(e))
|
if (is_explicit(e))
|
||||||
e = get_explicit_arg(e);
|
e = get_explicit_arg(e);
|
||||||
|
|
|
@ -159,6 +159,7 @@ class parser {
|
||||||
bool parse_local_notation_decl(buffer<notation_entry> * entries);
|
bool parse_local_notation_decl(buffer<notation_entry> * entries);
|
||||||
|
|
||||||
friend environment section_cmd(parser & p);
|
friend environment section_cmd(parser & p);
|
||||||
|
friend environment context_cmd(parser & p);
|
||||||
friend environment end_scoped_cmd(parser & p);
|
friend environment end_scoped_cmd(parser & p);
|
||||||
|
|
||||||
void push_local_scope();
|
void push_local_scope();
|
||||||
|
|
|
@ -54,8 +54,8 @@ struct token_config {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template class scoped_ext<token_config>;
|
template class scoped_ext<token_config, true>;
|
||||||
typedef scoped_ext<token_config> token_ext;
|
typedef scoped_ext<token_config, true> token_ext;
|
||||||
|
|
||||||
environment add_token(environment const & env, token_entry const & e) {
|
environment add_token(environment const & env, token_entry const & e) {
|
||||||
return token_ext::add_entry(env, get_dummy_ios(), e);
|
return token_ext::add_entry(env, get_dummy_ios(), e);
|
||||||
|
@ -188,8 +188,8 @@ struct notation_config {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template class scoped_ext<notation_config>;
|
template class scoped_ext<notation_config, true>;
|
||||||
typedef scoped_ext<notation_config> notation_ext;
|
typedef scoped_ext<notation_config, true> notation_ext;
|
||||||
|
|
||||||
environment add_notation(environment const & env, notation_entry const & e) {
|
environment add_notation(environment const & env, notation_entry const & e) {
|
||||||
return notation_ext::add_entry(env, get_dummy_ios(), e);
|
return notation_ext::add_entry(env, get_dummy_ios(), e);
|
||||||
|
|
|
@ -118,7 +118,7 @@ struct structure_cmd_fn {
|
||||||
|
|
||||||
/** \brief Include in m_level_names any section level referenced m_type and m_fields */
|
/** \brief Include in m_level_names any section level referenced m_type and m_fields */
|
||||||
void include_section_levels() {
|
void include_section_levels() {
|
||||||
if (!in_section(m_env))
|
if (!in_section_or_context(m_env))
|
||||||
return;
|
return;
|
||||||
name_set all_lvl_params;
|
name_set all_lvl_params;
|
||||||
all_lvl_params = collect_univ_params(m_type);
|
all_lvl_params = collect_univ_params(m_type);
|
||||||
|
@ -150,7 +150,7 @@ struct structure_cmd_fn {
|
||||||
The section parameters are stored in section_params
|
The section parameters are stored in section_params
|
||||||
*/
|
*/
|
||||||
void abstract_section_locals(buffer<expr> & section_params) {
|
void abstract_section_locals(buffer<expr> & section_params) {
|
||||||
if (!in_section(m_env))
|
if (!in_section_or_context(m_env))
|
||||||
return;
|
return;
|
||||||
expr_struct_set section_locals;
|
expr_struct_set section_locals;
|
||||||
collect_section_locals(section_locals);
|
collect_section_locals(section_locals);
|
||||||
|
|
|
@ -77,7 +77,7 @@ token_table init_token_table() {
|
||||||
"variables", "[private]", "[inline]", "[fact]", "[instance]", "[module]", "[coercion]",
|
"variables", "[private]", "[inline]", "[fact]", "[instance]", "[module]", "[coercion]",
|
||||||
"abbreviation", "opaque_hint", "evaluate", "check", "print", "end", "namespace", "section", "import",
|
"abbreviation", "opaque_hint", "evaluate", "check", "print", "end", "namespace", "section", "import",
|
||||||
"abbreviation", "inductive", "record", "renaming", "extends", "structure", "module", "universe",
|
"abbreviation", "inductive", "record", "renaming", "extends", "structure", "module", "universe",
|
||||||
"precedence", "infixl", "infixr", "infix", "postfix", "prefix", "notation",
|
"precedence", "infixl", "infixr", "infix", "postfix", "prefix", "notation", "context",
|
||||||
"exit", "set_option", "using", "calc_subst", "calc_refl", "calc_trans", "tactic_hint",
|
"exit", "set_option", "using", "calc_subst", "calc_refl", "calc_trans", "tactic_hint",
|
||||||
"add_begin_end_tactic", "set_begin_end_tactic", "instance", "#erase_cache", nullptr};
|
"add_begin_end_tactic", "set_begin_end_tactic", "instance", "#erase_cache", nullptr};
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@ void check_atomic(name const & n) {
|
||||||
throw exception(sstream() << "invalid declaration name '" << n << "', identifier must be atomic");
|
throw exception(sstream() << "invalid declaration name '" << n << "', identifier must be atomic");
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_in_section(parser const & p) {
|
void check_in_section_or_context(parser const & p) {
|
||||||
if (!in_section(p.env()))
|
if (!in_section_or_context(p.env()))
|
||||||
throw exception(sstream() << "invalid command, it must be used in a section");
|
throw exception(sstream() << "invalid command, it must be used in a section");
|
||||||
}
|
}
|
||||||
static name g_root("_root_");
|
static name g_root("_root_");
|
||||||
|
|
|
@ -10,7 +10,7 @@ Author: Leonardo de Moura
|
||||||
namespace lean {
|
namespace lean {
|
||||||
class parser;
|
class parser;
|
||||||
void check_atomic(name const & n);
|
void check_atomic(name const & n);
|
||||||
void check_in_section(parser const & p);
|
void check_in_section_or_context(parser const & p);
|
||||||
bool is_root_namespace(name const & n);
|
bool is_root_namespace(name const & n);
|
||||||
name remove_root_prefix(name const & n);
|
name remove_root_prefix(name const & n);
|
||||||
/** \brief Return the levels in \c ls that are defined in the section. */
|
/** \brief Return the levels in \c ls that are defined in the section. */
|
||||||
|
|
|
@ -24,12 +24,12 @@ static environment update(environment const & env, aliases_ext const & ext);
|
||||||
|
|
||||||
struct aliases_ext : public environment_extension {
|
struct aliases_ext : public environment_extension {
|
||||||
struct state {
|
struct state {
|
||||||
bool m_in_section;
|
bool m_in_section_or_context;
|
||||||
rb_map<name, list<name>, name_quick_cmp> m_aliases;
|
rb_map<name, list<name>, name_quick_cmp> m_aliases;
|
||||||
rb_map<name, name, name_quick_cmp> m_inv_aliases;
|
rb_map<name, name, name_quick_cmp> m_inv_aliases;
|
||||||
rb_map<name, name, name_quick_cmp> m_level_aliases;
|
rb_map<name, name, name_quick_cmp> m_level_aliases;
|
||||||
rb_map<name, name, name_quick_cmp> m_inv_level_aliases;
|
rb_map<name, name, name_quick_cmp> m_inv_level_aliases;
|
||||||
state():m_in_section(false) {}
|
state():m_in_section_or_context(false) {}
|
||||||
|
|
||||||
void add_expr_alias(name const & a, name const & e) {
|
void add_expr_alias(name const & a, name const & e) {
|
||||||
auto it = m_aliases.find(a);
|
auto it = m_aliases.find(a);
|
||||||
|
@ -62,7 +62,7 @@ struct aliases_ext : public environment_extension {
|
||||||
} else {
|
} else {
|
||||||
state s = head(scopes);
|
state s = head(scopes);
|
||||||
s.add_expr_alias(a, e);
|
s.add_expr_alias(a, e);
|
||||||
if (s.m_in_section) {
|
if (s.m_in_section_or_context) {
|
||||||
return cons(s, add_expr_alias_rec_core(tail(scopes), a, e));
|
return cons(s, add_expr_alias_rec_core(tail(scopes), a, e));
|
||||||
} else {
|
} else {
|
||||||
return cons(s, tail(scopes));
|
return cons(s, tail(scopes));
|
||||||
|
@ -71,16 +71,16 @@ struct aliases_ext : public environment_extension {
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_expr_alias_rec(name const & a, name const & e) {
|
void add_expr_alias_rec(name const & a, name const & e) {
|
||||||
if (m_state.m_in_section) {
|
if (m_state.m_in_section_or_context) {
|
||||||
m_scopes = add_expr_alias_rec_core(m_scopes, a, e);
|
m_scopes = add_expr_alias_rec_core(m_scopes, a, e);
|
||||||
} else {
|
} else {
|
||||||
add_expr_alias(a, e);
|
add_expr_alias(a, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(bool in_section) {
|
void push(bool in_section_or_context) {
|
||||||
m_scopes = cons(m_state, m_scopes);
|
m_scopes = cons(m_state, m_scopes);
|
||||||
m_state.m_in_section = in_section;
|
m_state.m_in_section_or_context = in_section_or_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop() {
|
void pop() {
|
||||||
|
@ -93,16 +93,16 @@ struct aliases_ext : public environment_extension {
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
static environment push_scope(environment const & env, bool in_section) {
|
static environment push_scope(environment const & env, scope_kind k) {
|
||||||
aliases_ext ext = get_extension(env);
|
aliases_ext ext = get_extension(env);
|
||||||
ext.push(in_section);
|
ext.push(k != scope_kind::Namespace);
|
||||||
environment new_env = update(env, ext);
|
environment new_env = update(env, ext);
|
||||||
if (!::lean::in_section(new_env))
|
if (!::lean::in_section_or_context(new_env))
|
||||||
new_env = add_aliases(new_env, get_namespace(new_env), name());
|
new_env = add_aliases(new_env, get_namespace(new_env), name());
|
||||||
return new_env;
|
return new_env;
|
||||||
}
|
}
|
||||||
|
|
||||||
static environment pop_scope(environment const & env, bool) {
|
static environment pop_scope(environment const & env, scope_kind) {
|
||||||
aliases_ext ext = get_extension(env);
|
aliases_ext ext = get_extension(env);
|
||||||
ext.pop();
|
ext.pop();
|
||||||
return update(env, ext);
|
return update(env, ext);
|
||||||
|
|
|
@ -27,10 +27,10 @@ void register_scoped_ext(name const & c, using_namespace_fn use, push_scope_fn p
|
||||||
}
|
}
|
||||||
|
|
||||||
struct scope_mng_ext : public environment_extension {
|
struct scope_mng_ext : public environment_extension {
|
||||||
name_set m_namespace_set; // all namespaces registered in the system
|
name_set m_namespace_set; // all namespaces registered in the system
|
||||||
list<name> m_namespaces; // stack of namespaces/sections
|
list<name> m_namespaces; // stack of namespaces/sections
|
||||||
list<name> m_headers; // namespace/section header
|
list<name> m_headers; // namespace/section header
|
||||||
list<bool> m_in_section;
|
list<scope_kind> m_scope_kinds;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct scope_mng_ext_reg {
|
struct scope_mng_ext_reg {
|
||||||
|
@ -55,9 +55,14 @@ list<name> const & get_namespaces(environment const & env) {
|
||||||
return get_extension(env).m_namespaces;
|
return get_extension(env).m_namespaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool in_section(environment const & env) {
|
bool in_section_or_context(environment const & env) {
|
||||||
scope_mng_ext const & ext = get_extension(env);
|
scope_mng_ext const & ext = get_extension(env);
|
||||||
return !is_nil(ext.m_in_section) && head(ext.m_in_section);
|
return !is_nil(ext.m_scope_kinds) && head(ext.m_scope_kinds) != scope_kind::Namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool in_context(environment const & env) {
|
||||||
|
scope_mng_ext const & ext = get_extension(env);
|
||||||
|
return !is_nil(ext.m_scope_kinds) && head(ext.m_scope_kinds) == scope_kind::Context;
|
||||||
}
|
}
|
||||||
|
|
||||||
environment using_namespace(environment const & env, io_state const & ios, name const & n, name const & c) {
|
environment using_namespace(environment const & env, io_state const & ios, name const & n, name const & c) {
|
||||||
|
@ -82,9 +87,9 @@ optional<name> to_valid_namespace_name(environment const & env, name const & n)
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string g_new_namespace_key("nspace");
|
static std::string g_new_namespace_key("nspace");
|
||||||
environment push_scope(environment const & env, io_state const & ios, bool add_sec, name const & n) {
|
environment push_scope(environment const & env, io_state const & ios, scope_kind k, name const & n) {
|
||||||
if (!add_sec && in_section(env))
|
if (k == scope_kind::Namespace && in_section_or_context(env))
|
||||||
throw exception("invalid namespace declaration, a namespace cannot be declared inside a section");
|
throw exception("invalid namespace declaration, a namespace cannot be declared inside a section or context");
|
||||||
name new_n = get_namespace(env) + n;
|
name new_n = get_namespace(env) + n;
|
||||||
scope_mng_ext ext = get_extension(env);
|
scope_mng_ext ext = get_extension(env);
|
||||||
bool save_ns = false;
|
bool save_ns = false;
|
||||||
|
@ -92,14 +97,14 @@ environment push_scope(environment const & env, io_state const & ios, bool add_s
|
||||||
save_ns = true;
|
save_ns = true;
|
||||||
ext.m_namespace_set.insert(new_n);
|
ext.m_namespace_set.insert(new_n);
|
||||||
}
|
}
|
||||||
ext.m_namespaces = cons(new_n, ext.m_namespaces);
|
ext.m_namespaces = cons(new_n, ext.m_namespaces);
|
||||||
ext.m_headers = cons(n, ext.m_headers);
|
ext.m_headers = cons(n, ext.m_headers);
|
||||||
ext.m_in_section = cons(add_sec, ext.m_in_section);
|
ext.m_scope_kinds = cons(k, ext.m_scope_kinds);
|
||||||
environment r = update(env, ext);
|
environment r = update(env, ext);
|
||||||
for (auto const & t : get_exts()) {
|
for (auto const & t : get_exts()) {
|
||||||
r = std::get<2>(t)(r, add_sec);
|
r = std::get<2>(t)(r, k);
|
||||||
}
|
}
|
||||||
if (!add_sec)
|
if (k == scope_kind::Namespace)
|
||||||
r = using_namespace(r, ios, n);
|
r = using_namespace(r, ios, n);
|
||||||
if (save_ns)
|
if (save_ns)
|
||||||
r = module::add(r, g_new_namespace_key, [=](serializer & s) { s << new_n; });
|
r = module::add(r, g_new_namespace_key, [=](serializer & s) { s << new_n; });
|
||||||
|
@ -122,16 +127,16 @@ register_module_object_reader_fn g_namespace_reader(g_new_namespace_key, namespa
|
||||||
environment pop_scope(environment const & env, name const & n) {
|
environment pop_scope(environment const & env, name const & n) {
|
||||||
scope_mng_ext ext = get_extension(env);
|
scope_mng_ext ext = get_extension(env);
|
||||||
if (is_nil(ext.m_namespaces))
|
if (is_nil(ext.m_namespaces))
|
||||||
throw exception("invalid end of scope, there are no open namespaces/sections");
|
throw exception("invalid end of scope, there are no open namespaces/sections/contexts");
|
||||||
if (n != head(ext.m_headers))
|
if (n != head(ext.m_headers))
|
||||||
throw exception(sstream() << "invalid end of scope, begin/end mistmatch, scope starts with '" << head(ext.m_headers) << "', and ends with '" << n << "'");
|
throw exception(sstream() << "invalid end of scope, begin/end mistmatch, scope starts with '" << head(ext.m_headers) << "', and ends with '" << n << "'");
|
||||||
bool in_section = head(ext.m_in_section);
|
scope_kind k = head(ext.m_scope_kinds);
|
||||||
ext.m_namespaces = tail(ext.m_namespaces);
|
ext.m_namespaces = tail(ext.m_namespaces);
|
||||||
ext.m_headers = tail(ext.m_headers);
|
ext.m_headers = tail(ext.m_headers);
|
||||||
ext.m_in_section = tail(ext.m_in_section);
|
ext.m_scope_kinds = tail(ext.m_scope_kinds);
|
||||||
environment r = update(env, ext);
|
environment r = update(env, ext);
|
||||||
for (auto const & t : get_exts()) {
|
for (auto const & t : get_exts()) {
|
||||||
r = std::get<3>(t)(r, in_section);
|
r = std::get<3>(t)(r, k);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -156,13 +161,14 @@ static int using_namespace_objects(lua_State * L) {
|
||||||
static int push_scope(lua_State * L) {
|
static int push_scope(lua_State * L) {
|
||||||
int nargs = lua_gettop(L);
|
int nargs = lua_gettop(L);
|
||||||
if (nargs == 1)
|
if (nargs == 1)
|
||||||
return push_environment(L, push_scope(to_environment(L, 1), get_io_state(L), true));
|
return push_environment(L, push_scope(to_environment(L, 1), get_io_state(L), scope_kind::Context));
|
||||||
else if (nargs == 2)
|
else if (nargs == 2)
|
||||||
return push_environment(L, push_scope(to_environment(L, 1), get_io_state(L), false, to_name_ext(L, 2)));
|
return push_environment(L, push_scope(to_environment(L, 1), get_io_state(L), scope_kind::Namespace, to_name_ext(L, 2)));
|
||||||
else if (nargs == 3)
|
scope_kind k = static_cast<scope_kind>(lua_tonumber(L, 3));
|
||||||
return push_environment(L, push_scope(to_environment(L, 1), get_io_state(L), lua_toboolean(L, 3), to_name_ext(L, 2)));
|
if (nargs == 3)
|
||||||
|
return push_environment(L, push_scope(to_environment(L, 1), get_io_state(L), k, to_name_ext(L, 2)));
|
||||||
else
|
else
|
||||||
return push_environment(L, push_scope(to_environment(L, 1), to_io_state(L, 4), lua_toboolean(L, 3), to_name_ext(L, 2)));
|
return push_environment(L, push_scope(to_environment(L, 1), to_io_state(L, 4), k, to_name_ext(L, 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pop_scope(lua_State * L) {
|
static int pop_scope(lua_State * L) {
|
||||||
|
@ -177,5 +183,11 @@ void open_scoped_ext(lua_State * L) {
|
||||||
SET_GLOBAL_FUN(using_namespace_objects, "using_namespace_objects");
|
SET_GLOBAL_FUN(using_namespace_objects, "using_namespace_objects");
|
||||||
SET_GLOBAL_FUN(push_scope, "push_scope");
|
SET_GLOBAL_FUN(push_scope, "push_scope");
|
||||||
SET_GLOBAL_FUN(pop_scope, "pop_scope");
|
SET_GLOBAL_FUN(pop_scope, "pop_scope");
|
||||||
|
|
||||||
|
lua_newtable(L);
|
||||||
|
SET_ENUM("Namespace", scope_kind::Namespace);
|
||||||
|
SET_ENUM("Section", scope_kind::Section);
|
||||||
|
SET_ENUM("Context", scope_kind::Context);
|
||||||
|
lua_setglobal(L, "scope_kind");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,22 +15,24 @@ Author: Leonardo de Moura
|
||||||
#include "library/module.h"
|
#include "library/module.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
enum class scope_kind { Namespace, Section, Context };
|
||||||
typedef environment (*using_namespace_fn)(environment const &, io_state const &, name const &);
|
typedef environment (*using_namespace_fn)(environment const &, io_state const &, name const &);
|
||||||
typedef environment (*push_scope_fn)(environment const &, bool);
|
typedef environment (*push_scope_fn)(environment const &, scope_kind);
|
||||||
typedef environment (*pop_scope_fn)(environment const &, bool);
|
typedef environment (*pop_scope_fn)(environment const &, scope_kind);
|
||||||
|
|
||||||
void register_scoped_ext(name const & n, using_namespace_fn use, push_scope_fn push, pop_scope_fn pop);
|
void register_scoped_ext(name const & n, using_namespace_fn use, push_scope_fn push, pop_scope_fn pop);
|
||||||
/** \brief Use objects defined in the namespace \c n, if \c c is not the anonymous name, then only object from "class" \c c are considered. */
|
/** \brief Use objects defined in the namespace \c n, if \c c is not the anonymous name, then only object from "class" \c c are considered. */
|
||||||
environment using_namespace(environment const & env, io_state const & ios, name const & n, name const & c = name());
|
environment using_namespace(environment const & env, io_state const & ios, name const & n, name const & c = name());
|
||||||
/** \brief Create a new scope, all scoped extensions are notified. */
|
/** \brief Create a new scope, all scoped extensions are notified. */
|
||||||
environment push_scope(environment const & env, io_state const & ios, bool section, name const & n = name());
|
environment push_scope(environment const & env, io_state const & ios, scope_kind k, name const & n = name());
|
||||||
/** \brief Delete the most recent scope, all scoped extensions are notified. */
|
/** \brief Delete the most recent scope, all scoped extensions are notified. */
|
||||||
environment pop_scope(environment const & env, name const & n = name());
|
environment pop_scope(environment const & env, name const & n = name());
|
||||||
bool has_open_scopes(environment const & env);
|
bool has_open_scopes(environment const & env);
|
||||||
|
|
||||||
name const & get_namespace(environment const & env);
|
name const & get_namespace(environment const & env);
|
||||||
list<name> const & get_namespaces(environment const & env);
|
list<name> const & get_namespaces(environment const & env);
|
||||||
bool in_section(environment const & env);
|
bool in_section_or_context(environment const & env);
|
||||||
|
bool in_context(environment const & env);
|
||||||
|
|
||||||
/** \brief Check if \c n may be a reference to a namespace, if it is return it.
|
/** \brief Check if \c n may be a reference to a namespace, if it is return it.
|
||||||
The procedure checks if \c n is a registered namespace, if it is not, it tries
|
The procedure checks if \c n is a registered namespace, if it is not, it tries
|
||||||
|
@ -49,7 +51,7 @@ void open_scoped_ext(lua_State * L);
|
||||||
\brief Auxilary template used to simplify the creation of environment extensions that support
|
\brief Auxilary template used to simplify the creation of environment extensions that support
|
||||||
the scope
|
the scope
|
||||||
*/
|
*/
|
||||||
template<typename Config>
|
template<typename Config, bool TransientSection = false>
|
||||||
class scoped_ext : public environment_extension {
|
class scoped_ext : public environment_extension {
|
||||||
typedef typename Config::state state;
|
typedef typename Config::state state;
|
||||||
typedef typename Config::entry entry;
|
typedef typename Config::entry entry;
|
||||||
|
@ -150,17 +152,23 @@ public:
|
||||||
static environment using_namespace_fn(environment const & env, io_state const & ios, name const & n) {
|
static environment using_namespace_fn(environment const & env, io_state const & ios, name const & n) {
|
||||||
return update(env, get(env).using_namespace(env, ios, n));
|
return update(env, get(env).using_namespace(env, ios, n));
|
||||||
}
|
}
|
||||||
static environment push_fn(environment const & env, bool) {
|
static environment push_fn(environment const & env, scope_kind k) {
|
||||||
return update(env, get(env).push());
|
if (k != scope_kind::Section || TransientSection)
|
||||||
|
return update(env, get(env).push());
|
||||||
|
else
|
||||||
|
return env;
|
||||||
}
|
}
|
||||||
static environment pop_fn(environment const & env, bool) {
|
static environment pop_fn(environment const & env, scope_kind k) {
|
||||||
return update(env, get(env).pop());
|
if (k != scope_kind::Section || TransientSection)
|
||||||
|
return update(env, get(env).pop());
|
||||||
|
else
|
||||||
|
return env;
|
||||||
}
|
}
|
||||||
static environment register_entry(environment const & env, io_state const & ios, name const & n, entry const & e) {
|
static environment register_entry(environment const & env, io_state const & ios, name const & n, entry const & e) {
|
||||||
return update(env, get(env)._register_entry(env, ios, n, e));
|
return update(env, get(env)._register_entry(env, ios, n, e));
|
||||||
}
|
}
|
||||||
static environment add_entry(environment env, io_state const & ios, entry const & e) {
|
static environment add_entry(environment env, io_state const & ios, entry const & e) {
|
||||||
if (in_section(env)) {
|
if ((!TransientSection && in_context(env)) || (TransientSection && in_section_or_context(env))) {
|
||||||
return update(env, get(env)._add_tmp_entry(env, ios, e));
|
return update(env, get(env)._add_tmp_entry(env, ios, e));
|
||||||
} else {
|
} else {
|
||||||
name n = get_namespace(env);
|
name n = get_namespace(env);
|
||||||
|
@ -189,6 +197,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Config>
|
template<typename Config, bool TransientSection>
|
||||||
typename scoped_ext<Config>::reg scoped_ext<Config>::g_ext;
|
typename scoped_ext<Config, TransientSection>::reg scoped_ext<Config, TransientSection>::g_ext;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
namespace foo
|
namespace foo
|
||||||
variable A : Type.{1}
|
variable A : Type.{1}
|
||||||
variable a : A
|
variable a : A
|
||||||
|
@ -6,25 +5,25 @@ namespace foo
|
||||||
variable c : A
|
variable c : A
|
||||||
end foo
|
end foo
|
||||||
|
|
||||||
section
|
context
|
||||||
using foo (renaming a->b x->y) (hiding c)
|
using foo (renaming a->b x->y) (hiding c)
|
||||||
check b
|
check b
|
||||||
check y
|
check y
|
||||||
check c -- Error
|
check c -- Error
|
||||||
end
|
end
|
||||||
|
|
||||||
section
|
context
|
||||||
using foo (a x)
|
using foo (a x)
|
||||||
check a
|
check a
|
||||||
check x
|
check x
|
||||||
check c -- Error
|
check c -- Error
|
||||||
end
|
end
|
||||||
|
|
||||||
section
|
context
|
||||||
using foo (a x) (hiding c) -- Error
|
using foo (a x) (hiding c) -- Error
|
||||||
end
|
end
|
||||||
|
|
||||||
section
|
context
|
||||||
using foo
|
using foo
|
||||||
check a
|
check a
|
||||||
check c
|
check c
|
||||||
|
@ -36,18 +35,18 @@ namespace foo
|
||||||
infix `*`:75 := f
|
infix `*`:75 := f
|
||||||
end foo
|
end foo
|
||||||
|
|
||||||
section
|
context
|
||||||
using foo
|
using foo
|
||||||
check a * c
|
check a * c
|
||||||
end
|
end
|
||||||
|
|
||||||
section
|
context
|
||||||
using [notation] foo -- use only the notation
|
using [notation] foo -- use only the notation
|
||||||
check foo.a * foo.c
|
check foo.a * foo.c
|
||||||
check a * c -- Error
|
check a * c -- Error
|
||||||
end
|
end
|
||||||
|
|
||||||
section
|
context
|
||||||
using [decls] foo -- use only the declarations
|
using [decls] foo -- use only the declarations
|
||||||
check f a c
|
check f a c
|
||||||
check a*c -- Error
|
check a*c -- Error
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
b : A
|
b : A
|
||||||
y : A
|
y : A
|
||||||
t14.lean:13:8: error: unknown identifier 'c'
|
t14.lean:12:8: error: unknown identifier 'c'
|
||||||
a : foo.A
|
a : foo.A
|
||||||
x : foo.A
|
x : foo.A
|
||||||
t14.lean:20:8: error: unknown identifier 'c'
|
t14.lean:19:8: error: unknown identifier 'c'
|
||||||
t14.lean:24:27: error: invalid 'using' command option, mixing explicit and implicit 'using' options
|
t14.lean:23:27: error: invalid 'using' command option, mixing explicit and implicit 'using' options
|
||||||
a : A
|
a : A
|
||||||
c : A
|
c : A
|
||||||
A : Type
|
A : Type
|
||||||
f a c : A
|
f a c : A
|
||||||
foo.f foo.a foo.c : foo.A
|
foo.f foo.a foo.c : foo.A
|
||||||
t14.lean:47:8: error: unknown identifier 'a'
|
t14.lean:46:8: error: unknown identifier 'a'
|
||||||
f a c : A
|
f a c : A
|
||||||
t14.lean:53:9: error: unexpected token
|
t14.lean:52:9: error: unexpected token
|
||||||
|
|
|
@ -5,7 +5,7 @@ Type
|
||||||
t3.lean:9:16: error: unknown universe 'v'
|
t3.lean:9:16: error: unknown universe 'v'
|
||||||
Type
|
Type
|
||||||
t3.lean:14:16: error: unknown universe 'z'
|
t3.lean:14:16: error: unknown universe 'z'
|
||||||
t3.lean:16:2: error: invalid namespace declaration, a namespace cannot be declared inside a section
|
t3.lean:16:2: error: invalid namespace declaration, a namespace cannot be declared inside a section or context
|
||||||
Type
|
Type
|
||||||
Type
|
Type
|
||||||
Type
|
Type
|
||||||
|
|
Loading…
Reference in a new issue