Example #1
0
    FuncAst Func(string[] metadata, Visibility visibility, bool mutable, TypeAst retType, Token name, string?asmName, bool asmNameIsName = true)
    {
        EnterScope();
        bool            vaArg  = false;
        List <ParamAst> paramz = new List <ParamAst>();

        Match(TokenKind.LeftParen);
        while (current.kind is not TokenKind.Eof and not TokenKind.RightParen)
        {
            if (current.kind is TokenKind.DotDotDot)
            {
                Next();
                vaArg = true;
                break;
            }

            ParamAst param = Param();

            paramz.Add(param);
            scope.DefineVar(param.name);
            if (current.kind is not TokenKind.RightParen)
            {
                Match(TokenKind.Comma);
            }
        }

        Match(TokenKind.RightParen);

        if (asmName is null || !asmNameIsName)
        {
            if (current.kind is TokenKind.Colon)
            {
                Next();
                asmName = Match(TokenKind.Str).text;
            }
            else if (metadata.Contains("naked"))
            {
                asmName = name.text;
            }
            else
            {
                StringBuilder sb = new StringBuilder(mutable ? "Symf$" : "Syf$");
                sb.Append(asmNameIsName ? name.text : asmName);
                foreach (ParamAst param in paramz)
                {
                    sb.Append(';');
                    sb.Append(param.type.name);
                }

                asmName = sb.ToString();
            }
        }

        // Single Expr Func
        if (current.kind is TokenKind.Arrow)
        {
            Next();
            ExprAst expr = Expr();
            MaybeEndLine();
            return(new FuncAst(metadata, visibility, mutable, retType, name, asmName ?? name.text, paramz.ToArray(), vaArg, new StmtAst[] { new RetStmtAst(Token.devault, expr) }));
        }

        List <StmtAst> body = new List <StmtAst>();

        Match(TokenKind.LeftBrace);
        while (current.kind is not TokenKind.Eof and not TokenKind.RightBrace)
        {
            body.Add(Stmt());
        }
        ExitScope();
        Match(TokenKind.RightBrace);

        MaybeEndLine();
        scope.DefineFunc(name.text);
        return(new FuncAst(metadata, visibility, mutable, retType, name, asmName ?? name.text, paramz.ToArray(), vaArg, body.ToArray()));
    }
Example #2
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());
        }
    }