示例#1
0
    ClassAst Class(string[] metadata, Visibility visibility)
    {
        Match(TokenKind.ClassKeyword);
        Token name = Match(TokenKind.Identifier);

        Match(TokenKind.LeftBrace);

        List <FieldAst> fields = new List <FieldAst>();

        while (current.kind is not TokenKind.Eof and not TokenKind.Semicol)
        {
            int start = pos;
            fields.Add(Field(fields));

            // maybe made function?
            if (current.kind is TokenKind.LeftParen)
            {
                BadCode.Report(new SyntaxError("func is not field", tokens[start]));
                break;
            }

            if (current.kind is not TokenKind.Semicol)
            {
                Match(TokenKind.Comma);
            }
        }

        EndLine();

        List <FuncAst> funcs = new List <FuncAst>();

        while (current.kind is not TokenKind.Eof and not TokenKind.RightBrace)
        {
            funcs.Add(Func(name.text, fields.ToArray()));
        }

        Match(TokenKind.RightBrace);
        MaybeEndLine();
        var clazz = new ClassAst(metadata, visibility, name, fields.ToArray(), funcs.ToArray());

        ctnrs.Add(clazz);
        return(clazz);
    }
示例#2
0
    LiteralExprAst LiteralExpr()
    {
        switch (current.kind)
        {
        case TokenKind.Str:
            return(new StrLiteralExprAst(current, Next().text));

        case TokenKind.CStr:
            return(new CStrLiteralExprAst(current, Next().text));

        case TokenKind.Char:
            return(new CharLiteralExprAst(current, Next().text[0], 8));

        case TokenKind.NullKeyword:
            return(new NullLiteralExprAst(Next()));

        case TokenKind.Hex:
            return(new IntLiteralExprAst(current, ulong.Parse(Next().text, NumberStyles.HexNumber)));

        case TokenKind.FHex:
            return(new FloatLiteralExprAst(current, double.Parse(Next().text, NumberStyles.HexNumber)));

        case TokenKind.Int:
            return(new IntLiteralExprAst(current, ulong.Parse(Next().text, NumberStyles.Integer)));

        case TokenKind.Float:
            return(new FloatLiteralExprAst(current, double.Parse(Next().text, NumberStyles.Float)));

        case TokenKind.TrueKeyword:
            Next();
            return(new BoolLiteralExprAst(current, true));

        case TokenKind.FalseKeyword:
            Next();
            return(new BoolLiteralExprAst(current, false));

        default:
            BadCode.Report(new SyntaxError("not a literal", current));
            return(new LiteralExprAst(current));
        }
    }
示例#3
0
    public Parser(string source, string file)
    {
        scope    = new Scope(this);
        folder   = Path.GetFileName(Path.GetDirectoryName(file) !);
        filename = Path.GetFileName(file);
        parsers.Add(folder + filename, this);

        Preprocessor preprocessor = new Preprocessor(source, folder, filename);

        tokens = preprocessor.PreProcess();

        foreach (Token token in tokens)
        {
            if (token.kind is TokenKind.Unknown)
            {
                BadCode.Report(new SyntaxError("unrecognized token", token));
            }
            else if (token.kind is TokenKind.HashTag)
            {
                throw new Exception("preprocessor directive after preprocessing!!");
            }
        }
    }
示例#4
0
    BreakStmtAst Break()
    {
        Token keywrd = Match(TokenKind.BreakKeyword);
        int   depth  = 1;

        if (current.kind is not TokenKind.Semicol)
        {
            Token depthKwrd = Next();
            if (depthKwrd.kind is not TokenKind.Int)
            {
                BadCode.Report(new SyntaxError("expected positive integer above 0", depthKwrd));
                MaybeEndLine();
                return(new BreakStmtAst(keywrd, depth));
            }

            depth = int.Parse(depthKwrd.text);
            if (depth <= 0)
            {
                BadCode.Report(new SyntaxError("expected positive integer above 0", depthKwrd));
            }
        }
        EndLine();
        return(new BreakStmtAst(keywrd, depth));
    }
示例#5
0
    ExprAst PrimExpr()
    {
        switch (current.kind)
        {
        case TokenKind.Percent:
            Token op = Next();
            return(new PreExprAst(PreOpcode(op.kind), op, PrimExpr()));

        case TokenKind.Identifier:
        {
            if (scope.VarExists(current.text))
            {
                return(new VarExprAst(Next()));
            }

            if (current.text is "stalloc")
            {
                return(StallocExpr());
            }
            if (current.text is "sizeof")
            {
                return(SizeofExpr());
            }

            if (scope.FuncExists(current.text))             // fnptr overloads
            {
                return(new FuncPtrAst(Next()));
            }
            if (!IsType(current))
            {
                BadCode.Report(new SyntaxError($"symbol '{current.text}' doesn't exist", current));
            }
            TypeAst type = Type();
            if (current.kind is TokenKind.LeftBracket)
            {
                return(ArrayExpr(eleType: type));
            }
            return(GroupExpr(groupType: type));
        }

        case TokenKind.LeftParen:
            Next();
            if (IsType(current))
            {
                TypeAst to    = Type();
                Token   open  = Match(TokenKind.RightParen);
                ExprAst value = PreExpr();
                return(new CastExprAst(value, open, to));
            }
            ExprAst expr = Expr();
            Match(TokenKind.RightParen);
            return(expr);

        case TokenKind.LeftBracket:
            if (IsType(next))
            {
                Next();
                TypeAst to    = Type();
                Token   open  = Match(TokenKind.RightBracket);
                ExprAst value = PreExpr();
                return(new BitCastExprAst(value, open, to));
            }
            return(ArrayExpr());

        default:
            return(LiteralExpr());
        }
    }