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; } }
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; }
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; }
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] ); }
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! }
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() ) ); }
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; }
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; }
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 ); }
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 ); }
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; }
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; }
public SchemeLambda( SchemeAST ast, ISchemeEnvironment currentEnv ) { Debug.Assert( false, "Should never be called!" ); }
public SchemeLambdaImpl(SchemeAST implementation, List<SchemeSymbol> _params, ISchemeEnvironment env) { this._implementation = implementation; this._params = _params; this._lambdaEnv = env; }
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 }
/* 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 );
public virtual SchemeObject evaluate(ref SchemeAST currentAST, SchemeEvaluator evaluator) { Debug.Assert( false, "Should never be called!" ); return null; }