示例#1
0
        private static void TryReadDigit(TokenizerContext context, List <StyleToken> output)
        {
            if (context.IsConsumed())
            {
                return;
            }
            bool foundDot   = false;
            int  startIndex = context.ptr;

            context.Save();
            if (context.input[context.ptr] == '-')
            {
                context.Advance();
            }

            if (!char.IsDigit(context.input[context.ptr]))
            {
                context.Restore();
                return;
            }

            // 1
            // 1.4
            // 1.4f

            while (context.HasMore() && (char.IsDigit(context.input[context.ptr]) || (!foundDot && context.input[context.ptr] == '.')))
            {
                if (context.input[context.ptr] == '.')
                {
                    foundDot = true;
                }

                context.Advance();
            }

            int    length = context.ptr - startIndex;
            string digit  = context.input.Substring(startIndex, length);

            context.Restore();
            output.Add(new StyleToken(StyleTokenType.Number, digit, context.line, context.column));
            context.Advance(length);

            // a trailing f should be considered part of a float, except the f is followed by more characters like in a unit '2fr'
            // we don't want it to appear in the value, though. If it's ever used to differentiate something we should add a
            // more specific type like StyleTokenType.Float? Also what about 'm' and 'd' postfixes?
            if (context.HasMore() && context.input[context.ptr] == 'f' && context.HasMuchMore(1) && !char.IsLetter(context.input[context.ptr + 1]))
            {
                context.Advance();
            }

            TryConsumeWhiteSpace(context);
        }
示例#2
0
        private static void TryConsumeComment(TokenizerContext context)
        {
            if (context.ptr + 1 >= context.input.Length)
            {
                return;
            }

            if (!(context.input[context.ptr] == '/' && context.input[context.ptr + 1] == '/'))
            {
                return;
            }

            while (context.HasMore())
            {
                char current = context.input[context.ptr];
                if (current == '\n')
                {
                    TryConsumeWhiteSpace(context);
                    TryConsumeComment(context);
                    return;
                }

                context.Advance();
            }
        }
示例#3
0
        private static void TryReadString(TokenizerContext context, List <StyleToken> output)
        {
            if (context.IsConsumed())
            {
                return;
            }
            if (context.input[context.ptr] != '"')
            {
                return;
            }
            int start = context.ptr;

            context.Save();
            context.Advance();

            while (context.HasMore() && context.input[context.ptr] != '"')
            {
                context.Advance();
            }

            if (context.IsConsumed())
            {
                context.Restore();
                return;
            }

            if (context.input[context.ptr] != '"')
            {
                context.Restore();
                return;
            }

            context.Advance();

            // strip the quotes
            // "abc"
            // 01234
            int    length    = context.ptr - start;
            string substring = context.input.Substring(start + 1, length - 2);

            context.Restore();
            output.Add(new StyleToken(StyleTokenType.String, substring, context.line, context.column));
            context.Advance(length);

            TryConsumeWhiteSpace(context);
        }
示例#4
0
        private static void TryConsumeWhiteSpace(TokenizerContext context)
        {
            if (context.IsConsumed())
            {
                return;
            }

            while (context.HasMore() && char.IsWhiteSpace(context.input[context.ptr]))
            {
                context.Advance();
            }
        }
示例#5
0
        private static void TryReadValue(TokenizerContext context, List <StyleToken> output)
        {
            if (context.IsConsumed())
            {
                return;
            }
            if (context.input[context.ptr] != '=')
            {
                return;
            }
            context.Save();

            context.Advance();
            TryConsumeWhiteSpace(context);
            int start = context.ptr;

            while (context.HasMore() && context.input[context.ptr] != ';' && context.input[context.ptr] != '\n')
            {
                if (context.input[context.ptr] == '/' && context.ptr + 1 < context.input.Length && context.input[context.ptr + 1] == '/')
                {
                    break;
                }

                context.Advance();
            }

            if (context.IsConsumed())
            {
                context.Restore();
                return;
            }

            string value = context.input.Substring(start, context.ptr - start);

            output.Add(new StyleToken(StyleTokenType.Value, value, context.line, context.column));
            TryConsumeWhiteSpace(context);
        }
示例#6
0
        private static void TryReadIdentifier(TokenizerContext context, List <StyleToken> output)
        {
            if (context.IsConsumed())
            {
                return;
            }
            int  start = context.ptr;
            char first = context.input[context.ptr];

            if (!char.IsLetter(first) && first != '_' && first != '$')
            {
                return;
            }

            context.Save();

            while (context.HasMore())
            {
                char character = context.input[context.ptr];

                if (!(char.IsLetterOrDigit(character) || character == '_' || character == '-' || character == '$'))
                {
                    break;
                }

                context.Advance();
            }

            int    length     = context.ptr - start;
            string identifier = context.input.Substring(start, length);

            context.Restore();
            output.Add(TransformIdentifierToTokenType(context, identifier));
            context.Advance(length);
            TryConsumeWhiteSpace(context);
        }
