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)); }
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())); }