Skip to content

Commit aea06a8

Browse files
author
DigitalCodeCrafter
committed
added debug notes to MIR
fixed some span problems in parser
1 parent 0d1a1fb commit aea06a8

9 files changed

Lines changed: 70 additions & 22 deletions

File tree

out.ks

-448 Bytes
Binary file not shown.

src/backend/kerboscript.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ impl KosEmitter {
7171
self.emit_rval(rval);
7272
self.emit(".\n");
7373
}
74+
Instr::Debug(_) => {},
7475
}
7576
}
7677

src/main.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use ksi::{backend, common::diagnostics::sinks::Diagnostics, mir, semantics, syntax};
1+
use ksi::{backend, common::diagnostics::sinks::Diagnostics, mir::{self, pretty}, semantics, syntax};
22

33

44
fn main() -> Result<(), ()> {
@@ -24,7 +24,12 @@ fn main() -> Result<(), ()> {
2424
eprintln!("{:#?}", diagnostics.diagnostics);
2525
}
2626

27-
println!("{}", out);
27+
let pretty_ir = pretty::format_body(&prog_ir, "main");
28+
for line in pretty_ir.lines() {
29+
println!("// {}", line);
30+
}
31+
32+
println!("\n\n{}", out);
2833
Ok(())
2934
}
3035

src/mir/lowerer.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ impl MirBuilder<'_> {
6666
fn lower_stmt(&mut self, stmt: t::Stmt) {
6767
match stmt.kind {
6868
t::StmtKind::Let { sym, value } => {
69-
let local = self.new_local(self.symbols.get(sym).ty.clone().expect("[Lowerer] Internal Error: local var symbol has no type annotation"));
69+
let symbol = self.symbols.get(sym);
70+
let local = self.new_local(symbol.ty.clone().expect("[Lowerer] Internal Error: local var symbol has no type annotation"));
7071
self.env.insert(sym, local);
72+
self.emit(Instr::Debug(DebugInfo { span: stmt.span, kind: DebugKind::DeclareLocal { local, name: symbol.name.clone() } }));
7173
self.lower_expr(Place { local, projection: Vec::new() }, value);
7274
}
7375
t::StmtKind::Expr(expr) => {
@@ -80,6 +82,7 @@ impl MirBuilder<'_> {
8082
}
8183

8284
fn lower_expr(&mut self, dest: Place, expr: t::Expr) {
85+
self.emit(Instr::Debug(DebugInfo { span: expr.span, kind: DebugKind::EnterExpr }));
8386
let rval = match expr.kind {
8487
t::ExprKind::Number { value, .. } => RValue::Use(Operand::Const(Const::Number(value))),
8588

@@ -112,6 +115,7 @@ impl MirBuilder<'_> {
112115
};
113116

114117
self.emit(Instr::Assign(dest, rval));
118+
self.emit(Instr::Debug(DebugInfo { span: expr.span, kind: DebugKind::ExitExpr }));
115119
}
116120
}
117121

src/mir/mir.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{mir::{BlockId, LocalId}, semantics::Type};
1+
use crate::{common::Span, mir::{BlockId, LocalId}, semantics::Type};
22
pub use crate::semantics::typed_ast::BinaryOp;
33

44
#[derive(Debug, PartialEq)]
@@ -28,6 +28,7 @@ pub enum Terminator {
2828
#[derive(Debug, PartialEq)]
2929
pub enum Instr {
3030
Assign(Place, RValue),
31+
Debug(DebugInfo),
3132
}
3233

3334
#[derive(Debug, PartialEq)]
@@ -61,3 +62,18 @@ pub enum Const {
6162
Unit,
6263
}
6364

65+
#[derive(Debug, PartialEq)]
66+
pub struct DebugInfo {
67+
pub span: Span,
68+
pub kind: DebugKind,
69+
}
70+
71+
#[derive(Debug, PartialEq)]
72+
pub enum DebugKind {
73+
EnterExpr,
74+
ExitExpr,
75+
DeclareLocal {
76+
local: LocalId,
77+
name: String,
78+
}
79+
}

src/mir/pretty.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,19 @@ pub fn format_rval(rv: &RValue) -> String {
4141
}
4242
}
4343

44+
pub fn format_debug_info(info: &DebugInfo) -> String {
45+
let note = match &info.kind {
46+
DebugKind::EnterExpr => "enter expression".to_string(),
47+
DebugKind::ExitExpr => "exit expression".to_string(),
48+
DebugKind::DeclareLocal { local, name } => format!("{} := l{}", name, local.index()),
49+
};
50+
format!("[{}..{}] debug: {}", info.span.start, info.span.end, note)
51+
}
52+
4453
pub fn format_instr(i: &Instr) -> String {
4554
match i {
4655
Instr::Assign(place, rvalue) => format!("{} = {}", format_place(place), format_rval(rvalue)),
56+
Instr::Debug(info) => format_debug_info(info),
4757
}
4858
}
4959

src/mir/verifier.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ impl FunctionIRVerifier<'_> {
7272
self.verify_place(place);
7373
self.verify_rval(rval);
7474
}
75+
Instr::Debug(info) => {
76+
if let DebugKind::DeclareLocal { local, .. } = info.kind {
77+
self.verify_local(local);
78+
}
79+
}
7580
}
7681
}
7782

