コード例 #1
0
        void ReadNumber(SourceUnit unit, ScanResult <LoreToken> result)
        {
            const string HexChars     = "abcdefABCDEF";
            var          accum        = new StringBuilder();
            var          isfloat      = false;
            var          nofloatstart = false;
            var          nofloatend   = false;
            var          ishex        = false;
            var          chr          = unit.Peek();

            if (chr == '.')
            {
                nofloatstart = true;
                accum.Append("0");
            }
            else if (chr == '0' && unit.See(2) && unit.Peek(1) == 'x')
            {
                ishex = true;
                unit.Skip(2);
            }
            if (!unit.See(0))
            {
                Throw("Unexpected end of file.");
            }
            while (unit.See(0) && (chr = unit.Peek()) > 0)
            {
                if (chr == '.')
                {
                    if (!unit.See(1) || !char.IsDigit(unit.Peek(1)))
                    {
                        nofloatend = true;
                        if (nofloatstart)
                        {
                            Throw("Floating-point literal must have a digit before or after the decimal point.");
                        }
                    }
                    if (isfloat)
                    {
                        break;
                        // Throw ("There can only be one decimal point in a floating-point literal.");
                    }
                    isfloat = true;
                    accum.Append(unit.Read());
                    if (nofloatend)
                    {
                        accum.Append('0');
                        break;
                    }
                    continue;
                }
                if (ishex)
                {
                    if (char.IsDigit(chr) || HexChars.Contains(chr))
                    {
                        accum.Append(unit.Read());
                        continue;
                    }
                    break;
                }
                if (char.IsDigit(chr))
                {
                    accum.Append(unit.Read());
                    continue;
                }
                break;
            }
            var   str      = accum.ToString();
            ulong hexvalue = 0;

            if (ishex)
            {
                if (!ulong.TryParse(str, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out hexvalue))
                {
                    try {
                        ulong.Parse(str, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo);
                    } catch (Exception e) {
                        Throw($"Unable to parse base-16 integer literal: {e.Message}.");
                    }
                }
            }
            else if (isfloat)
            {
                try {
                    float.Parse(str, NumberStyles.Float, NumberFormatInfo.InvariantInfo);
                } catch (Exception e) {
                    Throw($"Unable to parse floating-point literal: {e.Message}.");
                }
            }
            else
            {
                try {
                    ulong.Parse(str, NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
                } catch (Exception e) {
                    Throw($"Unable to parse integer literal: {e.Message}.");
                }
            }
            result.Token = isfloat ? LoreToken.FloatLiteral : LoreToken.IntLiteral;
            result.Value = ishex ? hexvalue.ToString() : str;
        }
コード例 #2
0
        private void ColorNone(string line, ColoredCharacter[] result, ref int index)
        {
            while (index < line.Length)
            {
                if (OutputIfNext(line, result, ref index, "//", CommentColor))
                {
                    for (var i = index; i < line.Length; i++, index++)
                    {
                        result[i] = new ColoredCharacter(line[i], CommentColor);
                    }

                    return;
                }

                if (OutputIfNext(line, result, ref index, "/*", CommentColor))
                {
                    _state             = TokenState.MultiComment;
                    _multiCommentDepth = 1;
                    return;
                }

                var ch = line[index];

                if (OutputIfNext(line, result, ref index, "\"", StringColor) ||
                    OutputIfNext(line, result, ref index, "\'", StringColor))
                {
                    _state            = TokenState.String;
                    _stringTerminator = ch;
                    return;
                }

                if (Operators.TryGetValue(ch, out var operators))
                {
                    var idx = index;
                    var op  = operators.FirstOrDefault(s => IsNext(line, idx, s));

                    if (op != null)
                    {
                        Output(result, ref index, op, OperatorColor);
                        continue;
                    }
                }

                if (char.IsLetter(ch) || ch == '_' || ch == '`')
                {
                    var start = index;

                    var isBacktick = ch == '`';

                    if (isBacktick)
                    {
                        index++; // opening backtick
                    }
                    while (index < line.Length && (char.IsLetterOrDigit(line[index]) || line[index] == '_'))
                    {
                        index++;
                    }

                    if (isBacktick && index < line.Length && line[index] == '`')
                    {
                        index++; // closing backtick
                    }
                    var word = line.Substring(start, index - start);
                    index = start;

                    if (isBacktick)
                    {
                        Output(result, ref index, word, OperatorColor);
                        continue;
                    }

                    if (Keywords.Contains(word))
                    {
                        Output(result, ref index, word, KeywordColor);
                        continue;
                    }

                    Output(result, ref index, word, IdentifierColor);
                    continue;
                }

                if (char.IsDigit(ch))
                {
                    var format     = NumberFormat.Decimal;
                    var hasDecimal = false;
                    var hasExp     = false;
                    var justTake   = false;

                    if (ch == '0' && index + 1 < line.Length)
                    {
                        var nextChar = line[index + 1];

                        if (nextChar == 'x' || nextChar == 'X')
                        {
                            format = NumberFormat.Hexadecimal;
                        }

                        if (nextChar == 'b' || nextChar == 'B')
                        {
                            format = NumberFormat.Binary;
                        }

                        if (format != NumberFormat.Decimal)
                        {
                            if (index + 2 < line.Length && line[index + 2] == '_')
                            {
                                result[index++] = new ColoredCharacter('0', NumberColor);
                                continue;
                            }

                            result[index + 0] = new ColoredCharacter('0', NumberColor);
                            result[index + 1] = new ColoredCharacter(nextChar, NumberColor);
                            index            += 2;
                        }
                    }

                    bool IsDigit(char c) =>
                    char.IsDigit(c) || (format == NumberFormat.Hexadecimal && HexChars.Contains(c));

                    while (index < line.Length)
                    {
                        var c = line[index];

                        if (justTake)
                        {
                            justTake        = false;
                            result[index++] = new ColoredCharacter(c, NumberColor);
                            continue;
                        }

                        if (c == '_' && (index + 1 < line.Length && IsDigit(line[index + 1])))
                        {
                            result[index++] = new ColoredCharacter(c, NumberColor);
                            continue;
                        }

                        if (format == NumberFormat.Decimal)
                        {
                            if (c == '.' && !hasDecimal && !hasExp)
                            {
                                hasDecimal = true;

                                if (index + 1 >= line.Length || !IsDigit(line[index + 1]))
                                {
                                    break;
                                }

                                result[index++] = new ColoredCharacter(c, NumberColor);
                                continue;
                            }

                            if ((c == 'e' || c == 'E') && !hasExp)
                            {
                                if (index + 1 < line.Length)
                                {
                                    var next = line[index + 1];
                                    if (next == '+' || next == '-')
                                    {
                                        justTake = true;
                                    }
                                }

                                hasExp          = true;
                                result[index++] = new ColoredCharacter(c, NumberColor);
                                continue;
                            }
                        }

                        if (!IsDigit(c))
                        {
                            break;
                        }

                        result[index++] = new ColoredCharacter(c, NumberColor);
                    }

                    continue;
                }

                result[index] = new ColoredCharacter(line[index], OtherColor);
                index++;
            }
        }