Skip to content

Commit 90fc256

Browse files
author
DigitalCodeCrafter
committed
working on kerboscript codegeneration
+ generated dominance list
1 parent 84adfac commit 90fc256

6 files changed

Lines changed: 100 additions & 12 deletions

File tree

src/backend/ks.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use std::collections::HashSet;
2+
3+
use crate::mir::{Block, BlockId, Body, Terminator};
4+
5+
fn preds_succs(blocks: &[Block]) -> (Vec<Vec<BlockId>>, Vec<Vec<BlockId>>) {
6+
let mut preds = vec![vec![]; blocks.len()];
7+
let mut succs = vec![vec![]; blocks.len()];
8+
9+
for b in 0..blocks.len() {
10+
let term = &blocks[b].terminator;
11+
let id = BlockId(b as u32);
12+
match term {
13+
Terminator::Goto(next) => {
14+
preds[next.0 as usize].push(id);
15+
succs[b].push(*next);
16+
}
17+
Terminator::Branch(_, tbb, ebb) => {
18+
preds[tbb.0 as usize].push(id);
19+
preds[ebb.0 as usize].push(id);
20+
succs[b].push(*tbb);
21+
succs[b].push(*ebb);
22+
}
23+
Terminator::Return(_) => {},
24+
Terminator::Unreachable => {},
25+
}
26+
}
27+
28+
(preds, succs)
29+
}
30+
31+
fn find_doms(blocks: &[Block], preds: &[Vec<BlockId>]) -> Vec<HashSet<BlockId>> {
32+
let all: HashSet<BlockId> = (0..blocks.len() as u32).map(BlockId).collect();
33+
let mut dom = vec![all.clone(); blocks.len()];
34+
dom[0].clear();
35+
dom[0].insert(BlockId(0));
36+
dom[0].shrink_to_fit();
37+
38+
let mut changed = true;
39+
while changed {
40+
changed = false;
41+
42+
for b in 1..blocks.len() {
43+
let mut new = all.clone();
44+
45+
for &p in &preds[b] {
46+
new = new.intersection(&dom[p.0 as usize]).cloned().collect();
47+
}
48+
49+
new.insert(BlockId(b as u32));
50+
51+
if new != dom[b] {
52+
dom[b] = new;
53+
changed = true;
54+
}
55+
}
56+
}
57+
58+
dom
59+
}
60+
61+
fn dominates(dom: &[HashSet<BlockId>], a: BlockId, b: BlockId) -> bool {
62+
dom[b.0 as usize].contains(&a)
63+
}
64+
65+
fn is_back_edge(dom: &[HashSet<BlockId>], from: BlockId, to: BlockId) -> bool {
66+
dominates(dom, to, from)
67+
}
68+
69+
pub fn print_doms(body: &Body) {
70+
let (preds, succs) = preds_succs(&body.blocks);
71+
let doms = find_doms(&body.blocks, &preds);
72+
for b in 0..body.blocks.len() {
73+
println!("{{ {} }} -> block{} -> {{ {} }}", preds[b].iter().map(|id| format!("block{}", id.0)).collect::<Vec<_>>().join(", "), b, succs[b].iter().map(|id| format!("block{}", id.0)).collect::<Vec<_>>().join(", "));
74+
}
75+
for b in 0..body.blocks.len() {
76+
println!("dom(block{}) = {{ {} }}", b, doms[b].iter().map(|id| format!("block{}", id.0)).collect::<Vec<_>>().join(", "));
77+
}
78+
}

src/backend/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod kerboscript;
2+
pub mod ks;
23

34

45
use crate::common::diagnostics::DiagnosticSink;

src/main.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,18 @@ fn main() -> Result<(), ()> {
2525

2626
run_passes(&mut prog_ir, &mut passes);
2727

28-
let out = backend::emit(&prog_ir, &mut diagnostics);
29-
30-
render_all(&content, &line_starts, &diagnostics.diagnostics);
31-
32-
let pretty_ir = pretty::format_body(&prog_ir, "main");
33-
for line in pretty_ir.lines() {
34-
println!("// {}", line);
35-
}
36-
37-
println!("\n\n{}", out);
28+
29+
// let out = backend::emit(&prog_ir, &mut diagnostics);
30+
31+
// render_all(&content, &line_starts, &diagnostics.diagnostics);
32+
33+
/*let pretty_ir = */ println!("{}", pretty::format_body(&prog_ir, "main"));
34+
// for line in pretty_ir.lines() {
35+
// println!("// {}", line);
36+
// }
37+
38+
backend::ks::print_doms(&prog_ir);
39+
// println!("\n\n{}", out);
3840
Ok(())
3941
}
4042

src/mir/lowerer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ pub fn lower(typed_ast: t::TypedAst, symbols: &SymbolTable, _diagnostics: &mut i
1010
}
1111

1212
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13-
pub struct LocalId(pub(super) u32);
13+
pub struct LocalId(pub u32);
1414
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15-
pub struct BlockId(pub(super) u32);
15+
pub struct BlockId(pub u32);
1616

1717
impl LocalId {
1818
pub fn index(&self) -> u32 { self.0 }

src/semantics/typechecker.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ impl<D: DiagnosticSink> TypeChecker<'_, '_, D> {
264264

265265
(Number, Number) => Some(Number),
266266
(Bool, Bool) => Some(Bool),
267+
(Unit, Unit) => Some(Unit),
267268

268269
_ => None,
269270
}

src/syntax/parser.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ impl<'a, 'd, D: DiagnosticSink> Parser<'a, 'd, D> {
423423
fn parse_if_expr(&mut self, tok: Token) -> Expr<'a> {
424424
let cond = self.parse_expression(0);
425425

426+
self.skip_newlines();
426427
let then_branch = match self.peek_token() {
427428
token @ Token { kind: TokenKind::LBrace, .. } => {
428429
self.stream.next();
@@ -437,8 +438,11 @@ impl<'a, 'd, D: DiagnosticSink> Parser<'a, 'd, D> {
437438
}
438439
};
439440

441+
let save = self.stream.get_position();
442+
self.skip_newlines();
440443
let else_branch = if matches!(self.peek_token().kind, TokenKind::Else) {
441444
self.stream.next();
445+
self.skip_newlines();
442446
match self.peek_token() {
443447
token @ Token { kind: TokenKind::LBrace, .. } => {
444448
self.stream.next();
@@ -453,10 +457,12 @@ impl<'a, 'd, D: DiagnosticSink> Parser<'a, 'd, D> {
453457
Diagnostic::error("expected a block")
454458
.with_span(other.span)
455459
);
460+
self.stream.set_position(save);
456461
Some(Expr { kind: ExprKind::Block { stmts: vec![], tail_expr: None }, span: Span::new(other.span.start, other.span.start) })
457462
}
458463
}
459464
} else {
465+
self.stream.set_position(save);
460466
None
461467
};
462468

0 commit comments

Comments
 (0)