private static ArraySegment <TokenData <MetaToken> > LexArguments <T>(string src, TokenData <MetaToken> context, ArraySegment <TokenData <T> > tokens, int layer = 0) where T : Enum { var parts = new List <ArraySegment <TokenData <T> > >(); var start = 0; var depth = 0; for (int i = 0; i < tokens.Count; i++) { var token = tokens[i]; if (!(token.Type is Token type)) { throw new SourceError(token.GetSourceIndex(), token.GetSourceLength(), SourceError.WrongContext); } if (type == Token.LeftBracket) { depth++; if (depth == 1) { start = i + 1; } } else if (type == Token.RightBracket) { if (depth == 1) { parts.Add(tokens.Slice(start, i - start)); start = i + 1; } depth--; } else if (type == Token.Seperator && depth == 1) { parts.Add(tokens.Slice(start, i - start)); start = i + 1; } } if (depth != 0) { throw new SourceError(tokens.First().GetSourceIndex(), tokens.First().GetSourceLength(), SourceError.InvalidSyntax); } return(parts.Select(part => new TokenData <MetaToken>(MetaToken.Argument, context.Start, context.Length, tokens.Select(t => (TokenData <Enum>)t).ToArray(), Trim(LexMeta(src, part, layer)))).ToArray()); }
public static Expression ParseExpression(TokenData <MetaToken> target, ArraySegment <TokenData <MetaToken> > tokens) { if (tokens.Count == 0) { return(new VoidExpression(target.Start, target.Length)); } else if (tokens.Count == 1) { var token = tokens[0]; switch (token.Type) { case MetaToken.SubExpression: return(ParseExpression(token, token.LogicalChildren)); case MetaToken.IdentifierExpression: { if (token.Attributes.TryGetValue(Tokens.Name, out string name)) { return(new IdentifierExpression(token.GetSourceIndex(), token.GetSourceLength(), name)); } else { throw new SourceError(token.GetSourceIndex(), token.GetSourceLength(), SourceError.MissingAttribute); } } case MetaToken.LiteralExpression: { if (token.Attributes.TryGetValue(Tokens.Value, out string value)) { return(new LiteralExpression(token.GetSourceIndex(), token.GetSourceLength(), Compiler.NativeInt, value)); } else { throw new SourceError(token.GetSourceIndex(), token.GetSourceLength(), SourceError.MissingAttribute); } } case MetaToken.Call: { if (token.Attributes.TryGetValue(Tokens.Name, out string name)) { return(new CallExpression(token.GetSourceIndex(), token.GetSourceLength(), name, token.LogicalChildren.Value.Select(child => ParseExpression(child, child.LogicalChildren)))); } else { throw new SourceError(token.GetSourceIndex(), token.GetSourceLength(), SourceError.MissingAttribute); } } default: throw new SourceError(token.GetSourceIndex(), token.GetSourceLength(), SourceError.WrongContext); } } else { var postfix = new List <TokenData <MetaToken> >(); var stack = new Stack <TokenData <MetaToken> >(); for (int i = 0; i < tokens.Count; i++) { var token = tokens[i]; switch (token.Type) { case MetaToken.SubExpression: postfix.Add(token); break; case MetaToken.Operator: stack.Push(token); break; case MetaToken.IdentifierExpression: postfix.Add(token); break; case MetaToken.LiteralExpression: postfix.Add(token); break; case MetaToken.Whitespace: break; default: throw new SourceError(token.GetSourceIndex(), token.GetSourceLength(), SourceError.WrongContext); } } while (stack.Count > 0) { postfix.Add(stack.Pop()); } if (postfix.Count == 3) { var left = ParseExpression(postfix[0], new ArraySegment <TokenData <MetaToken> >(new[] { postfix[0] })); var right = ParseExpression(postfix[1], new ArraySegment <TokenData <MetaToken> >(new[] { postfix[1] })); var token = postfix[2]; if (token.Type == MetaToken.Operator) { if (token.Attributes.TryGetValue(Tokens.Name, out string name)) { var op = new FunctionReference(target.GetSourceIndex(), target.GetSourceLength(), name, new[] { left.ReturnType, right.ReturnType }); return(new BinaryExpression(target.GetSourceIndex(), target.GetSourceLength(), left, op, right)); } else { throw new SourceError(token.GetSourceIndex(), token.GetSourceLength(), SourceError.MissingAttribute); } } else { throw new SourceError(token.GetSourceIndex(), token.GetSourceLength(), SourceError.InvalidExpression); } } throw new SourceError(target.GetSourceIndex(), target.GetSourceLength(), SourceError.InvalidExpression); } }