Skip to content

Commit

Permalink
Merge pull request #1086 from candy-lang/list-methods
Browse files Browse the repository at this point in the history
List methods
  • Loading branch information
JonasWanke authored Dec 19, 2024
2 parents c078657 + 9772291 commit ac6fb09
Show file tree
Hide file tree
Showing 10 changed files with 650 additions and 81 deletions.
9 changes: 7 additions & 2 deletions compiler_v4/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ pub struct AstText {
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum AstTextPart {
Text(Box<str>),
Text(AstResult<Box<str>>),
Interpolation {
expression: AstResult<Box<AstExpression>>,
closing_curly_brace_error: Option<AstError>,
Expand Down Expand Up @@ -381,6 +381,9 @@ impl CollectAstErrors for AstError {
impl CollectAstErrors for AstString {
fn collect_errors_to(&self, _errors: &mut Vec<CompilerError>) {}
}
impl CollectAstErrors for str {
fn collect_errors_to(&self, _errors: &mut Vec<CompilerError>) {}
}
impl CollectAstErrors for i64 {
fn collect_errors_to(&self, _errors: &mut Vec<CompilerError>) {}
}
Expand Down Expand Up @@ -594,7 +597,9 @@ impl CollectAstErrors for AstText {
impl CollectAstErrors for AstTextPart {
fn collect_errors_to(&self, errors: &mut Vec<CompilerError>) {
match &self {
Self::Text(_) => {}
Self::Text(text) => {
text.errors.collect_errors_to(errors);
}
Self::Interpolation {
expression,
closing_curly_brace_error,
Expand Down
35 changes: 17 additions & 18 deletions compiler_v4/src/ast_to_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1357,7 +1357,7 @@ impl<'c, 'a> BodyBuilder<'c, 'a> {
{
self.context.add_error(
expression.span.clone(),
format!("Expected type `{context_type:?}`, got `{type_:?}`."),
format!("Expected type `{context_type}`, got `{type_}`."),
);
(self.push_error(), Type::Error)
} else {
Expand Down Expand Up @@ -1397,9 +1397,11 @@ impl<'c, 'a> BodyBuilder<'c, 'a> {
.parts
.iter()
.map::<Id, _>(|it| match it {
AstTextPart::Text(text) => {
self.push(None, ExpressionKind::Text(text.clone()), NamedType::text())
}
AstTextPart::Text(text) => self.push(
None,
ExpressionKind::Text(text.value().cloned().unwrap_or_default()),
NamedType::text(),
),
AstTextPart::Interpolation { expression, .. } => {
if let Some(expression) = expression.value() {
// TODO: accept impl ToText
Expand Down Expand Up @@ -1547,7 +1549,7 @@ impl<'c, 'a> BodyBuilder<'c, 'a> {
LoweredExpression::Error => LoweredExpression::Error,
}
}
_ => todo!("Support calling other expressions"),
receiver => todo!("Support calling other expressions: {receiver:?}"),
}
}
AstExpressionKind::Navigation(navigation) => {
Expand Down Expand Up @@ -1610,7 +1612,7 @@ impl<'c, 'a> BodyBuilder<'c, 'a> {
);
LoweredExpression::Error
}
Type::Error => todo!(),
Type::Error => LoweredExpression::Error,
},
LoweredExpression::NamedTypeReference(type_) => {
let declaration = self.context.hir.type_declarations.get(&type_).unwrap();
Expand Down Expand Up @@ -1904,18 +1906,15 @@ impl<'c, 'a> BodyBuilder<'c, 'a> {
&argument_types,
);
return match result {
Ok(substitutions) => {
assert!(substitutions.is_empty());
self.push_lowered(
None,
ExpressionKind::Call {
function: id,
substitutions,
arguments: arguments.iter().map(|(id, _)| *id).collect(),
},
*type_.return_type,
)
}
Ok(substitutions) => self.push_lowered(
None,
ExpressionKind::Call {
function: id,
substitutions,
arguments: arguments.iter().map(|(id, _)| *id).collect(),
},
*type_.return_type,
),
Err(error) => {
self.context.add_error(
name.span.clone(),
Expand Down
52 changes: 31 additions & 21 deletions compiler_v4/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,8 @@ impl ToText for ExpressionKind {
builder.push("[");
builder.push_children_custom(
substitutions.iter(),
|builder, (id, type_)| {
builder.push(format!("{id}: {type_}"));
|builder, (type_parameter, type_argument)| {
builder.push(format!("{type_parameter} = {type_argument}"));
},
", ",
);
Expand All @@ -751,25 +751,10 @@ impl ToText for ExpressionKind {
builder.push("switch ");
value.build_text(builder);
builder.push(format!(": {enum_} {{"));
builder.push_children_custom_multiline(cases.iter(), |builder, case| {
builder.push(format!("case {}", case.variant));
if let Some(value_id) = case.value_id {
builder.push(format!("({value_id})"));
}
builder.push(" {");
builder.push_children_custom_multiline(
case.body.expressions.iter(),
|builder, (id, name, expression)| {
id.build_text(builder);
builder.push(format!(": {} = ", expression.type_));
if let Some(name) = name {
builder.push(format!("{name} = "));
}
expression.kind.build_text(builder);
},
);
builder.push("}");
});
builder.push_children_multiline(cases.iter());
if !cases.is_empty() {
builder.push_newline();
}
builder.push("}");
}
Self::Lambda { parameters, body } => {
Expand All @@ -788,6 +773,16 @@ pub struct SwitchCase {
pub value_id: Option<Id>,
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})"));
}
builder.push(" => ");
self.body.build_text(builder);
}
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, VariantArray)]
#[strum(serialize_all = "camelCase")]
Expand All @@ -806,6 +801,7 @@ pub enum BuiltinFunction {
IntSubtract,
IntToText,
ListFilled,
ListGenerate,
ListGet,
ListInsert,
ListLength,
Expand Down Expand Up @@ -966,6 +962,20 @@ impl BuiltinFunction {
.into(),
return_type: NamedType::list(ParameterType::new("T")).into(),
},
Self::ListGenerate => BuiltinFunctionSignature {
name: "builtinListGenerate".into(),
type_parameters: ["T".into()].into(),
parameters: [
("length".into(), NamedType::int().into()),
(
"itemGetter".into(),
FunctionType::new([NamedType::int().into()], ParameterType::new("T"))
.into(),
),
]
.into(),
return_type: NamedType::list(ParameterType::new("T")).into(),
},
Self::ListGet => BuiltinFunctionSignature {
name: "builtinListGet".into(),
type_parameters: ["T".into()].into(),
Expand Down
8 changes: 5 additions & 3 deletions compiler_v4/src/hir_to_mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl<'h> Context<'h> {
.get(&function_id)
.map(|function| (trait_, function))
})
.unwrap();
.unwrap_or_else(|| panic!("Unknown trait function: {function_id}"));
let self_type = function.signature.parameters[0]
.type_
.substitute(substitutions);
Expand Down Expand Up @@ -230,7 +230,9 @@ impl<'h> Context<'h> {
.collect::<Option<Vec<_>>>()
.is_some()
})
.unwrap()
.unwrap_or_else(|| {
panic!("No matching impl found for trait `{trait_}` with {substitutions:?}")
})
}
fn mangle_function(
&mut self,
Expand Down Expand Up @@ -478,7 +480,7 @@ impl<'c, 'h> BodyBuilder<'c, 'h> {
);
}
hir::ExpressionKind::CreateStruct { struct_, fields } => {
let struct_ = self.context.lower_type(&struct_.clone().into());
let struct_ = self.lower_type(&struct_.clone().into());
let fields = self.lower_ids(fields);
self.push(
id,
Expand Down
3 changes: 2 additions & 1 deletion compiler_v4/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ fn debug(options: DebugOptions) -> ProgramResult {
}
return Err(Exit::CodeContainsErrors);
}

let mono = hir_to_mono(&hir);
println!("{mono:?}");
println!("{}", mono.to_text(true));
}
}
Ok(())
Expand Down
Loading

0 comments on commit ac6fb09

Please sign in to comment.