예제 #1
0
        public object Apply(Machine machine, ValueEnvironment environment, object[] arguments)
        {
            object name = arguments[0];

            object result = machine.Evaluate(name, environment);

            Type type = null;

            if (!(result is Type))
            {
                if (name is INamed || name is string)
                    type = Utilities.GetType(name);

                if (type == null)
                    throw new ArgumentException("New should receive a type name");
            }
            else
                type = (Type)result;

            object[] parameters = new object[arguments.Length - 1];

            for (int k = 1; k < arguments.Length; k++)
                parameters[k - 1] = machine.Evaluate(arguments[k], environment);

            return Activator.CreateInstance(type, parameters);
        }
예제 #2
0
        public object ApplyToObject(object obj, Machine machine, ValueEnvironment environment, object[] arguments)
        {
            Type type = obj.GetType();
            INamed named = null;
            object[] pars = null;

            if (arguments[1] is IList)
            {
                IList parameters = (IList)arguments[1];
                named = (INamed)parameters[0];
                pars = new object[parameters.Count - 1];
                for (int k = 1; k < parameters.Count; k++)
                    pars[k - 1] = machine.Evaluate(parameters[k], environment);
            }
            else
            {
                named = (INamed)arguments[1];
                pars = new object[arguments.Length - 2];

                for (int k = 2; k < arguments.Length; k++)
                    pars[k - 2] = machine.Evaluate(arguments[k], environment);
            }

            return type.InvokeMember(named.Name, System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance, null, obj, pars);
        }
예제 #3
0
        public object Evaluate(Machine machine, ValueEnvironment environment)
        {
            // TODO get a predefined empty dictionary object
            IPersistentMap map = new DictionaryObject(new Hashtable());

            foreach (DictionaryEntry entry in this.map)
            {
                object key = machine.Evaluate(entry.Key, environment);
                object value = machine.Evaluate(entry.Value, environment);

                map = map.Associate(key, value);
            }

            return map;
        }
예제 #4
0
        public object Apply(Machine machine, ValueEnvironment environment, object[] arguments)
        {
            object result = null;
            ValueEnvironment newenv = null;

            foreach (object argument in arguments)
            {
                if (newenv == null)
                {
                    newenv = new ValueEnvironment(environment);

                    if (argument != null)
                    {
                        if (!(argument is ICollection))
                            throw new InvalidOperationException("Let must receive a list as first argument");

                        Utilities.EvaluateBindings(machine, newenv, (ICollection)argument);
                    }
                }
                else
                    result = machine.Evaluate(argument, newenv);
            }

            return result;
        }
예제 #5
0
        public object Evaluate(Machine machine, ValueEnvironment environment)
        {
            if (this.elements == null || this.elements.Count == 0)
                return null;

            IExpression formhead = (IExpression)Utilities.ToExpression(this.elements[0]);

            IFunction function = (IFunction)formhead.Evaluate(machine, environment);

            if (function == null)
            {
                if (this.elements[0] is INamed)
                    throw new InvalidOperationException(string.Format("Unknown form {0}", ((INamed)this.elements[0]).FullName));
                else
                    throw new InvalidOperationException(string.Format("Unknown form {0}", this.elements[0].ToString()));
            }

            object[] arguments = null;

            if (this.elements.Count > 1)
                arguments = new object[this.elements.Count - 1];

            if (function.IsSpecialForm)
                for (int k = 1; k < this.elements.Count; k++)
                    arguments[k - 1] = this.elements[k];
            else
                for (int k = 1; k < this.elements.Count; k++)
                    arguments[k - 1] = machine.Evaluate(this.elements[k], environment);

            return function.Apply(machine, environment, arguments);
        }
예제 #6
0
        public object Evaluate(Machine machine, ValueEnvironment environment)
        {
            IDictionary result = new Hashtable();

            foreach (object key in this.dictionary.Keys)
            {
                object value = this.dictionary[key];

                object newkey = machine.Evaluate(key, environment);

                object newvalue = machine.Evaluate(value, environment);

                result[newkey] = newvalue;
            }

            return result;
        }
