This repository has been archived by the owner on Nov 18, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
card.rs
80 lines (70 loc) · 2.59 KB
/
card.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use std::sync::Arc;
use ast::parser::{DummySpanStorage, ParseResult};
use codebase::code::Code;
use hir::meta::WithMeta;
use ids::{Entrypoint, FileId};
use mir::mir::Mir;
use ty::conclusion::TypeConclusions;
use crate::{
error::DeskcError,
hir_result::CardsResult,
parse_source_code,
query_result::{QueryError, QueryResult},
};
#[salsa::query_group(CardStorage)]
pub trait DeskcQueries {
#[salsa::input]
fn code(&self, id: FileId) -> Code;
fn ast(&self, id: FileId) -> Result<ParseResult, QueryError>;
fn cards(&self, id: FileId) -> QueryResult<CardsResult>;
fn hir(&self, entrypoint: Entrypoint) -> QueryResult<WithMeta<hir::expr::Expr>>;
fn typeinfer(&self, entrypoint: Entrypoint) -> QueryResult<TypeConclusions>;
fn mir(&self, entrypoint: Entrypoint) -> QueryResult<Mir>;
}
#[salsa::database(CardStorage)]
#[derive(Default)]
pub struct DeskCompiler {
storage: salsa::Storage<Self>,
}
impl salsa::Database for DeskCompiler {}
fn ast(db: &dyn DeskcQueries, id: FileId) -> Result<ParseResult, QueryError> {
let code = db.code(id);
match code {
Code::SourceCode { syntax, source } => Ok(parse_source_code(&syntax, &source)?),
Code::Ast(ast) => Ok(ParseResult::new(ast, DummySpanStorage)),
}
}
fn cards(db: &dyn DeskcQueries, id: FileId) -> QueryResult<CardsResult> {
let parsed = db.ast(id)?;
let (genhir, hir) = hirgen::gen_cards(&parsed.expr)?;
Ok(Arc::new(CardsResult {
cards: hir,
next_id: genhir.next_id(),
}))
}
fn hir(db: &dyn DeskcQueries, entrypoint: Entrypoint) -> QueryResult<WithMeta<hir::expr::Expr>> {
let cards_result = db.cards(entrypoint.file_id().clone())?;
let hir = match entrypoint {
Entrypoint::Card { file_id, card_id } => cards_result
.cards
.cards
.iter()
.find(|card| card.id == card_id)
.map(|card| Ok(card.hir.clone()))
.unwrap_or_else(|| Err(DeskcError::CardNotFound { card_id, file_id }))?,
Entrypoint::File(_) => cards_result.cards.file.clone(),
};
Ok(Arc::new(hir))
}
fn typeinfer(db: &dyn DeskcQueries, entrypoint: Entrypoint) -> QueryResult<TypeConclusions> {
let cards_result = db.cards(entrypoint.file_id().clone())?;
let hir = db.hir(entrypoint)?;
let conclusion = typeinfer::synth(cards_result.next_id, &hir)?;
Ok(Arc::new(conclusion))
}
fn mir(db: &dyn DeskcQueries, entrypoint: Entrypoint) -> QueryResult<Mir> {
let hir = db.hir(entrypoint.clone())?;
let conclusion = db.typeinfer(entrypoint)?;
let mir = mirgen::gen_mir(&hir, &conclusion)?;
Ok(Arc::new(mir))
}