Skip to content

Commit

Permalink
fix: expression body function
Browse files Browse the repository at this point in the history
  • Loading branch information
furesoft committed Dec 29, 2024
1 parent 91b062e commit f324b0a
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ namespace Socordia.CodeAnalysis.AST.Declarations;

public class FunctionDefinition : Declaration
{
public FunctionDefinition(Signature signature, Block? body)
public FunctionDefinition(Signature signature, bool isExpressionBody, Block? body)
{
Children.Add(signature);
Children.Add(body);
Properties.Set(nameof(IsExpressionBody), isExpressionBody);
}

public bool IsExpressionBody => (bool)Properties.GetOrDefault<bool>(nameof(IsExpressionBody));

public Signature Signature => (Signature)Children[0];
public Block? Body => (Block?)Children[1];
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public static AstNode Parse(TokenIterator iterator, Parser parser)
var signature = SignatureParser.Parse(parser);

Block body = null;
bool isExpressionBody = false;
if (iterator.IsMatch(TokenType.OpenCurly))
{
body = Statements.Statement.ParseBlock(parser);
Expand All @@ -20,12 +21,13 @@ public static AstNode Parse(TokenIterator iterator, Parser parser)
{
body = new Block([new ReturnStatement(Expression.Parse(parser))]);
iterator.Match(TokenType.Semicolon);
isExpressionBody = true;
}
else
{
signature.AddError("Function body is missing");
}

return new FunctionDefinition(signature, body);
return new FunctionDefinition(signature, isExpressionBody, body);
}
}
10 changes: 0 additions & 10 deletions NewSource/SocordiaC/Compilation/CollectFunctionsListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,12 @@ private IEnumerable<ParamDef> GetParameters(FunctionDefinition node, TypeDef typ
DefaultValue = Utils.GetLiteralValue(param.DefaultValue)
};

AddUnitAttribute(context, paramDef.GetCustomAttribs(false), param.Type, type);
result.Add(paramDef);
}

return result;
}

private static void AddUnitAttribute(Driver context, IList<CustomAttrib> attribs, TypeName paramType, TypeDef containingType)
{
if (paramType is UnitTypeName unit)
{
var unitType = Utils.GetTypeFromNode(unit, containingType);
attribs.Add(new CustomAttrib(context.KnownAttributes.UnitAttributeCtor, [])); //todo: use unittype if its implemented internally
}
}

private ParameterAttributes GetParameterAttributes(ParameterDeclaration node)
{
ParameterAttributes result = 0;
Expand Down
13 changes: 9 additions & 4 deletions NewSource/SocordiaC/Compilation/OperatorOverloadingHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,17 @@ public static class OperatorOverloadingHelpers
["default"] = "op_Default"
}.ToImmutableDictionary();

public static bool TryGetOperator(this TypeDesc type, string op, out MethodDef? opMethod, params TypeDefOrSpec[] args)
public static bool TryGetOperator(this TypeDesc type, string op, out MethodDesc? opMethod, params TypeDefOrSpec[] args)
{
var possibleMethods = type.Methods.Cast<MethodDef>()
if (type is PrimType)
{
opMethod = null;
return false;
}

var possibleMethods = type.Methods
.Where(_ => _ is { IsStatic: true, IsConstructor: false, IsDestructor: false, IsPublic: true }
&& _.Attribs.HasFlag(MethodAttributes.SpecialName)
&& _.Params.Length == args.Length
);

var nameMap = args.Length switch
Expand All @@ -58,7 +63,7 @@ public static bool TryGetOperator(this TypeDesc type, string op, out MethodDef?
for (var i = 0; i < args.Length; i++)
{
var arg = args[i];
var param = method.Params[i].Type;
var param = method.ParamSig[i].Type;

if (arg != param)
{
Expand Down
4 changes: 1 addition & 3 deletions NewSource/SocordiaC/Compilation/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ public static class Utils
return null;
}

var valueField = unitType.FindField("value__");

return valueField.Type;
return unitType;
}

if (node is SimpleTypeName id)
Expand Down
41 changes: 2 additions & 39 deletions NewSource/SocordiaC/Driver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public string GetNamespaceOf(AstNode node)
return node.Parent.Children.OfType<ModuleDeclaration>().FirstOrDefault()?.Canonicalize() ?? Settings.RootNamespace;
}

public void Compile()
public async Task Compile()
{
var hasError = () => PrintErrorsStage.Errors.Count >= 0;

Expand All @@ -65,47 +65,10 @@ public void Compile()
cfg.Add<PrintErrorsStage>();

cfg.Add<SaveModuleStage>();

/*cfg.When(_ => !hasError(_.Messages) && _.Options.OutputTree, _ => {
_.Add<EmitTreeStage>();
});
cfg.When(_ => !hasError(_.Messages), _ => {
_.Add<InitStage>();
});
cfg.When(_ => !hasError(_.Messages), _ => {
_.Add<IntermediateStage>();
});
cfg.When(_ => !hasError(_.Messages), _ => {
_.Add<TypeInheritanceStage>();
});
cfg.When(_ => !hasError(_.Messages), _ => {
_.Add<ExpandImplementationStage>();
});
cfg.When(_ => !hasError(_.Messages), _ => {
_.Add<ImplementationStage>();
});
cfg.When(_ => !hasError(_.Messages), _ => {
_.Add<InitEmbeddedResourcesStage>();
});
cfg.When(_ => !hasError(_.Messages), _ => {
_.Add<CompileTargetStage>();
});
cfg.When(_ => _.Messages.Any(), _ => {
_.Add<ReportErrorStage>();
});
*/
}
);

pipeline.Invoke(this);
await pipeline.Invoke(this);
}

public TypeDef GetFunctionType(string ns)
Expand Down
13 changes: 10 additions & 3 deletions NewSource/SocordiaC/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ public static class Program
public static void Main(string[] args)
{
Parser.Default.ParseArguments<DriverSettings>(args)
.WithParsed(options =>
.WithParsed(async void (options) =>
{
var driver = Driver.Create(options);
try
{
var driver = Driver.Create(options);

driver.Compile();
await driver.Compile();
}
catch (Exception e)
{
throw; // TODO handle exception
}
})
.WithNotParsed(errors =>
{
Expand Down
13 changes: 12 additions & 1 deletion NewSource/SocordiaC/Stages/CompileFunctionsStage.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using DistIL.AsmIO;
using DistIL.CodeGen.Cil;
using DistIL.IR;
using DistIL.IR.Utils;
Expand All @@ -23,7 +24,17 @@ public async Task<Driver> HandleAsync(Driver context, Func<Driver, Task<Driver>>
else
{
BodyCompilation.Listener.Listen(bodyCompilation, node);
builder.Emit(new ReturnInst());

if (node.IsExpressionBody && def.ReturnType == PrimType.Void)
{
var ret = (ReturnInst)bodyCompilation.Method.Body.EntryBlock.First;
ret.ReplaceWith(ret.Value);
}

if (def.ReturnType == PrimType.Void)
{
builder.Emit(new ReturnInst());
}
}

def.ILBody = ILGenerator.GenerateCode(def.Body);
Expand Down
1 change: 1 addition & 0 deletions NewSource/SocordiaC/compilation.sc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func main(): none {
}

private func test(hello: i32, flag: bool): i32 -> 42;
private func expressionBody(hello: i32, flag: bool): none -> print(42);

func complex(): Functions
{
Expand Down

0 comments on commit f324b0a

Please sign in to comment.