Ejemplo n.º 1
0
        private object EX_While(LispRuntimeCommand cmd, LispList program)
        {
            object retVal = null;

            if (program.items.Count < 2)
            {
                throw new LispParseException($"'{cmd.CommandName}' command must have at least 1 parameter. Line: {program.line}:{program.position}");
            }

            LispItem conditionalStatement = program.items[1];

            // body of the while loop
start:
            object conditionalResult = Run(conditionalStatement);

            CheckParameterType(cmd, 1, program, conditionalResult, typeof(bool), false);
            if ((bool)conditionalResult)
            {
                for (int i = 2; i < program.items.Count; i++)
                {
                    retVal = Run(program.items[i]);
                }
                goto start;
            }

            return(retVal);
        }
Ejemplo n.º 2
0
        private object EX_If(LispRuntimeCommand cmd, LispList program)
        {
            CheckParameterCount(cmd, program, 2, 3);

            LispItem conditionalStatement = program.items[1];
            LispItem trueStatement        = program.items[2];

            // run the condition
            object conditionResult = Run(conditionalStatement);

            CheckParameterType(cmd, 1, program, conditionResult, typeof(bool), false);

            if ((bool)conditionResult)
            {
                return(Run(trueStatement));
            }
            else if (program.items.Count == 4)
            {
                LispItem falseStatement = program.items[3];
                return(Run(falseStatement));
            }
            else
            {
                return(null);
            }
        }
Ejemplo n.º 3
0
        private object EX_Not(LispRuntimeCommand cmd, LispList program)
        {
            CheckParameterCount(cmd, program, 1);
            object result = Run(program.items[1]);

            CheckParameterType(cmd, 1, program, result, typeof(bool), false);
            return(!((bool)result));
        }
Ejemplo n.º 4
0
        private object Ex_LessThanEqual(LispRuntimeCommand cmd, LispList program)
        {
            CheckParameterCount(cmd, program, 2);
            long a = GetLongValue(cmd, program, 1, false);
            long b = GetLongValue(cmd, program, 2, false);

            return(a <= b);
        }
