Exemple #1
0
            private static void SkipWhitespaceAndComments(CodeReader cr)
            {
                bool isStillWhiteSpace = true;

                while (isStillWhiteSpace)
                {
                    while (!cr.EOF && char.IsWhiteSpace(cr.PeekChar()))
                    {
                        cr.AdvancePosition();
                    }

                    if (!cr.EOF && cr.PeekChar() == '/')
                    {
                        char ahead = cr.PeekCharAhead();
                        if (ahead != '\0')
                        {
                            switch (ahead)
                            {
                            case '/':
                                cr.AdvancePosition(2);
                                while (!cr.EOF && !cr.PeekChar().In('\n', '\r'))
                                {
                                    cr.AdvancePosition();
                                }
                                break;

                            case '*':
                                cr.AdvancePosition(2);
                                while (!cr.EOF && cr.PeekChar() != '*' && cr.PeekCharAhead() != '/')
                                {
                                    cr.AdvancePosition();
                                }
                                if (!cr.EOF)
                                {
                                    cr.AdvancePosition(2);
                                }
                                break;

                            default:
                                // Ran into a non-comment; whitespace must be over
                                isStillWhiteSpace = false;
                                break;
                            }
                        }
                        else
                        {
                            // EOF ahead
                            isStillWhiteSpace = false;
                        }
                    }
                    else
                    {
                        // Ran into a non-comment; whitespace must be over
                        isStillWhiteSpace = false;
                    }
                }
            }
