Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show constant values in Rich IR #846

Merged
merged 3 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 33 additions & 11 deletions compiler/frontend/src/lir/body.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{Expression, Id};
use super::{Constants, Expression, Id};
use crate::{
hir,
id::CountableId,
Expand Down Expand Up @@ -56,9 +56,13 @@ impl Bodies {
.enumerate()
.map(|(index, it)| (BodyId(index), it))
}
}
impl ToRichIr for Bodies {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {

pub fn build_rich_ir_with_constants(
&self,
builder: &mut RichIrBuilder,
constants: impl Into<Option<&Constants>>,
) {
let constants = constants.into();
builder.push_custom_multiline(self.ids_and_bodies(), |builder, (id, body)| {
let range = builder.push(id.to_string(), TokenType::Function, EnumSet::empty());

Expand Down Expand Up @@ -94,11 +98,16 @@ impl ToRichIr for Bodies {

builder.indent();
builder.push_newline();
body.build_rich_ir(builder);
body.build_rich_ir_with_constants(builder, constants);
builder.dedent();
});
}
}
impl ToRichIr for Bodies {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
self.build_rich_ir_with_constants(builder, None);
}
}

// Body

Expand Down Expand Up @@ -162,8 +171,12 @@ impl Body {
}
#[must_use]
pub fn expression(&self, id: Id) -> Option<&Expression> {
self.expressions
.get(id.to_usize() - self.expression_id_offset())
let expression_id_offset = self.expression_id_offset();
if id.to_usize() < expression_id_offset {
return None;
}

self.expressions.get(id.to_usize() - expression_id_offset)
}
#[must_use]
pub fn ids_and_expressions(&self) -> impl DoubleEndedIterator<Item = (Id, &Expression)> {
Expand Down Expand Up @@ -192,9 +205,13 @@ impl Body {
self.expressions.push(expression);
self.last_expression_id().unwrap()
}
}
impl ToRichIr for Body {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {

pub fn build_rich_ir_with_constants(
&self,
builder: &mut RichIrBuilder,
constants: impl Into<Option<&Constants>>,
) {
let constants = constants.into();
builder.push("# Original HIR IDs: ", TokenType::Comment, EnumSet::empty());
builder.push_children_custom(
self.original_hirs.iter().sorted(),
Expand Down Expand Up @@ -225,7 +242,12 @@ impl ToRichIr for Body {
let range = builder.push(id.to_string(), TokenType::Variable, EnumSet::empty());
builder.push_definition(*id, range);
builder.push(" = ", None, EnumSet::empty());
expression.build_rich_ir(builder);
expression.build_rich_ir_with_constants(builder, constants, self);
});
}
}
impl ToRichIr for Body {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
self.build_rich_ir_with_constants(builder, None);
}
}
47 changes: 39 additions & 8 deletions compiler/frontend/src/lir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ impl Display for ConstantId {
write!(f, "%{}", self.0)
}
}
impl ConstantId {
pub fn build_rich_ir_with_constants(
self,
builder: &mut RichIrBuilder,
constants: impl Into<Option<&Constants>>,
) {
self.build_rich_ir(builder);
if let Some(constants) = constants.into() {
builder.push("<", None, EnumSet::empty());
constants
.get(self)
.build_rich_ir_with_constants(builder, constants);
builder.push(">", None, EnumSet::empty());
}
}
}
impl ToRichIr for ConstantId {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
let range = builder.push(self.to_string(), TokenType::Constant, EnumSet::empty());
Expand Down Expand Up @@ -67,7 +83,7 @@ impl ToRichIr for Constants {
let range = builder.push(id.to_string(), TokenType::Constant, EnumSet::empty());
builder.push_definition(*id, range);
builder.push(" = ", None, EnumSet::empty());
constant.build_rich_ir(builder);
constant.build_rich_ir_with_constants(builder, self);
});
}
}
Expand All @@ -90,9 +106,13 @@ pub enum Constant {
Function(BodyId),
}

