pine_sema/scope.rs
1//! Name-kind classification and the global-only builtin list.
2//!
3//! Scopes themselves live in [`SymbolTable`](crate::SymbolTable): the analyzer
4//! resolves names against it directly, so there is no separate scope stack.
5
6/// What a declared name refers to. This drives rules like "you can't reassign a
7/// function" — only [`SymbolKind::Var`] is a reassignable value.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum SymbolKind {
10 /// A variable (`x = …`, loop variable, tuple binding, parameter).
11 Var,
12 Function,
13 Type,
14 Enum,
15 /// An import alias (`import foo/bar/1 as alias`).
16 Import,
17}
18
19impl SymbolKind {
20 /// A human-readable noun for diagnostics.
21 pub fn noun(self) -> &'static str {
22 match self {
23 SymbolKind::Var => "variable",
24 SymbolKind::Function => "function",
25 SymbolKind::Type => "type",
26 SymbolKind::Enum => "enum",
27 SymbolKind::Import => "import",
28 }
29 }
30
31 /// Pine keeps type declarations in a namespace separate from values, so a
32 /// UDT and a function/variable may share a name without colliding.
33 pub fn namespace(self) -> Namespace {
34 match self {
35 SymbolKind::Type | SymbolKind::Enum => Namespace::Type,
36 SymbolKind::Var | SymbolKind::Function | SymbolKind::Import => Namespace::Value,
37 }
38 }
39}
40
41/// The two namespaces a name can occupy; a redeclaration only collides within
42/// the same one.
43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub enum Namespace {
45 Type,
46 Value,
47}
48
49/// Functions Pine only permits at **global** scope (never inside `if`, loops, or
50/// function bodies).
51const GLOBAL_ONLY_FUNCTIONS: &[&str] = &[
52 "plot",
53 "plotshape",
54 "plotchar",
55 "plotcandle",
56 "plotbar",
57 "plotarrow",
58 "fill",
59];
60
61/// May `name` only be called at global scope?
62pub fn is_global_only(name: &str) -> bool {
63 GLOBAL_ONLY_FUNCTIONS.contains(&name)
64}