Ejemplo n.º 5
0
        public object RunList(LispList program)
        {
            object result = null;

            LispItem first = program.items.First();

            if (first is LispSymbol)
            {
                try
                {
                    LispSymbol         sym = first as LispSymbol;
                    LispRuntimeCommand cmd;
                    if (_commands.TryGetValue(sym.name, out cmd))
                    {
                        result = cmd.Command(cmd, program);
                        _logger.LogIf(_categories.ScriptLogging, Level.Debug, $"Run {first.line}:{first.position} Cmd:{cmd.CommandName}==>{(result ?? (object)"null")}");
                    }
                    else
                    {
                        throw new LispParseException($"Unknown command symbol '{sym.name}' Line: {sym.line}:{sym.position}");
                    }
                }
                catch (Exception ex)
                {
                    if (!(ex is LispParseException))
                    {
                        throw new LispParseException($"{ex.Message} Line {first.line}:{first.position}", ex);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            else if (first is LispList)
            {
                foreach (LispItem item in program.items)
                {
                    if (item is LispList)
                    {
                        result = Run(item as LispList);
                    }
                    else
                    {
                        throw new LispParseException($"Expected a LispList but got a {item.GetType().Name} Line: {item.line}:{item.position}");
                    }
                }
            }
            else
            {
                throw new LispParseException($"Can only execute lists and symbols. Line: {first.line}:{first.position}");
            }

            return(result);
        }
Ejemplo n.º 6
0
        private object Ex_GetArg(LispRuntimeCommand cmd, LispList list)
        {
            CheckParameterCount(cmd, list, 1, 2);
            string arg          = Run <string>(list.items[1]);
            object defaultValue = null;

            if (list.items.Count > 2)
            {
                defaultValue = Run <object>(list.items[2]);
            }
            else
            {
                defaultValue = string.Empty;
            }

            var    args        = Environment.GetCommandLineArgs();
            string returnValue = null;

            for (int i = 0; i < args.Length; i++)
            {
                var a = args[i];
                if (a == arg)
                {
                    if (i + 1 < args.Length)
                    {
                        returnValue = args[i + 1];
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (returnValue == null)
            {
                return(defaultValue);
            }

            switch (defaultValue)
            {
            case double d:
                return(double.Parse(returnValue));

            case int i:
                return(int.Parse(returnValue));

            default:
                return(returnValue);
            }
        }
Ejemplo n.º 7
0
        private object Ex_Assert(LispRuntimeCommand cmd, LispList list)
        {
            CheckParameterCount(cmd, list, 1);
            bool isOkay = Run <bool>(list.items[1]);

            if (isOkay)
            {
                return(true);
            }
            else
            {
                throw new Exception($"Failed Assert on {list.line}:{list.position}");
            }
        }
Ejemplo n.º 8
0
        protected long GetLongValue(LispRuntimeCommand cmd, LispList program, int index, bool allowNull)
        {
            object v = Run(program.items[index]);

            CheckParameterType(cmd, index, program, v, typeof(long), allowNull);
            if (null == v)
            {
                return(0);
            }
            else
            {
                return((long)v);
            }
        }
Ejemplo n.º 9
0
 protected static void CheckParameterCount(LispRuntimeCommand cmd, LispList program, params int[] expectedCounts)
 {
     if (!expectedCounts.Contains(program.items.Count - 1))
     {
         if (expectedCounts.Length == 1)
         {
             throw new LispParseException($"'{cmd.CommandName}' command must have exactly {expectedCounts[0]} parameters. Line: {program.line}:{program.position}");
         }
         else
         {
             throw new LispParseException($"'{cmd.CommandName}' command expects {expectedCounts.ToDelimited("","", " or ")} parameters. Line: {program.line}:{program.position}");
         }
     }
 }
Ejemplo n.º 10
0
        private object EX_SetVariable(LispRuntimeCommand cmd, LispList program)
        {
            CheckParameterCount(cmd, program, 2);

            // get parameters
            string variableName  = Run(program.items[1]) as string;
            object variableValue = Run(program.items[2]);

            CheckParameterType(cmd, 1, program, variableName, typeof(string), false);

            _var[variableName] = variableValue;

            return(variableValue);
        }
Ejemplo n.º 11
0
        public static void Execute(LispList program, Dictionary <string, string> environmentVariables, ILogger logger, ICategories categories)
        {
            LispExecuter executer = new LispExecuter(logger, categories);

            executer.SetEnvironment(environmentVariables);
            try
            {
                executer.Run <object>(program);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }
        }
Ejemplo n.º 12
0
        private object Ex_Or(LispRuntimeCommand cmd, LispList program)
        {
            CheckParameterCount(cmd, program, 2);
            object leftResult = Run(program.items[1]);

            CheckParameterType(cmd, 1, program, leftResult, typeof(bool), false);
            if ((bool)leftResult)
            {
                return(true);
            }

            object rightResult = Run(program.items[2]);

            CheckParameterType(cmd, 2, program, leftResult, typeof(bool), false);
            return((bool)rightResult);
        }
Ejemplo n.º 13
0
        private object Ex_Sub(LispRuntimeCommand cmd, LispList program)
        {
            if (program.items.Count - 1 < 2)
            {
                throw new LispParseException($"'{cmd.CommandName}' command must have at least 2 parameters. Line: {program.line}:{program.position}");
            }

            long accumulator = GetLongValue(cmd, program, 1, false);

            for (int i = 2; i < program.items.Count; i++)
            {
                long number = GetLongValue(cmd, program, i, false);
                accumulator -= number;
            }

            return(accumulator);
        }
Ejemplo n.º 14
0
        private object EX_GetVariableMember(LispRuntimeCommand cmd, LispList program)
        {
            CheckParameterCount(cmd, program, 2);
            int    c        = 1;
            object instance = Run(program.items[c++]);
            string name     = Run <string>(program.items[c++]);
            var    member   = instance.GetType().GetMember(name)[0];

            switch (member)
            {
            case PropertyInfo property:
                return(property.GetValue(instance));

            case FieldInfo field:
                return(field.GetValue(instance));
            }
            return(null);
        }
Ejemplo n.º 15
0
        private object EX_Equal(LispRuntimeCommand cmd, LispList program)
        {
            CheckParameterCount(cmd, program, 2);

            object value1 = Run(program.items[1]);
            object value2 = Run(program.items[2]);

            if (value1 == value2)
            {
                return(true);
            }

            if (value1 != null)
            {
                return(value1.Equals(value2));
            }

            return(false);
        }
Ejemplo n.º 16
0
        private object EX_GetEnvironment(LispRuntimeCommand cmd, LispList program)
        {
            CheckParameterCount(cmd, program, 1);

            string variableName = Run(program.items[1]) as string;

            CheckParameterType(cmd, 1, program, variableName, typeof(string), false);

            string value = null;

            if (_env.TryGetValue(variableName, out value))
            {
                return(value);
            }
            else
            {
                var item = program.items[1];
                throw new LispParseException($"GetEnvironment command failed.  Variable '{variableName}' doesn't exist. Line: {item.line}:{item.position}");
            }
        }
Ejemplo n.º 17
0
        private object EX_Loop(LispRuntimeCommand cmd, LispList program)
        {
            object retVal = null;

            if (program.items.Count < 3)
            {
                throw new LispParseException($"'{cmd.CommandName}' command must have at least 2 parameters. Line: {program.line}:{program.position}");
            }

            long loopCount = GetLongValue(cmd, program, 1, false);

            for (long i = 0; i < loopCount; i++)
            {
                for (int j = 2; j < program.items.Count; j++)
                {
                    retVal = Run(program.items[j]);
                }
            }

            return(retVal);
        }
Ejemplo n.º 18
0
        private object Ex_ForEach(LispRuntimeCommand cmd, LispList list)
        {
            if (list.items.Count < 3)
            {
                throw new LispParseException($"'{cmd.CommandName}' command expects more than 1 parameters. Line: {list.line}:{list.position}");
            }

            string variableName = Run <string>(list.items[1]);

            string[] loopItems = Run <string[]>(list.items[2]);

            foreach (string variableValue in loopItems)
            {
                SetVariable(variableName, variableValue);

                for (int i = 2; i < list.items.Count; i++)
                {
                    Run(list.items[i]);
                }
            }

            return(null);
        }
Ejemplo n.º 19
0
        internal LispList(List <LispToken> tokens, ref int index)
        {
            Init();
            if (index >= tokens.Count)
            {
                throw new LispParseException("Consturctor called but no tokens to parse!");
            }

            // check for left paranthesies
            LispToken token = tokens[index];

            if (token.type != TokenType.ParamLeft)
            {
                throw new LispParseException($"Lisp List must start with a left parantheses. Line {token.line}:{token.position}");
            }

            bool notFoundEnd = true;

            index++;

            for (; index < tokens.Count && notFoundEnd; index++)
            {
                token = tokens[index];
                switch (token.type)
                {
                case TokenType.ParamLeft:
                    LispList lst = new LispList(tokens, ref index);
                    lst.line     = token.line;
                    lst.position = token.position;
                    items.Add(lst);
                    break;

                case TokenType.ParamRight:
                    notFoundEnd = false;
                    index--;
                    break;

                case TokenType.Double:
                    items.Add(new LispDouble()
                    {
                        value = (double)token.lValue, line = token.line, position = token.position
                    });
                    break;

                case TokenType.Int:
                    items.Add(new LispInt()
                    {
                        value = (int)token.lValue, line = token.line, position = token.position
                    });
                    break;

                case TokenType.String:
                    items.Add(new LispString()
                    {
                        value = token.value, line = token.line, position = token.position
                    });
                    break;

                case TokenType.Symbol:
                    items.Add(new LispSymbol()
                    {
                        name = token.value, line = token.line, position = token.position
                    });
                    break;
                }
            }
        }
Ejemplo n.º 20
0
        protected static void CheckParameterType(LispRuntimeCommand cmd, int paramIndex, LispList program, object item, Type expectedType, bool allowNull)
        {
            if (null == item)
            {
                if (allowNull)
                {
                    return;
                }
                else
                {
                    throw new Exception(string.Format("'{0}' parameter {1} cannot be null. Line: {2}:{3}", cmd.CommandName, paramIndex, program.line, program.position));
                }
            }

            if (item.GetType() != expectedType)
            {
                throw new Exception(string.Format("'{0}' expected parameter {1} to be of type {2}. Line: {3}:{4}",
                                                  cmd.CommandName, paramIndex, expectedType, program.line, program.position));
            }
        }
Ejemplo n.º 21
0
 private object Ex_Array(LispRuntimeCommand cmd, LispList list)
 {
     return(list.items.Skip(1).Select(i => Run <string>(i)).ToArray());
 }
Ejemplo n.º 22
0
        public static LispList Parse(string lispString)
        {
            int line                = 1;
            int position            = 0;
            List <LispToken> tokens = new List <LispToken>();


            // tokenize the string
            for (int i = 0; i < lispString.Length; i++)
            {
                char c = lispString[i];

                position++;

                if (c == '\n')
                {
                    line++;
                    position = 1;
                }

                if (char.IsWhiteSpace(c))
                {
                    continue;
                }

                switch (c)
                {
                case '#':
                case ';':
                    // eat the comment comment until we find a new line.
                    int newIndex = lispString.IndexOf('\n', i);
                    if (newIndex > 0)
                    {
                        i = newIndex - 1;
                    }
                    else
                    {
                        i = lispString.Length;
                    }
                    break;

                case '(':
                    tokens.Add(new LispToken()
                    {
                        type = TokenType.ParamLeft, line = line, position = position
                    });
                    break;

                case ')':
                    tokens.Add(new LispToken()
                    {
                        type = TokenType.ParamRight, line = line, position = position
                    });
                    break;

                case '"':
                {
                    int  index;
                    bool isClosed = false;
                    for (index = i + 1; index < lispString.Length && !isClosed; index++)
                    {
                        char cc = lispString[index];

                        switch (cc)
                        {
                        case '"':
                            isClosed = true;
                            index--;
                            break;

                        case '\n':
                            throw new LispParseException($"String literal cannot contain a carriage return. Line {line}:{position}");
                        }
                    }

                    if (isClosed)
                    {
                        tokens.Add(new LispToken()
                            {
                                type = TokenType.String, value = lispString.Substring(i + 1, (index - 1) - i), line = line, position = position
                            });
                        i = index;
                    }
                    else
                    {
                        throw new LispParseException($"String not closed on line {line}:{position}");
                    }
                }
                break;

                default:
                {
                    if (char.IsLetter(c))
                    {
                        // it's a symbol
                        int index;
                        for (index = i; index < lispString.Length; index++)
                        {
                            char cc = lispString[index];
                            if (!char.IsLetterOrDigit(cc))
                            {
                                break;
                            }
                        }
                        tokens.Add(new LispToken()
                            {
                                type = TokenType.Symbol, value = lispString.Substring(i, index - i), line = line, position = position
                            });
                        position += (index - 1) - i;
                        i         = index - 1;
                    }
                    else if (char.IsDigit(c) || c == '.')
                    {
                        // it's a number
                        int index;
                        for (index = i; index < lispString.Length; index++)
                        {
                            char cc = lispString[index];
                            if (!(char.IsLetterOrDigit(cc) || cc == '.'))
                            {
                                break;
                            }
                        }

                        char   typeValue = lispString[index - 1];
                        string strValue  = lispString.Substring(i, index - i - 1);
                        switch (typeValue)
                        {
                        case 'd':
                        {
                            double lValue;
                            if (double.TryParse(strValue, out lValue))
                            {
                                tokens.Add(new LispToken()
                                        {
                                            type = TokenType.Double, value = strValue, lValue = lValue, line = line, position = position
                                        });
                            }
                            else
                            {
                                throw new LispParseException($"Not a valid double. Line: {line}:{position}");
                            }
                            break;
                        }

                        case 'i':
                        {
                            int lValue;
                            if (int.TryParse(strValue, out lValue))
                            {
                                tokens.Add(new LispToken()
                                        {
                                            type = TokenType.Int, value = strValue, lValue = lValue, line = line, position = position
                                        });
                            }
                            else
                            {
                                throw new LispParseException($"Not a valid int. Line: {line}:{position}");
                            }
                        }
                        break;

                        default:
                            throw new LispParseException($"Not a valid number type. Line:{line},{position}");
                        }

                        position += (index - 1) - i;
                        i         = index - 1;
                    }
                }
                break;
                }
            }

            // was there any tokens?
            if (tokens.Count == 0)
            {
                throw new Exception("Nothing parsable in the file!");
            }

            // perform balance check
            if (0 != tokens.Sum(t => ((t.type == TokenType.ParamLeft) ? 1 : (t.type == TokenType.ParamRight) ? -1 : 0)))
            {
                throw new LispParseException("Parathensies aren't balanced.");
            }

            int      token_index = 0;
            LispList root        = new LispList(tokens, ref token_index);

            return(root);
        }