Skip to content

Commit

Permalink
Merge pull request #1091 from candy-lang/advent-of-code
Browse files Browse the repository at this point in the history
Advent of Code
  • Loading branch information
jwbot authored Dec 21, 2024
2 parents ac6fb09 + 96672af commit 52cbce4
Show file tree
Hide file tree
Showing 6 changed files with 457 additions and 64 deletions.
22 changes: 21 additions & 1 deletion compiler_v4/src/hir_to_mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,14 @@ impl<'c, 'h> BodyBuilder<'c, 'h> {
} => {
let value = self.lower_id(*value);
let enum_ = self.lower_type(enum_);

let mono::TypeDeclaration::Enum { variants } =
&self.context.type_declarations[&enum_].as_ref().unwrap()
else {
unreachable!();
};
let variants = variants.clone();

let cases = cases
.iter()
.map(|case| {
Expand All @@ -566,7 +574,19 @@ impl<'c, 'h> BodyBuilder<'c, 'h> {
.map(|hir_id| (hir_id, self.id_generator.generate()));
mono::SwitchCase {
variant: case.variant.clone(),
value_id: value_ids.map(|(_, mir_id)| mir_id),
value: value_ids.map(|(_, mir_id)| {
(
mir_id,
variants
.iter()
.find(|it| it.name == case.variant)
.unwrap()
.value_type
.as_ref()
.unwrap()
.clone(),
)
}),
body: self
.build_inner(|builder| {
if let Some((hir_id, mir_id)) = value_ids {
Expand Down
43 changes: 30 additions & 13 deletions compiler_v4/src/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ impl Body {
match &expression.kind {
ExpressionKind::Int(_) | ExpressionKind::Text(_) => {}
ExpressionKind::CreateStruct { fields, .. } => {
defined_ids.extend(fields.iter());
referenced_ids.extend(fields.iter());
}
ExpressionKind::StructAccess { struct_, .. } => {
referenced_ids.insert(*struct_);
Expand All @@ -262,8 +262,15 @@ impl Body {
referenced_ids.insert(*lambda);
referenced_ids.extend(arguments.iter());
}
ExpressionKind::Switch { value, .. } => {
ExpressionKind::Switch { value, cases, .. } => {
referenced_ids.insert(*value);
for case in cases.iter() {
if let Some((value_id, _)) = &case.value {
referenced_ids.insert(*value_id);
}
case.body
.collect_defined_and_referenced_ids(defined_ids, referenced_ids);
}
}
ExpressionKind::Lambda(Lambda { parameters, body }) => {
defined_ids.extend(parameters.iter().map(|it| it.id));
Expand All @@ -273,17 +280,26 @@ impl Body {
}
}
#[must_use]
pub fn find_expression(&self, id: Id) -> Option<&Expression> {
pub fn find_expression(&self, id: Id) -> Option<(&str, Option<&Expression>)> {
self.expressions.iter().find_map(|(it_id, _, expression)| {
if *it_id == id {
return Some(expression);
return Some((expression.type_.as_ref(), Some(expression)));
}

match &expression.kind {
ExpressionKind::Switch { cases, .. } => {
cases.iter().find_map(|it| it.body.find_expression(id))
}
ExpressionKind::Lambda(Lambda { body, .. }) => body.find_expression(id),
ExpressionKind::Switch { cases, .. } => cases.iter().find_map(|it| {
if let Some((value_id, box value_type)) = &it.value
&& *value_id == id
{
return Some((value_type, None));
}
it.body.find_expression(id)
}),
ExpressionKind::Lambda(Lambda { parameters, body }) => parameters
.iter()
.find(|it| it.id == id)
.map(|it| (it.type_.as_ref(), None))
.or_else(|| body.find_expression(id)),
_ => None,
}
})
Expand Down Expand Up @@ -410,14 +426,14 @@ impl ToText for ExpressionKind {
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct SwitchCase {
pub variant: Box<str>,
pub value_id: Option<Id>,
pub value: Option<(Id, Box<str>)>,
pub body: Body,
}
impl ToText for SwitchCase {
fn build_text(&self, builder: &mut TextBuilder) {
builder.push(format!("{}", self.variant));
if let Some(value_id) = self.value_id {
builder.push(format!("({value_id})"));
if let Some((value_id, value_type)) = &self.value {
builder.push(format!("({value_id}: {value_type})"));
}
builder.push(" => ");
self.body.build_text(builder);
Expand Down Expand Up @@ -450,8 +466,9 @@ impl Lambda {
"Couldn't find expression {id} in declaration body {declaration_body:?}"
)
})
.type_
.clone()
.0
.to_string()
.into_boxed_str()
},
|it| it.type_.clone(),
)
Expand Down
43 changes: 16 additions & 27 deletions compiler_v4/src/mono_to_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ impl<'h> Context<'h> {
{list_type}* result_pointer = malloc(sizeof({list_type}));
result_pointer->length = {length}->value;
result_pointer->values = malloc({length}->value * sizeof({item_type}));
result_pointer->values = malloc({length}->value * sizeof({item_type}*));
for (uint64_t i = 0; i < {length}->value; i++) {{
result_pointer->values[i] = {item};
}}
Expand All @@ -442,7 +442,7 @@ impl<'h> Context<'h> {
{list_type}* result_pointer = malloc(sizeof({list_type}));
result_pointer->length = {length}->value;
result_pointer->values = malloc({length}->value * sizeof({item_type}));
result_pointer->values = malloc({length}->value * sizeof({item_type}*));
for (uint64_t i = 0; i < {length}->value; i++) {{
Int* index = malloc(sizeof(Int));
index->value = i;
Expand Down Expand Up @@ -483,8 +483,8 @@ impl<'h> Context<'h> {
{list_type}* result_pointer = malloc(sizeof({list_type}));
result_pointer->length = {list}->length + 1;
result_pointer->values = malloc(result_pointer->length * sizeof({item_type}));
memcpy(result_pointer->values, {list}->values, {index}->value * sizeof({item_type}));
result_pointer->values = malloc(result_pointer->length * sizeof({item_type}*));
memcpy(result_pointer->values, {list}->values, {index}->value * sizeof({item_type}*));
result_pointer->values[{index}->value] = {item};
memcpy(result_pointer->values + {index}->value + 1, {list}->values + {index}->value, ({list}->length - {index}->value) * sizeof({item_type}));
return result_pointer;",
Expand Down Expand Up @@ -513,7 +513,7 @@ impl<'h> Context<'h> {
"\
{list_type}* result_pointer = malloc(sizeof({list_type}));
result_pointer->length = 1;
result_pointer->values = malloc(sizeof({item_type}));
result_pointer->values = malloc(sizeof({item_type}*));
result_pointer->values[0] = {item0};
return result_pointer;",
item_type = substitutions["T"],
Expand All @@ -524,7 +524,7 @@ impl<'h> Context<'h> {
"\
{list_type}* result_pointer = malloc(sizeof({list_type}));
result_pointer->length = 2;
result_pointer->values = malloc(2 * sizeof({item_type}));
result_pointer->values = malloc(2 * sizeof({item_type}*));
result_pointer->values[0] = {item0};
result_pointer->values[1] = {item1};
return result_pointer;",
Expand All @@ -537,7 +537,7 @@ impl<'h> Context<'h> {
"\
{list_type}* result_pointer = malloc(sizeof({list_type}));
result_pointer->length = 3;
result_pointer->values = malloc(3 * sizeof({item_type}));
result_pointer->values = malloc(3 * sizeof({item_type}*));
result_pointer->values[0] = {item0};
result_pointer->values[1] = {item1};
result_pointer->values[2] = {item2};
Expand All @@ -552,7 +552,7 @@ impl<'h> Context<'h> {
"\
{list_type}* result_pointer = malloc(sizeof({list_type}));
result_pointer->length = 4;
result_pointer->values = malloc(4 * sizeof({item_type}));
result_pointer->values = malloc(4 * sizeof({item_type}*));
result_pointer->values[0] = {item0};
result_pointer->values[1] = {item1};
result_pointer->values[2] = {item2};
Expand All @@ -569,7 +569,7 @@ impl<'h> Context<'h> {
"\
{list_type}* result_pointer = malloc(sizeof({list_type}));
result_pointer->length = 5;
result_pointer->values = malloc(5 * sizeof({item_type}));
result_pointer->values = malloc(5 * sizeof({item_type}*));
result_pointer->values[0] = {item0};
result_pointer->values[1] = {item1};
result_pointer->values[2] = {item2};
Expand Down Expand Up @@ -599,9 +599,9 @@ impl<'h> Context<'h> {
{list_type}* result_pointer = malloc(sizeof({list_type}));
result_pointer->length = {list}->length - 1;
result_pointer->values = malloc(result_pointer->length * sizeof({item_type}));
memcpy(result_pointer->values, {list}->values, {index}->value * sizeof({item_type}));
memcpy(result_pointer->values + {index}->value, {list}->values + {index}->value + 1, ({list}->length - {index}->value - 1) * sizeof({item_type}));
result_pointer->values = malloc(result_pointer->length * sizeof({item_type}*));
memcpy(result_pointer->values, {list}->values, {index}->value * sizeof({item_type}*));
memcpy(result_pointer->values + {index}->value, {list}->values + {index}->value + 1, ({list}->length - {index}->value - 1) * sizeof({item_type}*));
return result_pointer;",
item_type = substitutions["T"],
list_type = function.return_type,
Expand All @@ -623,8 +623,8 @@ impl<'h> Context<'h> {
{list_type}* result_pointer = malloc(sizeof({list_type}));
result_pointer->length = {list}->length;
result_pointer->values = malloc(result_pointer->length * sizeof({item_type}));
memcpy(result_pointer->values, {list}->values, {list}->length * sizeof({item_type}));
result_pointer->values = malloc(result_pointer->length * sizeof({item_type}*));
memcpy(result_pointer->values, {list}->values, {list}->length * sizeof({item_type}*));
result_pointer->values[{index}->value] = {new_item};
return result_pointer;",
item_type = substitutions["T"],
Expand Down Expand Up @@ -835,25 +835,14 @@ impl<'h> Context<'h> {
enum_,
cases,
} => {
let TypeDeclaration::Enum { variants } = &self.mono.type_declarations[enum_] else {
unreachable!();
};

self.push(format!("{}* {id};\n", &expression.type_));

self.push(format!("switch ({value}->variant) {{"));
for case in cases.iter() {
self.push(format!("case {enum_}_{}:\n", case.variant));
if let Some(value_id) = case.value_id {
let variant_type = variants
.iter()
.find(|variant| variant.name == case.variant)
.unwrap()
.value_type
.as_ref()
.unwrap();
if let Some((value_id, value_type)) = &case.value {
self.push(format!(
"{variant_type}* {value_id} = {value}->value.{};\n",
"{value_type}* {value_id} = {value}->value.{};\n",
case.variant,
));
}
Expand Down
Loading

0 comments on commit 52cbce4

Please sign in to comment.