Skip to content

Commit

Permalink
feat: Add calling functions from the same type
Browse files Browse the repository at this point in the history
  • Loading branch information
furesoft committed Dec 26, 2024
1 parent a517013 commit d337b34
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 22 deletions.
77 changes: 55 additions & 22 deletions NewSource/SocordiaC/Compilation/Body/CallExpressionListener.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DistIL.AsmIO;
using DistIL.IR;
using MrKWatkins.Ast.Listening;
using Socordia.CodeAnalysis.AST;
using Socordia.CodeAnalysis.AST.Expressions;
Expand All @@ -12,6 +13,47 @@ protected override void ListenToNode(BodyCompilation context, CallExpression nod
{
var args = node.Arguments.Select(Utils.CreateValue);

if (CreateStaticExternalCall(context, node, args)) return;
if (CreateStaticContainingTypeCalls(context, node, args)) return;
if (CreatePrintCalls(context, node, args)) return;

node.AddError("Function not found");
}

private static bool CreateStaticContainingTypeCalls(BodyCompilation context, CallExpression node, IEnumerable<Value> args)
{
var candidates = GetStaticMethodCandidates(node, args, context.Builder.Method.Definition.DeclaringType);
if (candidates.Length == 0)
{
return false;
}

var method = candidates[0];
context.Builder.CreateCall(method, [.. args]);
return true;
}

private static bool CreatePrintCalls(BodyCompilation context, CallExpression node, IEnumerable<Value> args)
{
if (node.Callee.Name == "print")
{
var method = context.Driver.Compilation.Module.Resolver.FindMethod("System.Console::Write", [.. args]);
context.Builder.CreateCall(method, [.. args]);
return true;
}

if (node.Callee.Name == "println")
{
var method = context.Driver.Compilation.Module.Resolver.FindMethod("System.Console::WriteLine", [.. args]);
context.Builder.CreateCall(method, [.. args]);
return true;
}

return false;
}

private static bool CreateStaticExternalCall(BodyCompilation context, CallExpression node, IEnumerable<Value> args)
{
if (node.Parent is BinaryOperator { Operator: "'::", Left: BinaryOperator typeNode })
{
var typename = new QualifiedTypeName(typeNode);
Expand All @@ -20,15 +62,10 @@ protected override void ListenToNode(BodyCompilation context, CallExpression nod
if (type == null)
{
typename.AddError("Type not found");
return;
return true;
}

var candidates = type.Methods
.Where(m => m.Name == node.Callee.Name)
.Where(m => m.ParamSig.Count == node.Arguments.Count())
.Where(m => m.ParamSig.Zip(
args,
(p, a) => p.Type.IsAssignableTo(a.ResultType)).All(x => x)).ToArray();
var candidates = GetStaticMethodCandidates(node, args, type);

if (candidates.Length == 0)
{
Expand All @@ -37,23 +74,19 @@ protected override void ListenToNode(BodyCompilation context, CallExpression nod

var method = candidates[0];
context.Builder.CreateCall(method, [.. args]);
return;
}

if (node.Callee.Name == "print")
{
var method = context.Driver.Compilation.Module.Resolver.FindMethod("System.Console::Write", [.. args]);
context.Builder.CreateCall(method, [.. args]);
return;
return true;
}

if (node.Callee.Name == "println")
{
var method = context.Driver.Compilation.Module.Resolver.FindMethod("System.Console::WriteLine", [.. args]);
context.Builder.CreateCall(method, [.. args]);
return;
}
return false;
}

node.AddError("Function not found");
private static MethodDesc[] GetStaticMethodCandidates(CallExpression node, IEnumerable<Value> args, TypeDesc type)
{
return type.Methods
.Where(m => m.Name == node.Callee.Name && m.IsStatic)
.Where(m => m.ParamSig.Count == node.Arguments.Count())
.Where(m => m.ParamSig.Zip(
args,
(p, a) => p.Type.IsAssignableTo(a.ResultType)).All(x => x)).ToArray();
}
}
1 change: 1 addition & 0 deletions NewSource/SocordiaC/compilation.sc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ func main() -> none {
print("hello");
println("world");
System.Console::WriteLine("Hello World!");
test(42, true);
}

private func test(hello: i32, flag: bool) -> i32
Expand Down

0 comments on commit d337b34

Please sign in to comment.