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; }
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); }
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; }