diff --git a/NewSource/Socordia.CodeAnalysis/AST/Declarations/ClassDeclaration.cs b/NewSource/Socordia.CodeAnalysis/AST/Declarations/ClassDeclaration.cs index 5bc6f99d..52c23d7a 100644 --- a/NewSource/Socordia.CodeAnalysis/AST/Declarations/ClassDeclaration.cs +++ b/NewSource/Socordia.CodeAnalysis/AST/Declarations/ClassDeclaration.cs @@ -13,4 +13,17 @@ public ClassDeclaration(string name, List inheritances, List public string Name => Properties.GetOrThrow(nameof(Name)); public List Inheritances => Properties.GetOrThrow>(nameof(Inheritances)); +} + +public class EnumDeclaration : Declaration +{ + public EnumDeclaration(string name, TypeName baseType, List members) + { + Properties.Set(nameof(Name), name); + Properties.Set(nameof(BaseType), baseType); + Children.Add(members); + } + + public string Name => Properties.GetOrThrow(nameof(Name)); + public TypeName BaseType => Properties.GetOrThrow(nameof(BaseType)); } \ No newline at end of file diff --git a/NewSource/Socordia.CodeAnalysis/AST/Signature.cs b/NewSource/Socordia.CodeAnalysis/AST/Signature.cs index 577357cb..71642aa3 100644 --- a/NewSource/Socordia.CodeAnalysis/AST/Signature.cs +++ b/NewSource/Socordia.CodeAnalysis/AST/Signature.cs @@ -1,4 +1,5 @@ using Socordia.CodeAnalysis.AST.Declarations; +using Socordia.CodeAnalysis.AST.TypeNames; namespace Socordia.CodeAnalysis.AST; @@ -12,6 +13,6 @@ public Signature(AstNode name, AstNode? returnType, List p } public Identifier Name => (Identifier)Children[0]; - public AstNode? ReturnType => Children[1]; + public TypeName? ReturnType => (TypeName)Children[1]; public IEnumerable Parameters => Children.OfType(); } \ No newline at end of file diff --git a/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/Declarations/EnumDeclaration.cs b/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/Declarations/EnumDeclaration.cs index fb8722fa..7e2e6a8a 100644 --- a/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/Declarations/EnumDeclaration.cs +++ b/NewSource/Socordia.CodeAnalysis/Parsing/ParsePoints/Declarations/EnumDeclaration.cs @@ -1,18 +1,28 @@ -namespace Socordia.CodeAnalysis.Parsing.ParsePoints.Declarations; +using Socordia.CodeAnalysis.AST; +using Socordia.CodeAnalysis.AST.Declarations; +using Socordia.CodeAnalysis.AST.TypeNames; -/* -public sealed class EnumDeclaration : IParsePoint +namespace Socordia.CodeAnalysis.Parsing.ParsePoints.Declarations; + +public sealed class EnumDeclarationParser : IParsePoint { - public static LNode Parse(TokenIterator iterator, Parser parser) + public static AstNode Parse(TokenIterator iterator, Parser parser) { var keywordToken = iterator.Prev; + var nameToken = iterator.Match(TokenType.Identifier); + TypeName baseType = new SimpleTypeName("i32"); + if (iterator.ConsumeIfMatch(TokenType.Colon)) + { + baseType = TypeNameParser.Parse(parser); + } iterator.Match(TokenType.OpenCurly); - var members = ParsingHelpers.ParseSeperated(parser, TokenType.CloseCurly); + List members = []; //ParsingHelpers.ParseUntil(parser, TokenType.CloseCurly); + + iterator.Match(TokenType.CloseCurly); //remove if member parsing works - return SyntaxTree.Enum(LNode.Id(nameToken.Text), members).WithRange(keywordToken, iterator.Prev); + return new EnumDeclaration(nameToken.Text, baseType, members); } -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/NewSource/Socordia.CodeAnalysis/Parsing/Parser.ParsePoints.cs b/NewSource/Socordia.CodeAnalysis/Parsing/Parser.ParsePoints.cs index 713eca8e..49e2620d 100644 --- a/NewSource/Socordia.CodeAnalysis/Parsing/Parser.ParsePoints.cs +++ b/NewSource/Socordia.CodeAnalysis/Parsing/Parser.ParsePoints.cs @@ -21,10 +21,10 @@ public void InitParsePoints() //AddDeclarationParsePoint(TokenType.Union); AddDeclarationParsePoint(TokenType.Class); AddDeclarationParsePoint(TokenType.Function); + AddDeclarationParsePoint(TokenType.Enum); /* AddDeclarationParsePoint(TokenType.Constructor); AddDeclarationParsePoint(TokenType.Destructor); AddDeclarationParsePoint(TokenType.Type); - AddDeclarationParsePoint(TokenType.Enum); AddDeclarationParsePoint(TokenType.Macro); AddDeclarationParsePoint(TokenType.Interface); AddDeclarationParsePoint(TokenType.Implement);*/ diff --git a/NewSource/SocordiaC/Compilation/CollectClassesListener.cs b/NewSource/SocordiaC/Compilation/CollectClassesListener.cs index eda1724b..62da67c0 100644 --- a/NewSource/SocordiaC/Compilation/CollectClassesListener.cs +++ b/NewSource/SocordiaC/Compilation/CollectClassesListener.cs @@ -6,17 +6,16 @@ namespace SocordiaC.Compilation; -public class CollectClassesListener : Listener - where TNode : ClassDeclaration +public class CollectClassesListener : Listener { - protected override void ListenToNode(Driver context, TNode node) + protected override void ListenToNode(Driver context, ClassDeclaration node) { var type = context.Compilation.Module.CreateType(context.Settings.RootNamespace, node.Name, GetModifiers(node), GetBaseType(node, context.Compilation)); } - private TypeDefOrSpec? GetBaseType(TNode node, DistIL.Compilation compilation) + private TypeDefOrSpec? GetBaseType(ClassDeclaration node, DistIL.Compilation compilation) { if (node.Inheritances.Count == 0) { diff --git a/NewSource/SocordiaC/Compilation/CollectEnumListener.cs b/NewSource/SocordiaC/Compilation/CollectEnumListener.cs new file mode 100644 index 00000000..ab812cd1 --- /dev/null +++ b/NewSource/SocordiaC/Compilation/CollectEnumListener.cs @@ -0,0 +1,46 @@ +using System.Reflection; +using DistIL.AsmIO; +using MrKWatkins.Ast.Listening; +using Socordia.CodeAnalysis.AST; +using Socordia.CodeAnalysis.AST.Declarations; + +namespace SocordiaC.Compilation; + +public class CollectEnumListener : Listener +{ + protected override void ListenToNode(Driver context, EnumDeclaration node) + { + var type = context.Compilation.Module.CreateType(context.Settings.RootNamespace, node.Name, + GetModifiers(node), context.Compilation.Module.Resolver.Import(typeof(Enum))); + + type.CreateField("value__", new TypeSig(Utils.GetTypeFromNode(node.BaseType, type)), FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); + + // .field public static literal valuetype Color R = int32(0) + //type.CreateField("R", new TypeSig(type), FieldAttributes.Public | FieldAttributes.Literal | FieldAttributes.Static | FieldAttributes.HasDefault, 42); + } + + private TypeAttributes GetModifiers(Declaration node) + { + var attrs = TypeAttributes.Public; + + foreach (var modifier in node.Modifiers) + { + attrs |= modifier switch + { + Modifier.Static => TypeAttributes.Sealed | TypeAttributes.Abstract, + Modifier.Internal => TypeAttributes.NotPublic, + Modifier.Public => TypeAttributes.Public, + _ => throw new NotImplementedException() + }; + } + + if (node.Modifiers.Contains(Modifier.Private) || node.Modifiers.Contains(Modifier.Internal)) + { + attrs &= ~TypeAttributes.Public; + } + + return attrs | TypeAttributes.Sealed; + } + + protected override bool ShouldListenToChildren(Driver context, AstNode node) => true; +} \ No newline at end of file diff --git a/NewSource/SocordiaC/Compilation/Utils.cs b/NewSource/SocordiaC/Compilation/Utils.cs index edd611fb..d4b7563e 100644 --- a/NewSource/SocordiaC/Compilation/Utils.cs +++ b/NewSource/SocordiaC/Compilation/Utils.cs @@ -6,7 +6,7 @@ namespace SocordiaC.Compilation; public static class Utils { - public static TypeDesc? GetTypeFromNode(AstNode node, TypeDef containingType) + public static TypeDesc? GetTypeFromNode(TypeName node, TypeDef containingType) { if (node is SimpleTypeName id) { @@ -40,7 +40,7 @@ public static class Utils throw new Exception("cannot get type from node"); } - public static TypeDefOrSpec? GetTypeFromNode(AstNode node, ModuleDef module) + public static TypeDefOrSpec? GetTypeFromNode(TypeName node, ModuleDef module) { if (node is QualifiedTypeName qname) { diff --git a/NewSource/SocordiaC/Stages/ConvertToIrStage.cs b/NewSource/SocordiaC/Stages/ConvertToIrStage.cs index 644624ad..1e1ae8bd 100644 --- a/NewSource/SocordiaC/Stages/ConvertToIrStage.cs +++ b/NewSource/SocordiaC/Stages/ConvertToIrStage.cs @@ -12,7 +12,8 @@ public async Task HandleAsync(Driver context, Func> { var pipeline = CompositeListener.Build() .With(new CollectFunctionsListener(context.FunctionsType)) - .With(new CollectClassesListener()) + .With(new CollectClassesListener()) + .With(new CollectEnumListener()) .ToListener(); foreach (var tree in context.Trees) diff --git a/NewSource/SocordiaC/compilation.sc b/NewSource/SocordiaC/compilation.sc index 38ff29a9..2a8bf0c5 100644 --- a/NewSource/SocordiaC/compilation.sc +++ b/NewSource/SocordiaC/compilation.sc @@ -31,4 +31,14 @@ internal class Hello : System.Text.StringBuilder static class Blub { +} + +enum Color +{ + +} + +enum ShortColor : i8 +{ + } \ No newline at end of file