Example #1
0
        public static FunctionHeader Header(MatchIterator iterator)
        {
            iterator.AssertTokenType(TokenType.Type, out Token typeToken);
            iterator.AssertTokenType(TokenType.Name, out Token nameToken);
            iterator.AssertKeySymbol(Symbols.OpenBracket, out _);
            Token open = (Token)iterator.Current;

            CollectedParameters parameters;

            if (iterator.Next(out parameters))
            {
                iterator.MoveNext();
            }
            else
            {
                parameters = new CollectedParameters();
            }

            iterator.AssertKeySymbol(Symbols.CloseBracket, out _);
            Token end = (Token)iterator.Current;

            iterator.AssertEnd();

            FunctionTypeSignature typeSignature = new FunctionTypeSignature(parameters.Types);
            FunctionSignature     signature     = new FunctionSignature(
                FunctionSignature.Local, nameToken.Content, typeSignature);

            FunctionHeader result = new FunctionHeader(
                typeToken, nameToken, open, end, signature, parameters.Names);

            return(result);
        }
Example #2
0
        public static VariableAssignment Assignment(MatchIterator iterator)
        {
            if (!iterator.NextIsToken(TokenType.Type, out Token type))
            {
                type = null;
            }

            iterator.AssertTokenType(TokenType.Name, out Token name);


            if (iterator.Next(out List <CollectedIndex> indices))
            {
                iterator.MoveNext();
            }

            else
            {
                indices = new List <CollectedIndex>(0);
            }

            iterator.AssertTokenType(TokenType.Operator, out Token op);

            if (!iterator.NextIsExpression(out Expression value))
            {
                value = null;
            }

            iterator.AssertEnd();

            return(new VariableAssignment(type, name, indices, op, value));
        }
Example #3
0
        public static FunctionCall Call(MatchIterator iterator)
        {
            // It would be cool in patterner v2 if the pattern was constructed in the same method as the finalizer.
            // For example, a "dummy" matchIterator could be passed through here and pick up the requirements, perhaps?
            // This would, of course, require the big feature of pattern simplification
            // It would also require defining a special "Expression" subpattern? At this point it would be better if everything were an expression, I guess

            iterator.AssertTokenType(TokenType.Name, out Token name);
            iterator.AssertKeySymbol(Symbols.OpenBracket, out _);
            Token open = (Token)iterator.Current;

            if (iterator.Next(out List <Expression> arguments))
            {
                iterator.MoveNext();
            }

            else
            {
                arguments = new List <Expression>();
            }

            iterator.AssertKeySymbol(Symbols.CloseBracket, out _);
            Token end = (Token)iterator.Current;

            iterator.AssertEnd();

            FunctionCall result = new FunctionCall(name, open, end, arguments);

            return(result);
        }
Example #4
0
        public static VariableReference CreateReference(MatchIterator iterator)
        {
            iterator.AssertTokenType(TokenType.Name, out Token token);
            iterator.AssertEnd();

            return(new VariableReference(token));
        }
Example #5
0
        public static Command Create(MatchIterator iterator)
        {
            iterator.AssertTokenType(TokenType.KeyWord, out Token keyWord);
            iterator.AssertEnd();

            Command result = new Command(keyWord);

            return(result);
        }
Example #6
0
        public static Expression CreateOld(MatchIterator iterator)
        {
            Token opToken;

            if (iterator.NextIsToken(TokenType.Operator, out opToken))
            {
                // assume a left operator for now
                Expression righExpr = Create(iterator);
                return(new OperatorCall(opToken, null, righExpr));
            }

            Expression nextExpr;

            if (iterator.NextIsKeySymbol(Symbols.OpenBracket))
            {
                iterator.AssertExpression(out nextExpr);
                iterator.AssertKeySymbol(Symbols.CloseBracket, out _);
            }

            else
            {
                iterator.AssertExpression(out nextExpr);
            }

            if (iterator.AtEnd())
            {
                return(nextExpr);
            }

            if (iterator.Next(out List <CollectedIndex> indices))
            {
                foreach (CollectedIndex index in indices)
                {
                    nextExpr = new Indexer(nextExpr, index.Open, index.Index, index.Close);
                }

                iterator.MoveNext();
            }

            if (iterator.AtEnd())
            {
                return(nextExpr);
            }

            iterator.AssertTokenType(TokenType.Operator, out opToken);

            if (iterator.AtEnd())
            {
                // Assume a right operator for now
                return(new OperatorCall(opToken, nextExpr, null));
            }

            // Assume a binary operator for now
            Expression remainder = Create(iterator);

            return(new OperatorCall(opToken, nextExpr, remainder));
        }
Example #7
0
        public static Expression Create(MatchIterator iterator)
        {
            LinkedList <object> items = new LinkedList <object>();

            iterator.AssertNext();

            // postfix unary operators are not supported here
            // (Like i--, etc)
            // I don't think they are really needed for sprak, and defaulting
            // to assuming prefix simplifies things.

            while (true)
            {
                items.AddLast(GetValue(iterator));

                if (iterator.AtEnd())
                {
                    break;
                }

                iterator.AssertTokenType(TokenType.Operator, out Token op);
                items.AddLast(op);

                if (iterator.AtEnd())
                {
                    break;
                }
            }

            void ParseOperatorToken(LinkedListNode <object> opNode)
            {
                Token token = (Token)opNode.Value;
                LinkedListNode <object> leftNode  = opNode.Previous;
                LinkedListNode <object> rightNode = opNode.Next;

                Expression   left   = (Expression)leftNode.Value;
                Expression   right  = (Expression)rightNode?.Value;
                OperatorCall result = new OperatorCall(token, left, right);

                items.AddBefore(leftNode, result);

                items.Remove(leftNode);
                items.Remove(opNode);

                if (rightNode != null)
                {
                    items.Remove(rightNode);
                }
            }

            LinkedListNode <object> current, next;

            foreach (Operator[] group in Operator.OperatorPrecedenceGroups)
            {
                current = items.First.Next;

                while (current != null)
                {
                    next = current.Next?.Next;

                    Token token = (Token)current.Value;
                    if (Operator.TryParse(out Operator op, text:token.Content))
                    {
                        if (group.Contains(op))
                        {
                            ParseOperatorToken(current);
                        }
                    }

                    current = next;
                }
            }

            current = items.First.Next;
            while (current != null)
            {
                ParseOperatorToken(current);
                current = current.Next?.Next;
            }

            if (items.First.Next != null)
            {
                throw new Exception("Unable to parse all operators");
            }

            return((Expression)items.First.Value);
        }