Пример #1
0
        public SchemeLambdaTemplate( SchemeAST ast, ISchemeEnvironment currentEnv )
        {
            if (ast.children.Count < 2)
            {
                throw new SchemeWrongNumberOfArguments(String.Format("Lambda expects exactly two arguments. You have given me: {0}", ast.children.Count));
            }

            //really not beautiful, but this is the price we pay for using the AST data structure
            if (ast.children[0].currentObject != SchemeVoid.instance) // this is false for lambdas with no arguments
            {
                _params.Add((SchemeSymbol)ast.children[0].currentObject);
                foreach (SchemeAST child in ast.children[0].children)
                {
                    _params.Add((SchemeSymbol)child.currentObject);
                }
            }
            _implementation = new SchemeAST();

            _lambdaEnv = currentEnv ;

            for (int i = 1; i < ast.children.Count; i++)
            {
                _implementation.children.Add((SchemeAST)ast.children[i].Clone());
                _implementation.children[_implementation.children.Count - 1].parent = ast;
            }
        }
Пример #2
0
        public override SchemeObject evaluate(ref SchemeAST currentAST, SchemeEvaluator evaluator)
        {
            var list = lookupSymbolsFromEnv(ref currentAST, evaluator.currentEnvironment);
            Debug.Assert(list[0].GetType() == typeof(SchemeBuiltinOr));

            if (list.Count < 3)
            {
                throw new SchemeWrongNumberOfArguments(String.Format("Too few arguments! and need at least 2 arguments. You specified: {0}", list.Count - 1));
            }

            try
            {
                foreach (SchemeBool value in list.GetRange(1, list.Count - 1))
                {
                    if (value == SchemeTrue.instance)
                    {
                        return SchemeTrue.instance;
                    }
                }
            }
            catch (InvalidCastException)
            {
                throw new SchemeInvalidArgumentException("Builtin Function OR expects SchemeInteger or SchemeFloat as parameter. Got something else.");
            }

            return SchemeFalse.instance;
        }
Пример #3
0
        public override SchemeObject evaluate( ref SchemeAST currentAST, SchemeEvaluator evaluator )
        {
            var list = lookupSymbolsFromEnv( ref currentAST, evaluator.currentEnvironment );
            Debug.Assert( list[0].GetType() == typeof( SchemeBuiltinEquals ) );

            if( list.Count < 3 )
            {
                throw new SchemeWrongNumberOfArguments(String.Format("Too few arguments! SchemeEquals need at least 2 arguments. You specified: {0}", list.Count -1));
            }

            var firstVal = list[1];
            if( firstVal.GetType() != typeof( SchemeInteger ) )
            {
                throw new SchemeInvalidArgumentException( String.Format( "Invalid Argument Exception! SchemeEquals expects numbers as arugments. You provided: {0}", firstVal.GetType().ToString() ) );
            }

            try
            {
                foreach( SchemeInteger value in list.GetRange( 2, list.Count - 2 ) )
                {
                   if (! firstVal.Equals(value) )
                   {
                   return SchemeFalse.instance;
                   }
                }
            }
            catch( InvalidCastException )
            {
                throw new SchemeInvalidArgumentException( "Builtin Function Equals expects SchemeInteger or SchemeFloat as parameter. Got something else." );
            }

            return SchemeTrue.instance;
        }
Пример #4
0
        public override SchemeObject evaluate( ref SchemeAST currentAST, SchemeEvaluator evaluator )
        {
            if( currentAST.children.Count != 2 )
            {
            throw new SchemeWrongNumberOfArguments(String.Format("Scheme Cons expects exactly 2  arguments. You have given me: {0}", currentAST.children.Count -1));
            }
            var objects = lookupSymbolsFromEnv( ref currentAST, evaluator.currentEnvironment );

            return new SchemeList( objects[1], objects[2] );
        }
Пример #5
0
        public override SchemeObject evaluate( ref SchemeAST currentAST, SchemeEvaluator evaluator )
        {
            evaluator.currentEnvironment = _lambdaEnv;

            for( int i = 0; i < _params.Count; i++ )
            {
                var child = currentAST.children[i];
                if( child.currentObject.GetType() == typeof( SchemeSymbol ) )
                {
                    var val = evaluator.currentEnvironment.get( (SchemeSymbol) child.currentObject );

                    if( val == null )
                    {

                        val = evaluator.currentEnvironment.get( (SchemeSymbol) child.currentObject );

                        if( val == null )
                        {
                            throw new SchemeUndefinedSymbolException( String.Format( "Undefined Symbol!: {0}", child.currentObject ) );
                        }
                    }
                    evaluator.currentEnvironment.set( _params[i], val );
                }
                else
                {
                    evaluator.currentEnvironment.set( _params[i], (SchemeType) child.currentObject );
                }

            }

            var clonedImplementation = (SchemeAST) _implementation.Clone();

            var oldParent = currentAST.parent;
            var index = currentAST.parent.children.IndexOf( currentAST );
            currentAST.parent.children.Remove( currentAST );

            for( int i = 0; i < clonedImplementation.children.Count; i++ )
            {
                currentAST.parent.children.Insert( i + index, clonedImplementation.children[i] );
                clonedImplementation.children[i].parent = oldParent;

                if( i == clonedImplementation.children.Count - 1 )   // the last one being added
                {
                    currentAST.parent.children[i + index].hasOwnEnviornment = true; // set flag for enviornment switch
                }
            }

            currentAST = currentAST.parent.children[index];

            return null; //so ugly, but null means: to be evaluated again!
        }
