1
1
use crate :: error:: Error ;
2
- use crate :: parser:: { Block , Expr , ExprKind as EK , Parser } ;
2
+ use crate :: parser:: { Block , Expr , ExprKind as EK , FunctionBean , Parser } ;
3
3
use crate :: position:: Position ;
4
- use crate :: value:: { ImmutableString , Function , Object , Value } ;
4
+ use crate :: value:: { ImmutableString , Function , FunctionRust , FunctionKind , Object , Value } ;
5
5
use std:: collections:: BTreeMap ;
6
6
use std:: mem;
7
7
@@ -126,6 +126,10 @@ impl Context {
126
126
Ok ( self . eval_block ( & Parser :: parse_script ( source) ?) ?)
127
127
}
128
128
129
+ pub fn call_function ( & mut self , func : & Function , vals : Vec < Value > ) -> Result < Value , Value > {
130
+ Ok ( self . eval_call_inner_vals ( func, vals) ?)
131
+ }
132
+
129
133
fn eval_block ( & mut self , block : & Block ) -> Result < Value , Interrupt > {
130
134
self . scopes . push ( Object :: new ( ) ) ;
131
135
let result = self . eval_block_no_scope ( block) ;
@@ -418,10 +422,9 @@ impl Context {
418
422
_ => return Err ( Interrupt :: Error ( Error :: bad_iter ( position) ) ) ,
419
423
} ;
420
424
421
- let args = Vec :: new ( ) ;
422
-
425
+ let empty_args = Vec :: new ( ) ;
423
426
loop {
424
- let object_val = self . eval_call_inner ( next, & args ) ?;
427
+ let object_val = self . eval_call_inner_exprs ( next, & empty_args ) ?;
425
428
let object = match object_val {
426
429
Value :: Object ( ref object) => object,
427
430
_ => return Err ( Interrupt :: Error ( Error :: bad_iter_next ( position) ) ) ,
@@ -503,27 +506,58 @@ impl Context {
503
506
// the error is "localized" to the caller's location (i.e. the line/column point to `pos`).
504
507
let func = self . eval_expr ( func) ?;
505
508
if let Value :: Function ( ref func) = func {
506
- self . eval_call_inner ( func, args)
509
+ self . eval_call_inner_exprs ( func, args)
507
510
} else {
508
511
Err ( Interrupt :: Error ( Error :: not_a_function ( pos) ) )
509
512
}
510
513
}
511
514
512
- fn eval_call_inner ( & mut self , func : & Function , args : & Vec < Expr > ) -> Result < Value , Interrupt > {
515
+ fn eval_call_inner_exprs (
516
+ & mut self ,
517
+ func : & Function ,
518
+ args : & Vec < Expr > ,
519
+ ) -> Result < Value , Interrupt > {
520
+ let mut vals = Vec :: with_capacity ( args. len ( ) ) ;
521
+ for arg in args {
522
+ vals. push ( self . eval_expr ( arg) ?) ;
523
+ }
524
+
525
+ self . eval_call_inner_vals ( func, vals)
526
+ }
527
+
528
+ fn eval_call_inner_vals (
529
+ & mut self ,
530
+ func : & Function ,
531
+ vals : Vec < Value > ,
532
+ ) -> Result < Value , Interrupt > {
533
+ match func. kind ( ) {
534
+ FunctionKind :: Bean ( bean_func) => self . eval_call_bean ( bean_func, func. scopes ( ) , vals) ,
535
+ FunctionKind :: Rust ( rust_func) => self . eval_call_rust ( rust_func, vals) ,
536
+ }
537
+ }
538
+
539
+ fn eval_call_bean (
540
+ & mut self ,
541
+ func : & FunctionBean ,
542
+ scopes : & [ Object ] ,
543
+ mut vals : Vec < Value > ,
544
+ ) -> Result < Value , Interrupt > {
513
545
let scope = Object :: new ( ) ;
514
- for ( index, param) in func. def ( ) . params . iter ( ) . enumerate ( ) {
515
- let arg = match args. get ( index) {
516
- Some ( expr) => self . eval_expr ( expr) ?,
517
- None => Value :: Null ,
546
+ for param in func. params . iter ( ) {
547
+ let val = if vals. len ( ) > 0 {
548
+ vals. remove ( 0 )
549
+ } else {
550
+ Value :: Null
518
551
} ;
519
- scope. set ( param. clone ( ) , arg) ;
552
+
553
+ scope. set ( param. clone ( ) , val) ;
520
554
}
521
555
522
556
// Restore the original scope stack at the declaration site of the function:
523
- let ctx_scopes = mem:: replace ( & mut self . scopes , func . scopes ( ) . to_vec ( ) ) ;
557
+ let ctx_scopes = mem:: replace ( & mut self . scopes , scopes. to_vec ( ) ) ;
524
558
self . scopes . push ( scope) ;
525
559
526
- let result = match self . eval_expr ( & func. def ( ) . body ) {
560
+ let result = match self . eval_expr ( & func. body ) {
527
561
Ok ( value) => Ok ( value) ,
528
562
Err ( Interrupt :: Return { value, .. } ) => Ok ( match value {
529
563
Some ( value) => value,
@@ -543,6 +577,14 @@ impl Context {
543
577
result
544
578
}
545
579
580
+ fn eval_call_rust (
581
+ & mut self ,
582
+ func : & FunctionRust ,
583
+ vals : Vec < Value > ,
584
+ ) -> Result < Value , Interrupt > {
585
+ func ( self , vals) . map_err ( |val| Interrupt :: Error ( val) )
586
+ }
587
+
546
588
fn eval_bool_or ( & mut self , a : & Expr , b : & Expr ) -> Result < Value , Interrupt > {
547
589
let a = self . eval_expr ( a) ?. coerce_bool ( ) ;
548
590
if a {
@@ -616,11 +658,18 @@ pub enum Interrupt {
616
658
617
659
impl From < Interrupt > for Error {
618
660
fn from ( interrupt : Interrupt ) -> Error {
661
+ let value: Value = interrupt. into ( ) ;
662
+ Error :: Runtime ( value)
663
+ }
664
+ }
665
+
666
+ impl From < Interrupt > for Value {
667
+ fn from ( interrupt : Interrupt ) -> Value {
619
668
match interrupt {
620
- Interrupt :: Break { position, .. } => Error :: Runtime ( Error :: bad_break ( position) ) ,
621
- Interrupt :: Continue { position, .. } => Error :: Runtime ( Error :: bad_continue ( position) ) ,
622
- Interrupt :: Return { position, .. } => Error :: Runtime ( Error :: bad_return ( position) ) ,
623
- Interrupt :: Error ( value) => Error :: Runtime ( value) ,
669
+ Interrupt :: Break { position, .. } => Error :: bad_break ( position) ,
670
+ Interrupt :: Continue { position, .. } => Error :: bad_continue ( position) ,
671
+ Interrupt :: Return { position, .. } => Error :: bad_return ( position) ,
672
+ Interrupt :: Error ( value) => value,
624
673
}
625
674
}
626
675
}
0 commit comments