impl_display_via_richir!(Constant);
impl ToRichIr for Constant {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
impl Constant {
pub fn build_rich_ir_with_constants(
&self,
builder: &mut RichIrBuilder,
constants: impl Into<Option<&Constants>>,
) {
let constants = constants.into();
match self {
Self::Int(int) => {
int.build_rich_ir(builder);
Expand All @@ -107,15 +127,19 @@ impl ToRichIr for Constant {
builder.push_reference(ReferenceKey::Symbol(symbol.clone()), range);
if let Some(value) = value {
builder.push(" ", None, EnumSet::empty());
value.build_rich_ir(builder);
value.build_rich_ir_with_constants(builder, constants);
}
}
Self::Builtin(builtin) => {
builtin.build_rich_ir(builder);
}
Self::List(items) => {
builder.push("(", None, EnumSet::empty());
builder.push_children(items, ", ");
builder.push_children_custom(
items,
|builder, item| item.build_rich_ir_with_constants(builder, constants),
", ",
);
if items.len() <= 1 {
builder.push(",", None, EnumSet::empty());
}
Expand All @@ -126,9 +150,9 @@ impl ToRichIr for Constant {
builder.push_children_custom(
fields.iter().collect_vec(),
|builder, (key, value)| {
key.build_rich_ir(builder);
key.build_rich_ir_with_constants(builder, constants);
builder.push(": ", None, EnumSet::empty());
value.build_rich_ir(builder);
value.build_rich_ir_with_constants(builder, constants);
},
", ",
);
Expand All @@ -146,3 +170,10 @@ impl ToRichIr for Constant {
}
}
}

impl_display_via_richir!(Constant);
impl ToRichIr for Constant {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
self.build_rich_ir_with_constants(builder, None);
}
}
84 changes: 56 additions & 28 deletions compiler/frontend/src/lir/expression.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{BodyId, ConstantId, Id};
use super::{Body, BodyId, ConstantId, Constants, Id};
use crate::{
impl_display_via_richir,
rich_ir::{ReferenceKey, RichIrBuilder, ToRichIr, TokenType},
Expand Down Expand Up @@ -160,21 +160,30 @@ impl Expression {
}
}
}
}

impl_display_via_richir!(Expression);
impl ToRichIr for Expression {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
pub fn build_rich_ir_with_constants(
&self,
builder: &mut RichIrBuilder,
constants: impl Into<Option<&Constants>>,
body: impl Into<Option<&Body>>,
) {
let constants = constants.into();
let body = body.into();

match self {
Self::CreateTag { symbol, value } => {
let range = builder.push(symbol, TokenType::Symbol, EnumSet::empty());
builder.push_reference(ReferenceKey::Symbol(symbol.clone()), range);
builder.push(" ", None, EnumSet::empty());
value.build_rich_ir(builder);
value.build_rich_ir_with_constants(builder, constants, body);
}
Self::CreateList(items) => {
builder.push("(", None, EnumSet::empty());
builder.push_children(items, ", ");
builder.push_children_custom(
items,
|builder, it| it.build_rich_ir_with_constants(builder, constants, body),
", ",
);
if items.len() <= 1 {
builder.push(",", None, EnumSet::empty());
}
Expand All @@ -185,9 +194,9 @@ impl ToRichIr for Expression {
builder.push_children_custom(
fields.iter().collect_vec(),
|builder, (key, value)| {
key.build_rich_ir(builder);
key.build_rich_ir_with_constants(builder, constants, body);
builder.push(": ", None, EnumSet::empty());
value.build_rich_ir(builder);
value.build_rich_ir_with_constants(builder, constants, body);
},
", ",
);
Expand All @@ -200,48 +209,56 @@ impl ToRichIr for Expression {
if captured.is_empty() {
builder.push("nothing", None, EnumSet::empty());
} else {
builder.push_children(captured, ", ");
builder.push_children_custom(
captured,
|builder, it| it.build_rich_ir_with_constants(builder, constants, body),
", ",
);
}

builder.push(" }", None, EnumSet::empty());
}
Self::Constant(id) => id.build_rich_ir(builder),
Self::Reference(id) => id.build_rich_ir(builder),
Self::Constant(id) => id.build_rich_ir_with_constants(builder, constants),
Self::Reference(id) => id.build_rich_ir_with_constants(builder, constants, body),
Self::Dup { id, amount } => {
builder.push("dup ", None, EnumSet::empty());
id.build_rich_ir(builder);
id.build_rich_ir_with_constants(builder, constants, body);
builder.push(" by ", None, EnumSet::empty());
builder.push(amount.to_string(), None, EnumSet::empty());
}
Self::Drop(id) => {
builder.push("drop ", None, EnumSet::empty());
id.build_rich_ir(builder);
id.build_rich_ir_with_constants(builder, constants, body);
}
Self::Call {
function,
arguments,
responsible,
} => {
builder.push("call ", None, EnumSet::empty());
function.build_rich_ir(builder);
function.build_rich_ir_with_constants(builder, constants, body);
builder.push(" with ", None, EnumSet::empty());
if arguments.is_empty() {
builder.push("no arguments", None, EnumSet::empty());
} else {
builder.push_children(arguments, " ");
builder.push_children_custom(
arguments,
|builder, it| it.build_rich_ir_with_constants(builder, constants, body),
" ",
);
}
builder.push(" (", None, EnumSet::empty());
responsible.build_rich_ir(builder);
responsible.build_rich_ir_with_constants(builder, constants, body);
builder.push(" is responsible)", None, EnumSet::empty());
}
Self::Panic {
reason,
responsible,
} => {
builder.push("panicking because ", None, EnumSet::empty());
reason.build_rich_ir(builder);
reason.build_rich_ir_with_constants(builder, constants, body);
builder.push(" (", None, EnumSet::empty());
responsible.build_rich_ir(builder);
responsible.build_rich_ir_with_constants(builder, constants, body);
builder.push(" is at fault)", None, EnumSet::empty());
}
Self::TraceCallStarts {
Expand All @@ -251,13 +268,17 @@ impl ToRichIr for Expression {
responsible,
} => {
builder.push("trace: start of call of ", None, EnumSet::empty());
function.build_rich_ir(builder);
function.build_rich_ir_with_constants(builder, constants, body);
builder.push(" with ", None, EnumSet::empty());
builder.push_children(arguments, " ");
builder.push_children_custom(
arguments,
|builder, it| it.build_rich_ir_with_constants(builder, constants, body),
" ",
);
builder.push(" (", None, EnumSet::empty());
responsible.build_rich_ir(builder);
responsible.build_rich_ir_with_constants(builder, constants, body);
builder.push(" is responsible, code is at ", None, EnumSet::empty());
hir_call.build_rich_ir(builder);
hir_call.build_rich_ir_with_constants(builder, constants, body);
builder.push(")", None, EnumSet::empty());
}
Self::TraceCallEnds { return_value } => {
Expand All @@ -266,26 +287,33 @@ impl ToRichIr for Expression {
None,
EnumSet::empty(),
);
return_value.build_rich_ir(builder);
return_value.build_rich_ir_with_constants(builder, constants, body);
}
Self::TraceExpressionEvaluated {
hir_expression,
value,
} => {
builder.push("trace: expression ", None, EnumSet::empty());
hir_expression.build_rich_ir(builder);
hir_expression.build_rich_ir_with_constants(builder, constants, body);
builder.push(" evaluated to ", None, EnumSet::empty());
value.build_rich_ir(builder);
value.build_rich_ir_with_constants(builder, constants, body);
}
Self::TraceFoundFuzzableFunction {
hir_definition,
function,
} => {
builder.push("trace: found fuzzable function ", None, EnumSet::empty());
function.build_rich_ir(builder);
function.build_rich_ir_with_constants(builder, constants, body);
builder.push(" defined at ", None, EnumSet::empty());
hir_definition.build_rich_ir(builder);
hir_definition.build_rich_ir_with_constants(builder, constants, body);
}
}
}
}

impl_display_via_richir!(Expression);
impl ToRichIr for Expression {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
self.build_rich_ir_with_constants(builder, None, None);
}
}
16 changes: 16 additions & 0 deletions compiler/frontend/src/lir/id.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::{Body, Constants, Expression};
use crate::{
impl_countable_id,
rich_ir::{RichIrBuilder, ToRichIr, TokenType},
Expand All @@ -20,6 +21,21 @@ impl Debug for Id {
write!(f, "${}", self.0)
}
}
impl Id {
pub fn build_rich_ir_with_constants(
self,
builder: &mut RichIrBuilder,
constants: impl Into<Option<&Constants>>,
body: impl Into<Option<&Body>>,
) {
self.build_rich_ir(builder);
if let Some(body) = body.into() && let Some(Expression::Constant(constant_id)) = body.expression(self) {
builder.push("<", None, EnumSet::empty());
constant_id.build_rich_ir_with_constants(builder, constants);
builder.push(">", None, EnumSet::empty());
}
}
}
impl ToRichIr for Id {
fn build_rich_ir(&self, builder: &mut RichIrBuilder) {
let range = builder.push(self.to_string(), TokenType::Variable, EnumSet::empty());
Expand Down
3 changes: 2 additions & 1 deletion compiler/frontend/src/lir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl ToRichIr for Lir {

builder.push("# Bodies", TokenType::Comment, EnumSet::empty());
builder.push_newline();
self.bodies.build_rich_ir(builder);
self.bodies
.build_rich_ir_with_constants(builder, &self.constants);
}
}
Loading