private static void ProcessOptionalArguments(Cons argumentNameList, Cons argumentList, Environment localEnvironment) { // We need to add all the arguments to the closure's environment. while (argumentNameList != null) { Symbol argumentName = null; object argumentValue = null; // We need to get the name of the argument, it can either be just the name or, it can be // it's own Cons with the name and an expression for the default value. if (argumentNameList.Car() is Cons) { // It is a Cons, so extract the name and the default value. argumentName = (Symbol)argumentNameList.Caar(); argumentValue = argumentNameList.Cadar(); } else { argumentName = (Symbol)argumentNameList.Car(); } // Now, if the caller has specified a value for this argument, get it now. if (argumentList != null) { argumentValue = argumentList.Car(); argumentList = (Cons)argumentList.Cdr(); } // Finally add the parameter to the closure's list and then move onto the next argument. // Because the default can be any expression, we need to evaluate the value every time the // function is called. localEnvironment.AssignLocal(argumentName, Runtime.Eval(argumentValue, localEnvironment)); argumentNameList = (Cons)argumentNameList.Cdr(); } // Looks like the caller has supplied more parameters than the closure can use. if (argumentList != null) { throw new LSharpException("Too many parameters given."); } }
private static void ProcessKeyArguments(Cons argumentNameList, Cons argumentList, Environment localEnvironment) { // Make sure that all of the defined key arguments are inserted to the local enviroment with their // defaults. while (argumentNameList != null) { Symbol argumentName = null; object argumentValue = null; // We need to get the name of the argument, it can either be just the name or, it can be // it's own Cons with the name and an expression for the default value. if (argumentNameList.Car().GetType() == typeof(Cons)) { // It is a Cons, so extract the name and the default value. Because the default can be // any expression, we need to evaluate the value every time the function is called. argumentName = (Symbol)argumentNameList.Caar(); argumentValue = Runtime.Eval(argumentNameList.Cadar(), localEnvironment); } else { argumentName = (Symbol)argumentNameList.Car(); } // Add this variable to the closure's environment, then advance to the next parameter. localEnvironment.AssignLocal(argumentName, argumentValue); argumentNameList = (Cons)argumentNameList.Cdr(); } // Now that the parameters and their defaults have been added to the environment we can now // process the supplied arguments. while (argumentList != null) { // Because these are keyed parameters, the caller needs to specify the name of each // parameter. if (argumentList.Car().GetType() != typeof(Symbol)) { throw new LSharpException("Key parameters must be specified by name."); } // Grab the current parameter and the value associated with it. Then make sure that this // is a keyword. Symbol keywordName = (Symbol)argumentList.Car(); object argumentValue = argumentList.Cadr(); if (keywordName.Name[0] != ':') { throw new LSharpException(keywordName + " is not a valid keyword."); } // Now that we know they supplied a keyword, create a symbol out of it and make sure that // it exists. //keywordName = new Symbol(keywordName.Name.Substring(1)); keywordName = Symbol.FromName(keywordName.Name.Substring(1)); if (localEnvironment.Contains(keywordName) == false) { throw new LSharpException(keywordName + " is not a recognised keyword."); } // Update the parameter with the value that the user specified and then move onto the next // argument in the list. localEnvironment.AssignLocal(keywordName, argumentValue); argumentList = (Cons)argumentList.Cddr(); } }
private static void ProcessOptionalArguments(Cons argumentNameList, Cons argumentList, Environment localEnvironment) { // We need to add all the arguments to the closure's environment. while (argumentNameList != null) { Symbol argumentName = null; object argumentValue = null; // We need to get the name of the argument, it can either be just the name or, it can be // it's own Cons with the name and an expression for the default value. if (argumentNameList.Car().GetType() == typeof(Cons)) { // It is a Cons, so extract the name and the default value. argumentName = (Symbol)argumentNameList.Caar(); argumentValue = argumentNameList.Cadar(); } else { argumentName = (Symbol)argumentNameList.Car(); } // Now, if the caller has specified a value for this argument, get it now. if (argumentList != null) { argumentValue = argumentList.Car(); argumentList = (Cons)argumentList.Cdr(); } // Finally add the parameter to the closure's list and then move onto the next argument. // Because the default can be any expression, we need to evaluate the value every time the // function is called. localEnvironment.AssignLocal(argumentName, Runtime.Eval(argumentValue, localEnvironment)); argumentNameList = (Cons)argumentNameList.Cdr(); } // Looks like the caller has supplied more parameters than the closure can use. if (argumentList != null) { throw new LSharpException("Too many parameters given."); } }
private static void ProcessKeyArguments(Cons argumentNameList, Cons argumentList, Environment localEnvironment) { // Make sure that all of the defined key arguments are inserted to the local enviroment with their // defaults. while (argumentNameList != null) { Symbol argumentName = null; object argumentValue = null; // We need to get the name of the argument, it can either be just the name or, it can be // it's own Cons with the name and an expression for the default value. if (argumentNameList.Car() is Cons) { // It is a Cons, so extract the name and the default value. Because the default can be // any expression, we need to evaluate the value every time the function is called. argumentName = (Symbol)argumentNameList.Caar(); argumentValue = Runtime.Eval(argumentNameList.Cadar(), localEnvironment); } else { argumentName = (Symbol)argumentNameList.Car(); } // Add this variable to the closure's environment, then advance to the next parameter. localEnvironment.AssignLocal(argumentName, argumentValue); argumentNameList = (Cons)argumentNameList.Cdr(); } // Now that the parameters and their defaults have been added to the environment we can now // process the supplied arguments. while (argumentList != null) { // Because these are keyed parameters, the caller needs to specify the name of each // parameter. if (argumentList.Car().GetType() != typeof(Symbol)) { throw new LSharpException("Key parameters must be specified by name."); } // Grab the current parameter and the value associated with it. Then make sure that this // is a keyword. Symbol keywordName = (Symbol)argumentList.Car(); object argumentValue = argumentList.Cadr(); if (keywordName.Name[0] != ':') { throw new LSharpException(keywordName + " is not a valid keyword."); } // Now that we know they supplied a keyword, create a symbol out of it and make sure that // it exists. //keywordName = new Symbol(keywordName.Name.Substring(1)); keywordName = Symbol.FromName(keywordName.Name.Substring(1)); if (localEnvironment.Contains(keywordName) == false) { throw new LSharpException(keywordName + " is not a recognised keyword."); } // Update the parameter with the value that the user specified and then move onto the next // argument in the list. localEnvironment.AssignLocal(keywordName, argumentValue); argumentList = (Cons)argumentList.Cddr(); } }