Formatting
This commit is contained in:
@@ -237,7 +237,11 @@ impl<'a> Analyzer<'a> {
|
||||
Purity::Impure,
|
||||
)
|
||||
}
|
||||
BoundKind::Pipe { inputs, lambda, out_type } => {
|
||||
BoundKind::Pipe {
|
||||
inputs,
|
||||
lambda,
|
||||
out_type,
|
||||
} => {
|
||||
let mut analyzed_inputs = Vec::with_capacity(inputs.len());
|
||||
for input in inputs {
|
||||
analyzed_inputs.push(self.visit(Rc::new(input.clone())));
|
||||
@@ -288,7 +292,13 @@ impl<'a> Analyzer<'a> {
|
||||
p = p.min(vm.ty.purity);
|
||||
new_values.push(vm);
|
||||
}
|
||||
(BoundKind::Record { layout: layout.clone(), values: new_values }, p)
|
||||
(
|
||||
BoundKind::Record {
|
||||
layout: layout.clone(),
|
||||
values: new_values,
|
||||
},
|
||||
p,
|
||||
)
|
||||
}
|
||||
|
||||
BoundKind::Expansion {
|
||||
|
||||
+738
-708
File diff suppressed because it is too large
Load Diff
@@ -206,9 +206,10 @@ where
|
||||
},
|
||||
) => na == nb && aa == ab && ka == kb && va == vb && ca == cb,
|
||||
(BoundKind::FieldAccessor(a), BoundKind::FieldAccessor(b)) => a == b,
|
||||
(BoundKind::GetField { rec: ra, field: fa }, BoundKind::GetField { rec: rb, field: fb }) => {
|
||||
ra == rb && fa == fb
|
||||
}
|
||||
(
|
||||
BoundKind::GetField { rec: ra, field: fa },
|
||||
BoundKind::GetField { rec: rb, field: fb },
|
||||
) => ra == rb && fa == fb,
|
||||
(
|
||||
BoundKind::If {
|
||||
cond: ca,
|
||||
@@ -258,9 +259,16 @@ where
|
||||
(BoundKind::Again { args: aa }, BoundKind::Again { args: ab }) => aa == ab,
|
||||
(BoundKind::Block { exprs: ea }, BoundKind::Block { exprs: eb }) => ea == eb,
|
||||
(BoundKind::Tuple { elements: ea }, BoundKind::Tuple { elements: eb }) => ea == eb,
|
||||
(BoundKind::Record { layout: la, values: va }, BoundKind::Record { layout: lb, values: vb }) => {
|
||||
std::sync::Arc::ptr_eq(la, lb) && va == vb
|
||||
}
|
||||
(
|
||||
BoundKind::Record {
|
||||
layout: la,
|
||||
values: va,
|
||||
},
|
||||
BoundKind::Record {
|
||||
layout: lb,
|
||||
values: vb,
|
||||
},
|
||||
) => std::sync::Arc::ptr_eq(la, lb) && va == vb,
|
||||
(
|
||||
BoundKind::Expansion {
|
||||
original_call: ca,
|
||||
|
||||
@@ -89,7 +89,11 @@ impl CapturePass {
|
||||
args: Box::new(Self::transform(*args, capture_map)),
|
||||
};
|
||||
}
|
||||
BoundKind::Pipe { inputs, lambda, out_type } => {
|
||||
BoundKind::Pipe {
|
||||
inputs,
|
||||
lambda,
|
||||
out_type,
|
||||
} => {
|
||||
let mut t_inputs = Vec::with_capacity(inputs.len());
|
||||
for input in inputs {
|
||||
t_inputs.push(Self::transform(input, capture_map));
|
||||
|
||||
@@ -66,9 +66,7 @@ impl Dumper {
|
||||
self.log(&format!("Get: {} ({:?})", name.name, addr), node)
|
||||
}
|
||||
|
||||
BoundKind::FieldAccessor(k) => {
|
||||
self.log(&format!("FieldAccessor: .{}", k.name()), node)
|
||||
}
|
||||
BoundKind::FieldAccessor(k) => self.log(&format!("FieldAccessor: .{}", k.name()), node),
|
||||
|
||||
BoundKind::GetField { rec, field } => {
|
||||
self.log(&format!("GetField: .{}", field.name()), node);
|
||||
@@ -232,7 +230,10 @@ impl Dumper {
|
||||
}
|
||||
|
||||
BoundKind::Record { layout, values } => {
|
||||
self.log(&format!("Record (Layout: {} fields)", layout.fields.len()), node);
|
||||
self.log(
|
||||
&format!("Record (Layout: {} fields)", layout.fields.len()),
|
||||
node,
|
||||
);
|
||||
self.indent += 1;
|
||||
for v in values {
|
||||
self.visit(v);
|
||||
|
||||
@@ -386,7 +386,11 @@ impl Optimizer {
|
||||
)
|
||||
}
|
||||
|
||||
BoundKind::Pipe { inputs, lambda, out_type } => {
|
||||
BoundKind::Pipe {
|
||||
inputs,
|
||||
lambda,
|
||||
out_type,
|
||||
} => {
|
||||
let mut o_inputs = Vec::with_capacity(inputs.len());
|
||||
for input in inputs {
|
||||
o_inputs.push(self.visit_node(input, sub, path));
|
||||
@@ -559,17 +563,28 @@ impl Optimizer {
|
||||
.collect();
|
||||
(BoundKind::Tuple { elements }, node.ty.clone())
|
||||
}
|
||||
BoundKind::Record { ref layout, ref values } => {
|
||||
BoundKind::Record {
|
||||
ref layout,
|
||||
ref values,
|
||||
} => {
|
||||
let mapped_values: Vec<_> = values
|
||||
.iter()
|
||||
.map(|v| self.visit_node(v.clone(), sub, path))
|
||||
.collect();
|
||||
|
||||
if self.enabled && let Some(folded) = folder.try_fold_record(layout, &mapped_values, &node) {
|
||||
|
||||
if self.enabled
|
||||
&& let Some(folded) = folder.try_fold_record(layout, &mapped_values, &node)
|
||||
{
|
||||
return folded;
|
||||
}
|
||||
|
||||
(BoundKind::Record { layout: layout.clone(), values: mapped_values }, node.ty.clone())
|
||||
|
||||
(
|
||||
BoundKind::Record {
|
||||
layout: layout.clone(),
|
||||
values: mapped_values,
|
||||
},
|
||||
node.ty.clone(),
|
||||
)
|
||||
}
|
||||
BoundKind::Expansion {
|
||||
ref original_call,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, NodeMetrics};
|
||||
use crate::ast::nodes::Node;
|
||||
use crate::ast::types::{Purity, StaticType, Value, RecordLayout};
|
||||
use crate::ast::types::{Purity, RecordLayout, StaticType, Value};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
|
||||
@@ -158,7 +158,10 @@ impl UsageInfo {
|
||||
}
|
||||
self.collect(lambda);
|
||||
}
|
||||
BoundKind::Nop | BoundKind::FieldAccessor(_) | BoundKind::Extension(_) | BoundKind::Error => {}
|
||||
BoundKind::Nop
|
||||
| BoundKind::FieldAccessor(_)
|
||||
| BoundKind::Extension(_)
|
||||
| BoundKind::Error => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -132,10 +132,7 @@ impl Specializer {
|
||||
(BoundKind::Tuple { elements }, node.ty.clone())
|
||||
}
|
||||
BoundKind::Record { layout, values } => {
|
||||
let values = values
|
||||
.into_iter()
|
||||
.map(|v| self.visit_node(v))
|
||||
.collect();
|
||||
let values = values.into_iter().map(|v| self.visit_node(v)).collect();
|
||||
(BoundKind::Record { layout, values }, node.ty.clone())
|
||||
}
|
||||
BoundKind::Expansion {
|
||||
|
||||
@@ -48,7 +48,11 @@ impl TCO {
|
||||
args: Box::new(Self::transform(Rc::new((**args).clone()), false)),
|
||||
}
|
||||
}
|
||||
BoundKind::Pipe { inputs, lambda, out_type } => {
|
||||
BoundKind::Pipe {
|
||||
inputs,
|
||||
lambda,
|
||||
out_type,
|
||||
} => {
|
||||
let mut t_inputs = Vec::with_capacity(inputs.len());
|
||||
for input in inputs {
|
||||
t_inputs.push(Self::transform(Rc::new(input.clone()), false));
|
||||
|
||||
@@ -79,7 +79,12 @@ impl TypeChecker {
|
||||
Self { global_types }
|
||||
}
|
||||
|
||||
pub fn check(&self, node: BoundNode, arg_types: &[StaticType], diag: &mut Diagnostics) -> TypedNode {
|
||||
pub fn check(
|
||||
&self,
|
||||
node: BoundNode,
|
||||
arg_types: &[StaticType],
|
||||
diag: &mut Diagnostics,
|
||||
) -> TypedNode {
|
||||
match node.kind {
|
||||
BoundKind::Lambda {
|
||||
params,
|
||||
@@ -105,7 +110,12 @@ impl TypeChecker {
|
||||
StaticType::Tuple(arg_types.to_vec())
|
||||
};
|
||||
|
||||
let params_typed = self.check_params(params.as_ref().clone(), &arg_tuple_ty, &mut lambda_ctx, diag);
|
||||
let params_typed = self.check_params(
|
||||
params.as_ref().clone(),
|
||||
&arg_tuple_ty,
|
||||
&mut lambda_ctx,
|
||||
diag,
|
||||
);
|
||||
|
||||
// 4. Check body with the new types
|
||||
let body_typed = self.check_node((*body).clone(), &mut lambda_ctx, diag);
|
||||
@@ -212,7 +222,13 @@ impl TypeChecker {
|
||||
| StaticType::Record(_)
|
||||
| StaticType::Error => {}
|
||||
_ => {
|
||||
diag.push_error(format!("Cannot destructure type {} as a tuple/vector", specialized_ty), Some(node.identity.clone()));
|
||||
diag.push_error(
|
||||
format!(
|
||||
"Cannot destructure type {} as a tuple/vector",
|
||||
specialized_ty
|
||||
),
|
||||
Some(node.identity.clone()),
|
||||
);
|
||||
return Node {
|
||||
identity: node.identity,
|
||||
kind: BoundKind::Error,
|
||||
@@ -251,7 +267,10 @@ impl TypeChecker {
|
||||
}
|
||||
BoundKind::Error => (BoundKind::Error, StaticType::Error),
|
||||
_ => {
|
||||
diag.push_error("Invalid node in parameter list", Some(node.identity.clone()));
|
||||
diag.push_error(
|
||||
"Invalid node in parameter list",
|
||||
Some(node.identity.clone()),
|
||||
);
|
||||
(BoundKind::Error, StaticType::Error)
|
||||
}
|
||||
};
|
||||
@@ -263,7 +282,12 @@ impl TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_node(&self, node: BoundNode, ctx: &mut TypeContext, diag: &mut Diagnostics) -> TypedNode {
|
||||
fn check_node(
|
||||
&self,
|
||||
node: BoundNode,
|
||||
ctx: &mut TypeContext,
|
||||
diag: &mut Diagnostics,
|
||||
) -> TypedNode {
|
||||
let (kind, ty) = match node.kind {
|
||||
BoundKind::Nop => (BoundKind::Nop, StaticType::Void),
|
||||
|
||||
@@ -306,7 +330,9 @@ impl TypeChecker {
|
||||
)
|
||||
}
|
||||
|
||||
BoundKind::FieldAccessor(k) => (BoundKind::FieldAccessor(k), StaticType::FieldAccessor(k)),
|
||||
BoundKind::FieldAccessor(k) => {
|
||||
(BoundKind::FieldAccessor(k), StaticType::FieldAccessor(k))
|
||||
}
|
||||
|
||||
BoundKind::GetField { rec, field } => {
|
||||
let rec_typed = self.check_node(*rec, ctx, diag);
|
||||
@@ -315,14 +341,24 @@ impl TypeChecker {
|
||||
if let Some(idx) = layout.index_of(field) {
|
||||
layout.fields[idx].1.clone()
|
||||
} else {
|
||||
diag.push_error(format!("Record does not have field :{}", field.name()), Some(rec_typed.identity.clone()));
|
||||
diag.push_error(
|
||||
format!("Record does not have field :{}", field.name()),
|
||||
Some(rec_typed.identity.clone()),
|
||||
);
|
||||
StaticType::Error
|
||||
}
|
||||
}
|
||||
StaticType::Any => StaticType::Any,
|
||||
StaticType::Error => StaticType::Error,
|
||||
_ => {
|
||||
diag.push_error(format!("Cannot access field :{} on non-record type {}", field.name(), rec_typed.ty), Some(rec_typed.identity.clone()));
|
||||
diag.push_error(
|
||||
format!(
|
||||
"Cannot access field :{} on non-record type {}",
|
||||
field.name(),
|
||||
rec_typed.ty
|
||||
),
|
||||
Some(rec_typed.identity.clone()),
|
||||
);
|
||||
StaticType::Error
|
||||
}
|
||||
};
|
||||
@@ -463,7 +499,12 @@ impl TypeChecker {
|
||||
TypeContext::new(64, upvalue_types, ctx.global_types, Some(ctx));
|
||||
|
||||
// 3. Check parameters and body
|
||||
let params_typed = self.check_params(params.as_ref().clone(), &StaticType::Any, &mut lambda_ctx, diag);
|
||||
let params_typed = self.check_params(
|
||||
params.as_ref().clone(),
|
||||
&StaticType::Any,
|
||||
&mut lambda_ctx,
|
||||
diag,
|
||||
);
|
||||
|
||||
// Set current params type for 'again' validation
|
||||
lambda_ctx.current_params_ty = Some(params_typed.ty.clone());
|
||||
@@ -515,7 +556,13 @@ impl TypeChecker {
|
||||
let ret_ty = match callee_typed.ty.resolve_call(&args_typed.ty) {
|
||||
Some(ty) => ty,
|
||||
None => {
|
||||
diag.push_error(format!("Invalid arguments for function call. Expected {}, got {}", callee_typed.ty, args_typed.ty), Some(node.identity.clone()));
|
||||
diag.push_error(
|
||||
format!(
|
||||
"Invalid arguments for function call. Expected {}, got {}",
|
||||
callee_typed.ty, args_typed.ty
|
||||
),
|
||||
Some(node.identity.clone()),
|
||||
);
|
||||
StaticType::Error
|
||||
}
|
||||
};
|
||||
@@ -553,7 +600,13 @@ impl TypeChecker {
|
||||
if let Some(expected_ty) = &ctx.current_params_ty
|
||||
&& !expected_ty.is_assignable_from(&args_typed.ty)
|
||||
{
|
||||
diag.push_error(format!("Type mismatch in 'again' call: expected {}, but got {}", expected_ty, args_typed.ty), Some(node.identity.clone()));
|
||||
diag.push_error(
|
||||
format!(
|
||||
"Type mismatch in 'again' call: expected {}, but got {}",
|
||||
expected_ty, args_typed.ty
|
||||
),
|
||||
Some(node.identity.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
(
|
||||
@@ -606,13 +659,13 @@ impl TypeChecker {
|
||||
BoundKind::Record { layout, values } => {
|
||||
let mut typed_values = Vec::with_capacity(values.len());
|
||||
let mut fields_ty = Vec::with_capacity(values.len());
|
||||
|
||||
|
||||
for (i, v) in values.into_iter().enumerate() {
|
||||
let vt = self.check_node(v, ctx, diag);
|
||||
fields_ty.push((layout.fields[i].0, vt.ty.clone()));
|
||||
typed_values.push(vt);
|
||||
}
|
||||
|
||||
|
||||
let new_layout = crate::ast::types::RecordLayout::get_or_create(fields_ty);
|
||||
(
|
||||
BoundKind::Record {
|
||||
@@ -639,7 +692,13 @@ impl TypeChecker {
|
||||
}
|
||||
|
||||
BoundKind::Extension(_ext) => {
|
||||
diag.push_error(format!("TypeChecking for extension '{}' not implemented", _ext.display_name()), Some(node.identity.clone()));
|
||||
diag.push_error(
|
||||
format!(
|
||||
"TypeChecking for extension '{}' not implemented",
|
||||
_ext.display_name()
|
||||
),
|
||||
Some(node.identity.clone()),
|
||||
);
|
||||
(BoundKind::Error, StaticType::Error)
|
||||
}
|
||||
BoundKind::Error => (BoundKind::Error, StaticType::Error),
|
||||
|
||||
Reference in New Issue
Block a user