prism_compiler/lang/
mod.rs

1use crate::lang::env::{Env, UniqueVariableId};
2use crate::lang::error::TypeError;
3use prism_parser::core::pos::Pos;
4use prism_parser::core::span::Span;
5use std::collections::{HashMap, HashSet};
6use std::fmt::{Display, Formatter};
7use std::ops::Deref;
8
9mod beta_reduce;
10mod beta_reduce_head;
11pub mod display;
12pub mod env;
13pub mod error;
14mod expect_beq;
15mod expect_beq_internal;
16pub mod from_action_result;
17pub mod is_beta_equal;
18pub mod simplify;
19pub mod type_check;
20
21type QueuedConstraint = (
22    (Env, HashMap<UniqueVariableId, usize>),
23    (UnionIndex, Env, HashMap<UniqueVariableId, usize>),
24);
25
26#[derive(Default)]
27pub struct TcEnv {
28    pub values: Vec<PartialExpr>,
29    pub value_origins: Vec<ValueOrigin>,
30    value_types: HashMap<UnionIndex, UnionIndex>,
31
32    tc_id: usize,
33    pub errors: Vec<TypeError>,
34    toxic_values: HashSet<UnionIndex>,
35
36    // Queues
37    queued_beq_free: HashMap<UnionIndex, Vec<QueuedConstraint>>,
38    // queued_tc: HashMap<UnionIndex, (Env, UnionIndex)>,
39}
40
41#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
42pub enum ValueOrigin {
43    /// This is an AST node directly from the source code
44    SourceCode(Span),
45    /// This is the type of another AST node
46    TypeOf(UnionIndex),
47    /// This is an AST node generated from expanding the given free variable
48    FreeSub(UnionIndex),
49    /// This is an (initally free) AST node generated because type checking a node failed
50    Failure,
51}
52
53#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
54pub struct UnionIndex(usize);
55
56impl Display for UnionIndex {
57    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
58        write!(f, "[{}]", self.0)
59    }
60}
61
62impl Deref for UnionIndex {
63    type Target = usize;
64
65    fn deref(&self) -> &Self::Target {
66        &self.0
67    }
68}
69
70#[derive(Copy, Clone, Eq, PartialEq, Debug)]
71pub enum PartialExpr {
72    Free,
73    Type,
74    Let(UnionIndex, UnionIndex),
75    DeBruijnIndex(usize),
76    FnType(UnionIndex, UnionIndex),
77    FnConstruct(UnionIndex),
78    FnDestruct(UnionIndex, UnionIndex),
79    Shift(UnionIndex, usize),
80    TypeAssert(UnionIndex, UnionIndex),
81}
82
83impl TcEnv {
84    pub fn store_from_source(&mut self, e: PartialExpr, span: Span) -> UnionIndex {
85        self.store(e, ValueOrigin::SourceCode(span))
86    }
87
88    pub fn store_test(&mut self, e: PartialExpr) -> UnionIndex {
89        self.store(
90            e,
91            ValueOrigin::SourceCode(Span::new(Pos::start(), Pos::start())),
92        )
93    }
94
95    fn store(&mut self, e: PartialExpr, origin: ValueOrigin) -> UnionIndex {
96        self.values.push(e);
97        self.value_origins.push(origin);
98        UnionIndex(self.values.len() - 1)
99    }
100
101    pub fn reset(&mut self) {
102        self.queued_beq_free.clear();
103        self.errors.clear();
104        self.toxic_values.clear();
105        self.tc_id = 0;
106    }
107}