public IEnumerable <FnDecl> FindMatchingSignatures(FnCall call) { var matches = FnDecls.Where(x => x.Id.Text == call.Id.Text).ToArray(); foreach (var fn in matches) { // Check parameter counts. if (fn.Params.Count == call.Args.Count) { var all = true; // Check parameter types. for (int i = 0; i < fn.Params.Count; i++) { var param = fn.Params[i]; var arg = call.Args[i]; if (param.TypeDecl != arg.TypeDecl) { all = false; break; } } if (all) { yield return(fn); } } } }
public FnDecl?FindFn(FnCall call, bool thisBlockOnly = false) { if (call.ParentAccess != null && !thisBlockOnly) { return(call.ParentAccess.Left.TypeDecl.Body.FindFn(call, thisBlockOnly: true)); } var matches = FindMatchingSignatures(call).ToArray(); if (matches.Length == 0) { if (Parent == null || thisBlockOnly) { return(null); } return(Parent.FindFn(call)); } return(matches.Single()); }
public static void Emit(TranspilerStream stream, ast.FnCall fn, bool forward) { if (fn.Id.Text == "#cpp" || fn.Id.Text == "#cpp_forward" && forward) { // Writes C++ code directly, like a macro, in the forward declaration. foreach (var arg in fn.Args) { if (arg is ast.StrExpr expr) { stream.WriteLine( expr.Value.Text.Substring(1, expr.Value.Text.Length - 2) .Replace("#__", Compiler.Prefix)); } else { throw new CompileError(arg.Token, "#cpp only takes string literals"); } } } }