Beispiel #1
0
        private void ProcedureDeclaration()
        {
            var procedureInfo = new CustomProcedureInfo();

            tokens.Eat(TokenType.Learn);

            var nameToken = tokens.Eat(TokenType.Identifier);

            procedureInfo.Name = nameToken.Value;

            var arguments = new ListVariable();

            while (tokens.CurrentToken.Type == TokenType.Colon)
            {
                tokens.Eat(TokenType.Colon);
                arguments.Add(tokens.Eat(TokenType.Identifier).Value);
            }
            procedureInfo.Arguments = arguments.ToArray();

            var procTokens = new List <Token>();

            while (tokens.CurrentToken.Type != TokenType.End)
            {
                procTokens.Add(tokens.Eat());
            }

            procTokens.Add(new Token(TokenType.ProgramEnd, "", new TokenPosition(0, 0, 0)));

            tokens.Eat(TokenType.End);
            procedureInfo.Tokens = procTokens.ToArray();

            if (ProcedureExists(procedureInfo.Name))
            {
                throw new ScriptException($"Er bestaat al een procedure '{procedureInfo.Name}'", nameToken);
            }

            procedures[procedureInfo.Name.ToLower()] = procedureInfo;
        }
Beispiel #2
0
        private Node ParseFactor()
        {
            var position = tokens.CurrentToken.Location;

            if (tokens.CurrentToken.Type == TokenType.ParenthesisLeft)
            {
                tokens.Eat(TokenType.ParenthesisLeft);

                Node node;

                if (tokens.CurrentToken.Type == TokenType.Identifier)
                {
                    // Vararg procedure call
                    var name                = tokens.Eat(TokenType.Identifier);
                    var procedure           = ResolveProcedure(name);
                    var argumentExpressions = new List <Node>();
                    while (tokens.CurrentToken.Type != TokenType.ParenthesisRight)
                    {
                        argumentExpressions.Add(ParseExpression());
                    }

                    node = new ProcedureCallNode(position)
                    {
                        Name = name, ArgumentExpressions = argumentExpressions.ToArray()
                    };
                }
                else
                {
                    node = ParseExpression();
                }

                tokens.Eat(TokenType.ParenthesisRight);

                return(node);
            }
            else if (tokens.CurrentToken.Type == TokenType.BracketLeft)
            {
                // List
                tokens.Eat(TokenType.BracketLeft);

                var values = new ListVariable();
                while (tokens.CurrentToken.Type != TokenType.BracketRight)
                {
                    values.Add(tokens.Eat().LiteralValue);
                }

                tokens.Eat(TokenType.BracketRight);

                return(new ListNode(position)
                {
                    Values = values
                });
            }
            else if (tokens.CurrentToken.Type == TokenType.Integer)
            {
                var token = tokens.Eat(TokenType.Integer);
                return(new IntegerNode(position)
                {
                    Value = Convert.ToInt32(token.Value)
                });
            }
            else if (tokens.CurrentToken.Type == TokenType.True || tokens.CurrentToken.Type == TokenType.False)
            {
                var token = tokens.Eat();
                return(new BooleanNode(position)
                {
                    Value = token.Value.Equals("welwaar", StringComparison.CurrentCultureIgnoreCase)
                });
            }
            else if (tokens.CurrentToken.Type == TokenType.Colon)
            {
                tokens.Eat(TokenType.Colon);
                var variableName = tokens.Eat(TokenType.Identifier);

                return(new VariableNode(position)
                {
                    Name = variableName
                });
            }
            else if (tokens.CurrentToken.Type == TokenType.StringLiteral)
            {
                var value = tokens.Eat(TokenType.StringLiteral);
                return(new StringLiteralNode(position)
                {
                    Value = value
                });
            }
            else if (tokens.CurrentToken.Type == TokenType.Identifier)
            {
                var name                = tokens.Eat(TokenType.Identifier);
                var procedure           = ResolveProcedure(name);
                var argumentExpressions = new List <Node>();

                for (int i = 0; i < procedure.Arguments.Length; i++)
                {
                    argumentExpressions.Add(ParseExpression());
                }

                return(new ProcedureCallNode(position)
                {
                    Name = name, ArgumentExpressions = argumentExpressions.ToArray()
                });
            }

            throw new ScriptException($"Onverwachte invoer: {tokens.CurrentToken}", tokens.CurrentToken);
        }
