Exemple #1
0
        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());
        }
Exemple #2
0
        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);
            }
        }