Exemple #2
0
            private static Token ReadToken(CodeReader cr, bool gms2)
            {
                SkipWhitespaceAndComments(cr);
                if (cr.EOF)
                {
                    return(new Token(Token.TokenKind.EOF));
                }

                if (cr.PeekChar() == '#')
                {
                    // Skip preprocessor directive/macro/etc. Maybe support could be added later... but not yet.
                    while (!cr.EOF)
                    {
                        if (cr.PeekChar() == '\n')
                        {
                            break;
                        }
                        cr.AdvancePosition();
                    }
                }

                char c = cr.PeekChar();

                if (!char.IsLetter(c) && c != '_')
                {
                    // Numbers/hex
                    if (c == '$' || (c == '0' && cr.PeekCharAhead() == 'x'))
                    {
                        return(ReadHexLiteral(cr));
                    }
                    if (char.IsDigit(c) || (c == '.' && char.IsDigit(cr.PeekCharAhead())))
                    {
                        return(ReadNumberLiteral(cr));
                    }

                    // Strings
                    if (gms2)
                    {
                        if (c == '@')
                        {
                            char c2 = cr.PeekCharAhead();
                            if (c2 == '"' || c2 == '\'')
                            {
                                cr.AdvancePosition();
                                return(ReadStringLiteralNoEscape(cr));
                            }
                        }
                        else if (c == '"')
                        {
                            return(ReadStringLiteral(cr));
                        }
                    }
                    else
                    {
                        if (c == '"' || c == '\'')
                        {
                            return(ReadStringLiteral(cr));
                        }
                    }

                    // Operators/everything else
                    switch (c)
                    {
                    case '{':
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.OpenBlock, cr.GetPositionInfo(cr.Position - 1)));

                    case '}':
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.CloseBlock, cr.GetPositionInfo(cr.Position - 1)));

                    case '(':
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.OpenParen, cr.GetPositionInfo(cr.Position - 1)));

                    case ')':
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.CloseParen, cr.GetPositionInfo(cr.Position - 1)));

                    case '|':
                    {
                        char ahead = cr.PeekCharAhead();
                        if (ahead != '\0')
                        {
                            switch (ahead)
                            {
                            case '|':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.LogicalOr, cr.GetPositionInfo(cr.Position - 2)));

                            case '=':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.AssignOr, cr.GetPositionInfo(cr.Position - 2)));
                            }
                        }
                    }
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.BitwiseOr, cr.GetPositionInfo(cr.Position - 1)));

                    case '^':
                    {
                        char ahead = cr.PeekCharAhead();
                        if (ahead != '\0')
                        {
                            switch (ahead)
                            {
                            case '^':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.LogicalXor, cr.GetPositionInfo(cr.Position - 2)));

                            case '=':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.AssignXor, cr.GetPositionInfo(cr.Position - 2)));
                            }
                        }
                    }
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.BitwiseXor, cr.GetPositionInfo(cr.Position - 1)));

                    case '&':
                    {
                        char ahead = cr.PeekCharAhead();
                        if (ahead != '\0')
                        {
                            switch (ahead)
                            {
                            case '&':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.LogicalAnd, cr.GetPositionInfo(cr.Position - 2)));

                            case '=':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.AssignAnd, cr.GetPositionInfo(cr.Position - 2)));
                            }
                        }
                    }
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.BitwiseAnd, cr.GetPositionInfo(cr.Position - 1)));

                    case '%':
                    {
                        if (cr.PeekCharAhead() == '=')
                        {
                            cr.AdvancePosition(2);
                            return(new Token(Token.TokenKind.AssignMod, cr.GetPositionInfo(cr.Position - 2)));
                        }
                    }
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.Mod, cr.GetPositionInfo(cr.Position - 1)));

                    case '~':
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.BitwiseNegate, cr.GetPositionInfo(cr.Position - 1)));

                    case '!':
                        cr.AdvancePosition();
                        if (cr.PeekChar() == '=')
                        {
                            cr.AdvancePosition();
                            return(new Token(Token.TokenKind.CompareNotEqual, cr.GetPositionInfo(cr.Position - 2)));
                        }
                        return(new Token(Token.TokenKind.Not, cr.GetPositionInfo(cr.Position - 1)));

                    case '[':
                    {
                        char ahead = cr.PeekCharAhead();
                        if (ahead != '\0')
                        {
                            switch (ahead)
                            {
                            case '?':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.OpenArrayMap, cr.GetPositionInfo(cr.Position - 2)));

                            case '@':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.OpenArrayBaseArray, cr.GetPositionInfo(cr.Position - 2)));

                            case '#':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.OpenArrayGrid, cr.GetPositionInfo(cr.Position - 2)));

                            case '|':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.OpenArrayList, cr.GetPositionInfo(cr.Position - 2)));
                            }
                        }
                    }
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.OpenArray, cr.GetPositionInfo(cr.Position - 1)));

                    case ']':
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.CloseArray, cr.GetPositionInfo(cr.Position - 1)));

                    case '*':
                        cr.AdvancePosition();
                        if (cr.PeekChar() == '=')
                        {
                            cr.AdvancePosition();
                            return(new Token(Token.TokenKind.AssignTimes, cr.GetPositionInfo(cr.Position - 2)));
                        }
                        return(new Token(Token.TokenKind.Times, cr.GetPositionInfo(cr.Position - 1)));

                    case '/':
                        cr.AdvancePosition();
                        if (cr.PeekChar() == '=')
                        {
                            cr.AdvancePosition();
                            return(new Token(Token.TokenKind.AssignDivide, cr.GetPositionInfo(cr.Position - 2)));
                        }
                        return(new Token(Token.TokenKind.Divide, cr.GetPositionInfo(cr.Position - 1)));

                    case '+':
                        cr.AdvancePosition();
                        {
                            char next = cr.PeekChar();
                            if (next == '=')
                            {
                                cr.AdvancePosition();
                                return(new Token(Token.TokenKind.AssignPlus, cr.GetPositionInfo(cr.Position - 2)));
                            }
                            if (next == '+')
                            {
                                cr.AdvancePosition();
                                return(new Token(Token.TokenKind.Increment, cr.GetPositionInfo(cr.Position - 2)));
                            }
                        }
                        return(new Token(Token.TokenKind.Plus, cr.GetPositionInfo(cr.Position - 1)));

                    case '-':
                        cr.AdvancePosition();
                        {
                            char next = cr.PeekChar();
                            if (next == '=')
                            {
                                cr.AdvancePosition();
                                return(new Token(Token.TokenKind.AssignMinus, cr.GetPositionInfo(cr.Position - 2)));
                            }
                            if (next == '-')
                            {
                                cr.AdvancePosition();
                                return(new Token(Token.TokenKind.Decrement, cr.GetPositionInfo(cr.Position - 2)));
                            }
                        }
                        return(new Token(Token.TokenKind.Minus, cr.GetPositionInfo(cr.Position - 1)));    // converted to negate later if necessary

                    case ',':
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.Comma, cr.GetPositionInfo(cr.Position - 1)));

                    case '.':
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.Dot, cr.GetPositionInfo(cr.Position - 1)));

                    case ':':
                        cr.AdvancePosition();
                        if (cr.PeekChar() == '=')
                        {
                            cr.AdvancePosition();
                            return(new Token(Token.TokenKind.Assign, ":=", cr.GetPositionInfo(cr.Position - 2)));    // Apparently this exists
                        }
                        return(new Token(Token.TokenKind.Colon, cr.GetPositionInfo(cr.Position - 1)));

                    case ';':
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.EndStatement, cr.GetPositionInfo(cr.Position - 1)));

                    case '=':
                        cr.AdvancePosition();
                        if (cr.PeekChar() == '=')
                        {
                            cr.AdvancePosition();
                            return(new Token(Token.TokenKind.CompareEqual, cr.GetPositionInfo(cr.Position - 2)));
                        }
                        return(new Token(Token.TokenKind.Assign, "=", cr.GetPositionInfo(cr.Position - 1)));

                    case '<':
                    {
                        char ahead = cr.PeekCharAhead();
                        if (ahead != '\0')
                        {
                            switch (ahead)
                            {
                            case '<':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.BitwiseShiftLeft, cr.GetPositionInfo(cr.Position - 2)));

                            case '=':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.CompareLessEqual, cr.GetPositionInfo(cr.Position - 2)));

                            case '>':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.CompareNotEqual, cr.GetPositionInfo(cr.Position - 2)));            // <> exists, it's just legacy
                            }
                        }
                    }
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.CompareLess, cr.GetPositionInfo(cr.Position - 1)));

                    case '>':
                    {
                        char ahead = cr.PeekCharAhead();
                        if (ahead != '\0')
                        {
                            switch (ahead)
                            {
                            case '>':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.BitwiseShiftRight, cr.GetPositionInfo(cr.Position - 2)));

                            case '=':
                                cr.AdvancePosition(2);
                                return(new Token(Token.TokenKind.CompareGreaterEqual, cr.GetPositionInfo(cr.Position - 2)));
                            }
                        }
                    }
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.CompareGreater, cr.GetPositionInfo(cr.Position - 1)));

                    case '?':
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.Conditional, cr.GetPositionInfo(cr.Position - 1)));

                    default:
                        cr.AdvancePosition();
                        return(new Token(Token.TokenKind.Error, c.ToString(), cr.GetPositionInfo(cr.Position - 1)));
                    }
                }
                else
                {
                    // Identifier
                    return(ReadIdentifier(cr));
                }
            }
