Exemple #1
0
    DeclFuncAst DeclFunc(string[] metadata, Visibility visibility, bool mutable, TypeAst retType, Token name)
    {
        scope.DefineFunc(name.text);
        List <ParamAst> paramz = new List <ParamAst>();

        Match(TokenKind.LeftParen);
        bool vaArg = false;

        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);
            if (current.kind is not TokenKind.RightParen)
            {
                Match(TokenKind.Comma);
            }
        }

        Match(TokenKind.RightParen);

        string asmName;

        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("Syf$");
            sb.Append(name.text);
            foreach (ParamAst param in paramz)
            {
                sb.Append(';');
                sb.Append(param.type.name);
            }

            asmName = sb.ToString();
        }

        MaybeEndLine();

        // TODO: class fn decls
        return(new DeclFuncAst(metadata, visibility, mutable, retType, name, asmName, paramz.ToArray(), vaArg));
    }
Exemple #2
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()));
    }