/// <summary> /// Parses an include statement. /// </summary> public ParseResult ParseInclude(List <Token> tokens) { var skip = _engine.ExpectType(TokenTypes.StringLiteral, tokens); if (string.IsNullOrEmpty(_engine.Root)) { _engine.ThrowError("Engine path invalid!", tokens[1]); } var desiredFile = tokens[1].Value.EndsWith(".skt") ? tokens[1].Value : tokens[1].Value + ".skt"; var path = Path.GetFullPath(Path.Combine(_engine.Root, desiredFile)); var fileName = SkryptEngine.MakeRelativePath(_engine.Root, path); var fileStream = File.Open(path, FileMode.Open); string includedCode; using (var sr = new StreamReader(fileStream)) { includedCode = sr.ReadToEnd(); } _engine.Files[fileName] = includedCode; var oldParsingFile = _engine.CurrentParsingFile; _engine.CurrentParsingFile = path; var includeTokens = _engine.Tokenizer.Tokenize(includedCode); _engine.TokenProcessor.ProcessTokens(includeTokens); var programNode = _engine.GeneralParser.Parse(includeTokens); var node = new IncludeNode { Nodes = programNode.Nodes, Path = fileName }; _engine.CurrentParsingFile = oldParsingFile; return(new ParseResult { Node = node, Delta = 3 }); }
/// <summary> /// Parses a list of tokens into a method node /// </summary> public ParseResult Parse(List <Token> tokens) { var index = 0; SkipInfo skip; ParseResult result; skip = _engine.ExpectType(TokenTypes.Identifier, tokens); index += skip.Delta; skip = _engine.ExpectValue("(", tokens, index); index += skip.Delta; result = _engine.GeneralParser.ParseSurrounded("(", ")", index, tokens, ParseParameters); var parameterNode = result.Node; index += result.Delta; skip = _engine.ExpectValue("{", tokens, index); index += skip.Delta; result = _engine.GeneralParser.ParseSurrounded("{", "}", index, tokens, _engine.GeneralParser.Parse); var blockNode = result.Node; index += result.Delta + 1; var returnNode = new Node { Body = tokens[1].Value, Type = TokenTypes.MethodDeclaration }; returnNode.Nodes.Add(blockNode); returnNode.Nodes.Add(parameterNode); return(new ParseResult { Node = returnNode, Delta = index + 1 }); }
/// <summary> /// Parses a class definition. /// </summary> public ParseResult Parse(List <Token> tokens) { var i = 0; var skip = _engine.ExpectType(TokenTypes.Identifier, tokens, i); i += skip.Delta; skip = _engine.ExpectValue(new string[] { ":", "{" }, tokens, i); i += skip.Delta; var inheritNode = new Node { Body = "Inherit", Type = TokenTypes.Inherit }; // Class inherits from another class or classes. if (tokens[i].Equals(":", TokenTypes.Punctuator)) { var isIdentifier = true; var nextToken = default(Token); var s = _engine.ExpectType(TokenTypes.Identifier, tokens); i++; while (i < tokens.Count) { var token = tokens[i]; if (i < tokens.Count - 2) { nextToken = tokens[i + 1]; } if (token.Type == TokenTypes.EndOfExpression) { break; } if (isIdentifier) { inheritNode.Add(_engine.ExpressionParser.Parse(new List <Token> { tokens[i] }).Node); // No curly bracket means there could be another class to inherit from. // Before that a seperator ',' token has to be present. if (!(nextToken?.Equals("{", TokenTypes.Punctuator) ?? false) && i < tokens.Count - 1) { var sk = _engine.ExpectValue(",", tokens, i); isIdentifier = false; } else { break; } } else { // An object (identifier token) has to be present after a seperator ',' token. var sk = _engine.ExpectType(TokenTypes.Identifier, tokens, i); isIdentifier = true; } i++; } i++; } // Parse class body. var SurroundedTokens = _engine.GeneralParser.GetSurroundedTokens("{", "}", i, tokens); var node = ParseContents(SurroundedTokens, tokens[1].Value); var result = new ParseResult { Node = node, Delta = SurroundedTokens.Count + 1 }; var classNode = new ClassNode { InheritNode = inheritNode, BodyNode = result.Node, Name = tokens[1].Value, Token = tokens[0] }; i += result.Delta + 1; return(new ParseResult { Node = classNode, Delta = i + 1 }); }