@@ -38,6 +38,10 @@ pub trait CallableFormals {
38
38
pub trait Callable : CallableFormals {
39
39
fn match_args ( & self , args : List , stack : & mut CallStack ) -> Result < ( List , List ) , Signal > {
40
40
let mut formals = self . formals ( ) ;
41
+ // instead of using a List for ellipsis I want an ExprList
42
+
43
+ let mut expr_ellipsis: ExprList = ExprList :: new ( ) ;
44
+
41
45
let mut ellipsis: List = List :: new ( ) ;
42
46
let mut matched_args: List = List :: new ( ) ;
43
47
@@ -67,19 +71,27 @@ pub trait Callable: CallableFormals {
67
71
68
72
// backfill unnamed args, populating ellipsis with overflow
69
73
for ( key, value) in args. iter_pairs ( ) {
70
- match key {
74
+ match ( key, value . clone ( ) ) {
71
75
// named args go directly to ellipsis, they did not match a formal
72
- Character :: Some ( arg) => ellipsis. push_named ( Character :: Some ( arg) , value) ,
76
+ ( Character :: Some ( arg) , Obj :: Promise ( _, e, _) ) => {
77
+ expr_ellipsis. push_named ( Character :: Some ( arg. clone ( ) ) . as_option ( ) , e) ;
78
+ ellipsis. push_named ( Character :: Some ( arg) , value) ;
79
+ }
73
80
74
81
// unnamed args populate next formal, or ellipsis if formals exhausted
75
- Character :: NA => {
82
+ ( Character :: NA , value ) => {
76
83
let next_unassigned_formal = formals. remove ( 0 ) ;
77
84
if let Some ( ( Some ( param) , _) ) = next_unassigned_formal {
78
85
matched_args. push_named ( Character :: Some ( param) , value) ;
79
86
} else {
87
+ let Obj :: Promise ( _, e, _) = value. clone ( ) else {
88
+ unreachable ! ( )
89
+ } ;
90
+ expr_ellipsis. push_named ( Character :: NA . as_option ( ) , e) ;
80
91
ellipsis. push_named ( Character :: NA , value) ;
81
92
}
82
93
}
94
+ _ => unreachable ! ( ) ,
83
95
}
84
96
}
85
97
@@ -91,8 +103,20 @@ pub trait Callable: CallableFormals {
91
103
)
92
104
}
93
105
106
+ use crate :: callable:: builtins:: BUILTIN ;
107
+
108
+ let list = BUILTIN . get ( "list" ) . cloned ( ) . unwrap ( ) ;
109
+
110
+ // convert the expr_ellipsis to an Obj::Promise where the expression is a call into List
111
+
112
+ let a = Obj :: Promise (
113
+ None ,
114
+ Expr :: Call ( Box :: new ( Expr :: Primitive ( list) ) , expr_ellipsis) ,
115
+ stack. last_frame ( ) . env ( ) . clone ( ) ,
116
+ ) ;
117
+
94
118
if let Some ( Expr :: Ellipsis ( Some ( name) ) ) = remainder. get ( 0 ) {
95
- matched_args. push_named ( Character :: Some ( name) , Obj :: List ( ellipsis . clone ( ) ) ) ;
119
+ matched_args. push_named ( Character :: Some ( name) , a ) ;
96
120
} else if !remainder. is_empty ( ) {
97
121
matched_args. push_named (
98
122
Character :: Some ( "..." . to_string ( ) ) ,
0 commit comments