示例#7
0
        private static void TryReadCharacters(TokenizerContext context, string match, StyleTokenType styleTokenType, List <StyleToken> output)
        {
            if (context.ptr + match.Length > context.input.Length)
            {
                return;
            }
            for (int i = 0; i < match.Length; i++)
            {
                if (context.input[context.ptr + i] != match[i])
                {
                    return;
                }
            }

            output.Add(new StyleToken(styleTokenType, match, context.line, context.column));
            TryConsumeWhiteSpace(context.Advance(match.Length));
        }
示例#8
0
        private static void TryConsumeWhiteSpace(TokenizerContext context)
        {
            if (context.IsConsumed())
            {
                return;
            }

            while (context.ptr < context.input.Length)
            {
                char c = context.input[context.ptr];
                if (!(c == ' ' || c >= '\t' && c <= '\r' || (c == ' ' || c == '\x0085')))
                {
                    break;
                }

                context.Advance();
            }
        }
示例#9
0
        private static void TryReadCharacterSequence(TokenizerContext context, string match1, string match2, ExpressionTokenType expressionTokenType, StructList <ExpressionToken> output)
        {
            if (context.ptr + match1.Length > context.input.Length)
            {
                return;
            }

            int ptr = context.ptr;

            for (int i = 0; i < match1.Length; i++)
            {
                if (context.input[ptr++] != match1[i])
                {
                    return;
                }
            }

            while (ptr < context.input.Length)
            {
                if (char.IsWhiteSpace(context.input[ptr]))
                {
                    ptr++;
                }
                else
                {
                    break;
                }
            }

            for (int i = 0; i < match2.Length; i++)
            {
                if (context.input[ptr++] != match2[i])
                {
                    return;
                }
            }

            output.Add(new ExpressionToken(expressionTokenType, match1 + " " + match2, context.line, context.column));
            TryConsumeWhiteSpace(context.Advance(ptr - context.ptr));
        }
示例#10
0
        private static void TryReadHashColor(TokenizerContext context, List <StyleToken> output)
        {
            if (context.IsConsumed())
            {
                return;
            }
            if (context.input[context.ptr] != '#')
            {
                return;
            }

            int start = context.ptr;

            while (context.HasMore() && context.input[context.ptr] != ';' && !char.IsWhiteSpace(context.input[context.ptr]))
            {
                context.Advance();
            }

            string colorHash = context.input.Substring(start, context.ptr - start);

            output.Add(new StyleToken(StyleTokenType.HashColor, colorHash, context.line, context.column));

            TryConsumeWhiteSpace(context);
        }
示例#11
0
        private static void TryReadDigit(TokenizerContext context, StructList <ExpressionToken> output)
        {
            if (context.IsConsumed())
            {
                return;
            }
            bool foundDot   = false;
            int  startIndex = context.ptr;

            context.Save();
            if (context.input[context.ptr] == '-')
            {
                context.Advance();
            }

            if (!char.IsDigit(context.input[context.ptr]))
            {
                context.Restore();
                return;
            }

            while (context.HasMore() && (char.IsDigit(context.input[context.ptr]) || (!foundDot && context.input[context.ptr] == '.')))
            {
                if (context.input[context.ptr] == '.')
                {
                    foundDot = true;
                }

                context.Advance();
            }


            if (context.HasMore())
            {
                char next = context.input[context.ptr];
                // todo -- enable the below to making parsing numbers better in the compiler (since we already know what type to try to parse it as)
                //ExpressionTokenType type = ExpressionTokenType.Number;
//                if (next == 'f') {
//                    type = ExpressionTokenType.Number_Float;
//                }
//
//                if (next == 'd') {
//                    type = ExpressionTokenType.Number_Double;
//                }
//
//                if (next == 'l') {
//                    type = ExpressionTokenType.Number_Long;
//                }
//
//                if (next == 'u') {
//                    // todo -- check for ul here
//                    type = ExpressionTokenType.Number_UInt;
//                }
//
//                if (next == 'm') {
//                    type = ExpressionTokenType.Number_Decimal;
//                }

                if (next == 'f' || next == 'd' || next == 'l' || next == 'u' || next == 'm')
                {
                    if (next != '.')
                    {
                        context.Advance();
                    }
                }
            }

//            if (context.HasMore()
//                && context.input[context.ptr] == 'f'
//                && context.input[context.ptr - 1] != '.') {
//                context.Advance();
//            }

            int    length = context.ptr - startIndex;
            string digit  = context.input.Substring(startIndex, length);

            context.Restore();
            output.Add(new ExpressionToken(ExpressionTokenType.Number, digit, context.line, context.column));
            context.Advance(length);

            TryConsumeWhiteSpace(context);
        }