public override void run( State state ) { // We execute by running the "lhs" and "rhs", and then applying the operator to them, // producing another value. If the result of either is an LValue, we have to dereference it. state.pushAction( new Step( this, st => { object right = LValue.Deref( st ); if( this.op == "+=" ) { object left = st.popResult(); // This one is a bit trickier since we do different things based on different // types, and the left side needs to be an LValue. if( !(left is LValue) ) throw CoralException.GetArg( "Left-hand side of += must be LValue" ); // We need to write the LValue back, but keep the result value on // the result stack since this can be used as a normal expression too. LValue lv = (LValue)left; object val = lv.read( st ); val = Plus( val, right ); lv.write( st, val ); st.pushResult( val ); } else { if( this.left != null ) { object left = LValue.Deref( st ); st.pushResult( s_operations[this.op]( left, right ) ); } else if( this.op == "-" ) { st.pushResult( s_operations[this.op]( null, right ) ); } else if( this.op == "!" ) { st.pushResult( !((bool)Util.CoerceBool( right ) ) ); } else throw CoralException.GetInvProg( "Unary operator not supported" ); } } ) ); this.right.run( state ); if( this.left != null ) this.left.run( state ); else state.pushResult( null ); }
/// <summary> /// Implements the string.join method. /// </summary> static void MethodJoin( State state, object[] args ) { // Args should be a separator string and an array of stuff to join. if( args.Length != 2 ) throw CoralException.GetArg( "string.join must be called with a separator string and an array of strings" ); string sep = Util.CoerceString( args[0] ); string[] arr = Util.CoerceStringArray( args[1] ); state.pushResult( String.Join( sep, arr ) ); }