Exemple #3
0
            private static Token ReadStringLiteral(CodeReader cr)
            {
                StringBuilder sb = new StringBuilder();

                int  index = cr.Position;
                char type  = cr.PeekChar();

                cr.AdvancePosition();

                char c  = cr.PeekChar();
                char c2 = cr.PeekCharAhead();

                while (!cr.EOF)
                {
                    switch (c)
                    {
                    // Escape character
                    case '\\':
                        if (cr.compileContext.Data?.IsGameMaker2() == false)
                        {
                            sb.Append(c);
                            cr.AdvancePosition();
                            c  = cr.PeekChar();
                            c2 = cr.PeekCharAhead();
                            continue;
                        }
                        cr.AdvancePosition();
                        c  = cr.PeekChar();
                        c2 = cr.PeekCharAhead();
                        switch (c)
                        {
                        case 'a':
                            sb.Append('\a');
                            break;

                        case 'n':
                            sb.Append('\n');
                            break;

                        case 'r':
                            sb.Append('\r');
                            break;

                        case 't':
                            sb.Append('\t');
                            break;

                        case 'v':
                            sb.Append('\v');
                            break;

                        case 'f':
                            sb.Append('\f');
                            break;

                        case 'b':
                            sb.Append('\b');
                            break;

                        case '\n':
                            break;

                        case 'u':
                        {
                            int calc = 0;
                            for (int i = 0; i < 4 && (IsHexCharacter(c2)); i++)
                            {
                                calc *= 16;
                                calc  = (!char.IsDigit(c2)) ? (calc + char.ToLower(c2) - 87) : (calc + c2 - 48);
                                cr.AdvancePosition();
                                c  = cr.PeekChar();
                                c2 = cr.PeekCharAhead();
                            }
                            sb.Append((char)(ushort)calc);
                        }
                        break;

                        case 'x':
                            cr.AdvancePosition();
                            c  = cr.PeekChar();
                            c2 = cr.PeekCharAhead();
                            if (IsHexCharacter(c))
                            {
                                char[] arr = new char[2] {
                                    c, ' '
                                };
                                for (int i = 1; i < 2; i++)
                                {
                                    if (!IsHexCharacter(c2))
                                    {
                                        break;
                                    }
                                    c      = cr.PeekChar();
                                    c2     = cr.PeekCharAhead();
                                    arr[i] = c;
                                }
                                char value = (char)Convert.ToInt32(new string(arr), 16);
                                sb.Append(value);
                            }
                            break;

                        default:
                            if (c >= '0' && c <= '7')
                            {
                                // Octal
                                StringBuilder sb2 = new StringBuilder();
                                sb2.Append(c);
                                for (int i = 1; i < 3; i++)
                                {
                                    if (c2 < '0' || c > '7')
                                    {
                                        break;
                                    }
                                    cr.AdvancePosition();
                                    c = cr.PeekChar();
                                    if (c == '\0')
                                    {
                                        c = ' ';
                                    }
                                    c2 = cr.PeekCharAhead();
                                    if (c2 == '\0')
                                    {
                                        c2 = ' ';
                                    }

                                    sb2.Append(c);
                                }
                                sb.Append(Convert.ToInt32(sb2.ToString(), 8));
                            }
                            else
                            {
                                sb.Append(c);
                            }
                            break;
                        }
                        cr.AdvancePosition();
                        c  = cr.PeekChar();
                        c2 = cr.PeekCharAhead();
                        continue;

                    default:
                        if (c == type)
                        {
                            break;
                        }
                        sb.Append(c);
                        cr.AdvancePosition();
                        c  = cr.PeekChar();
                        c2 = cr.PeekCharAhead();
                        continue;
                    }
                    break;
                }

                cr.AdvancePosition();

                return(new Token(Token.TokenKind.String, sb.ToString(), cr.GetPositionInfo(index)));
            }