From 567adbd04418adfd4dcca6b63083bfb5a5595290 Mon Sep 17 00:00:00 2001 From: Ashton Wiersdorf Date: Wed, 24 Jan 2024 15:41:44 -0700 Subject: [PATCH] Function calls under repetition working --- main.rhm | 73 ++++++++++++++--------------------------------- tests/general.rhm | 18 ++++++++++++ 2 files changed, 39 insertions(+), 52 deletions(-) diff --git a/main.rhm b/main.rhm index 99f8dbd..d76ed91 100644 --- a/main.rhm +++ b/main.rhm @@ -65,76 +65,45 @@ expr.macro '$func dyn_app ($args, ...)': $func #%call ($temps, ...)' | '$func #%call ($args, ...)' -// repet.macro '$func dyn_app ($(args :: repet_meta.Parsed))': -// ~op_stx self -// println("func: " +& func.to_source_string() +& "\nargs: " +& args.to_source_string()) -// def '($func_orig, $func_name, $func_expr, $func_depth, $func_use_depth, $func_statinfos, $func_is_immed)': -// repet_meta.unpack_list(func) -// def '($orig, $name, $expr, $depth, $use_depth, $statinfos, $is_immed)': -// repet_meta.unpack_list(args) -// unless func_depth.unwrap() == 0 && depth.unwrap() == 1 -// | error("only handle argument repetitions right now") -// def (pred, si): // ← just a way to grab the static info we need? -// annot_meta.unpack_predicate(match 'List' | '$(p :: annot_meta.Parsed)': p) -// repet_meta.pack_list('($self(), -// $name, -// for PairList: -// each: -// elem: ($expr) :~ PairList -// $func_expr dyn_app (elem), -// $depth, -// $use_depth, -// $si, -// #false)') - repet.macro '$func dyn_app ($(args :: repet_meta.Parsed), ...)': ~op_stx self - println("here") + + fun + | max([n]): n + | max([n, ns, ...]): + let m = max([ns, ...]) + if m > n | m | n + def '($func_orig, $func_name, $func_expr, $func_depth, $func_use_depth, $func_statinfos, $func_is_immed)': repet_meta.unpack_list(func) def ['($orig, $name, $expr, $depth, $use_depth, $statinfos, $is_immed)', ...]: [repet_meta.unpack_list(args), ...] - println("expr: " +& [expr, ...]) - List.map(['($orig, $name, $expr, $depth, $use_depth, $statinfos, $is_immed)', ...], println) - unless func_depth.unwrap() == 0 && for all (d: [depth.unwrap(), ...]): d == 1 || d == 0 | error("only handle argument repetitions and constants right now") - def args_depth_set = {depth.unwrap(), ...} - unless args_depth_set.length() == 0 || args_depth_set.length() == 1 - | error("don't know how to handle multiple use depths in arguments " +& args_depth_set) - def args_this_depth = if args_depth_set.length() == 0 | 0 | [depth, ...][0] - - println("got depth: " +& args_this_depth) - - // def depth_set = {depth.unwrap(), ...} - // unless depth_set.length() == 0 || depth_set.length() == 1 - // | error("don't know how to handle multiple use depths in arguments " +& depth_set) - // def this_depth = if depth_set.length() == 0 | 0 | [depth, ...][0] - def (pred, si): annot_meta.unpack_predicate(match 'List' | '$(p :: annot_meta.Parsed)': p) - def [temps, ...] = [Syntax.make_temp_id(expr), ...] - - // for PairList: - // each: - // $temps: $expr :~ PairList; - // ... - // 42, - // $func_expr #%call ($temps, ...), + def temps_depths = [[Syntax.make_temp_id(expr), expr, depth.unwrap()], ...] + def [[repet_temps, repet_exprs, _d1], ...] = (for List (i: temps_depths): keep_when i[2] == 1; i) + def [[const_temps, const_exprs, _dz], ...] = (for List (i: temps_depths): keep_when i[2] == 0; i) + def [[all_temps, _expr, _depth], ...] = temps_depths + def max_depth = max([depth.unwrap(), ...]) repet_meta.pack_list('($self, $func_name, - for PairList: - each: - $temps: $expr :~ PairList - ... - $func_expr dyn_app ($temps, ...), + block: + let $const_temps = $const_exprs + ... + for PairList: + each: + $repet_temps: $repet_exprs :~ PairList + ... + $func_expr dyn_app ($all_temps, ...), 2, // can hardcode I think... we check that the args depth is 1 above - $args_this_depth, + $max_depth, $si, #false)') diff --git a/tests/general.rhm b/tests/general.rhm index dac4018..d9124e2 100644 --- a/tests/general.rhm +++ b/tests/general.rhm @@ -133,10 +133,28 @@ check_dyn: /// Repetition macros +// fun top_foo(x, y): x + 2 * y + +// for PairList: +// each: +// foo: [1, 2, 3] +// bar: [2, 4, 8] +// top_foo(foo, bar) + check_dyn: block: fun foo(x :: Dyn) :: Dyn: x + 1 + fun bar(x, y): + x + 2 * y + + fun baz(x, y, z): + x + z * y + def [xs, ...] = [1, 2, 3] + def [ys, ...] = [2, 4, 6] [foo(xs), ...] + [bar(xs, ys), ...] + [bar(1, xs), ...] + [baz(1, ys, 3), ...]