@ -1,5 +1,7 @@
use crate ::{
use crate ::{
environment ::lexical_environment ::new_function_environment ,
environment ::lexical_environment ::{
new_declarative_environment , new_function_environment , VariableScope ,
} ,
js ::{
js ::{
function ::{ create_unmapped_arguments_object , Function , RegularFunction } ,
function ::{ create_unmapped_arguments_object , Function , RegularFunction } ,
object ::{ ObjectKind , INSTANCE_PROTOTYPE , PROTOTYPE } ,
object ::{ ObjectKind , INSTANCE_PROTOTYPE , PROTOTYPE } ,
@ -71,6 +73,13 @@ impl Executor for Interpreter {
ExprDef ::Const ( Const ::String ( ref str ) ) = > Ok ( to_value ( str . to_owned ( ) ) ) ,
ExprDef ::Const ( Const ::String ( ref str ) ) = > Ok ( to_value ( str . to_owned ( ) ) ) ,
ExprDef ::Const ( Const ::Bool ( val ) ) = > Ok ( to_value ( val ) ) ,
ExprDef ::Const ( Const ::Bool ( val ) ) = > Ok ( to_value ( val ) ) ,
ExprDef ::Block ( ref es ) = > {
ExprDef ::Block ( ref es ) = > {
{
let env = & mut self . realm . environment ;
env . push ( new_declarative_environment ( Some (
env . get_current_environment_ref ( ) . clone ( ) ,
) ) ) ;
}
let mut obj = to_value ( None ::< ( ) > ) ;
let mut obj = to_value ( None ::< ( ) > ) ;
for e in es . iter ( ) {
for e in es . iter ( ) {
let val = self . run ( e ) ? ;
let val = self . run ( e ) ? ;
@ -84,6 +93,8 @@ impl Executor for Interpreter {
obj = val ;
obj = val ;
}
}
}
}
self . realm . environment . pop ( ) ;
Ok ( obj )
Ok ( obj )
}
}
ExprDef ::Local ( ref name ) = > {
ExprDef ::Local ( ref name ) = > {
@ -215,9 +226,11 @@ impl Executor for Interpreter {
Function ::RegularFunc ( RegularFunction ::new ( * expr . clone ( ) , args . clone ( ) ) ) ;
Function ::RegularFunc ( RegularFunction ::new ( * expr . clone ( ) , args . clone ( ) ) ) ;
let val = Gc ::new ( ValueData ::Function ( Box ::new ( GcCell ::new ( function ) ) ) ) ;
let val = Gc ::new ( ValueData ::Function ( Box ::new ( GcCell ::new ( function ) ) ) ) ;
if name . is_some ( ) {
if name . is_some ( ) {
self . realm
self . realm . environment . create_mutable_binding (
. environment
name . clone ( ) . expect ( "No name was supplied" ) ,
. create_mutable_binding ( name . clone ( ) . expect ( "No name was supplied" ) , false ) ;
false ,
VariableScope ::Function ,
) ;
self . realm . environment . initialize_binding (
self . realm . environment . initialize_binding (
name . as_ref ( ) . expect ( "Could not get name as reference" ) ,
name . as_ref ( ) . expect ( "Could not get name as reference" ) ,
val . clone ( ) ,
val . clone ( ) ,
@ -355,7 +368,11 @@ impl Executor for Interpreter {
for i in 0 .. data . args . len ( ) {
for i in 0 .. data . args . len ( ) {
let name = data . args . get ( i ) . expect ( "Could not get data argument" ) ;
let name = data . args . get ( i ) . expect ( "Could not get data argument" ) ;
let expr = v_args . get ( i ) . expect ( "Could not get argument" ) ;
let expr = v_args . get ( i ) . expect ( "Could not get argument" ) ;
env . create_mutable_binding ( name . clone ( ) , false ) ;
env . create_mutable_binding (
name . clone ( ) ,
false ,
VariableScope ::Function ,
) ;
env . initialize_binding ( name , expr . to_owned ( ) ) ;
env . initialize_binding ( name , expr . to_owned ( ) ) ;
}
}
let result = self . run ( & data . expr ) ;
let result = self . run ( & data . expr ) ;
@ -380,16 +397,17 @@ impl Executor for Interpreter {
let val = self . run ( val_e ) ? ;
let val = self . run ( val_e ) ? ;
match ref_e . def {
match ref_e . def {
ExprDef ::Local ( ref name ) = > {
ExprDef ::Local ( ref name ) = > {
if * self . realm . environment . get_binding_value ( & name ) ! = ValueData ::Undefined
if self . realm . environment . has_binding ( name ) {
{
// Binding already exists
// Binding already exists
self . realm
self . realm
. environment
. environment
. set_mutable_binding ( & name , val . clone ( ) , true ) ;
. set_mutable_binding ( & name , val . clone ( ) , true ) ;
} else {
} else {
self . realm
self . realm . environment . create_mutable_binding (
. environment
name . clone ( ) ,
. create_mutable_binding ( name . clone ( ) , true ) ;
true ,
VariableScope ::Function ,
) ;
self . realm . environment . initialize_binding ( name , val . clone ( ) ) ;
self . realm . environment . initialize_binding ( name , val . clone ( ) ) ;
}
}
}
}
@ -408,9 +426,11 @@ impl Executor for Interpreter {
Some ( v ) = > self . run ( & v ) ? ,
Some ( v ) = > self . run ( & v ) ? ,
None = > Gc ::new ( ValueData ::Undefined ) ,
None = > Gc ::new ( ValueData ::Undefined ) ,
} ;
} ;
self . realm
self . realm . environment . create_mutable_binding (
. environment
name . clone ( ) ,
. create_mutable_binding ( name . clone ( ) , false ) ;
false ,
VariableScope ::Function ,
) ;
self . realm . environment . initialize_binding ( & name , val ) ;
self . realm . environment . initialize_binding ( & name , val ) ;
}
}
Ok ( Gc ::new ( ValueData ::Undefined ) )
Ok ( Gc ::new ( ValueData ::Undefined ) )
@ -422,18 +442,22 @@ impl Executor for Interpreter {
Some ( v ) = > self . run ( & v ) ? ,
Some ( v ) = > self . run ( & v ) ? ,
None = > Gc ::new ( ValueData ::Undefined ) ,
None = > Gc ::new ( ValueData ::Undefined ) ,
} ;
} ;
self . realm
self . realm . environment . create_mutable_binding (
. environment
name . clone ( ) ,
. create_mutable_binding ( name . clone ( ) , false ) ;
false ,
VariableScope ::Block ,
) ;
self . realm . environment . initialize_binding ( & name , val ) ;
self . realm . environment . initialize_binding ( & name , val ) ;
}
}
Ok ( Gc ::new ( ValueData ::Undefined ) )
Ok ( Gc ::new ( ValueData ::Undefined ) )
}
}
ExprDef ::ConstDecl ( ref vars ) = > {
ExprDef ::ConstDecl ( ref vars ) = > {
for ( name , value ) in vars . iter ( ) {
for ( name , value ) in vars . iter ( ) {
self . realm
self . realm . environment . create_immutable_binding (
. environment
name . clone ( ) ,
. create_immutable_binding ( name . clone ( ) , false ) ;
false ,
VariableScope ::Block ,
) ;
let val = self . run ( & value ) ? ;
let val = self . run ( & value ) ? ;
self . realm . environment . initialize_binding ( & name , val ) ;
self . realm . environment . initialize_binding ( & name , val ) ;
}
}
@ -485,9 +509,11 @@ impl Interpreter {
for i in 0 .. data . args . len ( ) {
for i in 0 .. data . args . len ( ) {
let name = data . args . get ( i ) . expect ( "Could not get data argument" ) ;
let name = data . args . get ( i ) . expect ( "Could not get data argument" ) ;
let expr : & Value = arguments_list . get ( i ) . expect ( "Could not get argument" ) ;
let expr : & Value = arguments_list . get ( i ) . expect ( "Could not get argument" ) ;
self . realm
self . realm . environment . create_mutable_binding (
. environment
name . clone ( ) ,
. create_mutable_binding ( name . clone ( ) , false ) ;
false ,
VariableScope ::Function ,
) ;
self . realm
self . realm
. environment
. environment
. initialize_binding ( name , expr . clone ( ) ) ;
. initialize_binding ( name , expr . clone ( ) ) ;
@ -495,9 +521,11 @@ impl Interpreter {
// Add arguments object
// Add arguments object
let arguments_obj = create_unmapped_arguments_object ( arguments_list ) ;
let arguments_obj = create_unmapped_arguments_object ( arguments_list ) ;
self . realm
self . realm . environment . create_mutable_binding (
. environment
"arguments" . to_string ( ) ,
. create_mutable_binding ( "arguments" . to_string ( ) , false ) ;
false ,
VariableScope ::Function ,
) ;
self . realm
self . realm
. environment
. environment
. initialize_binding ( "arguments" , arguments_obj ) ;
. initialize_binding ( "arguments" , arguments_obj ) ;