Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
yhara committed Jul 14, 2023
1 parent 24dac8f commit ea49f25
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 33 deletions.
59 changes: 30 additions & 29 deletions lib/skc_ast2hir/src/convert_exprs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,12 +598,15 @@ impl<'hir_maker> HirMaker<'hir_maker> {
// The variable is in this scope
let detail = match cap.detail {
LambdaCaptureDetail::CapLVar { name }
| LambdaCaptureDetail::CapOmittableArg { name } =>
HirLambdaCaptureDetail::CaptureLVar { name }
LambdaCaptureDetail::CapFnArg { idx } =>
| LambdaCaptureDetail::CapOmittableArg { name } => {
HirLambdaCaptureDetail::CaptureLVar { name }
}
LambdaCaptureDetail::CapFnArg { idx } => {
HirLambdaCaptureDetail::CaptureArg { idx }
LambdaCaptureDetail::CapMethodTyArg { idx } =>
HirLambdaCaptureDetail::CaptureMethodTyArg { idx }
}
LambdaCaptureDetail::CapMethodTyArg { idx, n_params } => {
HirLambdaCaptureDetail::CaptureMethodTyArg { idx, n_params }
}
};
ret.push(HirLambdaCapture {
ty: cap.ty,
Expand Down Expand Up @@ -673,8 +676,7 @@ impl<'hir_maker> HirMaker<'hir_maker> {
found.as_mut().map(|x| x.set_cidx(existing));
Some(existing)
} else {
let cidx = lambda_ctx.captures.len();
lambda_ctx.push_lambda_capture(cap);
let cidx = lambda_ctx.push_lambda_capture(cap);
found.as_mut().map(|x| x.set_cidx(cidx));
Some(cidx)
}
Expand Down Expand Up @@ -865,33 +867,32 @@ impl<'hir_maker> HirMaker<'hir_maker> {
Hir::class_tvar_ref(cls_ty, typaram_ref, base_ty, locs.clone())
}
TyParamKind::Method => {
if matches!(self.ctx_stack.top(), HirMakerContext::Method(method_ctx)) {
let cls_ty = typaram_ref.clone().into_term_ty();
let n_args = method_ctx.signature.params.len();
Hir::method_tvar_ref(cls_ty, typaram_ref, n_args, locs.clone())
} else {
let lambda_ctx = self.ctx_stack.lambda_ctx().unwrap();
let (opt_method_ctx, opt_lambda_ctx) = self.ctx_stack.method_and_lambda_ctx();
let n_params = opt_method_ctx.unwrap().signature.params.len();
if let Some(mut lambda_ctx) = opt_lambda_ctx {
// We're in a lambda so the tyarg should be captured in it
let ty = typaram_ref.upper_bound.to_term_ty();
let cap = LambdaCapture {
???
ctx_idx: scope.ctx_idx,
is_lambda_scope: scope.is_lambda_scope,
ty: lvar.ty.clone(),
ctx_idx: self.ctx_stack.method_ctx_idx(),
is_lambda_scope: false,
ty: ty.clone(),
upcast_needed: false,
readonly: lvar.readonly,
detail: LambdaCaptureDetail::CapLVar {
name: name.to_string(),
readonly: true,
detail: LambdaCaptureDetail::CapMethodTyArg {
idx: typaram_ref.idx,
n_params,
},
};
if let Some(existing) = lambda_ctx.check_already_captured(&cap) {
found.as_mut().map(|x| x.set_cidx(existing));
Some(existing)
let cidx = if let Some(existing) = lambda_ctx.check_already_captured(&cap) {
existing
} else {
let cidx = lambda_ctx.captures.len();
lambda_ctx.push_lambda_capture(cap);
found.as_mut().map(|x| x.set_cidx(cidx));
Some(cidx)
}
Hir::lambda_capture_ref(todo)
lambda_ctx.push_lambda_capture(cap)
};
Hir::lambda_capture_ref(ty, cidx, false, locs.clone())
} else {
// Not in a lambda so we can just get the tyarg
let cls_ty = typaram_ref.clone().into_term_ty();
Hir::method_tvar_ref(cls_ty, typaram_ref, n_params, locs.clone())
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions lib/skc_ast2hir/src/ctx_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,24 @@ impl CtxStack {
None
}

/// Returns the method ctx (if any) and nearest enclosing lambda ctx (if any).
pub fn method_and_lambda_ctx(&self) -> (Option<&MethodCtx>, Option<&mut LambdaCtx>) {
let m = None;
let l = None;
for x in self.vec.iter_mut().rev() {
match x {
HirMakerContext::Method(c) => m = Some(c),
HirMakerContext::Lambda(c) => {
if l.is_none() {
l = Some(c)
}
}
_ => (),
}
}
(m, l)
}

/// Return ctx of nearest enclosing lambda, if any
pub fn lambda_ctx(&self) -> Option<&LambdaCtx> {
for x in self.vec.iter().rev() {
Expand Down
6 changes: 3 additions & 3 deletions lib/skc_ast2hir/src/hir_maker_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ pub enum LambdaCaptureDetail {
// (Currently implemented as a local variable.)
CapOmittableArg { name: String },
// Capturing a method-wise type parameter
CapMethodTyArg { idx: usize },
CapMethodTyArg { idx: usize, n_params: usize },
}

impl LambdaCapture {
Expand All @@ -220,8 +220,8 @@ impl LambdaCapture {
LambdaCaptureDetail::CapFnArg { idx: idx2 },
) => idx == idx2,
(
LambdaCaptureDetail::CapMethodTyArg { idx },
LambdaCaptureDetail::CapMethodTyArg { idx: idx2 },
LambdaCaptureDetail::CapMethodTyArg { idx, .. },
LambdaCaptureDetail::CapMethodTyArg { idx: idx2, .. },
) => idx == idx2,
(
LambdaCaptureDetail::CapOmittableArg { name },
Expand Down
4 changes: 4 additions & 0 deletions lib/skc_codegen/src/gen_exprs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,10 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
let deref = false;
self.gen_lambda_capture_ref(ctx, cidx, deref)
}
HirLambdaCaptureDetail::CaptureMethodTyArg { idx, n_params } => {
// Method-wise type arguments are passed as llvm function parameter.
self.gen_arg_ref(ctx, &(n_params + idx))
}
};
if cap.upcast_needed {
let ty = struct_type.get_field_type_at_index(i as u32).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion lib/skc_hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ pub enum HirLambdaCaptureDetail {
/// Method/Function argument
CaptureArg { idx: usize },
/// Method-wise type argument
CaptureMethodTyArg { idx: usize },
CaptureMethodTyArg { idx: usize, n_params: usize },
/// Variable in the current `captures`
CaptureFwd { cidx: usize },
}
Expand Down

0 comments on commit ea49f25

Please sign in to comment.