public static Object DefClass(Cons args, Environment environment) { string className = args.First().ToString(); Cons superClasses = args.Cadr() as Cons; string superClass = null; string interfaces = null; if (superClasses != null) { superClass = superClasses.First().ToString(); if (superClasses.Length() >= 2) { StringBuilder b = new StringBuilder(); b.Append(superClasses.Second()); foreach (object item in (Cons)superClasses.Cddr()) { b.Append(", " + item); } interfaces = b.ToString(); } } return(ClassBuilder.CreateClass(className, superClass, interfaces)); }
/// <summary> /// Process the arguments passed to a closure, and add them to the given enviroment. /// </summary> /// <param name="argumentNameList">The list of names and kewords the closure was created with.</param> /// <param name="argumentList">The arguments passed to the closure.</param> /// <param name="localEnvironment">The closure's local variables.</param> /// <returns>Nothing.</returns> public static void ProcessArguments(Cons argumentNameList, Cons argumentList, Environment localEnvironment) { while (argumentNameList != null) { // Get the name for the closure's parameter. Then check to see if it's a keyword, if it is then // process the keyword. Otherwise set up that parameter in the closure's enviroment with the // caller specified value. Symbol argumentName = (Symbol)argumentNameList.Car(); switch (argumentName.ToString()) { case "&rest": argumentName = (Symbol)argumentNameList.Cadr(); localEnvironment.AssignLocal(argumentName, argumentList); argumentNameList = null; argumentList = null; break; case "&optional": ProcessOptionalArguments((Cons)argumentNameList.Cdr(), argumentList, localEnvironment); argumentNameList = null; argumentList = null; break; case "&key": ProcessKeyArguments((Cons)argumentNameList.Cdr(), argumentList, localEnvironment); argumentNameList = null; argumentList = null; break; default: if (argumentList == null) { throw new LSharpException("Not enough parameters given."); } localEnvironment.AssignLocal(argumentName, argumentList.Car()); argumentList = (Cons)argumentList.Cdr(); argumentNameList = (Cons)argumentNameList.Cdr(); break; } } // Looks like the caller has supplied more parameters than the closure can use. if (argumentList != null) { throw new LSharpException("Too many parameters given."); } }
public static object Item(Cons args, Environment environment) { int index = (int)args.Car(); Array array = (Array) args.Cadr(); return array.GetValue(index); }
/// <summary> /// Process the arguments passed to a closure, and add them to the given enviroment. /// </summary> /// <param name="argumentNameList">The list of names and kewords the closure was created with.</param> /// <param name="argumentList">The arguments passed to the closure.</param> /// <param name="localEnvironment">The closure's local variables.</param> /// <returns>Nothing.</returns> public static void ProcessArguments(Cons argumentNameList, Cons argumentList, Environment localEnvironment) { while (argumentNameList != null) { // Get the name for the closure's parameter. Then check to see if it's a keyword, if it is then // process the keyword. Otherwise set up that parameter in the closure's enviroment with the // caller specified value. Symbol argumentName = (Symbol)argumentNameList.Car(); switch (argumentName.ToString()) { case "&rest": argumentName = (Symbol)argumentNameList.Cadr(); localEnvironment.AssignLocal(argumentName, argumentList); argumentNameList = null; argumentList = null; break; case "&optional": ProcessOptionalArguments((Cons)argumentNameList.Cdr(), argumentList, localEnvironment); argumentNameList = null; argumentList = null; break; case "&key": ProcessKeyArguments((Cons)argumentNameList.Cdr(), argumentList, localEnvironment); argumentNameList = null; argumentList = null; break; default: if (argumentList == null) { throw new LSharpException("Not enough parameters given."); } localEnvironment.AssignLocal(argumentName, argumentList.Car()); argumentList = (Cons)argumentList.Cdr(); argumentNameList = (Cons)argumentNameList.Cdr(); break; } } // 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 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(); } }