diff --git a/NewSource/Socordia.CodeAnalysis/AST/Declarations/FunctionDefinition.cs b/NewSource/Socordia.CodeAnalysis/AST/Declarations/FunctionDefinition.cs index 00e60790..9760cab5 100644 --- a/NewSource/Socordia.CodeAnalysis/AST/Declarations/FunctionDefinition.cs +++ b/NewSource/Socordia.CodeAnalysis/AST/Declarations/FunctionDefinition.cs @@ -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(nameof(IsExpressionBody)); + public Signature Signature => (Signature)Children[0]; public Block? Body => (Block?)Children[1]; } \ No newline at end of file diff --git a/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/Declarations/FunctionDefinitionParser.cs b/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/Declarations/FunctionDefinitionParser.cs index 241f68fe..80f0b122 100644 --- a/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/Declarations/FunctionDefinitionParser.cs +++ b/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/Declarations/FunctionDefinitionParser.cs @@ -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); @@ -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); } } diff --git a/NewSource/SocordiaC/Compilation/CollectFunctionsListener.cs b/NewSource/SocordiaC/Compilation/CollectFunctionsListener.cs index 84c127ee..7a0ee9d2 100644 --- a/NewSource/SocordiaC/Compilation/CollectFunctionsListener.cs +++ b/NewSource/SocordiaC/Compilation/CollectFunctionsListener.cs @@ -53,22 +53,12 @@ private IEnumerable 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 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; diff --git a/NewSource/SocordiaC/Compilation/OperatorOverloadingHelpers.cs b/NewSource/SocordiaC/Compilation/OperatorOverloadingHelpers.cs index 68788dc5..e083c8a0 100644 --- a/NewSource/SocordiaC/Compilation/OperatorOverloadingHelpers.cs +++ b/NewSource/SocordiaC/Compilation/OperatorOverloadingHelpers.cs @@ -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() + 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 @@ -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) { diff --git a/NewSource/SocordiaC/Compilation/Utils.cs b/NewSource/SocordiaC/Compilation/Utils.cs index 0a7c43d3..e8ef69a1 100644 --- a/NewSource/SocordiaC/Compilation/Utils.cs +++ b/NewSource/SocordiaC/Compilation/Utils.cs @@ -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) diff --git a/NewSource/SocordiaC/Driver.cs b/NewSource/SocordiaC/Driver.cs index 8dc6f4b3..e9ad7512 100644 --- a/NewSource/SocordiaC/Driver.cs +++ b/NewSource/SocordiaC/Driver.cs @@ -50,7 +50,7 @@ public string GetNamespaceOf(AstNode node) return node.Parent.Children.OfType().FirstOrDefault()?.Canonicalize() ?? Settings.RootNamespace; } - public void Compile() + public async Task Compile() { var hasError = () => PrintErrorsStage.Errors.Count >= 0; @@ -65,47 +65,10 @@ public void Compile() cfg.Add(); cfg.Add(); - - /*cfg.When(_ => !hasError(_.Messages) && _.Options.OutputTree, _ => { - _.Add(); - }); - - cfg.When(_ => !hasError(_.Messages), _ => { - _.Add(); - }); - - cfg.When(_ => !hasError(_.Messages), _ => { - _.Add(); - }); - - cfg.When(_ => !hasError(_.Messages), _ => { - _.Add(); - }); - - cfg.When(_ => !hasError(_.Messages), _ => { - _.Add(); - }); - - cfg.When(_ => !hasError(_.Messages), _ => { - _.Add(); - }); - - cfg.When(_ => !hasError(_.Messages), _ => { - _.Add(); - }); - - cfg.When(_ => !hasError(_.Messages), _ => { - _.Add(); - }); - - cfg.When(_ => _.Messages.Any(), _ => { - _.Add(); - }); - */ } ); - pipeline.Invoke(this); + await pipeline.Invoke(this); } public TypeDef GetFunctionType(string ns) diff --git a/NewSource/SocordiaC/Program.cs b/NewSource/SocordiaC/Program.cs index 48c8fcc4..38c8f715 100644 --- a/NewSource/SocordiaC/Program.cs +++ b/NewSource/SocordiaC/Program.cs @@ -7,11 +7,18 @@ public static class Program public static void Main(string[] args) { Parser.Default.ParseArguments(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 => { diff --git a/NewSource/SocordiaC/Stages/CompileFunctionsStage.cs b/NewSource/SocordiaC/Stages/CompileFunctionsStage.cs index 66c1fde7..176a978c 100644 --- a/NewSource/SocordiaC/Stages/CompileFunctionsStage.cs +++ b/NewSource/SocordiaC/Stages/CompileFunctionsStage.cs @@ -1,3 +1,4 @@ +using DistIL.AsmIO; using DistIL.CodeGen.Cil; using DistIL.IR; using DistIL.IR.Utils; @@ -23,7 +24,17 @@ public async Task HandleAsync(Driver context, Func> 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); diff --git a/NewSource/SocordiaC/compilation.sc b/NewSource/SocordiaC/compilation.sc index 11cb0bcb..8dd6d3c0 100644 --- a/NewSource/SocordiaC/compilation.sc +++ b/NewSource/SocordiaC/compilation.sc @@ -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 {