diff --git a/NewSource/Socordia.CodeAnalysis/AST/Statements/ReturnStatement.cs b/NewSource/Socordia.CodeAnalysis/AST/Statements/ReturnStatement.cs index ce59d8f4..865077df 100644 --- a/NewSource/Socordia.CodeAnalysis/AST/Statements/ReturnStatement.cs +++ b/NewSource/Socordia.CodeAnalysis/AST/Statements/ReturnStatement.cs @@ -7,5 +7,5 @@ public ReturnStatement(AstNode expression) Children.Add(expression); } - public AstNode Expression => Children.First; + public AstNode Value => Children.First; } \ 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 1ed5a565..241f68fe 100644 --- a/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/Declarations/FunctionDefinitionParser.cs +++ b/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/Declarations/FunctionDefinitionParser.cs @@ -1,5 +1,6 @@ using Socordia.CodeAnalysis.AST; using Socordia.CodeAnalysis.AST.Declarations; +using Socordia.CodeAnalysis.AST.Statements; namespace Socordia.CodeAnalysis.Parsing.ParsePoints.Declarations; @@ -10,6 +11,21 @@ public static AstNode Parse(TokenIterator iterator, Parser parser) var keywordToken = iterator.Prev; var signature = SignatureParser.Parse(parser); - return new FunctionDefinition(signature, Statements.Statement.ParseBlock(parser)); + Block body = null; + if (iterator.IsMatch(TokenType.OpenCurly)) + { + body = Statements.Statement.ParseBlock(parser); + } + else if (iterator.ConsumeIfMatch(TokenType.Arrow)) + { + body = new Block([new ReturnStatement(Expression.Parse(parser))]); + iterator.Match(TokenType.Semicolon); + } + else + { + signature.AddError("Function body is missing"); + } + + return new FunctionDefinition(signature, body); } } diff --git a/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/SignatureParser.cs b/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/SignatureParser.cs index 30e6df71..bceda527 100644 --- a/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/SignatureParser.cs +++ b/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/SignatureParser.cs @@ -37,13 +37,13 @@ public static Signature Parse(Parser parser) //generics.Add(LNode.Call(Symbols.Where, LNode.List(genericName, LNode.Call(CodeSymbols.Base, bases)))); } - if (iterator.IsMatch(TokenType.Arrow)) + if (iterator.IsMatch(TokenType.Colon)) { iterator.NextToken(); returnType = TypeNameParser.Parse(parser); } - return SyntaxTree.Signature(name, returnType, parameters, generics); + return new Signature(name, returnType, parameters, generics); } } \ No newline at end of file diff --git a/NewSource/Socordia.CodeAnalysis/Parsing/SyntaxTree.cs b/NewSource/Socordia.CodeAnalysis/Parsing/SyntaxTree.cs index 58f00de6..ae0b782f 100644 --- a/NewSource/Socordia.CodeAnalysis/Parsing/SyntaxTree.cs +++ b/NewSource/Socordia.CodeAnalysis/Parsing/SyntaxTree.cs @@ -145,11 +145,6 @@ public static LNode NullableType(LNode type) return Factory.Call(Symbols.NullableType, LNode.List(type)); } - public static Signature Signature(AstNode name, AstNode type, List parameters, List generics) - { - return new Signature(name, type, parameters, generics); - } - public static AstNode SizeOf(AstNode type) { return new SizeOf(type); diff --git a/NewSource/SocordiaC/Compilation/Body/BodyCompilation.cs b/NewSource/SocordiaC/Compilation/Body/BodyCompilation.cs index 531c18c2..ad3401fb 100644 --- a/NewSource/SocordiaC/Compilation/Body/BodyCompilation.cs +++ b/NewSource/SocordiaC/Compilation/Body/BodyCompilation.cs @@ -11,5 +11,6 @@ public record BodyCompilation(Driver Driver, MethodDef Method, IRBuilder Builder CompositeListener.Build() .With(new VariableDeclarationListener()) .With(new CallExpressionListener()) + .With(new ReturnStatementListener()) .ToListener(); } \ No newline at end of file diff --git a/NewSource/SocordiaC/Compilation/Body/ReturnStatementListener.cs b/NewSource/SocordiaC/Compilation/Body/ReturnStatementListener.cs new file mode 100644 index 00000000..b33a0519 --- /dev/null +++ b/NewSource/SocordiaC/Compilation/Body/ReturnStatementListener.cs @@ -0,0 +1,15 @@ +using DistIL.IR; +using MrKWatkins.Ast.Listening; +using Socordia.CodeAnalysis.AST; +using Socordia.CodeAnalysis.AST.Statements; + +namespace SocordiaC.Compilation.Body; + +public class ReturnStatementListener : Listener +{ + protected override void ListenToNode(BodyCompilation context, ReturnStatement node) + { + var value = Utils.CreateValue(node.Value); + context.Builder.Emit(new ReturnInst(value)); + } +} \ No newline at end of file diff --git a/NewSource/SocordiaC/Compilation/CollectFunctionsListener.cs b/NewSource/SocordiaC/Compilation/CollectFunctionsListener.cs index 8ac98d2f..be0df933 100644 --- a/NewSource/SocordiaC/Compilation/CollectFunctionsListener.cs +++ b/NewSource/SocordiaC/Compilation/CollectFunctionsListener.cs @@ -1,22 +1,30 @@ using System.Reflection; using DistIL.AsmIO; +using DistIL.IR; using MrKWatkins.Ast.Listening; using Socordia.CodeAnalysis.AST; using Socordia.CodeAnalysis.AST.Declarations; +using Socordia.CodeAnalysis.AST.Statements; using MethodBody = DistIL.IR.MethodBody; namespace SocordiaC.Compilation; public class CollectFunctionsListener() : Listener { + private TypeDesc GetReturnType(FunctionDefinition node, TypeDef type) + { + return Utils.GetTypeFromNode(node.Signature.ReturnType, type); + } + protected override void ListenToNode(Driver context, FunctionDefinition node) { var attrs = GetModifiers(node); var type = context.GetFunctionType(context.GetNamespaceOf(node)); var parameters = GetParameters(node, type); + var returnType = GetReturnType(node, type); var method = type.CreateMethod(node.Signature.Name.Name, - Utils.GetTypeFromNode(node.Signature.ReturnType, type), [..parameters], attrs); + returnType, [..parameters], attrs); if (!node.Modifiers.Contains(Modifier.Extern)) { diff --git a/NewSource/SocordiaC/compilation.sc b/NewSource/SocordiaC/compilation.sc index bcc9a027..977f4ed2 100644 --- a/NewSource/SocordiaC/compilation.sc +++ b/NewSource/SocordiaC/compilation.sc @@ -1,6 +1,6 @@ module TestSuite; -func main() -> none { +func main(): none { let myFlag = true; print("hello"); @@ -9,22 +9,19 @@ func main() -> none { test(42, true); } -private func test(hello: i32, flag: bool) -> i32 -{ - -} +private func test(hello: i32, flag: bool): i32 -> 42; -func complex() -> Functions +func complex(): Functions { } -func external() -> System.Text.StringBuilder +func external(): System.Text.StringBuilder { } -func internal_type() -> Hello +func internal_type(): Hello { }