예제 #7
0
        public object Apply(Machine machine, ValueEnvironment environment, object[] arguments)
        {
            object result = null;

            foreach (object argument in arguments)
                result = machine.Evaluate(argument, environment);

            return result;
        }
예제 #8
0
        public object Evaluate(Machine machine, ValueEnvironment environment)
        {
            object[] result = new object[this.vector.Count];

            for (int k = 0; k < this.vector.Length; k++)
                result[k] = machine.Evaluate(this.vector[k], environment);

            return PersistentVector.Create(result);
        }
예제 #9
0
        public object Apply(Machine machine, ValueEnvironment environment, object[] arguments)
        {
            if (arguments == null || arguments.Length < 2)
                throw new InvalidOperationException("If should receive a test and a body");
            if (arguments.Length > 3)
                throw new InvalidOperationException("Too many arguments to If");

            object result = machine.Evaluate(arguments[0], environment);

            if (Utilities.IsFalse(result))
            {
                if (arguments.Length == 3)
                    return machine.Evaluate(arguments[2], environment);
                return null;
            }
            else
                return machine.Evaluate(arguments[1], environment);
        }
예제 #10
0
        public object Apply(Machine machine, ValueEnvironment environment, object[] arguments)
        {
            if (arguments == null || arguments.Length == 0)
                return null;

            object result = null;
            ValueEnvironment newenv = null;
            string[] names = null;

            newenv = new ValueEnvironment(environment);

            object argument = arguments[0];

            if (argument != null)
            {
                if (!(argument is ICollection))
                    throw new InvalidOperationException("Let must receive a list as first argument");

                names = Utilities.EvaluateBindings(machine, newenv, (ICollection)argument);
            }

            for (int k = 1; k < arguments.Length; k++)
                result = machine.Evaluate(arguments[k], newenv);

            while (result != null && result is RecursionData)
            {
                RecursionData data = (RecursionData)result;

                if (Utilities.GetArity(data.Arguments) != Utilities.GetArity(names))
                    throw new InvalidOperationException("Invalid recursion data");

                newenv = new ValueEnvironment(environment);
                result = null;

                for (int k = 0; k < names.Length; k++)
                    newenv.SetValue(names[k], data.Arguments[k]);

                for (int k = 1; k < arguments.Length; k++)
                    result = machine.Evaluate(arguments[k], newenv);
            }

            return result;
        }
예제 #11
0
        public object Apply(Machine machine, ValueEnvironment environment, object[] arguments)
        {
            Symbol symbol = (Symbol)arguments[0];

            if (!string.IsNullOrEmpty(symbol.Namespace))
                throw new InvalidOperationException("Defined name should not have namespace");

            Variable variable = Utilities.ToVariable(machine, environment, symbol);

            object value = machine.Evaluate(arguments[1], environment);

            if (symbol.Metadata != null)
            {
                IDictionary dictionary = (IDictionary)symbol.Metadata;
                IDictionary evaluated = new Hashtable();

                foreach (object key in dictionary.Keys)
                {
                    object val = machine.Evaluate(dictionary[key], environment);
                    evaluated[key] = val;
                }

                variable.ResetMetadata(new DictionaryObject(evaluated));
            }
            else
                variable.ResetMetadata(null);

            IPersistentMap metadata = variable.Metadata;

            if (metadata != null && metadata.ContainsKey(macroKeyword))
                if ((bool)metadata.ValueAt(macroKeyword) && value is DefinedFunction)
                    value = ((DefinedFunction)value).ToMacro();

            machine.SetVariableValue(variable, value);

            if (value is IFunction && ((IFunction)value).IsSpecialForm)
                machine.Environment.SetValue(variable.Name, value, true);

            return value;
        }
예제 #12
0
        public object Apply(Machine machine, ValueEnvironment environment, object[] arguments)
        {
            object name = arguments[0];

            object result = machine.Evaluate(name, environment);

            Type type = null;

            if (name is INamed || name is string)
                type = Utilities.GetType(name);

            if (type != null)
                return this.ApplyToType(type, machine, environment, arguments);

            return this.ApplyToObject(result, machine, environment, arguments);
        }