Пример #6
0
        public override SchemeObject evaluate( ref SchemeAST currentAST, SchemeEvaluator evaluator )
        {
            if( currentAST.children.Count < 2 || currentAST.children.Count > 3 )
            {
                throw new SchemeWrongNumberOfArguments( String.Format( "The If-statement expects 2 or 3 arguments (condition, branch1, branch2). You provided {0}", currentAST.children.Count - 1 ) );
            }

            _condition = currentAST.children[0];
            _trueBranch = currentAST.children[1];

            if( currentAST.children.Count == 3 )
            {
                _falseBranch = currentAST.children[2];
            }

            if( _condition.currentObject == SchemeTrue.instance )
            {
                var old_parent = currentAST.parent;
                _trueBranch.parent = currentAST.parent;

                int postition = currentAST.parent.children.IndexOf( currentAST );
                currentAST.parent.children.Remove( currentAST );
                currentAST.parent.children.Add( _trueBranch );

                currentAST = _trueBranch;
                return null;
            }

            if( _condition.currentObject == SchemeFalse.instance )
            {
                if( _falseBranch != null )
                {
                    var old_parent = currentAST.parent;
                    _falseBranch.parent = currentAST.parent;
                    int postition = currentAST.parent.children.IndexOf( currentAST );
                    currentAST.parent.children.Remove( currentAST );
                    currentAST.parent.children.Add( _falseBranch );
                    currentAST = _falseBranch;
                    return null;
                }
                else
                {
                    return SchemeVoid.instance;
                }
            }

            throw new SchemeInvalidArgumentException( String.Format( "Invalid Argument in If-condition: Your condtion has to evalue to either #t or #f, but it evaluated to {0}", _condition.ToString() ) );
        }
Пример #7
0
        public override SchemeObject evaluate( ref SchemeAST currentAST, SchemeEvaluator evaluator )
        {
            if( currentAST.children.Count != 1 )
            {
                throw new SchemeWrongNumberOfArguments( String.Format( "Scheme cdr expects exactly on argument of type scheme cons. You have provided: {0}", currentAST.children.Count ) );
            }

            if( ! ( currentAST.children[0].currentObject.GetType() ==  typeof(SchemeList) ) )
            {
              throw new SchemeInvalidArgumentException( String.Format("Scheme cdr epects an arguement of type scheme cons. Your argument was: {0} of type{1}" , currentAST.children[0].ToString(), currentAST.children[0].GetType().ToString()));
            }

            var cons = (SchemeList) currentAST.children[0].currentObject;

            return cons.cdr;
        }
Пример #8
0
        public override SchemeObject evaluate( ref SchemeAST currentAST, SchemeEvaluator evaluator )
        {
            if( currentAST.children.Count != _params.Count )
            {
                throw new SchemeWrongNumberOfArguments( String.Format( "Lambda expects exactly two arguments. You have given me: {0}", currentAST.children.Count ) );
            }

                    var tmp = _lambdaEnv.getClonedEnv(evaluator.currentEnvironment);
                    //_lambdaEnv.setParent(evaluator.currentEnvironment);
                       //evaluator.currentEnvironment = _lambdaEnv;

                    SchemeLambda lambda = new SchemeLambdaImpl(_implementation, _params, new SchemeEnvironment(tmp) );

            lambda.evaluate(ref currentAST, evaluator);
            return null;
        }
Пример #9
0
 public override SchemeObject evaluate( ref SchemeAST currentAST, SchemeEvaluator evaluator )
 {
     var list = lookupSymbolsFromEnv( ref currentAST, evaluator.currentEnvironment );
     Debug.Assert(list[0].GetType() == typeof(SchemeBuiltInPlus));
     int sum = 0;
     try
     {
         foreach( SchemeInteger summand in list.GetRange( 1, list.Count - 1 ) ) //all args, but not the current method object
         {
             sum += summand.value;
         }
     }
     catch( InvalidCastException )
     {
         throw new SchemeInvalidArgumentException("Builtin Function + expects SchemeInteger or SchemeFloat as parameter. Got something else.");
     }
     return new SchemeInteger( sum );
 }
