diff options
Diffstat (limited to 'Compiler/FunctionReference.cs')
| -rw-r--r-- | Compiler/FunctionReference.cs | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/Compiler/FunctionReference.cs b/Compiler/FunctionReference.cs new file mode 100644 index 0000000..cf120ad --- /dev/null +++ b/Compiler/FunctionReference.cs @@ -0,0 +1,129 @@ +namespace Q1.Compiler; + +using System.Reflection.Metadata; +using System.Text; + +public class FunctionReference +{ + // TODO: Implement return type + public string Name; + public string Type; + public List<FunctionOverload> Overloads = new(); + + public FunctionReference(string name, string type) + { + this.Type = type; + this.Name = name; + } + + public string GetBranchName(FunctionOverload overload) + { + List<(string paramName, string paramType)> parameters = overload + .ParameterNames + .Zip(overload.ParameterTypes) + .ToList(); + + StringBuilder branchName = new(); + branchName.Append($"_{this.Name}"); + + if (parameters.Count > 0) + { + branchName.Append($"_{string.Join("__", parameters + .Select(x => $"{x.paramType}_{x.paramName}"))}"); + } + + return branchName.ToString(); + } + + public string GetBranchFriendlyName(FunctionOverload overload) + { + List<(string paramName, string paramType)> parameters = overload + .ParameterNames + .Zip(overload.ParameterTypes) + .ToList(); + + StringBuilder branchName = new(); + branchName.Append($"{this.Type} {this.Name}"); + branchName.Append("("); + + branchName.Append(string.Join(", ", parameters + .Select(x => $"{x.paramType} {x.paramName}"))); + + branchName.Append(")"); + + return branchName.ToString(); + } + + public FunctionOverload CreateOverloadWithBody(List<string> parameterNames, List<string> parameterTypes) + { + FunctionOverload? existingOverload = this.Overloads + .FirstOrDefault(x => x.ParamsMatch(parameterNames, parameterTypes)); + + if (existingOverload != null) + { + if (existingOverload.BodyImplemented) + throw new CompilerException($"Cannot define another overload for {this.Name}," + + $" as one with an identical signature and body already exists."); + + existingOverload.BodyImplemented = true; + return existingOverload; + } + else + { + FunctionOverload newOverload = new(parameterNames, parameterTypes, true); + this.Overloads.Add(newOverload); + return newOverload; + } + } + + public FunctionOverload CreateOverloadWithoutBody(List<string> parameterNames, List<string> parameterTypes) + { + FunctionOverload? existingOverload = this.Overloads + .FirstOrDefault(x => x.ParamsMatch(parameterNames, parameterTypes)); + + if (existingOverload != null) + { + if (!existingOverload.BodyImplemented) + throw new CompilerException($"Cannot prototype another overload for {this.Name}," + + $" as one with an identical signature already exists."); + return existingOverload; + } + else + { + FunctionOverload newOverload = new(parameterNames, parameterTypes, false); + this.Overloads.Add(newOverload); + return newOverload; + } + } + public FunctionOverload GetOverload(int paramsCount) + { + FunctionOverload? overload = this.Overloads + .FirstOrDefault(x => x.ParameterTypes.Count == paramsCount); + + if (overload != null) + return overload; + + throw new CompilerException($"Overload for {this.Name} with {paramsCount} arguments could not be found."); + } +} + +public class FunctionOverload +{ + // TODO: Implement return type + public List<string> ParameterTypes; + public List<string> ParameterNames; + public bool BodyImplemented; + + public FunctionOverload(List<string> parameterNames, List<string> parameterTypes, bool bodyImplemented) + { + this.ParameterTypes = parameterTypes; + this.ParameterNames = parameterNames; + this.BodyImplemented = bodyImplemented; + } + + public bool ParamsMatch(List<string> parameterNames, List<string> parameterTypes) + { + return this.ParameterNames.SequenceEqual(parameterNames) + && this.ParameterTypes.SequenceEqual(parameterTypes); + } +}
\ No newline at end of file |
