gbas/frontend/
session.rs

1use backend;
2use codebase::CodebaseError;
3use diagnostics;
4use diagnostics::InternalDiagnostic;
5use frontend;
6use frontend::{Downstream, Token};
7use span;
8use std::borrow::BorrowMut;
9use std::fmt::Debug;
10use std::marker;
11
12pub trait Session {
13    type Ident: Into<String> + Debug + PartialEq;
14    type Span: span::Span;
15    fn analyze_file(&mut self, path: Self::Ident) -> Result<(), CodebaseError>;
16    fn invoke_macro(
17        &mut self,
18        name: (Self::Ident, Self::Span),
19        args: MacroArgs<Self::Ident, Self::Span>,
20    );
21    fn emit_diagnostic(&mut self, diagnostic: InternalDiagnostic<Self::Span>);
22    fn emit_item(&mut self, item: backend::Item<Self::Span>);
23    fn define_label(&mut self, label: (String, Self::Span));
24    fn define_macro(
25        &mut self,
26        name: (impl Into<Self::Ident>, Self::Span),
27        params: Vec<(Self::Ident, Self::Span)>,
28        tokens: Vec<(Token<Self::Ident>, Self::Span)>,
29    );
30    fn set_origin(&mut self, origin: backend::RelocExpr<Self::Span>);
31}
32
33pub type MacroArgs<I, S> = Vec<Vec<(Token<I>, S)>>;
34
35pub struct Components<F, B, D, BMF, BMB, BMD>
36where
37    F: frontend::Frontend,
38    B: backend::Backend<F::Span>,
39    D: diagnostics::DiagnosticsListener<F::Span>,
40    BMF: BorrowMut<F>,
41    BMB: BorrowMut<B>,
42    BMD: BorrowMut<D>,
43{
44    frontend: BMF,
45    backend: BMB,
46    diagnostics: BMD,
47    phantom: marker::PhantomData<(F, B, D)>,
48}
49
50pub type BorrowedComponents<'a, F, B, D> = Components<F, B, D, &'a mut F, &'a mut B, &'a mut D>;
51
52impl<F, B, D, BMF, BMB, BMD> Components<F, B, D, BMF, BMB, BMD>
53where
54    F: frontend::Frontend,
55    B: backend::Backend<F::Span>,
56    D: diagnostics::DiagnosticsListener<F::Span>,
57    BMF: BorrowMut<F>,
58    BMB: BorrowMut<B>,
59    BMD: BorrowMut<D>,
60{
61    pub fn new(
62        frontend: BMF,
63        backend: BMB,
64        diagnostics: BMD,
65    ) -> Components<F, B, D, BMF, BMB, BMD> {
66        Components {
67            frontend,
68            backend,
69            diagnostics,
70            phantom: marker::PhantomData,
71        }
72    }
73
74    pub fn build_object(self) -> B::Object
75    where
76        BMB: Into<B>,
77    {
78        self.backend.into().into_object()
79    }
80}
81
82impl<F, B, D, BMF, BMB, BMD> Session for Components<F, B, D, BMF, BMB, BMD>
83where
84    F: frontend::Frontend,
85    B: backend::Backend<F::Span>,
86    D: diagnostics::DiagnosticsListener<F::Span>,
87    BMF: BorrowMut<F>,
88    BMB: BorrowMut<B>,
89    BMD: BorrowMut<D>,
90{
91    type Ident = F::Ident;
92    type Span = F::Span;
93
94    fn analyze_file(&mut self, path: Self::Ident) -> Result<(), CodebaseError> {
95        self.frontend.borrow_mut().analyze_file(
96            path,
97            Downstream {
98                backend: self.backend.borrow_mut(),
99                diagnostics: self.diagnostics.borrow_mut(),
100            },
101        )
102    }
103
104    fn invoke_macro(
105        &mut self,
106        name: (Self::Ident, Self::Span),
107        args: MacroArgs<Self::Ident, Self::Span>,
108    ) {
109        self.frontend.borrow_mut().invoke_macro(
110            name,
111            args,
112            Downstream {
113                backend: self.backend.borrow_mut(),
114                diagnostics: self.diagnostics.borrow_mut(),
115            },
116        )
117    }
118
119    fn emit_diagnostic(&mut self, diagnostic: InternalDiagnostic<Self::Span>) {
120        self.diagnostics.borrow_mut().emit_diagnostic(diagnostic)
121    }
122
123    fn emit_item(&mut self, item: backend::Item<Self::Span>) {
124        self.backend.borrow_mut().emit_item(item)
125    }
126
127    fn define_label(&mut self, label: (String, Self::Span)) {
128        self.backend.borrow_mut().add_label(label)
129    }
130
131    fn define_macro(
132        &mut self,
133        name: (impl Into<Self::Ident>, Self::Span),
134        params: Vec<(Self::Ident, Self::Span)>,
135        tokens: Vec<(Token<Self::Ident>, Self::Span)>,
136    ) {
137        self.frontend
138            .borrow_mut()
139            .define_macro(name, params, tokens)
140    }
141
142    fn set_origin(&mut self, origin: backend::RelocExpr<Self::Span>) {
143        self.backend.borrow_mut().set_origin(origin)
144    }
145}