Beispiel #3
0
        public Interpreter()
        {
            RegisterFunction("herhaal", new string[] { "count", "commands" }, (_context, _arguments) => {
                if (!(_arguments[1] is ListVariable))
                {
                    throw new ScriptException("Herhaal verwacht een lijst van opdrachten", _context.CallToken);
                }
                //_context.GetArgument("count");
                var memorySpace = new MemorySpace(memory);
                PushMemorySpace(memorySpace);

                var tokens = Lexer.Tokenize(string.Join(" ", (ListVariable)_arguments[1])).ToArray();

                try
                {
                    for (int i = 0; i < (int)_arguments[0]; i++)
                    {
                        memorySpace.Set("iteratie", i + 1);
                        Interpret(tokens);
                    }
                }catch (Exception ex)
                {
                    throw new ScriptException($"Fout in herhaal", _context.CallToken, ex);
                }

                PopMemorySpace();

                return(null);
            });

            RegisterFunction("zolang", new string[] { "uitdrukking", "opdrachten" }, (_context, _arguments) => {
                var expressionTokens = Lexer.Tokenize(string.Join(" ", (ListVariable)_arguments[0])).ToArray();
                var bodyTokens       = Lexer.Tokenize(string.Join(" ", (ListVariable)_arguments[1])).ToArray();

                while (Convert.ToBoolean(InterpretExpression(expressionTokens)))
                {
                    Interpret(bodyTokens);
                }

                return(null);
            });

            RegisterFunction("telherhaal", new string[] {}, (_context, _arguments) => {
                if (!memory.ContainsRecursive("iteratie"))
                {
                    throw new ScriptException("Telherhaal kan alleen binnen een herhaal opdracht gebruikt worden");
                }

                return(memory.Get("iteratie"));
            });

            RegisterFunction("en", new string[] { "aanduiding1", "aanduiding2" }, (_context, _arguments) => {
                return(_arguments.All(arg => Convert.ToBoolean(arg)));
            });

            RegisterFunction("of", new string[] { "aanduiding1", "aanduiding2" }, (_context, _arguments) => {
                return(_arguments.Any(arg => Convert.ToBoolean(arg)));
            });

            RegisterFunction("niet", new string[] { "aanduiding" }, (_context, _arguments) => {
                return(!Convert.ToBoolean(_arguments[0]));
            });

            RegisterFunction("als", new string[] { "conditie", "alsWelwaar", "alsNietwaar" }, (_context, _arguments) => {
                var boolean = Convert.ToBoolean(_arguments[0]);

                if (_arguments[1] is ListVariable && _arguments[2] is ListVariable)
                {
                    var trueTokens  = _arguments[1] as ListVariable;
                    var falseTokens = _arguments[2] as ListVariable;

                    var memorySpace = new MemorySpace(memory);
                    PushMemorySpace(memorySpace);

                    var tokens = Lexer.Tokenize(string.Join(" ", boolean ? trueTokens : falseTokens)).ToArray();
                    Interpret(tokens);

                    PopMemorySpace();
                    return(null);
                }
                else
                {
                    return(boolean ? _arguments[1] : _arguments[2]);
                }
            });

            RegisterFunction("test", new string[] { "conditie" }, (_context, _arguments) => {
                var boolean = Convert.ToBoolean(_arguments[0]);

                memory.Set("testResultaat", boolean);
                return(null);
            });

            RegisterFunction("alswaar", new string[] { "instructies" }, (_context, _arguments) => {
                if (!memory.ContainsRecursive("testResultaat"))
                {
                    throw new ScriptException("Alswaar kan alleen na een aanroep van test gebruikt worden");
                }

                if (Convert.ToBoolean(memory.Get("testResultaat")))
                {
                    var memorySpace = new MemorySpace(memory);
                    PushMemorySpace(memorySpace);

                    var tokens = Lexer.Tokenize(string.Join(" ", _arguments[0] as ListVariable)).ToArray();
                    Interpret(tokens);

                    PopMemorySpace();
                }

                return(null);
            });

            RegisterFunction("alsnietwaar", new string[] { "instructies" }, (_context, _arguments) => {
                if (!memory.ContainsRecursive("testResultaat"))
                {
                    throw new ScriptException("Alsnietwaar kan alleen na een aanroep van test gebruikt worden");
                }

                if (!Convert.ToBoolean(memory.Get("testResultaat")))
                {
                    var memorySpace = new MemorySpace(memory);
                    PushMemorySpace(memorySpace);

                    var tokens = Lexer.Tokenize(string.Join(" ", _arguments[0] as ListVariable)).ToArray();
                    Interpret(tokens);

                    PopMemorySpace();
                }

                return(null);
            });

            RegisterFunction("lijst", new string[] { "arg1", "arg2" }, (_context, _arguments) => {
                var result = new ListVariable();

                foreach (var arg in _arguments)
                {
                    result.Add(arg.ToString());
                }

                return(result);
            });

            RegisterFunction("openafbeelding", new string[] { "naam" }, (_context, _arguments) => {
                var fileName = _arguments[0].ToString();

                return(Image.FromFile(fileName));
            });

            RegisterFunction("aantal", new string[] { "aanduiding" }, (_context, _arguments) => {
                var target = _arguments[0];

                if (target is ListVariable)
                {
                    return((target as ListVariable).Count);
                }
                else
                {
                    throw new ScriptException($"Aantal verwacht een lijst", _context.CallToken);
                }
            });

            RegisterFunction("plaatservoor", new string[] { "aanduiding", "lijst" }, (_context, _arguments) => {
                var target   = _arguments[1];
                var addition = _arguments[0];

                if (target is ListVariable)
                {
                    var newList = new ListVariable((target as ListVariable));

                    newList.Insert(0, addition.ToString());
                    return(newList);
                }
                else
                {
                    throw new ScriptException($"Plaatservoor verwacht een aanduiding en een lijst", _context.CallToken);
                }
            });

            RegisterFunction("plaatserachter", new string[] { "aanduiding", "lijst" }, (_context, _arguments) => {
                var target   = _arguments[1];
                var addition = _arguments[0];

                if (target is ListVariable)
                {
                    var newList = new ListVariable((target as ListVariable));

                    newList.Add(addition.ToString());
                    return(newList);
                }
                else
                {
                    throw new ScriptException($"Plaatserachter verwacht een aanduiding en een lijst", _context.CallToken);
                }
            });

            RegisterFunction("eerste", new string[] { "aanduiding" }, (_context, _arguments) => {
                var target = _arguments[0];

                if (target is ListVariable)
                {
                    var list = target as ListVariable;
                    if (list.Count == 0)
                    {
                        throw new ScriptException($"Ik kan niet het eerste element van een lege lijst opvragen", _context.CallToken);
                    }

                    return(list[0]);
                }
                else
                {
                    throw new ScriptException($"Eerste verwacht een lijst", _context.CallToken);
                }
            });

            RegisterFunction("laatste", new string[] { "aanduiding" }, (_context, _arguments) => {
                var target = _arguments[0];

                if (target is ListVariable)
                {
                    var list = target as ListVariable;
                    if (list.Count == 0)
                    {
                        throw new ScriptException($"Ik kan niet het laatste element van een lege lijst opvragen", _context.CallToken);
                    }

                    return(list[list.Count - 1]);
                }
                else
                {
                    throw new ScriptException($"Laatste verwacht een lijst", _context.CallToken);
                }
            });

            RegisterFunction("mineerste", new string[] { "lijst" }, (_context, _arguments) => {
                var list = _arguments[0];

                if (list is ListVariable)
                {
                    var newList = new ListVariable((list as ListVariable));

                    newList.RemoveAt(0);
                    return(newList);
                }
                else
                {
                    throw new ScriptException($"Mineerste verwacht een lijst", _context.CallToken);
                }
            });

            RegisterFunction("minlaatste", new string[] { "lijst" }, (_context, _arguments) => {
                var list = _arguments[0];

                if (list is ListVariable)
                {
                    var newList = new ListVariable((list as ListVariable));

                    newList.RemoveAt(newList.Count - 1);
                    return(newList);
                }
                else
                {
                    throw new ScriptException($"Minlaatste verwacht een lijst", _context.CallToken);
                }
            });

            RegisterFunction("element", new string[] { "welke", "aanduiding" }, (_context, _arguments) => {
                var index  = _arguments[0];
                var source = _arguments[1];

                if (source is ListVariable)
                {
                    return(((ListVariable)source) [Convert.ToInt32(index)]);
                }

                return(null);
            });

            RegisterFunction("woord", new string[] { "arg1", "arg2" }, (_context, _arguments) => {
                var result = new StringBuilder();

                foreach (var arg in _arguments)
                {
                    result.Append(arg.ToString());
                }

                return(result.ToString());
            });

            RegisterFunction("gok", new string[] { "maximum" }, (_context, _arguments) => {
                var max = (int)_arguments[0];
                return(random.Next(max - 1));
            });

            RegisterFunction("wacht", new string[] { "duration" }, (_context, _arguments) => {
                Thread.Sleep((int)_arguments[0]);
                return(null);
            });

            globalMemory = new MemorySpace();
            memory       = globalMemory;
        }