src/semantics/resolver.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ struct ScopeId(u32);
2525
// Symbols
2626

2727
pub struct Symbol {
28+
pub name: String,
2829
kind: SymbolKind,
2930
scope: ScopeId,
3031
def_span: Span,
@@ -138,6 +139,7 @@ impl<'d, D: DiagnosticSink> Resolver<'d, D> {
138139
match &stmt.kind {
139140
p::StmtKind::Let { name, .. } => {
140141
let symbol = self.symbols.insert(Symbol {
142+
name: name.to_string(),
141143
kind: SymbolKind::Local,
142144
scope: self.current_scope,
143145
def_span: stmt.span,

src/syntax/parser.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ impl<'a, 'd, D: DiagnosticSink> Parser<'a, 'd, D> {
141141

142142
let terminator = self.expect_terminator();
143143

144-
let span = terminator.map(|t| t.span.concat(&let_kw.span)).unwrap_or(let_kw.span);
144+
let span = let_kw.span.concat(&terminator.map(|t| t.span).unwrap_or(value.span));
145145

146146
Stmt { kind: StmtKind::Let { name, value }, span }
147147
}
@@ -150,7 +150,7 @@ impl<'a, 'd, D: DiagnosticSink> Parser<'a, 'd, D> {
150150
let expr = self.parse_expression(0);
151151
let terminator = self.expect_terminator();
152152

153-
let span = terminator.map(|t| t.span.concat(&expr.span)).unwrap_or(expr.span);
153+
let span = expr.span.concat(&terminator.map(|t| t.span).unwrap_or(expr.span));
154154

155155
Stmt { kind: StmtKind::Expr(expr), span }
156156
}
@@ -160,14 +160,13 @@ impl<'a, 'd, D: DiagnosticSink> Parser<'a, 'd, D> {
160160
self.skip_newlines();
161161
match self.peek_token() {
162162
Token { kind: TokenKind::Semicolon, .. } => self.stream.next(),
163-
Token { kind: TokenKind::RBrace | TokenKind::EOF, .. } => None,
163+
Token { kind: TokenKind::RBrace, .. } => None,
164+
_ if save != self.stream.get_position() => {
165+
self.stream.set_position(save);
166+
self.stream.next()
167+
}
168+
Token { kind: TokenKind::EOF, .. } => self.stream.next(),
164169
other => {
165-
// skipped at least one newline
166-
if save != self.stream.get_position() {
167-
self.stream.set_position(save);
168-
return self.stream.next();
169-
}
170-
171170
self.diags.emit(
172171
Diagnostic::error("missing statement terminator")
173172
.with_span(other.span)
@@ -178,7 +177,6 @@ impl<'a, 'd, D: DiagnosticSink> Parser<'a, 'd, D> {
178177
}
179178
}
180179

181-
// FIXME: This might recover beyond a scope termination.
182180
fn recover_to_stmt_start(&mut self) {
183181
let mut save = self.stream.get_position();
184182
while let Some(tok) = self.stream.next() {
@@ -319,7 +317,7 @@ impl<'a, 'd, D: DiagnosticSink> Parser<'a, 'd, D> {
319317
}
320318
};
321319

322-
let span = closing_tok.map(|t| t.span.concat(&tok.span)).unwrap_or(tok.span);
320+
let span = tok.span.concat(&closing_tok.map(|t| t.span).unwrap_or(expr.span));
323321

324322
Expr { span, ..expr }
325323
}
@@ -348,14 +346,21 @@ impl<'a, 'd, D: DiagnosticSink> Parser<'a, 'd, D> {
348346
}
349347
};
350348

351-
let span = closing_tok.map(|t| t.span.concat(&tok.span)).unwrap_or(tok.span);
352-
353-
let tail_expr = match stmts.pop() {
354-
Some(Stmt { kind: StmtKind::Expr(expr), span }) if expr.span == span => Some(Box::new(expr)),
355-
Some(other) => { stmts.push(other); None }
349+
let tail_expr = match stmts.last() {
350+
Some(Stmt { kind: StmtKind::Expr(expr), span }) if expr.span == *span => {
351+
let Stmt { kind: StmtKind::Expr(expr), .. } = stmts.pop().unwrap() else { unreachable!() };
352+
Some(Box::new(expr))
353+
}
356354
_ => None,
357355
};
358356

357+
// yes, I know this is a lot but it makes sense. ( "{" -> last stmt -> tail expr -> "}" )
358+
let span = tok.span.concat(&closing_tok.map(|t| t.span)
359+
.or(tail_expr.as_ref().map(|e| e.span))
360+
.or(stmts.last().map(|s| s.span))
361+
.unwrap_or(tok.span)
362+
);
363+
359364
Expr {
360365
kind: ExprKind::Block { stmts, tail_expr },
361366
span,
@@ -467,10 +472,10 @@ let a = x + 2\r
467472
},
468473
span: Span::new(40, 46)
469474
}),
470-
span: Span::new(40, 46)
475+
span: Span::new(40, 48)
471476
}
472477
],
473-
span: Span::new(2, 46),
478+
span: Span::new(2, 48),
474479
};
475480

476481
assert_eq!(parser.parse_program(), expected);

0 commit comments

Comments
 (0)