Пример #10
0
        public override SchemeObject evaluate( ref SchemeAST currentAST, SchemeEvaluator evaluator )
        {
            var list = lookupSymbolsFromEnv( ref currentAST, evaluator.currentEnvironment );
            Debug.Assert( list[0].GetType() == typeof( ScehemBuiltinModulo ) );

            if( list.Count != 3 )
            {
            throw new SchemeWrongNumberOfArguments(String.Format("Invalid number of Arguments specified! Builtinfunction modulo expects exactly two parametrs. you specified: {0}", list.Count -1));
            }
            int mod = 0;
            try
            {
              mod = ((SchemeInteger) list[1]).value % ((SchemeInteger) list[2]).value;
            }
            catch( InvalidCastException )
            {
                throw new SchemeInvalidArgumentException( "Builtin Function + expects SchemeInteger or SchemeFloat as parameter. Got something else." );
            }
            return new SchemeInteger( mod );
        }
Пример #11
0
        internal static List<SchemeObject> lookupSymbolsFromEnv( ref SchemeAST currentAST, ISchemeEnvironment environment )
        {
            List<SchemeObject> ret = new List<SchemeObject>();
            ret.Add( environment.get( (SchemeSymbol) currentAST.currentObject ) );
             // not nice, but it works
              /*  if( ret[0] == null ) // this holds true if the currentObjcet is NOT in the symbol table. Then it might either be an integer or a float and has not been redefined or the function is unknown
            {
                ret.RemoveAt( 0 );
                int intValue;
                var symbol = ( (SchemeSymbol) currentAST.currentObject ).value;
                if( int.TryParse( symbol, out intValue ) )
                {
                    ret.Add( new SchemeInteger( intValue ) );
                }
                else //TODO extend for floats
                {
                    throw new SchemeUndefinedSymbolException( String.Format( "Undefined Symbol: {0}", symbol ) );
                }
            }   */

            foreach (SchemeAST child in currentAST.children)
            {
                if( child.currentObject.GetType() == typeof( SchemeSymbol ) )
                {
                    var symbol = (SchemeSymbol) child.currentObject;
                    ret.Add( environment.get( symbol ) );

                    if( ret[ret.Count -1]== null )  //objcet is not in symbol list, check for integer and float!
                    {
                            throw new SchemeUndefinedSymbolException( String.Format( "Undefined Symbol: {0}", symbol.value ) );
                    }
                }
                else
                {
                    ret.Add( child.currentObject );
                }
            }
            return ret;
        }
Пример #12
0
        public override SchemeObject evaluate( ref SchemeAST currentAST, SchemeEvaluator evaluator )
        {
            if( currentAST.children.Count != 2 )
            {
                throw new SchemeWrongNumberOfArguments( String.Format( "Wrong number of arguments!'define' expects exactly two arguments. You provided: {0}", currentAST.children.Count ) );
            }

                var param = currentAST.children[1];

                SchemeObject value;
            if( param.currentObject.GetType() == typeof( SchemeSymbol ) )
            {
                 value = lookupSymbolsFromEnv( ref param, evaluator.currentEnvironment )[0];
            }
            else
            {
                 value = param.currentObject;
            }

            evaluator.currentEnvironment.set( (SchemeSymbol) currentAST.children[0].currentObject, (SchemeType) value );

            return SchemeVoid.instance;
        }
Пример #13
0
 public SchemeLambda( SchemeAST ast, ISchemeEnvironment currentEnv )
 {
     Debug.Assert( false, "Should never be called!" );
 }
Пример #14
0
 public SchemeLambdaImpl(SchemeAST implementation, List<SchemeSymbol> _params, ISchemeEnvironment env)
 {
     this._implementation = implementation;
     this._params = _params;
     this._lambdaEnv = env;
 }
Пример #15
0
 public override SchemeObject evaluate( ref SchemeAST currentAST, SchemeEvaluator evaluator )
 {
     return new SchemeLambdaTemplate( currentAST, evaluator.currentEnvironment );     // The current class is only a wrapper for the lambda keyword. This call creates the new SchemeLambda Object
 }
Пример #16
0
        /*  public SchemeObject evaluate( ref SchemeAST currentAST, ISchemeEnvironment env )
        {
            this.currentAST = currentAST;
            this.environment = env;

            //syntax like define is a special case where we don't want the expresisons to be evaluated!
            if( handleSyntax() )
            {
                return SchemeVoid.instance;
            }
            else
            {
                var methodObjects = lookupSymbolsFromEnv();
                return evaluateInternal( methodObjects.GetRange( 1, methodObjects.Count - 1 ) );
            }

        }   */
        public abstract SchemeObject evaluate(ref SchemeAST currentAST, SchemeEvaluator evaluator );
Пример #17
0
 public virtual SchemeObject evaluate(ref SchemeAST currentAST, SchemeEvaluator evaluator)
 {
     Debug.Assert( false, "Should never be called!" );
     return null;
 }