pag_parser/type_system/
context.rs

1// Copyright (c) 2023 Paguroidea Developers
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9use crate::type_system::Type;
10use crate::utilities::Symbol;
11use std::borrow::Cow;
12
13use std::collections::HashMap;
14
15pub(super) struct TypeContext<'src> {
16    guarded: bool,
17    gamma: HashMap<Symbol<'src>, Type<'src>>,
18}
19
20impl<'src> TypeContext<'src> {
21    pub fn new() -> Self {
22        Self {
23            guarded: false,
24            gamma: HashMap::new(),
25        }
26    }
27    pub fn lookup(&self, sym: Symbol<'src>) -> Option<Cow<Type<'src>>> {
28        let target = self.gamma.get(&sym)?;
29        Some(if self.guarded {
30            Cow::Owned(Type {
31                guarded: true,
32                ..target.clone()
33            })
34        } else {
35            Cow::Borrowed(target)
36        })
37    }
38    pub fn guarded<F, R>(&mut self, f: F) -> R
39    where
40        F: FnOnce(&mut Self) -> R,
41    {
42        let backup = self.guarded;
43        self.guarded = true;
44        let result = f(self);
45        self.guarded = backup;
46        result
47    }
48    pub fn with<F, R>(&mut self, sym: Symbol<'src>, r#type: Type<'src>, f: F) -> R
49    where
50        F: FnOnce(&mut Self) -> R,
51    {
52        let backup = self.gamma.insert(sym, r#type);
53        let result = f(self);
54        if let Some(backup) = backup {
55            self.gamma.insert(sym, backup);
56        } else {
57            self.gamma.remove(&sym);
58        }
59        result
60    }
61}