diff --git a/compiler/Properties/launchSettings.json b/compiler/Properties/launchSettings.json index 27f38ac2..117f5fdd 100644 --- a/compiler/Properties/launchSettings.json +++ b/compiler/Properties/launchSettings.json @@ -63,6 +63,11 @@ "compile vein test 5": { "commandName": "Project", "commandLineArgs": "build C:\\git\\std\\asd\\asd.vproj" + }, + + "compile std library": { + "commandName": "Project", + "commandLineArgs": "build ..\\..\\..\\..\\lib\\vein.std\\std\\std.vproj --ignore-cache" } } } \ No newline at end of file diff --git a/compiler/cmd/NewCommand.cs b/compiler/cmd/NewCommand.cs index 37d1e540..536ef03c 100644 --- a/compiler/cmd/NewCommand.cs +++ b/compiler/cmd/NewCommand.cs @@ -46,7 +46,7 @@ public override int Execute(CommandContext context, NewCommandSettings settings) curDir.File("app.vein").WriteAllText( $""" #space "{name}" - #use "vein/lang" + #use "std" class App {"{"} public static master(): void diff --git a/compiler/compilation/CompilationTask.cs b/compiler/compilation/CompilationTask.cs index 35351b68..1117cd6f 100644 --- a/compiler/compilation/CompilationTask.cs +++ b/compiler/compilation/CompilationTask.cs @@ -189,7 +189,7 @@ private bool ProcessFiles(IReadOnlyCollection files, IReadOnlyCollecti read_task.Increment(1); try { - var result = syntax.CompilationUnit.ParseVein(value); + var result = syntax.CompilationUnitV2.ParseVein(value); result.FileEntity = key; result.SourceText = value; // apply root namespace into includes diff --git a/compiler/compilation/parts/args.cs b/compiler/compilation/parts/args.cs index 32627ef2..df2b4f39 100644 --- a/compiler/compilation/parts/args.cs +++ b/compiler/compilation/parts/args.cs @@ -19,19 +19,50 @@ private VeinArgumentRef[] GenerateArgument(MethodDeclarationSyntax method, Docum throw new SkipStatementException(); } - if (!method.Modifiers.Any(x => x.ModificatorKind == ModificatorKind.Static)) + if (method.Modifiers.All(x => x.ModificatorKind != ModificatorKind.Static)) args.Add(new VeinArgumentRef(VeinArgumentRef.THIS_ARGUMENT, FetchType(method.OwnerClass.Identifier, doc))); if (method.Parameters.Count == 0) return args.ToArray(); + + return args.Concat(Convert(method.Parameters, method)).ToArray(); + } + + private IEnumerable Convert(List args, MethodDeclarationSyntax method) + { + VeinClass selector(TypeExpression exp) => FetchType(exp.Typeword, method.OwnerDocument); - return args.Concat(method.Parameters.Select(parameter => new VeinArgumentRef + foreach (var parameter in args) { - Type = parameter.Type.IsSelf ? - FetchType(method.OwnerClass.Identifier, doc) : - FetchType(parameter.Type, doc), - Name = parameter.Identifier.ExpressionString + var name = parameter.Identifier.ExpressionString; + var generic = method.GenericTypes.FirstOrDefault(x => x.Typeword.Equals(parameter.Type)); + var constraints = + method.TypeParameterConstraints.FirstOrDefault(x => x.GenericIndex.Typeword.Equals(parameter.Type)); - })).ToArray(); + var classGeneric = method.OwnerClass.GenericTypes.FirstOrDefault(x => x.Typeword.Equals(parameter.Type)); + var classGenericConstrains = method.OwnerClass.TypeParameterConstraints.FirstOrDefault(x => x.GenericIndex.Typeword.Equals(parameter.Type)); + + if (generic is not null && classGeneric is not null) + { + Log.Defer.Error($"Detected conflict of declaration generic types, generic type '[red bold]{parameter.Type.Identifier}[/]' " + + $"is declared in the '[red bold]{method.Identifier}[/]' method and in the '[red bold]{method.OwnerClass.Identifier}[/]' class", generic, method.OwnerDocument); + throw new SkipStatementException(); + } + + if (generic is not null && constraints is not null) + yield return new VeinArgumentRef(name, + generic.Typeword.ToTypeArg([constraints.ToConstraint(selector)])); + else if (generic is not null) + yield return new VeinArgumentRef(name, generic.Typeword.ToTypeArg([])); + else if (classGeneric is not null && classGenericConstrains is not null) + yield return new VeinArgumentRef(name, + classGeneric.Typeword.ToTypeArg([classGenericConstrains.ToConstraint(selector)])); + else if (classGeneric is not null) + yield return new VeinArgumentRef(name, classGeneric.Typeword.ToTypeArg([])); + else if(parameter.Type.IsSelf) + yield return new VeinArgumentRef(name, FetchType(method.OwnerClass.Identifier, method.OwnerDocument)); + else + yield return new VeinArgumentRef(name, FetchType(parameter.Type, method.OwnerDocument)); + } } } diff --git a/compiler/compilation/parts/aspects.cs b/compiler/compilation/parts/aspects.cs index b50732d4..1807c345 100644 --- a/compiler/compilation/parts/aspects.cs +++ b/compiler/compilation/parts/aspects.cs @@ -69,17 +69,17 @@ public ClassBuilder CompileAspect(AspectDeclarationSyntax member, DocumentDeclar public void CompileAspectFor(FieldDeclarationSyntax dec, DocumentDeclaration doc, VeinField field) => CompileAspectFor(dec.Aspects, x => - $"aspect/{x.Name}/class/{field.Owner.Name}/field/{dec.Field.Identifier}.", + $"aspect{Aspect.ASPECT_METADATA_DIVIDER}{x.Name}{Aspect.ASPECT_METADATA_DIVIDER}class{Aspect.ASPECT_METADATA_DIVIDER}{field.Owner.Name}{Aspect.ASPECT_METADATA_DIVIDER}field{Aspect.ASPECT_METADATA_DIVIDER}{dec.Field.Identifier}.", doc, field, AspectTarget.Field); public void CompileAspectFor(MethodDeclarationSyntax dec, DocumentDeclaration doc, VeinMethod method) => CompileAspectFor(dec.Aspects, x => - $"aspect/{x.Name}/class/{method.Owner.Name}/method/{method.Name}.", + $"aspect{Aspect.ASPECT_METADATA_DIVIDER}{x.Name}{Aspect.ASPECT_METADATA_DIVIDER}class{Aspect.ASPECT_METADATA_DIVIDER}{method.Owner.Name}{Aspect.ASPECT_METADATA_DIVIDER}method{Aspect.ASPECT_METADATA_DIVIDER}{method.Name}.", doc, method, AspectTarget.Method); public void CompileAspectFor(ClassDeclarationSyntax dec, DocumentDeclaration doc, VeinClass clazz) => CompileAspectFor(dec.Aspects, x => - $"aspect/{x.Name}/class/{clazz.Name}.", doc, clazz, AspectTarget.Class); + $"aspect{Aspect.ASPECT_METADATA_DIVIDER}{x.Name}{Aspect.ASPECT_METADATA_DIVIDER}class{Aspect.ASPECT_METADATA_DIVIDER}{clazz.Name}.", doc, clazz, AspectTarget.Class); private void CompileAspectFor( List aspects, diff --git a/compiler/compilation/parts/classes.cs b/compiler/compilation/parts/classes.cs index 0ad2f7a6..d1dcdadc 100644 --- a/compiler/compilation/parts/classes.cs +++ b/compiler/compilation/parts/classes.cs @@ -83,7 +83,6 @@ private ClassFlags GenerateClassFlags(ClassDeclarationSyntax clazz) continue; case { IsNative: true }: case { IsForwarded: true }: - case { IsAlias: true }: case { IsAspectUsage: true }: continue; //case VeinAnnotationKind.Readonly when !clazz.IsStruct: @@ -142,6 +141,11 @@ private ClassFlags GenerateClassFlags(ClassDeclarationSyntax clazz) public List<(ClassBuilder clazz, MemberDeclarationSyntax member)> LinkClasses((FileInfo, DocumentDeclaration doc) tuple) => LinkClasses(tuple.doc, Types.Storage); + + public void GenerateLinksForAliases(DocumentDeclaration doc) + { + + } public List<(ClassBuilder clazz, MemberDeclarationSyntax member)> LinkClasses(DocumentDeclaration doc, VeinCore types) { var classes = new List<(ClassBuilder clazz, MemberDeclarationSyntax member)>(); @@ -167,6 +171,18 @@ private ClassFlags GenerateClassFlags(ClassDeclarationSyntax clazz) else Log.Defer.Warn($"[grey]Member[/] [yellow underline]'{member.GetType().Name}'[/] [grey]is not supported.[/]"); } + foreach (var alias in doc.Aliases) + { + if (alias.IsType) + { + var type = FetchType(alias.Type!.Typeword, doc); + Context.Module.alias_table.Add(new VeinAliasType($"{module.Name}%global::{doc.Name}/{alias.AliasName.ExpressionString}", + type)); + KnowClasses.Add(alias.AliasName, type); + } + else + Log.Defer.Warn($"Method [grey]Alias[/] [yellow underline]'{alias.AliasName.ExpressionString}'[/] [grey]is not supported.[/]"); + } return classes; } @@ -176,9 +192,6 @@ public ClassBuilder CompileClass(ClassDeclarationSyntax member, DocumentDeclarat void _defineClass(ClassBuilder clz) { KnowClasses.Add(member.Identifier, clz); - if (member.Aspects.FirstOrDefault(x => x.IsAlias)?.Args?.SingleOrDefault().Value is not StringLiteralExpressionSyntax alias) - return; - KnowClasses.Add(new IdentifierExpression(alias.Value), clz); } diff --git a/compiler/compilation/parts/inheritance.cs b/compiler/compilation/parts/inheritance.cs index 796853e0..c528037a 100644 --- a/compiler/compilation/parts/inheritance.cs +++ b/compiler/compilation/parts/inheritance.cs @@ -3,7 +3,6 @@ namespace vein.compilation; using System.Linq; using ishtar.emit; using syntax; -using static runtime.VeinTypeCode; public partial class CompilationTask { diff --git a/compiler/compilation/parts/methods.cs b/compiler/compilation/parts/methods.cs index ffe77b52..a9080645 100644 --- a/compiler/compilation/parts/methods.cs +++ b/compiler/compilation/parts/methods.cs @@ -81,6 +81,9 @@ private MethodFlags GenerateMethodFlags(MethodDeclarationSyntax method) case "abstract": flags |= MethodFlags.Virtual; continue; + case "async": + flags |= MethodFlags.Async; + continue; default: Log.Defer.Error( $"In [orange]'{method.Identifier}'[/] method [red bold]{mod.ModificatorKind}[/] " + @@ -96,7 +99,11 @@ private MethodFlags GenerateMethodFlags(MethodDeclarationSyntax method) $"Modificator [red bold]public[/] cannot be combined with [red bold]private[/] " + $"in [orange]'{method.Identifier}'[/] method.", method.ReturnType, method.OwnerClass.OwnerDocument); - + if (flags.HasFlag(MethodFlags.Async) && !method.ReturnType.IsAsyncJob) + Log.Defer.Error( + $"Method [orange]'{method.Identifier}'[/] has marked as [red bold]async[/] " + + $"but return type is not [red bold]Job[/] ", + method.ReturnType, method.OwnerClass.OwnerDocument); return flags; } diff --git a/compiler/compilation/parts/types.cs b/compiler/compilation/parts/types.cs index 2a6cb2d1..bed0702f 100644 --- a/compiler/compilation/parts/types.cs +++ b/compiler/compilation/parts/types.cs @@ -4,41 +4,26 @@ namespace vein.compilation; using reflection; using runtime; using syntax; -using static runtime.VeinTypeCode; public partial class CompilationTask { private void LoadAliases() { - foreach (var clazz in Target.LoadedModules.SelectMany(x => x.class_table) - .Where(x => x.Aspects.Any(x => x.IsAlias()))) + foreach (var alias in Target.LoadedModules.SelectMany(x => x.alias_table).OfType()) { - var aliases = clazz.Aspects.Where(x => x.IsAlias()).Select(x => x.AsAlias()); - - if (aliases.Count() > 1) - { - Log.Defer.Error($"[red bold]Detected multiple alises[/] '[purple underline]{aliases.Select(x => x.Name)}[/]'"); - continue; - } - - var alias = aliases.Single(); - - var class_id = new IdentifierExpression(clazz.Name); - var alias_id = new IdentifierExpression(alias.Name); - + var class_id = new IdentifierExpression(alias.type.Name); + var alias_id = new IdentifierExpression(alias.aliasName.Name); Status.VeinStatus($"Load alias [grey]'{class_id}'[/] -> [grey]'{alias_id}'[/]..."); - if (!KnowClasses.ContainsKey(class_id)) - KnowClasses[class_id] = clazz; - if (!KnowClasses.ContainsKey(alias_id)) - KnowClasses[alias_id] = clazz; + KnowClasses.TryAdd(class_id, alias.type); + KnowClasses.TryAdd(alias_id, alias.type); } } private VeinClass FetchType(IdentifierExpression typename, DocumentDeclaration doc) { - if (KnowClasses.ContainsKey(typename)) - return KnowClasses[typename]; + if (KnowClasses.TryGetValue(typename, out var type)) + return type; var retType = module.TryFindType(typename.ExpressionString, doc.Includes); diff --git a/include/ishtar.h b/include/ishtar.h index 75f755cb..d3d4c0fd 100644 --- a/include/ishtar.h +++ b/include/ishtar.h @@ -406,14 +406,14 @@ typedef union { uint64_t ul; float f_r4; double f; - // Note: C does not have a native decimal type + // C does not have a native decimal type struct { uint64_t low; uint64_t mid; uint64_t high; uint16_t sign_scale; } d; - // Note: C does not have a native Half type + // C does not have a native Half type uint16_t hf; void* p; } ishtar_stackval_union_t; @@ -533,6 +533,37 @@ typedef struct { uint64_t vtable_size; } ishtar_class_t; +typedef struct { + void* mem_base; + void* reg_base; +} ishtar_gc_stack_base; + + +// ishtar GC +ishtar_stackval_t* ishtar_gc_allocvalue(ishtar_callframe_t* frame); +ishtar_stackval_t* ishtar_gc_allocvalue(ishtar_class_t* clazz, ishtar_callframe_t* frame); +ishtar_stackval_t* ishtar_gc_allocatestack(ishtar_callframe_t* frame, int32_t size); +void ishtar_gc_freestack(ishtar_callframe_t* frame, ishtar_stackval_t* stack, int32_t size); +void ishtar_gc_freevalue(ishtar_stackval_t* value); +void** ishtar_gc_allocvtable(uint32_t size); +ishtar_object_t* ishtar_gc_alloctypeinfoobject(ishtar_class_t* clazz, ishtar_callframe_t* frame); +ishtar_object_t* ishtar_gc_allocfieldinfoobject(void* field, ishtar_callframe_t* frame); +ishtar_object_t* ishtar_gc_allocmethodinfoobject(ishtar_method_t* method, ishtar_callframe_t* frame); +ishtar_object_t* ishtar_gc_allocobject(ishtar_class_t* clazz, ishtar_callframe_t* frame); +void ishtar_gc_freeobject(ishtar_object_t** obj, ishtar_callframe_t* frame); +void ishtar_gc_freeobject(ishtar_object_t* obj, ishtar_callframe_t* frame); +bool ishtar_gc_isalive(ishtar_object_t* obj); +void ishtar_gc_objectregisterfinalizer(ishtar_object_t* obj, void* proc, ishtar_callframe_t* frame); +void ishtar_gc_registerweaklink(ishtar_object_t* obj, void** link, bool longlive); +void ishtar_gc_unregisterweaklink(void** link, bool longlive); +long ishtar_gc_getusedmemorysize(); +void ishtar_gc_collect(); +void ishtar_gc_register_thread(ishtar_gc_stack_base* attr); +void ishtar_gc_unregister_thread() ; +bool ishtar_gc_get_stack_base(ishtar_gc_stack_base* attr); +// end ishtar GC + + #ifdef __cplusplus } #endif diff --git a/lib/ast/syntax/Classes.cs b/lib/ast/syntax/Classes.cs index 23adcfd5..cf123966 100644 --- a/lib/ast/syntax/Classes.cs +++ b/lib/ast/syntax/Classes.cs @@ -112,32 +112,57 @@ select ClassDeclarationSyntax.Create(heading, classBody) .SetStart(heading.Transform.pos) .SetPos(classBody.Transform); - /// example: class Program { void main() {} } + protected internal virtual Parser ClassDeclarationBody => from @class in Parse.IgnoreCase("class").Text().Token() .Or(Parse.IgnoreCase("interface").Text().Token()) .Or(Parse.IgnoreCase("struct").Text().Token()).Commented(this) from className in IdentifierExpression.Token().Positioned() - from interfaces in Parse.IgnoreCase(":").Token().Then(t => TypeReference.Positioned().DelimitedBy(Parse.Char(',').Token())).Optional() + from generics in GenericsDeclarationParser.Token().Optional() + from interfaces in Parse.IgnoreCase(":").Token() + .Then(_ => TypeReference.Positioned().DelimitedBy(Parse.Char(',').Token())).Optional() from skippedComments in CommentParser.AnyComment.Token().Many() + from constraints in GenericConstraintParser.Token().Optional() from openBrace in Parse.Char('{').Token().Commented(this) from members in ClassMemberDeclaration.Positioned().Token().Many() from closeBrace in Parse.Char('}').Token().Commented(this) let classBody = new ClassDeclarationSyntax { Identifier = className, - IsInterface = @class.Value == "interface", - IsStruct = @class.Value == "struct", - Inheritances = interfaces.GetOrElse(Enumerable.Empty()).ToList(), + IsInterface = @class.Value == Keywords.INTERFACE, + IsStruct = @class.Value == Keywords.STRUCT, + Inheritances = interfaces.GetOrEmpty().ToList(), Members = ConvertConstructors(members, className).ToList(), InnerComments = closeBrace.LeadingComments.ToList(), TrailingComments = closeBrace.TrailingComments.ToList(), + TypeParameterConstraints = constraints.GetOrEmpty().ToList(), + GenericTypes = generics.GetOrEmpty().ToList() } select ClassDeclarationSyntax.Create(null, classBody) .SetStart(@class.Transform.pos) .SetEnd(closeBrace.Transform.pos) .As(); + + protected internal virtual Parser> GenericConstraintParser => + from keyword in Parse.IgnoreCase("when").Token() + from data in GenericConstraintUnitParser.Positioned().DelimitedBy(Parse.Char(',').Token()) + select data.ToList(); + + protected internal virtual Parser GenericConstraintUnitParser => + from genericIndex in TypeExpression.Token().Positioned() + from keyword1 in Parse.IgnoreCase("is").Token() + from constraint in TypeExpression.Token().Positioned() + select new TypeParameterConstraintSyntax(genericIndex, constraint); + + protected internal virtual Parser> GenericsDeclarationParser => + from openBrace in Parse.Char('<').Token().Commented(this) + from types in TypeExpression.Token().Positioned().DelimitedBy(Parse.Char(',')) + from closeBrace in Parse.Char('>').Token().Commented(this) + select types.ToList(); + + + private IEnumerable ConvertConstructors(IEnumerable members, IdentifierExpression className) { diff --git a/lib/ast/syntax/Expression.cs b/lib/ast/syntax/Expression.cs index 83f5861c..cf4c0374 100644 --- a/lib/ast/syntax/Expression.cs +++ b/lib/ast/syntax/Expression.cs @@ -279,6 +279,7 @@ from h in Parse.Char('?').Optional() from h in Parse.Char('*').Optional() select new PointerSpecifierValue(h.IsDefined); + // type protected internal virtual Parser TypeExpression => from type in BaseType.Or(namespace_or_type_name.Token()).Positioned() from meta in nullable_specifier diff --git a/lib/ast/syntax/Keywords.cs b/lib/ast/syntax/Keywords.cs new file mode 100644 index 00000000..12a22891 --- /dev/null +++ b/lib/ast/syntax/Keywords.cs @@ -0,0 +1,11 @@ +namespace vein.syntax; + +public partial class VeinSyntax +{ + public static class Keywords + { + public const string INTERFACE = "interface"; + public const string CLASS = "class"; + public const string STRUCT = "struct"; + } +} diff --git a/lib/ast/syntax/ModificatorSyntax.cs b/lib/ast/syntax/ModificatorSyntax.cs index 2582a6e3..1d6b1e04 100644 --- a/lib/ast/syntax/ModificatorSyntax.cs +++ b/lib/ast/syntax/ModificatorSyntax.cs @@ -1,40 +1,37 @@ -namespace vein.syntax -{ - using System; - using System.Collections.Generic; - using Sprache; +namespace vein.syntax; - public enum ModificatorKind - { - Public, - Protected, - Private, - Static, - Const, - Extern, - Internal, - Override, - Global, - Virtual, - Readonly, - Abstract - } +using System; +using System.Collections.Generic; +using Sprache; - public class ModificatorSyntax : BaseSyntax, IPositionAware - { - public override SyntaxType Kind => SyntaxType.Modificator; - public override IEnumerable ChildNodes => new[] { this }; +public enum ModificatorKind +{ + Public, + Protected, + Private, + Static, + Const, + Extern, + Internal, + Override, + Global, + Virtual, + Readonly, + Abstract, + Async +} - public ModificatorKind ModificatorKind { get; } +public class ModificatorSyntax(string mod) : BaseSyntax, IPositionAware +{ + public override SyntaxType Kind => SyntaxType.Modificator; + public override IEnumerable ChildNodes => new[] { this }; + public ModificatorKind ModificatorKind { get; } = Enum.Parse(mod, true); - public ModificatorSyntax(string mod) - => this.ModificatorKind = Enum.Parse(mod, true); - public new ModificatorSyntax SetPos(Position startPos, int length) - { - base.SetPos(startPos, length); - return this; - } + public new ModificatorSyntax SetPos(Position startPos, int length) + { + base.SetPos(startPos, length); + return this; } } diff --git a/lib/ast/syntax/VeinSyntax.cs b/lib/ast/syntax/VeinSyntax.cs index 17b757d1..60231748 100644 --- a/lib/ast/syntax/VeinSyntax.cs +++ b/lib/ast/syntax/VeinSyntax.cs @@ -1,3 +1,5 @@ +using vein.syntax; + namespace vein.syntax { using System.Collections.Generic; @@ -50,6 +52,7 @@ internal virtual Parser Keyword(string text) => Keyword("protected")).Or( Keyword("virtual")).Or( Keyword("abstract")).Or( + Keyword("async")).Or( Keyword("readonly")).Or( Keyword("private")).Or( Keyword("internal")).Or( @@ -133,9 +136,11 @@ from modifiers in Modifier.Many() // Test() : void {} // Test() : void; protected internal virtual Parser MethodParametersAndBody => + from generics in GenericsDeclarationParser.Token().Optional() from parameters in MethodParameters from @as in Parse.Char(':').Token().Commented(this) from type in TypeReference.Commented(this) + from constraints in GenericConstraintParser.Token().Optional() from methodBody in BlockShortform().Or(Block.Or(Parse.Char(';').Return(new EmptyBlockSyntax()))) .Token().Positioned().Commented(this) select new MethodDeclarationSyntax @@ -143,9 +148,12 @@ from type in TypeReference.Commented(this) Parameters = parameters, Body = methodBody.Value, ReturnType = type.Value, - EndPoint = methodBody.Transform?.pos ?? type.Transform.pos + EndPoint = methodBody.Transform?.pos ?? type.Transform.pos, + GenericTypes = generics.GetOrEmpty().ToList(), + TypeParameterConstraints = constraints.GetOrEmpty().ToList() }; + protected internal virtual Parser CtorParametersAndBody => from parameters in MethodParameters from methodBody in BlockShortform().Or(Block.Or(Parse.Char(';').Return(new EmptyBlockSyntax()))) @@ -186,6 +194,7 @@ select kinds.ToArray()) from directives in SpaceSyntax.Token() .Or(UseSyntax.Token()).Many() + from aliases in AliasDeclaration.Token().Many().Optional() from members in AspectDeclaration.Select(x => x.As()) .Or(ClassDeclaration.Select(x => x.As())).Token().AtLeastOnce() from whiteSpace in Parse.WhiteSpace.Many() diff --git a/lib/ast/syntax/ast/ClassDeclarationSyntax.cs b/lib/ast/syntax/ast/ClassDeclarationSyntax.cs index a6fcea45..1035db8b 100644 --- a/lib/ast/syntax/ast/ClassDeclarationSyntax.cs +++ b/lib/ast/syntax/ast/ClassDeclarationSyntax.cs @@ -73,9 +73,16 @@ public ClassDeclarationSyntax(MemberDeclarationSyntax heading, ClassDeclarationS TrailingComments = classBody.TrailingComments; } - public static ClassDeclarationSyntax Create(MemberDeclarationSyntax heading, ClassDeclarationSyntax classBody) => - classBody.IsInterface ? new InterfaceDeclarationSyntax(heading, classBody) : - new ClassDeclarationSyntax(heading, classBody); + public static ClassDeclarationSyntax Create(MemberDeclarationSyntax heading, ClassDeclarationSyntax classBody) + { + if (classBody.IsInterface) + return new InterfaceDeclarationSyntax(heading, classBody); + return new ClassDeclarationSyntax(heading, classBody) + { + GenericTypes = classBody.GenericTypes, + TypeParameterConstraints = classBody.TypeParameterConstraints + }; + } public override SyntaxType Kind => SyntaxType.Class; @@ -106,7 +113,8 @@ public static ClassDeclarationSyntax Create(MemberDeclarationSyntax heading, Cla public List Fields => Members.OfType().ToList(); public List Properties => Members.OfType().ToList(); - + public List TypeParameterConstraints { get; set; } = new(); + public List GenericTypes { get; set; } = new(); public new ClassDeclarationSyntax SetPos(Position startPos, int length) { diff --git a/lib/ast/syntax/ast/MethodDeclarationSyntax.cs b/lib/ast/syntax/ast/MethodDeclarationSyntax.cs index d9b25378..d10884a3 100644 --- a/lib/ast/syntax/ast/MethodDeclarationSyntax.cs +++ b/lib/ast/syntax/ast/MethodDeclarationSyntax.cs @@ -3,15 +3,10 @@ namespace vein.syntax using System.Collections.Generic; using System.Linq; using runtime; - using vein.extensions; + using extensions; - public class MethodDeclarationSyntax : MemberDeclarationSyntax + public class MethodDeclarationSyntax(MemberDeclarationSyntax? heading = null) : MemberDeclarationSyntax(heading) { - public MethodDeclarationSyntax(MemberDeclarationSyntax heading = null) - : base(heading) - { - } - public override SyntaxType Kind => SyntaxType.Method; public override IEnumerable ChildNodes => @@ -23,10 +18,14 @@ public MethodDeclarationSyntax(MemberDeclarationSyntax heading = null) public List Parameters { get; set; } = new(); - public BlockSyntax Body { get; set; } + public BlockSyntax? Body { get; set; } public bool IsAbstract => Body == null; + public List TypeParameterConstraints { get; set; } = new(); + public List GenericTypes { get; set; } = new(); + + public string GetQualityName() => $"{Identifier}({Parameters.Select(x => $"{(x.Type.IsSelf ? OwnerClass.Identifier : x.Type.Identifier)}").Join(",")})"; @@ -55,7 +54,7 @@ public static bool IsEquals(this MethodDeclarationSyntax @this, VeinMethod metho { if (!$"{@this.Identifier}".Equals(method.RawName)) return false; - var args = method.Arguments + var args = method.Signature.Arguments .Where(x => !x.Name.Equals(VeinArgumentRef.THIS_ARGUMENT)) .ToList(); if (@this.Parameters.Count != args.Count) diff --git a/lib/ast/syntax/ast/SyntaxType.cs b/lib/ast/syntax/ast/SyntaxType.cs index 45eb5fbc..10cb3483 100644 --- a/lib/ast/syntax/ast/SyntaxType.cs +++ b/lib/ast/syntax/ast/SyntaxType.cs @@ -64,6 +64,8 @@ public enum SyntaxType WhileStatement, GCDeclaration, SyncDeclaration, - DirectiveDeclaration + DirectiveDeclaration, + TypeParameterConstraint, + Alias } } diff --git a/lib/ast/syntax/ast/TypeParameterConstraintSyntax.cs b/lib/ast/syntax/ast/TypeParameterConstraintSyntax.cs new file mode 100644 index 00000000..d362853e --- /dev/null +++ b/lib/ast/syntax/ast/TypeParameterConstraintSyntax.cs @@ -0,0 +1,30 @@ +namespace vein.syntax; + +using runtime; +using Sprache; + +public class TypeParameterConstraintSyntax(TypeExpression genericIndex, TypeExpression constraint) : BaseSyntax, IPositionAware +{ + public TypeExpression GenericIndex { get; } = genericIndex; + public TypeExpression Constraint { get; } = constraint; + public override SyntaxType Kind => SyntaxType.TypeParameterConstraint; + public override IEnumerable ChildNodes => GetNodes([GenericIndex, Constraint]); + public new TypeParameterConstraintSyntax SetPos(Position startPos, int length) + { + base.SetPos(startPos, length); + return this; + } + + public bool IsBittable => Constraint.ExpressionString.Equals("bittable"); + public bool IsClass => Constraint.ExpressionString.Equals("class"); + + public VeinBaseConstraint ToConstraint(Func classSelector) + { + if (IsBittable) + return new VeinBaseConstraintConstBittable(); + if (IsClass) + return new VeinBaseConstraintConstClass(); + return new VeinBaseConstraintConstType(classSelector(constraint)); + } +} + diff --git a/lib/ast/syntax/ast/TypeSyntax.cs b/lib/ast/syntax/ast/TypeSyntax.cs index 4784eddd..5c52f55a 100644 --- a/lib/ast/syntax/ast/TypeSyntax.cs +++ b/lib/ast/syntax/ast/TypeSyntax.cs @@ -3,10 +3,11 @@ namespace vein.syntax using System.Collections.Generic; using System.Linq; using extensions; + using runtime; using Sprache; using stl; - public class TypeSyntax : BaseSyntax, IPositionAware + public class TypeSyntax : BaseSyntax, IPositionAware, IEquatable { public TypeSyntax(IEnumerable qualifiedName) { @@ -55,6 +56,7 @@ public override IEnumerable ChildNodes public List TypeParameters { get; set; } = new(); public bool IsArray { get; set; } public bool IsPointer { get; set; } + public bool IsAsyncJob => Identifier.ExpressionString.Equals("Job"); public int ArrayRank { get; set; } @@ -80,5 +82,24 @@ TypeSyntax IPositionAware.SetPos(Position startPos, int length) base.SetPos(startPos, length); return this; } + + public bool Equals(TypeSyntax? other) + { + if (other == null) return false; + return other.Identifier.Equals(Identifier); + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((TypeSyntax)obj); + } + + public override int GetHashCode() => HashCode.Combine(Namespaces, Identifier, TypeParameters, IsArray, IsPointer, ArrayRank, PointerRank); + + public VeinTypeArg ToTypeArg(IReadOnlyList constraint) => + new(Identifier.ExpressionString, constraint); } } diff --git a/lib/vein.std/std/.gitignore b/lib/vein.std/.gitignore similarity index 100% rename from lib/vein.std/std/.gitignore rename to lib/vein.std/.gitignore diff --git a/lib/vein.std/std/src/vein/lang/App.vein b/lib/vein.std/std/App.vein similarity index 68% rename from lib/vein.std/std/src/vein/lang/App.vein rename to lib/vein.std/std/App.vein index 76d5a301..24050232 100644 --- a/lib/vein.std/std/src/vein/lang/App.vein +++ b/lib/vein.std/std/App.vein @@ -1,22 +1,22 @@ -#space "vein/lang" +#space "std" public static class App { [native("__internal__", "@_get_os_value")] private extern static @_get_os_value(): i32; [native("__internal__", "@_exit")] - private extern static @_exit(msg: string, exitCode: i32): void; + private extern static @_exit(msg: string, exitCode: i32): Void; [native("__internal__", "@_switch_flag")] - private extern static @_switch_flag(key: string, value: bool): void; - + private extern static @_switch_flag(key: string, value: bool): Void; + public static GetFrameworkName(): string { return "Application.getPlatform()"; } - public static Shutdown(msg: string, exitCode: i32): void + public static Shutdown(msg: string, exitCode: i32): Void |> Application.@_exit(msg, exitCode); - public static SwitchFlag(key: string, value: bool): void + public static SwitchFlag(key: string, value: bool): Void |> @_switch_flag(key, value); } diff --git a/lib/vein.std/std/src/vein/lang/Array.vein b/lib/vein.std/std/Array.vein similarity index 64% rename from lib/vein.std/std/src/vein/lang/Array.vein rename to lib/vein.std/std/Array.vein index cd677081..30b5fdda 100644 --- a/lib/vein.std/std/src/vein/lang/Array.vein +++ b/lib/vein.std/std/Array.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" [special, forwarded] public class Array @@ -20,8 +20,8 @@ public class Array return "Array"; } - public static empty: Array = new object[0]; + public static empty: Array = new Object[0]; - //protected extern _indexer_get(index: i64): object; - //protected extern _indexer_set(index: i64, o: object): void; + //protected extern _indexer_get(index: i64): Object; + //protected extern _indexer_set(index: i64, o: Object): Void; } \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/BitConvert.vein b/lib/vein.std/std/BitConvert.vein similarity index 86% rename from lib/vein.std/std/src/vein/lang/BitConvert.vein rename to lib/vein.std/std/BitConvert.vein index aa9003e3..58ea8cd0 100644 --- a/lib/vein.std/std/src/vein/lang/BitConvert.vein +++ b/lib/vein.std/std/BitConvert.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" diff --git a/lib/vein.std/std/src/vein/lang/Boolean.vein b/lib/vein.std/std/Boolean.vein similarity index 77% rename from lib/vein.std/std/src/vein/lang/Boolean.vein rename to lib/vein.std/std/Boolean.vein index 78bbc4f7..317351f6 100644 --- a/lib/vein.std/std/src/vein/lang/Boolean.vein +++ b/lib/vein.std/std/Boolean.vein @@ -1,7 +1,7 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("bool")] +[special, forwarded] public struct Boolean : ValueType { [native("!!value")] @@ -14,4 +14,4 @@ public struct Boolean : ValueType public const FalseString: string = "false"; } -alias bool <| Boolean; \ No newline at end of file +global alias bool <| Boolean; \ No newline at end of file diff --git a/lib/vein.std/std/Byte.vein b/lib/vein.std/std/Byte.vein new file mode 100644 index 00000000..d04304c3 --- /dev/null +++ b/lib/vein.std/std/Byte.vein @@ -0,0 +1,11 @@ +#space "std" + + +[special, forwarded] +public struct Byte : ValueType +{ + [native("!!value")] + private _value: ValueType; +} + +global alias u8 <| Byte; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Char.vein b/lib/vein.std/std/Char.vein similarity index 55% rename from lib/vein.std/std/src/vein/lang/Char.vein rename to lib/vein.std/std/Char.vein index 3ab6de37..bd7d3a80 100644 --- a/lib/vein.std/std/src/vein/lang/Char.vein +++ b/lib/vein.std/std/Char.vein @@ -1,11 +1,11 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("char")] +[special, forwarded] public struct Char : ValueType { [native("!!value")] private _value: ValueType; } -alias char <| Char; \ No newline at end of file +global alias char <| Char; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Decimal.vein b/lib/vein.std/std/Decimal.vein similarity index 85% rename from lib/vein.std/std/src/vein/lang/Decimal.vein rename to lib/vein.std/std/Decimal.vein index 60f77857..e7e11cfb 100644 --- a/lib/vein.std/std/src/vein/lang/Decimal.vein +++ b/lib/vein.std/std/Decimal.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" [special, forwarded] diff --git a/lib/vein.std/std/src/vein/lang/Double.vein b/lib/vein.std/std/Double.vein similarity index 56% rename from lib/vein.std/std/src/vein/lang/Double.vein rename to lib/vein.std/std/Double.vein index 46fffd60..d04f9635 100644 --- a/lib/vein.std/std/src/vein/lang/Double.vein +++ b/lib/vein.std/std/Double.vein @@ -1,7 +1,7 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("f64")] +[special, forwarded] public struct Double : ValueType { [native("!!value")] @@ -9,4 +9,4 @@ public struct Double : ValueType } -alias f64 <| Double; \ No newline at end of file +global alias f64 <| Double; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Exception.vein b/lib/vein.std/std/Exception.vein similarity index 97% rename from lib/vein.std/std/src/vein/lang/Exception.vein rename to lib/vein.std/std/Exception.vein index 6130562a..ef4ca137 100644 --- a/lib/vein.std/std/src/vein/lang/Exception.vein +++ b/lib/vein.std/std/Exception.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" [special, forwarded] diff --git a/lib/vein.std/std/src/vein/lang/Float.vein b/lib/vein.std/std/Float.vein similarity index 56% rename from lib/vein.std/std/src/vein/lang/Float.vein rename to lib/vein.std/std/Float.vein index 52967ebe..f0305fa0 100644 --- a/lib/vein.std/std/src/vein/lang/Float.vein +++ b/lib/vein.std/std/Float.vein @@ -1,11 +1,11 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("f32")] +[special, forwarded] public struct Float : ValueType { [native("!!value")] private _value: ValueType; } -alias f32 <| Float; \ No newline at end of file +global alias f32 <| Float; \ No newline at end of file diff --git a/lib/vein.std/std/GC.vein b/lib/vein.std/std/GC.vein new file mode 100644 index 00000000..d50c50a8 --- /dev/null +++ b/lib/vein.std/std/GC.vein @@ -0,0 +1,15 @@ +#space "std" + + +public static class GC +{ + public static allocated: i64 + |> self._get_allocated(); + public static alive_Objects: i64 + |> self._get_alive_Objects(); + + [native("__internal__", "i_call_GC_get_allocated")] + private static extern _get_allocated(): i64; + [native("__internal__", "i_call_GC_get_alive_objects")] + private static extern _get_alive_Objects(): i64; +} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Guid.vein b/lib/vein.std/std/Guid.vein similarity index 94% rename from lib/vein.std/std/src/vein/lang/Guid.vein rename to lib/vein.std/std/Guid.vein index 705d3e24..ffd6fd09 100644 --- a/lib/vein.std/std/src/vein/lang/Guid.vein +++ b/lib/vein.std/std/Guid.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" diff --git a/lib/vein.std/std/src/vein/lang/Half.vein b/lib/vein.std/std/Half.vein similarity index 91% rename from lib/vein.std/std/src/vein/lang/Half.vein rename to lib/vein.std/std/Half.vein index 2a62fc18..cd5a888b 100644 --- a/lib/vein.std/std/src/vein/lang/Half.vein +++ b/lib/vein.std/std/Half.vein @@ -1,9 +1,9 @@ -#space "vein/lang" +#space "std" -alias f16 <| Half; +global alias f16 <| Half; -[special, forwarded, alias("f16")] +[special, forwarded] public struct Half : ValueType { [native("!!value")] @@ -36,4 +36,4 @@ public struct Half : ValueType [special] public NaN: f16 |> IEEEConsts.getHalfNaN(); -}; \ No newline at end of file +} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Int16.vein b/lib/vein.std/std/Int16.vein similarity index 70% rename from lib/vein.std/std/src/vein/lang/Int16.vein rename to lib/vein.std/std/Int16.vein index 75d8bc37..92a8704f 100644 --- a/lib/vein.std/std/src/vein/lang/Int16.vein +++ b/lib/vein.std/std/Int16.vein @@ -1,7 +1,7 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("i16")] +[special, forwarded] public struct Int16 : ValueType { [native("!!value")] @@ -11,4 +11,4 @@ public struct Int16 : ValueType public const MinValue: i16 = -32768; } -alias i16 <| Int16; +global alias i16 <| Int16; diff --git a/lib/vein.std/std/src/vein/lang/Int32.vein b/lib/vein.std/std/Int32.vein similarity index 82% rename from lib/vein.std/std/src/vein/lang/Int32.vein rename to lib/vein.std/std/Int32.vein index 83b859d8..45fe3184 100644 --- a/lib/vein.std/std/src/vein/lang/Int32.vein +++ b/lib/vein.std/std/Int32.vein @@ -1,7 +1,7 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("i32")] +[special, forwarded] public struct Int32 : ValueType { [native("!!value")] @@ -19,4 +19,4 @@ public struct Int32 : ValueType */ } -alias i32 <| Int32; \ No newline at end of file +global alias i32 <| Int32; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Int64.vein b/lib/vein.std/std/Int64.vein similarity index 73% rename from lib/vein.std/std/src/vein/lang/Int64.vein rename to lib/vein.std/std/Int64.vein index a5e445d4..26caf4c8 100644 --- a/lib/vein.std/std/src/vein/lang/Int64.vein +++ b/lib/vein.std/std/Int64.vein @@ -1,7 +1,7 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("i64")] +[special, forwarded] public struct Int64 : ValueType { [native("!!value")] @@ -11,4 +11,4 @@ public struct Int64 : ValueType public const MinValue: i64 = -9223372036854775808; } -alias i64 <| Int64; +global alias i64 <| Int64; diff --git a/lib/vein.std/std/src/vein/lang/Math.vein b/lib/vein.std/std/Math.vein similarity index 93% rename from lib/vein.std/std/src/vein/lang/Math.vein rename to lib/vein.std/std/Math.vein index bffa1265..371f8037 100644 --- a/lib/vein.std/std/src/vein/lang/Math.vein +++ b/lib/vein.std/std/Math.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" diff --git a/lib/vein.std/std/Object.vein b/lib/vein.std/std/Object.vein new file mode 100644 index 00000000..56cd4b41 --- /dev/null +++ b/lib/vein.std/std/Object.vein @@ -0,0 +1,9 @@ +#space "std" + + +[special, forwarded] +public class Object +{ + public virtual toString(): string + |> ""; +} \ No newline at end of file diff --git a/lib/vein.std/std/Out.vein b/lib/vein.std/std/Out.vein new file mode 100644 index 00000000..d0531b5c --- /dev/null +++ b/lib/vein.std/std/Out.vein @@ -0,0 +1,17 @@ +#space "std" + + +public static class Out +{ + [native("__internal__", "@_println")] + public extern static @_println(value: Object): Void; + [native("__internal__", "@_println")] + public extern static @_println(value: i32): Void; + + public static print(value: string): Void + |> Out.@_println(value); + + public static print(value: i32): Void + |> Out.@_println(value); +} + diff --git a/lib/vein.std/std/README.md b/lib/vein.std/std/README.md index e85a065e..0dcd9fc0 100644 --- a/lib/vein.std/std/README.md +++ b/lib/vein.std/std/README.md @@ -1,47 +1,2 @@ ---- +## A standard core library for Ishtar VM and Vein Lang -> Vein is an open source high-level strictly-typed programming language with a standalone OS, arm and quantum computing support. - ---- - -## OS Support - -OS | Version | Architectures -------------------------------|-------------------------------|---------------- -Windows 10 | 1607+ | x64, ARM64 -OSX | 10.14+ | x64 -Linux | | x64, ARM64 - - -## Compiling from source - -### Building on Windows - -For building, you need the following tools: -- dotnet 6.0 -- Win10 SDK -- vsbuild-tools-2019 with MSVC 2019, MSVC142 for ARM64 - - -Checkout mana sources -```bash -git clone https://github.com/vein-lang/vein.git --recurse-submodules -cd ./vein-lang -git fetch --prune --unshallow --tags - -dotnet restore -``` - -#### Compile IshtarVM -Go to ishtar folder -```base -cd ./runtime/ishtar.vm -``` -Compile for Windows 10 x64 -```bash -dotnet publish -r win10-x64 -c Release -``` -Compile for Windows 10 ARM64 -``` -dotnet publish -r win-arm64 -c Release -``` \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Range.vein b/lib/vein.std/std/Range.vein similarity index 91% rename from lib/vein.std/std/src/vein/lang/Range.vein rename to lib/vein.std/std/Range.vein index 14b56dfd..fa69306c 100644 --- a/lib/vein.std/std/src/vein/lang/Range.vein +++ b/lib/vein.std/std/Range.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" [special] diff --git a/lib/vein.std/std/src/vein/lang/String.vein b/lib/vein.std/std/String.vein similarity index 93% rename from lib/vein.std/std/src/vein/lang/String.vein rename to lib/vein.std/std/String.vein index e81cdd68..ef5e2571 100644 --- a/lib/vein.std/std/src/vein/lang/String.vein +++ b/lib/vein.std/std/String.vein @@ -1,6 +1,6 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("string")] +[special, forwarded] public class String : Object { [native("!!value")] @@ -37,7 +37,7 @@ public class String : Object private extern static Concat(v1: string, v2: string): string; // temporary using vm_bridge, todo: rework to using vein-code [native("__internal__", "i_call_String_Equal")] - private extern static Equal(v1: string, v2: string): string; + private extern static Equal(v1: string, v2: string): bool; public static format(template: string, o1: Object): string diff --git a/lib/vein.std/std/src/vein/lang/StringBuilder.vein_ b/lib/vein.std/std/StringBuilder.vein_ similarity index 100% rename from lib/vein.std/std/src/vein/lang/StringBuilder.vein_ rename to lib/vein.std/std/StringBuilder.vein_ diff --git a/lib/vein.std/std/Testable.vein b/lib/vein.std/std/Testable.vein new file mode 100644 index 00000000..b46fbc7c --- /dev/null +++ b/lib/vein.std/std/Testable.vein @@ -0,0 +1,16 @@ +#space "std" + +public class Testable +{ + public static master(): Void + { + Out.print("yamete..."); + + + aboba(1, "test string"); + } + + public static aboba(t: T, b: E): Void { + Out.print("yamete..."); + } +} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Thread.vein b/lib/vein.std/std/Thread.vein_ similarity index 62% rename from lib/vein.std/std/src/vein/lang/Thread.vein rename to lib/vein.std/std/Thread.vein_ index 37c579b3..8e28b04e 100644 --- a/lib/vein.std/std/src/vein/lang/Thread.vein +++ b/lib/vein.std/std/Thread.vein_ @@ -1,31 +1,34 @@ -#space "vein/lang" +#space "std" public class Thread : Object { [native("__internal__", "@_threading_begin_affinity")] - public extern static BeginAffinity(): void; + public extern static BeginAffinity(): Void; [native("__internal__", "@_threading_end_affinity")] - public extern static EndAffinity(): void; + public extern static EndAffinity(): Void; [native("__internal__", "@_threading_begin_critical_region")] - public extern static BeginCriticalRegion(): void; + public extern static BeginCriticalRegion(): Void; [native("__internal__", "@_threading_end_critical_region")] - public extern static EndCriticalRegion(): void; + public extern static EndCriticalRegion(): Void; [native("__internal__", "@_threading_memory_barrier")] - public extern static MemoryBarrier(): void; + public extern static MemoryBarrier(): Void; [native("__internal__", "@_threading_yield")] - public extern static Yield(): void; + public extern static Yield(): Void; [native("__internal__", "@_threading_create")] public extern static Create(fn: Function): Thread; [native("__internal__", "@_threading_sleep")] public extern static Sleep(ms: u32): Thread; - public Join(): void { - Thread._join(this); - } - public Start(): void { - Thread._start(this); - } + private _fn: Function; + + new(fn: Function) + |> self._fn = _fn; + + public Join(): Void + |> Thread._join(this); + public Start(): Void + |> Thread._start(this); [native("__internal__", "@_threading_join")] private extern static _join(thread: Thread): Thread; diff --git a/lib/vein.std/std/src/vein/lang/TimeSpan.vein b/lib/vein.std/std/TimeSpan.vein similarity index 97% rename from lib/vein.std/std/src/vein/lang/TimeSpan.vein rename to lib/vein.std/std/TimeSpan.vein index eff5c5b3..660e18ef 100644 --- a/lib/vein.std/std/src/vein/lang/TimeSpan.vein +++ b/lib/vein.std/std/TimeSpan.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" public class TimeSpan { diff --git a/lib/vein.std/std/src/vein/lang/UInt16.vein b/lib/vein.std/std/UInt16.vein similarity index 69% rename from lib/vein.std/std/src/vein/lang/UInt16.vein rename to lib/vein.std/std/UInt16.vein index c4120a0b..7847f412 100644 --- a/lib/vein.std/std/src/vein/lang/UInt16.vein +++ b/lib/vein.std/std/UInt16.vein @@ -1,7 +1,7 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("u16")] +[special, forwarded] public struct UInt16 : ValueType { [native("!!value")] @@ -11,4 +11,4 @@ public struct UInt16 : ValueType public const MinValue: u16 = 0; } -alias u16 <| UInt16; \ No newline at end of file +global alias u16 <| UInt16; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/UInt32.vein b/lib/vein.std/std/UInt32.vein similarity index 70% rename from lib/vein.std/std/src/vein/lang/UInt32.vein rename to lib/vein.std/std/UInt32.vein index f1904deb..fb46c954 100644 --- a/lib/vein.std/std/src/vein/lang/UInt32.vein +++ b/lib/vein.std/std/UInt32.vein @@ -1,7 +1,7 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("u32")] +[special, forwarded] public struct UInt32 : ValueType { [native("!!value")] @@ -11,4 +11,4 @@ public struct UInt32 : ValueType public const MinValue: self = 0; } -alias u32 <| UInt32; \ No newline at end of file +global alias u32 <| UInt32; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/UInt64.vein b/lib/vein.std/std/UInt64.vein similarity index 71% rename from lib/vein.std/std/src/vein/lang/UInt64.vein rename to lib/vein.std/std/UInt64.vein index 282eca1b..38c8a668 100644 --- a/lib/vein.std/std/src/vein/lang/UInt64.vein +++ b/lib/vein.std/std/UInt64.vein @@ -1,6 +1,6 @@ -#space "vein/lang" +#space "std" -[special, forwarded, alias("u64")] +[special, forwarded] public struct UInt64 : ValueType { [native("!!value")] @@ -10,4 +10,4 @@ public struct UInt64 : ValueType public const MinValue: self = 0; } -alias u64 <| UInt64; \ No newline at end of file +global alias u64 <| UInt64; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/ValueType.vein b/lib/vein.std/std/ValueType.vein similarity index 89% rename from lib/vein.std/std/src/vein/lang/ValueType.vein rename to lib/vein.std/std/ValueType.vein index c2c97d17..e6a6fdee 100644 --- a/lib/vein.std/std/src/vein/lang/ValueType.vein +++ b/lib/vein.std/std/ValueType.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" [special, forwarded] diff --git a/lib/vein.std/std/Void.vein b/lib/vein.std/std/Void.vein new file mode 100644 index 00000000..4a0713f3 --- /dev/null +++ b/lib/vein.std/std/Void.vein @@ -0,0 +1,5 @@ +#space "std" + + +[special, forwarded] +public struct Void : ValueType { } \ No newline at end of file diff --git a/lib/vein.std/std/asd/app.vein b/lib/vein.std/std/asd/app.vein deleted file mode 100644 index 1e79462a..00000000 --- a/lib/vein.std/std/asd/app.vein +++ /dev/null @@ -1,44 +0,0 @@ -#space "test" -#use "vein/lang" - -struct App { - public static master(): void { - - if (false) { - Out.print("Assert: if (false) got true! BAD"); - } - - let a1 = 1 == 1; // true - - if (!a1) { - Out.print("Assert: 1 == 1 got false!"); - } - - let a4 = 1 < 2; // true - - if (!a4) { - Out.print("Assert: 1 < 2 got false!"); - } - - let a5 = 1 <= 2; // true - - if (!a5) { - Out.print("Assert: 1 <= 2 got false!"); - } - } - - - static Fib(x: i32): i32 { - if (x == 0) return 0; - - auto prev = 0; - auto next = 1; - for (auto i = 1; i < x; i++) - { - auto sum = prev + next; - prev = next; - next = sum; - } - return next; - } -} \ No newline at end of file diff --git a/lib/vein.std/std/asd/asd.vproj b/lib/vein.std/std/asd/asd.vproj deleted file mode 100644 index eeae0f45..00000000 --- a/lib/vein.std/std/asd/asd.vproj +++ /dev/null @@ -1,7 +0,0 @@ -version: 1.0.0.0 -author: -- name: yuuki - github: '' -license: MIT license -packages: -- std@0.14.3 diff --git a/lib/vein.std/std/asd/asd_ffi.ll b/lib/vein.std/std/asd/asd_ffi.ll deleted file mode 100644 index 26ba7014..00000000 --- a/lib/vein.std/std/asd/asd_ffi.ll +++ /dev/null @@ -1,17 +0,0 @@ -; ModuleID = '_ffi' -source_filename = "_ffi" -target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" - -declare i32 @kernel32_GetConsoleWindow() - -define { [16 x i8], i32 } @GetConsoleWindow(ptr %0, i32 %1) { -entry: - %2 = call i32 @kernel32_GetConsoleWindow() - %retStackVal = alloca { [16 x i8], i32 }, align 8 - %retDataPtr = getelementptr inbounds { [16 x i8], i32 }, ptr %retStackVal, i32 0, i32 0 - store i32 %2, ptr %retDataPtr, align 4 - %retTypePtr = getelementptr inbounds { [16 x i8], i32 }, ptr %retStackVal, i32 0, i32 1 - store i32 9, ptr %retTypePtr, align 4 - %retVal = load { [16 x i8], i32 }, ptr %retStackVal, align 4 - ret { [16 x i8], i32 } %retVal -} diff --git a/lib/vein.std/std/asd/na.vein b/lib/vein.std/std/asd/na.vein deleted file mode 100644 index 939f78dd..00000000 --- a/lib/vein.std/std/asd/na.vein +++ /dev/null @@ -1,9 +0,0 @@ -#space "test" - -#use "vein/lang" - -public static class Na -{ - [native("kernel32", "GetConsoleWindow")] - public static extern foobar(): i32; -} \ No newline at end of file diff --git a/lib/vein.std/std/asd/output.o b/lib/vein.std/std/asd/output.o deleted file mode 100644 index 9fd25220..00000000 Binary files a/lib/vein.std/std/asd/output.o and /dev/null differ diff --git a/lib/vein.std/std/asd/std_ffi.ll b/lib/vein.std/std/asd/std_ffi.ll deleted file mode 100644 index 2dace21c..00000000 --- a/lib/vein.std/std/asd/std_ffi.ll +++ /dev/null @@ -1,3 +0,0 @@ -; ModuleID = '_ffi' -source_filename = "_ffi" -target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/lib/vein.std/std/src/vein/lang/aspects/Aspect.vein b/lib/vein.std/std/aspects/Aspect.vein similarity index 93% rename from lib/vein.std/std/src/vein/lang/aspects/Aspect.vein rename to lib/vein.std/std/aspects/Aspect.vein index c04d1c73..11eb9e06 100644 --- a/lib/vein.std/std/src/vein/lang/aspects/Aspect.vein +++ b/lib/vein.std/std/aspects/Aspect.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" [special, forwarded] public class Aspect : Object diff --git a/lib/vein.std/std/src/vein/lang/aspects/LineAspect.vein b/lib/vein.std/std/aspects/LineAspect.vein similarity index 100% rename from lib/vein.std/std/src/vein/lang/aspects/LineAspect.vein rename to lib/vein.std/std/aspects/LineAspect.vein diff --git a/lib/vein.std/std/src/vein/lang/collections/IYieldable.vein b/lib/vein.std/std/collections/IYieldable.vein similarity index 75% rename from lib/vein.std/std/src/vein/lang/collections/IYieldable.vein rename to lib/vein.std/std/collections/IYieldable.vein index b3aa17df..f2e35961 100644 --- a/lib/vein.std/std/src/vein/lang/collections/IYieldable.vein +++ b/lib/vein.std/std/collections/IYieldable.vein @@ -3,9 +3,9 @@ public interface IYieldable { - Current: object { get; set; } + Current: Object { get; set; } public MoveNext(): bool; - public Reset(): void; + public Reset(): Void; } public interface IYield diff --git a/lib/vein.std/std/collections/List.vein1 b/lib/vein.std/std/collections/List.vein1 new file mode 100644 index 00000000..9f92a15a --- /dev/null +++ b/lib/vein.std/std/collections/List.vein1 @@ -0,0 +1,35 @@ +#space "vein/lang" + +public class List +{ + Add(value: T): Void; + Remove(value: T): Void; + RemoveAt(index: i32): Void; + AddRange(values: T[]): Void; + Get(index: i32): T; +} + + +public class Queue +{ + Enqueue(value: T): Void; + Dequeue(): T; + Clear(): Void; +} + + +public class Map +{ + Add(key: TKey, value: TValue): Void; + Remove(key: TKey): Void; + ContainsKey(key: TKey): Void; + Get(key: TKey): TValue; +} + +public class Stack +{ + Push(value: T): Void; + Peek(): T; + Pop(): T; + Clear(): Void; +} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/collections/Yieldable.vein b/lib/vein.std/std/collections/Yieldable.vein similarity index 79% rename from lib/vein.std/std/src/vein/lang/collections/Yieldable.vein rename to lib/vein.std/std/collections/Yieldable.vein index e1e02d65..00f0a875 100644 --- a/lib/vein.std/std/src/vein/lang/collections/Yieldable.vein +++ b/lib/vein.std/std/collections/Yieldable.vein @@ -4,8 +4,8 @@ public class Yieldable { - private _current: object; - public Current: object + private _current: Object; + public Current: Object { get { diff --git a/lib/vein.std/std/src/vein/lang/diag/Stopwatch.vein b/lib/vein.std/std/diag/Stopwatch.vein similarity index 89% rename from lib/vein.std/std/src/vein/lang/diag/Stopwatch.vein rename to lib/vein.std/std/diag/Stopwatch.vein index c8182cea..44429252 100644 --- a/lib/vein.std/std/src/vein/lang/diag/Stopwatch.vein +++ b/lib/vein.std/std/diag/Stopwatch.vein @@ -28,15 +28,15 @@ public class Stopwatch } - public Start(): void { } - public Stop(): void { } - public Reset(): void + public Start(): Void { } + public Stop(): Void { } + public Reset(): Void { elapsed = 0; isRunning = false; startTimeStamp = 0; } - public Restart(): void + public Restart(): Void { elapsed = 0; startTimeStamp = this.getTimestamp(); diff --git a/lib/vein.std/std/src/icon.png b/lib/vein.std/std/icon.png similarity index 100% rename from lib/vein.std/std/src/icon.png rename to lib/vein.std/std/icon.png diff --git a/lib/vein.std/std/src/vein/lang/internal/IEEEConsts.vein b/lib/vein.std/std/internal/IEEEConsts.vein similarity index 98% rename from lib/vein.std/std/src/vein/lang/internal/IEEEConsts.vein rename to lib/vein.std/std/internal/IEEEConsts.vein index ae6f8224..67c743b4 100644 --- a/lib/vein.std/std/src/vein/lang/internal/IEEEConsts.vein +++ b/lib/vein.std/std/internal/IEEEConsts.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" internal static class IEEEConsts { diff --git a/lib/vein.std/std/src/vein/lang/internal/Sys.vein_ b/lib/vein.std/std/internal/Sys.vein_ similarity index 100% rename from lib/vein.std/std/src/vein/lang/internal/Sys.vein_ rename to lib/vein.std/std/internal/Sys.vein_ diff --git a/lib/vein.std/std/src/vein/lang/network/Ipv4Addr.vein b/lib/vein.std/std/network/Ipv4Addr.vein similarity index 75% rename from lib/vein.std/std/src/vein/lang/network/Ipv4Addr.vein rename to lib/vein.std/std/network/Ipv4Addr.vein index e4bc89eb..a099c0e6 100644 --- a/lib/vein.std/std/src/vein/lang/network/Ipv4Addr.vein +++ b/lib/vein.std/std/network/Ipv4Addr.vein @@ -20,14 +20,14 @@ public class TcpSocket { public listen(backlog: i32, fn: Function): boolean; - public accept(handle: raw, read: Function, write: Function): void; + public accept(handle: raw, read: Function, write: Function): Void; - public write(handle: raw, req: raw, cb: Function): void; - public read(handle: raw, resp: raw, cb: Function): void; + public write(handle: raw, req: raw, cb: Function): Void; + public read(handle: raw, resp: raw, cb: Function): Void; - public keepAlive(enable: bool, delay: u32): void; + public keepAlive(enable: bool, delay: u32): Void; public isReadable(handle: raw): boolean; public isWritable(handle: raw): boolean; diff --git a/lib/vein.std/std/network/NetworkStream.vein b/lib/vein.std/std/network/NetworkStream.vein new file mode 100644 index 00000000..1217d8d5 --- /dev/null +++ b/lib/vein.std/std/network/NetworkStream.vein @@ -0,0 +1,12 @@ +#space "vein/lang/network" + +#use "vein/lang" + +public class NetworkStream : Object +{ + /* + public read(): u8[] {} + public write(u8s: u8[]): Void {} + public flush(): Void {} + */ +} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/network/TcpListener.vein b/lib/vein.std/std/network/TcpListener.vein similarity index 96% rename from lib/vein.std/std/src/vein/lang/network/TcpListener.vein rename to lib/vein.std/std/network/TcpListener.vein index 9c1248ef..79427460 100644 --- a/lib/vein.std/std/src/vein/lang/network/TcpListener.vein +++ b/lib/vein.std/std/network/TcpListener.vein @@ -24,7 +24,7 @@ public class TcpListener return _active; } - public Start(): void + public Start(): Void { //this._socket.Listen(9999); } diff --git a/lib/vein.std/std/src/vein/lang/network/TcpSocket.vein b/lib/vein.std/std/network/TcpSocket.vein similarity index 94% rename from lib/vein.std/std/src/vein/lang/network/TcpSocket.vein rename to lib/vein.std/std/network/TcpSocket.vein index b9f8cd1e..385c1d58 100644 --- a/lib/vein.std/std/src/vein/lang/network/TcpSocket.vein +++ b/lib/vein.std/std/network/TcpSocket.vein @@ -2,7 +2,7 @@ #use "vein/lang" -public class TcpSocket +public class TcpSocket2 { private _port: u16; private _is_listing: bool; @@ -25,7 +25,7 @@ public class TcpSocket public IsListed(): bool { return _is_listing; } public IsConnected(): bool { return _connected; } - public Bind(): void + public Bind(): Void { } public Send(buffer: u8[]): i32 @@ -37,7 +37,7 @@ public class TcpSocket return 0; } - public Listen(cq: i32): void + public Listen(cq: i32): Void { /* auto errorCode = TcpSocket._sock_listen(this._handle, cq); diff --git a/lib/vein.std/std/src/vein/lang/numeric/BigInt.vein b/lib/vein.std/std/numeric/BigInt.vein similarity index 100% rename from lib/vein.std/std/src/vein/lang/numeric/BigInt.vein rename to lib/vein.std/std/numeric/BigInt.vein diff --git a/lib/vein.std/std/src/vein/lang/numeric/Quaternion.vein b/lib/vein.std/std/numeric/Quaternion.vein similarity index 100% rename from lib/vein.std/std/src/vein/lang/numeric/Quaternion.vein rename to lib/vein.std/std/numeric/Quaternion.vein diff --git a/lib/vein.std/std/raw.vein b/lib/vein.std/std/raw.vein new file mode 100644 index 00000000..c337a601 --- /dev/null +++ b/lib/vein.std/std/raw.vein @@ -0,0 +1,9 @@ +#space "std" + + +[special, forwarded, native] +internal struct Raw {} + + +global alias raw <| Raw; +global alias ptr <| Raw; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/reflection/Field.vein_ b/lib/vein.std/std/reflection/Field.vein_ similarity index 100% rename from lib/vein.std/std/src/vein/lang/reflection/Field.vein_ rename to lib/vein.std/std/reflection/Field.vein_ diff --git a/lib/vein.std/std/src/vein/lang/reflection/Function.vein b/lib/vein.std/std/reflection/Function.vein similarity index 66% rename from lib/vein.std/std/src/vein/lang/reflection/Function.vein rename to lib/vein.std/std/reflection/Function.vein index 6e325610..04206f1f 100644 --- a/lib/vein.std/std/src/vein/lang/reflection/Function.vein +++ b/lib/vein.std/std/reflection/Function.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" public class Function : Object { @@ -18,20 +18,21 @@ public class Function : Object internal new() { } // internal ctor - public call(): object + /* + public call(): Object |> self._call(this, Array.empty); - public call(args: Array): object + public call(args: Array): Object |> self._call(this, args); - public static createFunctionFrom(target: object, name: string): Function + public static createFunctionFrom(target: Object, name: string): Function |> self._createFn(target, name, false, true); - public static createFunctionFrom(target: object, name: string, ignoreCase: boolean): Function + public static createFunctionFrom(target: Object, name: string, ignoreCase: boolean): Function |> self._createFn(target, name, ignoreCase, true); - public static createFunctionFrom(target: object, name: string, ignoreCase: boolean, throwWhenFailBind: boolean): Function + public static createFunctionFrom(target: Object, name: string, ignoreCase: boolean, throwWhenFailBind: boolean): Function |> self._createFn(target, name, ignoreCase, throwWhenFailBind); [native("__internal__", "i_call_Function_call")] - private static extern _call(f: Function, args: Array): object; + private static extern _call(f: Function, args: Array): Object; [native("__internal__", "i_call_Function_create")] - private static extern _createFn(target: object, name: string, ignoreCase: boolean, throwWhenFailBind: boolean): Function; + private static extern _createFn(target: Object, name: string, ignoreCase: boolean, throwWhenFailBind: boolean): Function;*/ } \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/reflection/Type.vein b/lib/vein.std/std/reflection/Type.vein similarity index 93% rename from lib/vein.std/std/src/vein/lang/reflection/Type.vein rename to lib/vein.std/std/reflection/Type.vein index faf15343..9687b2eb 100644 --- a/lib/vein.std/std/src/vein/lang/reflection/Type.vein +++ b/lib/vein.std/std/reflection/Type.vein @@ -1,6 +1,6 @@ -#space "vein/lang" +#space "std" -#use "vein/lang/workspace" +#use "std/workspace" public class Type { @@ -35,7 +35,7 @@ public class Type - public static findByName(s: string): Type + /*public static findByName(s: string): Type |> self._findByName(s); public static tryFindByName(s: string): Type @@ -58,5 +58,5 @@ public class Type [native("__internal__", "i_call_Type_findByName")] private static extern _findByName(name: string): Type; [native("__internal__", "i_call_Type_findMethod")] - private static extern _findMethod(t: Type, name: string): Function; + private static extern _findMethod(t: Type, name: string): Function;*/ } \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/reflection/faults.vein b/lib/vein.std/std/reflection/faults.vein similarity index 94% rename from lib/vein.std/std/src/vein/lang/reflection/faults.vein rename to lib/vein.std/std/reflection/faults.vein index 17fcc30b..5d87407d 100644 --- a/lib/vein.std/std/src/vein/lang/reflection/faults.vein +++ b/lib/vein.std/std/reflection/faults.vein @@ -1,4 +1,4 @@ -#space "vein/lang" +#space "std" public class TypeNotFoundFault : Exception { diff --git a/lib/vein.std/std/src/readme.md b/lib/vein.std/std/src/readme.md deleted file mode 100644 index 0dcd9fc0..00000000 --- a/lib/vein.std/std/src/readme.md +++ /dev/null @@ -1,2 +0,0 @@ -## A standard core library for Ishtar VM and Vein Lang - diff --git a/lib/vein.std/std/src/vein/lang/Byte.vein b/lib/vein.std/std/src/vein/lang/Byte.vein deleted file mode 100644 index 51a39d42..00000000 --- a/lib/vein.std/std/src/vein/lang/Byte.vein +++ /dev/null @@ -1,20 +0,0 @@ -#space "vein/lang" - - -[special, forwarded, alias("u8")] -public struct Byte : ValueType -{ - [native("!!value")] - private _value: ValueType; - - public foo(): void - |> Call.call(); - - public foo(): void { - while(true) { - let a = 15; - } - } -} - -alias u8 <| Byte; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/GC.vein b/lib/vein.std/std/src/vein/lang/GC.vein deleted file mode 100644 index 80632037..00000000 --- a/lib/vein.std/std/src/vein/lang/GC.vein +++ /dev/null @@ -1,15 +0,0 @@ -#space "vein/lang" - - -public static class GC -{ - public static allocated: u64 - |> self._get_allocated(); - public static alive_objects: u64 - |> self._get_alive_objects(); - - [native("__internal__", "i_call_GC_get_allocated")] - private static extern _get_allocated(): u64; - [native("__internal__", "i_call_GC_get_alive_objects")] - private static extern _get_alive_objects(): u64; -} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Object.vein b/lib/vein.std/std/src/vein/lang/Object.vein deleted file mode 100644 index 1c32530d..00000000 --- a/lib/vein.std/std/src/vein/lang/Object.vein +++ /dev/null @@ -1,9 +0,0 @@ -#space "vein/lang" - - -[special, forwarded, alias("object")] -public class Object -{ - public virtual toString(): string - |> ""; -} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Out.vein b/lib/vein.std/std/src/vein/lang/Out.vein deleted file mode 100644 index 37e2f41f..00000000 --- a/lib/vein.std/std/src/vein/lang/Out.vein +++ /dev/null @@ -1,17 +0,0 @@ -#space "vein/lang" - - -public static class Out -{ - [native("__internal__", "@_println")] - public extern static @_println(value: Object): void; - [native("__internal__", "@_println")] - public extern static @_println(value: i32): void; - - public static print(value: string): void - |> Out.@_println(value); - - public static print(value: i32): void - |> Out.@_println(value); -} - diff --git a/lib/vein.std/std/src/vein/lang/Testable.vein b/lib/vein.std/std/src/vein/lang/Testable.vein deleted file mode 100644 index 57543a4a..00000000 --- a/lib/vein.std/std/src/vein/lang/Testable.vein +++ /dev/null @@ -1,9 +0,0 @@ -#space "vein/lang" - -public class Testable -{ - public static master(): void - { - Out.print("yamete..."); - } -} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/Void.vein b/lib/vein.std/std/src/vein/lang/Void.vein deleted file mode 100644 index 99bace7b..00000000 --- a/lib/vein.std/std/src/vein/lang/Void.vein +++ /dev/null @@ -1,7 +0,0 @@ -#space "vein/lang" - - -[special, forwarded, alias("void")] -public struct Void : ValueType { } - -alias Void <| void; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/collections/List.vein b/lib/vein.std/std/src/vein/lang/collections/List.vein deleted file mode 100644 index 42ebaee3..00000000 --- a/lib/vein.std/std/src/vein/lang/collections/List.vein +++ /dev/null @@ -1,35 +0,0 @@ -#space "vein/lang" - -public class List -{ - Add(value: T): void; - Remove(value: T): void; - RemoveAt(index: i32): void; - AddRange(values: T[]): void; - Get(index: i32): T; -} - - -public class Queue -{ - Enqueue(value: T): void; - Dequeue(): T; - Clear(): void; -} - - -public class Map -{ - Add(key: TKey, value: TValue): void; - Remove(key: TKey): void; - ContainsKey(key: TKey): void; - Get(key: TKey): TValue; -} - -public class Stack -{ - Push(value: T): void; - Peek(): T; - Pop(): T; - Clear(): void; -} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/network/NetworkStream.vein b/lib/vein.std/std/src/vein/lang/network/NetworkStream.vein deleted file mode 100644 index e960512e..00000000 --- a/lib/vein.std/std/src/vein/lang/network/NetworkStream.vein +++ /dev/null @@ -1,12 +0,0 @@ -#space "vein/lang/network" - -#use "vein/lang" - -public class NetworkStream : object -{ - /* - public read(): u8[] {} - public write(u8s: u8[]): void {} - public flush(): void {} - */ -} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/raw.vein b/lib/vein.std/std/src/vein/lang/raw.vein deleted file mode 100644 index 654b3525..00000000 --- a/lib/vein.std/std/src/vein/lang/raw.vein +++ /dev/null @@ -1,9 +0,0 @@ -#space "vein/lang" - - -[special, forwarded, native, alias("raw")] -internal struct Raw {} - - -alias raw <| Raw; -alias ptr <| Raw; \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/threading/IshtarTask.vein b/lib/vein.std/std/src/vein/lang/threading/IshtarTask.vein deleted file mode 100644 index b25613a3..00000000 --- a/lib/vein.std/std/src/vein/lang/threading/IshtarTask.vein +++ /dev/null @@ -1,14 +0,0 @@ -#space "vein/lang" - -public class Job {} - -alias MyMethod(f: i32): void; -public class Job -{ - -} - -public class Job[TResult] when TResult is i32 -{ - -} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/workspace/Deprecated.vein b/lib/vein.std/std/src/vein/lang/workspace/Deprecated.vein deleted file mode 100644 index 10fe46a6..00000000 --- a/lib/vein.std/std/src/vein/lang/workspace/Deprecated.vein +++ /dev/null @@ -1,4 +0,0 @@ -#space "vein/lang/workspace" -#use "vein/lang" - -public aspect DeprecatedAspect(); \ No newline at end of file diff --git a/lib/vein.std/std/src/std.vproj b/lib/vein.std/std/std.vproj similarity index 100% rename from lib/vein.std/std/src/std.vproj rename to lib/vein.std/std/std.vproj diff --git a/lib/vein.std/std/test/icon.png b/lib/vein.std/std/test/icon.png deleted file mode 100644 index e6fda943..00000000 Binary files a/lib/vein.std/std/test/icon.png and /dev/null differ diff --git a/lib/vein.std/std/test/readme.md b/lib/vein.std/std/test/readme.md deleted file mode 100644 index e85a065e..00000000 --- a/lib/vein.std/std/test/readme.md +++ /dev/null @@ -1,47 +0,0 @@ ---- - -> Vein is an open source high-level strictly-typed programming language with a standalone OS, arm and quantum computing support. - ---- - -## OS Support - -OS | Version | Architectures -------------------------------|-------------------------------|---------------- -Windows 10 | 1607+ | x64, ARM64 -OSX | 10.14+ | x64 -Linux | | x64, ARM64 - - -## Compiling from source - -### Building on Windows - -For building, you need the following tools: -- dotnet 6.0 -- Win10 SDK -- vsbuild-tools-2019 with MSVC 2019, MSVC142 for ARM64 - - -Checkout mana sources -```bash -git clone https://github.com/vein-lang/vein.git --recurse-submodules -cd ./vein-lang -git fetch --prune --unshallow --tags - -dotnet restore -``` - -#### Compile IshtarVM -Go to ishtar folder -```base -cd ./runtime/ishtar.vm -``` -Compile for Windows 10 x64 -```bash -dotnet publish -r win10-x64 -c Release -``` -Compile for Windows 10 ARM64 -``` -dotnet publish -r win-arm64 -c Release -``` \ No newline at end of file diff --git a/lib/vein.std/std/test/test.std.vproj b/lib/vein.std/std/test/test.std.vproj deleted file mode 100644 index b4b0ec70..00000000 --- a/lib/vein.std/std/test/test.std.vproj +++ /dev/null @@ -1,15 +0,0 @@ -sdk: no-runtime -version: 1.0.0.0-preview -packages: - - ./../src/std.vproj -packable: true -author: - - name: 'Yuuki Wesp' - github: '0xF6' -license: MIT -urls: - BugUrl: https://github.com/vein-lang/std - HomepageUrl: https://github.com/vein-lang/std - Repository: https://github.com/vein-lang/std - otherUrls: - discord: https://discord.gg/213123 diff --git a/lib/vein.std/std/test/test.vein b/lib/vein.std/std/test/test.vein deleted file mode 100644 index ac5e58af..00000000 --- a/lib/vein.std/std/test/test.vein +++ /dev/null @@ -1,12 +0,0 @@ -#space "test" - -#use "vein/lang" - -public class Testable -{ - public static master(): void - { - Out.print("yamete..."); - FooBar.GetConsoleWindow(); - } -} diff --git a/lib/vein.std/std/test/testffi.vein b/lib/vein.std/std/test/testffi.vein deleted file mode 100644 index 7fb66beb..00000000 --- a/lib/vein.std/std/test/testffi.vein +++ /dev/null @@ -1,9 +0,0 @@ -#space "test" - -#use "vein/lang" - - -public class FooBar { - [native("kernel32", "GetConsoleWindow")] - public extern static GetConsoleWindow(): raw; -} \ No newline at end of file diff --git a/lib/vein.std/std/threading/IshtarTask.vein b/lib/vein.std/std/threading/IshtarTask.vein new file mode 100644 index 00000000..85e2539c --- /dev/null +++ b/lib/vein.std/std/threading/IshtarTask.vein @@ -0,0 +1,3 @@ +#space "std" + +class Job{} \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/threading/Promise.vein b/lib/vein.std/std/threading/Promise.vein2 similarity index 76% rename from lib/vein.std/std/src/vein/lang/threading/Promise.vein rename to lib/vein.std/std/threading/Promise.vein2 index 38d9cf01..f3c1df1a 100644 --- a/lib/vein.std/std/src/vein/lang/threading/Promise.vein +++ b/lib/vein.std/std/threading/Promise.vein2 @@ -1,8 +1,8 @@ -#space "vein/lang" +#space "std" public struct Promise { - public Wait(): void; + public Wait(): Void; public TryWait(time: TimeSpan): bool; @@ -10,8 +10,8 @@ public struct Promise public Then(onResolved: Function): Promise; public Catch(onRejected: Function): Promise; - public static WaitAll(list: Promise[]): void; - public static WaitAny(list: Promise[]): void; + public static WaitAll(list: Promise[]): Void; + public static WaitAny(list: Promise[]): Void; public static WhenAll(list: Promise[]): Promise[]; public static WhenAny(list: Promise[]): Promise; public static When(list: Promise[], predicate: PromiseSelector): Promise; diff --git a/lib/vein.std/std/workspace/Deprecated.vein b/lib/vein.std/std/workspace/Deprecated.vein new file mode 100644 index 00000000..e28f2fab --- /dev/null +++ b/lib/vein.std/std/workspace/Deprecated.vein @@ -0,0 +1,4 @@ +#space "std/workspace" +#use "std" + +public aspect DeprecatedAspect(); \ No newline at end of file diff --git a/lib/vein.std/std/src/vein/lang/workspace/MaybeNullable.vein b/lib/vein.std/std/workspace/MaybeNullable.vein similarity index 67% rename from lib/vein.std/std/src/vein/lang/workspace/MaybeNullable.vein rename to lib/vein.std/std/workspace/MaybeNullable.vein index ae0bb61d..853889be 100644 --- a/lib/vein.std/std/src/vein/lang/workspace/MaybeNullable.vein +++ b/lib/vein.std/std/workspace/MaybeNullable.vein @@ -1,5 +1,5 @@ -#space "vein/lang/workspace" -#use "vein/lang" +#space "std/workspace" +#use "std" // hmm, maybe need add syntax-sugar for mark as nullable public aspect MaybeNullableAspect(); \ No newline at end of file diff --git a/lib/vein.std/vein.std.csproj b/lib/vein.std/vein.std.csproj index fba8ccf9..139da079 100644 --- a/lib/vein.std/vein.std.csproj +++ b/lib/vein.std/vein.std.csproj @@ -9,9 +9,8 @@ - - - + diff --git a/runtime/common/reflection/Aspect.cs b/runtime/common/reflection/Aspect.cs index fb27d407..5f289f5f 100644 --- a/runtime/common/reflection/Aspect.cs +++ b/runtime/common/reflection/Aspect.cs @@ -4,7 +4,7 @@ namespace vein.reflection using System.Collections.Generic; using System.Diagnostics; using System.Linq; - using vein.runtime; + using runtime; public class AspectArgument { @@ -70,6 +70,8 @@ public static class AspectExtensions public class Aspect { + public const string ASPECT_METADATA_DIVIDER = "#"; + public string Name { get; } public AspectTarget Target { get; } @@ -96,11 +98,11 @@ public static Aspect[] Deconstruct(Dictionary dictionary) { static AspectTarget getTarget(FieldName name) { - if (name.fullName.Contains("/method/")) + if (name.fullName.Contains($"{ASPECT_METADATA_DIVIDER}method{ASPECT_METADATA_DIVIDER}")) return AspectTarget.Method; - if (name.fullName.Contains("/field/")) + if (name.fullName.Contains($"{ASPECT_METADATA_DIVIDER}field{ASPECT_METADATA_DIVIDER}")) return AspectTarget.Field; - if (name.fullName.Contains("/class/")) + if (name.fullName.Contains($"{ASPECT_METADATA_DIVIDER}class{ASPECT_METADATA_DIVIDER}")) return AspectTarget.Class; throw new UnknownAspectTargetException(name); @@ -110,7 +112,7 @@ static AspectTarget getTarget(FieldName name) // shit var groups = - dictionary.Where(x => x.Key.fullName.StartsWith("aspect/")) + dictionary.Where(x => x.Key.fullName.StartsWith($"aspect{ASPECT_METADATA_DIVIDER}")) .Select(x => (getTarget(x.Key), x)) .GroupBy(x => x.Item1) .ToArray(); @@ -143,24 +145,24 @@ static AspectTarget getTarget(FieldName name) // rly shit var groupClasses = classes.GroupBy(x => - x.Key.fullName.Replace("aspect/", "") - .Replace("/class", "") + x.Key.fullName.Replace($"aspect{ASPECT_METADATA_DIVIDER}", "") + .Replace($"{ASPECT_METADATA_DIVIDER}class", "") .Split('.').First()); var groupMethods = methods.GroupBy(x => - x.Key.fullName.Replace("aspect/", "") - .Replace("/class", "") - .Replace("/method", "") + x.Key.fullName.Replace($"aspect{ASPECT_METADATA_DIVIDER}", "") + .Replace($"{ASPECT_METADATA_DIVIDER}class", "") + .Replace($"{ASPECT_METADATA_DIVIDER}method", "") .Split('.').First()); var groupFields = fields.GroupBy(x => - x.Key.fullName.Replace("aspect/", "") - .Replace("/class", "") - .Replace("/field", "") + x.Key.fullName.Replace($"aspect{ASPECT_METADATA_DIVIDER}", "") + .Replace($"{ASPECT_METADATA_DIVIDER}class", "") + .Replace($"{ASPECT_METADATA_DIVIDER}field", "") .Split('.').First()); foreach (var groupClass in groupClasses) { - var aspectName = groupClass.Key.Split('/').First(); - var aspectClass = groupClass.Key.Split('/').Last(); + var aspectName = groupClass.Key.Split(ASPECT_METADATA_DIVIDER).First(); + var aspectClass = groupClass.Key.Split(ASPECT_METADATA_DIVIDER).Last(); var aspect = new AspectOfClass(aspectName, aspectClass); foreach (var (key, value) in groupClass) { @@ -171,9 +173,9 @@ static AspectTarget getTarget(FieldName name) } foreach (var groupMethod in groupMethods) { - var aspectName = groupMethod.Key.Split('/')[0]; - var aspectClass = groupMethod.Key.Split('/')[1]; - var aspectMethod = groupMethod.Key.Split('/')[2]; + var aspectName = groupMethod.Key.Split(ASPECT_METADATA_DIVIDER)[0]; + var aspectClass = groupMethod.Key.Split(ASPECT_METADATA_DIVIDER)[1]; + var aspectMethod = groupMethod.Key.Split(ASPECT_METADATA_DIVIDER)[2]; var aspect = new AspectOfMethod(aspectName, aspectClass, aspectMethod); foreach (var (key, value) in groupMethod) { @@ -184,9 +186,9 @@ static AspectTarget getTarget(FieldName name) } foreach (var groupMethod in groupFields) { - var aspectName = groupMethod.Key.Split('/')[0]; - var aspectClass = groupMethod.Key.Split('/')[1]; - var aspectField = groupMethod.Key.Split('/')[2]; + var aspectName = groupMethod.Key.Split(ASPECT_METADATA_DIVIDER)[0]; + var aspectClass = groupMethod.Key.Split(ASPECT_METADATA_DIVIDER)[1]; + var aspectField = groupMethod.Key.Split(ASPECT_METADATA_DIVIDER)[2]; var aspect = new AspectOfField(aspectName, aspectClass, aspectField); foreach (var (key, value) in groupMethod) { diff --git a/runtime/common/reflection/TypeName.cs b/runtime/common/reflection/TypeName.cs index 9a719add..f846b928 100644 --- a/runtime/common/reflection/TypeName.cs +++ b/runtime/common/reflection/TypeName.cs @@ -1,115 +1,112 @@ -namespace vein.runtime +namespace vein.runtime; + +using System; +using System.Linq; +using System.Text.RegularExpressions; +using extensions; + +public class InvalidTypeNameException(string msg) : Exception(msg); +public class QualityTypeName(string fullName) : IEquatable { - using System; - using System.Linq; - using System.Text.RegularExpressions; - using extensions; + private string _name, _namespace, _asmName, _nameWithNS; + private readonly string _fullName = fullName; - public class InvalidTypeNameException : Exception { public InvalidTypeNameException(string msg) : base(msg) { } } - public class QualityTypeName : IEquatable + public string Name { - private string _name, _namespace, _asmName, _nameWithNS; - private readonly string _fullName; - - public string Name + get { - get - { - if (_name is not null) - return _name; - return _name = _fullName.Split('/').Last(); - } + if (_name is not null) + return _name; + return _name = _fullName.Split('/').Last(); } + } - public string Namespace + public string Namespace + { + get { - get - { - if (_namespace is not null) - return _namespace; - return _namespace = _fullName - .Split('/') - .SkipLast(1).Join("/") - .Split("%").Skip(1) - .Join("/"); - } + if (_namespace is not null) + return _namespace; + return _namespace = _fullName + .Split('/') + .SkipLast(1).Join("/") + .Split("%").Skip(1) + .Join("/"); } + } - public string AssemblyName + public string AssemblyName + { + get { - get - { - if (_asmName is not null) - return _asmName; - return _asmName = _fullName.Split("%").SkipLast(1).Join(); - } + if (_asmName is not null) + return _asmName; + return _asmName = _fullName.Split("%").SkipLast(1).Join(); } + } - public string NameWithNS + public string NameWithNS + { + get { - get - { - if (_nameWithNS is not null) - return _nameWithNS; - return _nameWithNS = _fullName.Split("%").Skip(1).Join(); - } + if (_nameWithNS is not null) + return _nameWithNS; + return _nameWithNS = _fullName.Split("%").Skip(1).Join(); } + } - public string FullName => _fullName; - - public QualityTypeName(string fullName) => this._fullName = fullName; + public string FullName => _fullName; - public QualityTypeName(string asmName, string name, string ns) : this($"{asmName}%{ns}/{name}") - { - this._namespace = ns; - this._name = name; - this._asmName = asmName; - this._nameWithNS = $"{ns}/{name}"; - } + public QualityTypeName(string asmName, string name, string ns) : this($"{asmName}%{ns}/{name}") + { + _namespace = ns; + _name = name; + _asmName = asmName; + _nameWithNS = $"{ns}/{name}"; + } - public static implicit operator QualityTypeName(string name) - { - if (!Regex.IsMatch(name, @"(.+)\%global::(.+)\/(.+)")) - throw new InvalidTypeNameException($"'{name}' is not valid type name."); - return new QualityTypeName(name); - } + public static implicit operator QualityTypeName(string name) + { + if (!Regex.IsMatch(name, @"(.+)\%global::(.+)\/(.+)")) + throw new InvalidTypeNameException($"'{name}' is not valid type name."); + return new QualityTypeName(name); + } - public override string ToString() => _fullName; + public override string ToString() => _fullName; - internal T TryGet(Func t) where T : class + internal T TryGet(Func t) where T : class + { + try { - try - { - return t(this); - } - catch - { - return null; - } + return t(this); } - - public static bool operator ==(QualityTypeName q1, QualityTypeName q2) + catch { - if (q1 is null or { _fullName: null }) return false; - if (q2 is null or { _fullName: null }) return false; - return q1._fullName.Equals(q2._fullName, StringComparison.InvariantCultureIgnoreCase); + return null; } + } - public static bool operator !=(QualityTypeName q1, QualityTypeName q2) => !(q1 == q2); - protected bool Equals(QualityTypeName other) => _fullName == other._fullName; + public static bool operator ==(QualityTypeName q1, QualityTypeName q2) + { + if (q1 is null or { _fullName: null }) return false; + if (q2 is null or { _fullName: null }) return false; + return q1._fullName.Equals(q2._fullName, StringComparison.InvariantCultureIgnoreCase); + } - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((QualityTypeName)obj); - } + public static bool operator !=(QualityTypeName q1, QualityTypeName q2) => !(q1 == q2); + protected bool Equals(QualityTypeName other) => _fullName == other._fullName; - public override int GetHashCode() => (_fullName != null ? _fullName.GetHashCode() : 0); - bool IEquatable.Equals(QualityTypeName other) => Equals(other); + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((QualityTypeName)obj); } + + public override int GetHashCode() => (_fullName != null ? _fullName.GetHashCode() : 0); + bool IEquatable.Equals(QualityTypeName other) => Equals(other); } diff --git a/runtime/common/reflection/UnresolvedWaveClass.cs b/runtime/common/reflection/UnresolvedWaveClass.cs index bec1a5a3..2c772b09 100644 --- a/runtime/common/reflection/UnresolvedWaveClass.cs +++ b/runtime/common/reflection/UnresolvedWaveClass.cs @@ -1,10 +1,10 @@ namespace vein.reflection { - using vein.runtime; + using runtime; public class UnresolvedVeinClass : VeinClass { public UnresolvedVeinClass(QualityTypeName fullName) - => this.FullName = fullName; + => FullName = fullName; } } diff --git a/runtime/common/reflection/VeinArgumentRef.cs b/runtime/common/reflection/VeinArgumentRef.cs index 1b6fdfbe..d7985360 100644 --- a/runtime/common/reflection/VeinArgumentRef.cs +++ b/runtime/common/reflection/VeinArgumentRef.cs @@ -1,30 +1,46 @@ -namespace vein.runtime +namespace vein.runtime; +#nullable enable +using System; + +public class VeinArgumentRef { - using System; + public const string THIS_ARGUMENT = ""; + + public VeinComplexType ComplexType { get; private set; } + public string Name { get; } + - public class VeinArgumentRef + public void Temp_ReplaceType(VeinClass @class) { - public const string THIS_ARGUMENT = ""; + if (IsGeneric) throw new NotSupportedException(); + ComplexType = @class; + } + - public VeinClass Type { get; set; } - public string Name { get; set; } + public VeinTypeArg TypeArg => ComplexType.TypeArg; + public VeinClass Type => ComplexType.Class; - public VeinArgumentRef() { } - public VeinArgumentRef(string name, VeinClass clazz) - => (Name, Type) = (name, clazz); + public bool IsGeneric => ComplexType.IsGeneric; - public static VeinArgumentRef Create(VeinCore types, (string name, VeinTypeCode code) data) - { - var (name, code) = data; - return new VeinArgumentRef - { - Name = name, - Type = code.AsClass()(types) - }; - } + public VeinArgumentRef(string name, VeinClass clazz) + { + Name = name; + ComplexType = clazz; + } - public static VeinArgumentRef Create(VeinCore types, (VeinTypeCode code, string name) data) => - Create(types, (data.name, data.code)); + public VeinArgumentRef(string name, VeinTypeArg typeArg) + { + Name = name; + ComplexType = typeArg; } + + public string ToTemplateString() => ComplexType!.ToTemplateString(); + + + public static VeinArgumentRef Create(VeinCore types, (string name, VeinTypeCode code) data) + => new(data.name, data.code.AsClass()(types)); + + public static VeinArgumentRef Create(VeinCore types, (VeinTypeCode code, string name) data) => + Create(types, (data.name, data.code)); } diff --git a/runtime/common/reflection/VeinBaseConstraint.cs b/runtime/common/reflection/VeinBaseConstraint.cs new file mode 100644 index 00000000..9ef12fa6 --- /dev/null +++ b/runtime/common/reflection/VeinBaseConstraint.cs @@ -0,0 +1,35 @@ +namespace vein.runtime; + +using System; +using System.Collections.Generic; + +public record VeinBaseConstraint(VeinTypeParameterConstraint Constraint); + + +public record VeinBaseConstraintConstType(VeinClass classes) + : VeinBaseConstraint(VeinTypeParameterConstraint.TYPE); + +public record VeinBaseConstraintConstBittable() + : VeinBaseConstraint(VeinTypeParameterConstraint.BITTABLE); + +public record VeinBaseConstraintConstClass() + : VeinBaseConstraint(VeinTypeParameterConstraint.CLASS); + +public record VeinBaseConstraintConstSignature(VeinClass @interface) + : VeinBaseConstraint(VeinTypeParameterConstraint.SIGNATURE); + +[Flags] +public enum VeinTypeParameterConstraint : int +{ + TYPE = 1 << 1, // when T is Type + BITTABLE = 1 << 2, // when T is bittable + SIGNATURE = 1 << 3, // when T is { new(), method(): i32 } + CLASS = 1 << 4, // when T is class +} + + +public record VeinTypeArg(string Name, IReadOnlyList Constraints) +{ + public override string ToString() => $"µ{Name}"; + public string ToTemplateString() => ToString(); +} diff --git a/runtime/common/reflection/VeinClass.cs b/runtime/common/reflection/VeinClass.cs index 4ca67a0c..a0e34619 100644 --- a/runtime/common/reflection/VeinClass.cs +++ b/runtime/common/reflection/VeinClass.cs @@ -11,7 +11,7 @@ namespace vein.runtime using static VeinTypeCode; #if DEBUG - public static class DebugRefenrence + public static class DebugReference { private static ulong ID = 0; @@ -31,29 +31,32 @@ public class VeinClass : IEquatable, IAspectable public List Fields { get; } = new(); public List Methods { get; set; } = new(); public VeinTypeCode TypeCode { get; set; } = TYPE_CLASS; - public bool IsPrimitive => TypeCode is not TYPE_CLASS and not TYPE_NONE and not TYPE_STRING; - public bool IsValueType => IsPrimitive || this.Walk(x => x.Name == "ValueType"); - public bool IsInterface => Flags.HasFlag(ClassFlags.Interface); public VeinModule Owner { get; set; } public List Aspects { get; } = new(); #if DEBUG - public ulong ReferenceID = DebugRefenrence.Get(); + public ulong ReferenceID = DebugReference.Get(); #endif - + public string CreationPlace { get; set; } internal VeinClass(QualityTypeName name, VeinClass parent, VeinModule module) { - this.FullName = name; + FullName = name; if (parent is not null) - this.Parents.Add(parent); - this.Owner = module; + Parents.Add(parent); + Owner = module; + CreationPlace = Environment.StackTrace; } internal VeinClass(QualityTypeName name, VeinClass[] parents, VeinModule module) { - this.FullName = name; - this.Parents.AddRange(parents); - this.Owner = module; + FullName = name; + Parents.AddRange(parents); + Owner = module; + CreationPlace = Environment.StackTrace; + } + + protected VeinClass() + { + CreationPlace = Environment.StackTrace; } - protected VeinClass() { } public bool IsSpecial => Flags.HasFlag(ClassFlags.Special); public bool IsPublic => Flags.HasFlag(ClassFlags.Public); @@ -62,6 +65,9 @@ protected VeinClass() { } public bool IsStatic => Flags.HasFlag(ClassFlags.Static); public bool IsInternal => Flags.HasFlag(ClassFlags.Internal); public bool IsAspect => Flags.HasFlag(ClassFlags.Aspect); + public bool IsPrimitive => TypeCode is not TYPE_CLASS and not TYPE_NONE and not TYPE_STRING; + public bool IsValueType => IsPrimitive || this.Walk(x => x.Name == "ValueType"); + public bool IsInterface => Flags.HasFlag(ClassFlags.Interface); public virtual VeinMethod GetDefaultDtor() => GetOrCreateTor("dtor"); public virtual VeinMethod GetDefaultCtor() => GetOrCreateTor("ctor"); @@ -76,23 +82,50 @@ public override string ToString() => $"{FullName}, {Flags}"; - public VeinMethod FindMethod(string name, IEnumerable args_types, bool includeThis = false) => - this.Methods.Concat(Parents.SelectMany(x => x.Methods)) + public VeinMethod FindMethod(string name, IEnumerable user_types, bool includeThis = false) => + Methods.Concat(Parents.SelectMany(x => x.Methods)) .FirstOrDefault(x => { + var userTypes = user_types.ToList(); + var nameHas = x.RawName.Equals(name); - var args = x.Arguments.Where(z => includeThis || NotThis(z)).Select(z => z.Type).ToArray(); - var argsHas = args.SequenceEqual(args_types); - if (nameHas && !argsHas) - { - argsHas = CheckInheritance(args_types.ToArray(), args); - } + if (!nameHas) + return false; + + var args = x.Signature.Arguments.Where(z => includeThis || NotThis(z)).Select(z => z.ComplexType).ToList(); + var argsHas = CheckCompatibility(userTypes, args); - return nameHas && argsHas; + if (!argsHas && !args.Any(z => z.IsGeneric)) + argsHas = CheckInheritance(userTypes.ToArray(), args.Select(z => z.Class).ToArray()); + + return argsHas; }); - // TODO + private bool CheckCompatibility(List userArgs, List methodArgs) + { + if (userArgs.Count != methodArgs.Count) return false; + + Dictionary genericMap = new(); + + for (int i = 0; i < userArgs.Count; i++) + { + var userType = userArgs[i]; + var methodType = methodArgs[i]; + + if (methodType.IsGeneric) + { + var genericName = methodType.TypeArg.Name; + if (genericMap.TryAdd(genericName, userType)) continue; + if (!genericMap[genericName].FullName.Equals(userType.FullName)) + return false; + } + else if (!methodType.Class.FullName.Equals(userType.FullName)) + return false; + } + return true; + } + private bool CheckInheritance(VeinClass[] current, VeinClass[] target) { if (current.Length != target.Length) @@ -131,7 +164,7 @@ public bool IsInner(VeinClass clazz) public static bool NotThis(VeinArgumentRef arg) => !arg.Name.Equals(VeinArgumentRef.THIS_ARGUMENT); public VeinField FindField(string name) => - this.Fields.Concat(Parents.SelectMany(x => x.Fields)) + Fields.Concat(Parents.SelectMany(x => x.Fields)) .FirstOrDefault(x => x.Name.Equals(name)); public VeinProperty FindProperty(string name) @@ -184,7 +217,7 @@ public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; + if (obj.GetType() != GetType()) return false; return Equals((VeinClass)obj); } diff --git a/runtime/common/reflection/VeinCore.cs b/runtime/common/reflection/VeinCore.cs index a04f150c..84a2b4be 100644 --- a/runtime/common/reflection/VeinCore.cs +++ b/runtime/common/reflection/VeinCore.cs @@ -66,29 +66,29 @@ private void init() { var asmName = "std%"; var coreModule = new VeinModule("std", new Version(1, 0, 0), this); - ObjectClass = new($"{asmName}global::vein/lang/Object", (VeinClass)null, coreModule) { TypeCode = VeinTypeCode.TYPE_OBJECT }; - ValueTypeClass = new($"{asmName}global::vein/lang/ValueType", (VeinClass)null, coreModule) { TypeCode = VeinTypeCode.TYPE_OBJECT }; - VoidClass = new($"{asmName}global::vein/lang/Void", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_VOID }; - StringClass = new($"{asmName}global::vein/lang/String", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_STRING }; - ByteClass = new($"{asmName}global::vein/lang/Byte", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_U1 }; - SByteClass = new($"{asmName}global::vein/lang/SByte", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_I1 }; - Int16Class = new($"{asmName}global::vein/lang/Int16", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_I2 }; - Int32Class = new($"{asmName}global::vein/lang/Int32", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_I4 }; - Int64Class = new($"{asmName}global::vein/lang/Int64", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_I8 }; - UInt16Class = new($"{asmName}global::vein/lang/UInt16", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_U2 }; - UInt32Class = new($"{asmName}global::vein/lang/UInt32", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_U4 }; - UInt64Class = new($"{asmName}global::vein/lang/UInt64", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_U8 }; - HalfClass = new($"{asmName}global::vein/lang/Half", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_R2 }; - FloatClass = new($"{asmName}global::vein/lang/Float", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_R4 }; - DoubleClass = new($"{asmName}global::vein/lang/Double", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_R8 }; - DecimalClass = new($"{asmName}global::vein/lang/Decimal", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_R16 }; - BoolClass = new($"{asmName}global::vein/lang/Boolean", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_BOOLEAN }; - CharClass = new($"{asmName}global::vein/lang/Char", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_CHAR }; - ArrayClass = new($"{asmName}global::vein/lang/Array", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_ARRAY }; - ExceptionClass = new($"{asmName}global::vein/lang/Exception", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_CLASS }; - RawClass = new($"{asmName}global::vein/lang/Raw", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_RAW }; - AspectClass = new($"{asmName}global::vein/lang/Aspect", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_CLASS }; - FunctionClass = new($"{asmName}global::vein/lang/Function", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_FUNCTION }; + ObjectClass = new($"{asmName}global::std/Object", (VeinClass)null, coreModule) { TypeCode = VeinTypeCode.TYPE_OBJECT }; + ValueTypeClass = new($"{asmName}global::std/ValueType", (VeinClass)null, coreModule) { TypeCode = VeinTypeCode.TYPE_OBJECT }; + VoidClass = new($"{asmName}global::std/Void", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_VOID }; + StringClass = new($"{asmName}global::std/String", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_STRING }; + ByteClass = new($"{asmName}global::std/Byte", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_U1 }; + SByteClass = new($"{asmName}global::std/SByte", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_I1 }; + Int16Class = new($"{asmName}global::std/Int16", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_I2 }; + Int32Class = new($"{asmName}global::std/Int32", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_I4 }; + Int64Class = new($"{asmName}global::std/Int64", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_I8 }; + UInt16Class = new($"{asmName}global::std/UInt16", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_U2 }; + UInt32Class = new($"{asmName}global::std/UInt32", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_U4 }; + UInt64Class = new($"{asmName}global::std/UInt64", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_U8 }; + HalfClass = new($"{asmName}global::std/Half", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_R2 }; + FloatClass = new($"{asmName}global::std/Float", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_R4 }; + DoubleClass = new($"{asmName}global::std/Double", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_R8 }; + DecimalClass = new($"{asmName}global::std/Decimal", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_R16 }; + BoolClass = new($"{asmName}global::std/Boolean", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_BOOLEAN }; + CharClass = new($"{asmName}global::std/Char", ValueTypeClass, coreModule) { TypeCode = VeinTypeCode.TYPE_CHAR }; + ArrayClass = new($"{asmName}global::std/Array", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_ARRAY }; + ExceptionClass = new($"{asmName}global::std/Exception", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_CLASS }; + RawClass = new($"{asmName}global::std/Raw", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_RAW }; + AspectClass = new($"{asmName}global::std/Aspect", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_CLASS }; + FunctionClass = new($"{asmName}global::std/Function", ObjectClass, coreModule) { TypeCode = VeinTypeCode.TYPE_FUNCTION }; } } } diff --git a/runtime/common/reflection/VeinMethod.cs b/runtime/common/reflection/VeinMethod.cs index 092438f2..3db16575 100644 --- a/runtime/common/reflection/VeinMethod.cs +++ b/runtime/common/reflection/VeinMethod.cs @@ -1,56 +1,105 @@ namespace vein.runtime { + using System; using System.Collections.Generic; using System.Linq; - using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using extensions; using reflection; - public class VeinMethod : VeinMethodBase, IAspectable + public record VeinComplexType { - public VeinClass ReturnType { get; set; } - public VeinClass Owner { get; protected internal set; } - public readonly Dictionary Locals = new(); - public List Aspects { get; } = new(); + private readonly VeinTypeArg _typeArg; + private readonly VeinClass _class; - protected VeinMethod() : base(null, 0) { } - - internal VeinMethod(string name, MethodFlags flags, VeinClass returnType, VeinClass owner, - params VeinArgumentRef[] args) - : base(name, flags, args) + public VeinComplexType(VeinClass @class) => _class = @class; + + public VeinComplexType(VeinTypeArg typeArg) => _typeArg = typeArg; + + public bool IsGeneric => _typeArg is not null; + + + public VeinTypeArg TypeArg => _typeArg; + public VeinClass Class => _class; + + + public static implicit operator VeinComplexType(VeinClass cpx) => new(cpx); + public static implicit operator VeinComplexType(VeinTypeArg cpx) => new(cpx); + + + public static implicit operator VeinClass(VeinComplexType cpx) { - this.Owner = owner; - this.ReturnType = returnType; + if (cpx.IsGeneric) + throw new NotSupportedException($"Trying summon non generic vein type, but complex type is generic"); + return cpx._class; } - public override string ToString() - => $"{Owner.Name}::{RawName}({Arguments.Select(x => $"{x.Name}: {x.Type.Name}").Join(',')})"; + public static implicit operator VeinTypeArg(VeinComplexType cpx) + { + if (cpx.IsGeneric) + throw new NotSupportedException($"Trying summon generic type, but complex type is non generic vein type"); + return cpx._typeArg; + } + + public string ToTemplateString() => IsGeneric ? + _typeArg.ToTemplateString() : + _class.FullName.ToString(); } + public record VeinMethodSignature( + VeinComplexType ReturnType, + IReadOnlyList Arguments) + { + public int ArgLength => Arguments.Count; + + public override string ToString() => $"({Arguments.Where(NotThis).Select(x => $"{x.ToTemplateString()}").Join(',')}) -> {ReturnType.ToTemplateString()}"; + + + private bool NotThis(VeinArgumentRef @ref) => !@ref.Name.Equals(VeinArgumentRef.THIS_ARGUMENT); - public abstract class VeinMethodBase : VeinMember + public bool IsGeneric => Arguments.Any(x => x.IsGeneric); + + public string ToTemplateString() => ToString(); + } + + public class VeinMethod : VeinMember, IAspectable { - [MethodImpl(MethodImplOptions.NoOptimization)] - protected VeinMethodBase(string name, MethodFlags flags, params VeinArgumentRef[] args) + public VeinMethodSignature Signature { get; private set; } + public VeinClass ReturnType => Signature.ReturnType; + public VeinClass Owner { get; protected internal set; } + public Dictionary Locals { get; } = new(); + public List Aspects { get; } = new(); + + + public void Temp_ReplaceReturnType(VeinClass clazz) => Signature = Signature with { ReturnType = clazz }; + + + internal VeinMethod(string name, MethodFlags flags, VeinClass returnType, VeinClass owner, params VeinArgumentRef[] args) { - this.Arguments.AddRange(args); - this.Name = this.RegenerateName(name); - this.Flags = flags; + Owner = owner; + Flags = flags; + Signature = new VeinMethodSignature(returnType, args); + Name = RegenerateName(name); } - private string RegenerateName(string n) => - Regex.IsMatch(n, @"\S+\((.+)?\)", RegexOptions.Compiled) - ? n : GetFullName(n, Arguments); + internal VeinMethod(string name, MethodFlags flags, VeinTypeArg returnType, VeinClass owner, params VeinArgumentRef[] args) + { + Owner = owner; + Flags = flags; + Signature = new VeinMethodSignature(returnType, args); + Name = RegenerateName(name); + } - public static string GetFullName(string name, IEnumerable args) - => $"{name}({args.Where(x => !x.Name.Equals(VeinArgumentRef.THIS_ARGUMENT)).Select(x => x.Type?.Name).Join(",")})"; - public static string GetFullName(string name, IEnumerable<(string argName, string typeName)> args) - => $"{name}({args.Where(x => !x.argName.Equals(VeinArgumentRef.THIS_ARGUMENT)).Select(x => x.typeName).Join(",")})"; + private string RegenerateName(string n) => + Regex.IsMatch(n, @"\S+\((.+)?\)", RegexOptions.Compiled) + ? n : GetFullName(n, Signature.ReturnType, Signature.Arguments); - public static string GetFullName(string name, IEnumerable args) - => $"{name}({args.Select(x => x.Name).Join(",")})"; + public static string GetFullName(string name, VeinComplexType returnType, IEnumerable args) + => $"{name}{new VeinMethodSignature(returnType, args.ToList()).ToTemplateString()}"; + + public static string GetFullName(string name, VeinComplexType returnType, IEnumerable args) + => $"{name}{new VeinMethodSignature(returnType, args.Select((x, y) => new VeinArgumentRef(y.ToString(), x)).ToList()).ToTemplateString()}"; public MethodFlags Flags { get; set; } @@ -68,10 +117,6 @@ public static string GetFullName(string name, IEnumerable args) public sealed override string Name { get; protected set; } public string RawName => Name.Split('(').First(); - public List Arguments { get; } = new(); - - public int ArgLength => Arguments.Count; - public override VeinMemberKind Kind => VeinMemberKind.Method; } } diff --git a/runtime/common/reflection/VeinModule.cs b/runtime/common/reflection/VeinModule.cs index 007f5e32..26e5caf9 100644 --- a/runtime/common/reflection/VeinModule.cs +++ b/runtime/common/reflection/VeinModule.cs @@ -23,6 +23,7 @@ public class VeinModule protected internal readonly List alias_table = new(); protected internal readonly Dictionary strings_table = new(); protected internal readonly Dictionary types_table = new(); + protected internal readonly Dictionary generics_table = new(); protected internal readonly Dictionary fields_table = new(); protected internal readonly MutexStorage Interlocker = new (); diff --git a/runtime/ishtar.base/emit/ModuleReader.cs b/runtime/ishtar.base/emit/ModuleReader.cs index cb695778..05adedc7 100644 --- a/runtime/ishtar.base/emit/ModuleReader.cs +++ b/runtime/ishtar.base/emit/ModuleReader.cs @@ -106,6 +106,18 @@ public static T[] ReadSpecialByteArray(this BinaryReader bin) where T : Enum return result.ToArray(); } + public static T[] ReadSpecialInt32Array(this BinaryReader bin) where T : Enum + { + Debug.Assert(bin.ReadInt32() == 0x19, "[magic number] bin.ReadInt32() == 0x19"); + var sign = bin.ReadIshtarString(); + var size = bin.ReadInt32(); + var result = new List(); + foreach (int _ in ..size) + result.Add((T)(object)bin.ReadInt32()); + Debug.Assert(bin.ReadInt32() == 0x61, "[magic number] bin.ReadInt32() == 0x61"); + return result.ToArray(); + } + public static byte[] ReadSpecialDirectByteArray(this BinaryReader bin) { Debug.Assert(bin.ReadInt32() == 0x19, "[magic number] bin.ReadInt32() == 0x19"); @@ -131,7 +143,7 @@ public static void WriteArray(this BinaryWriter bin, T[] arr, Action deps, Func resolver) { @@ -223,6 +235,38 @@ public static ModuleReader Read(byte[] arr, IReadOnlyList deps, Func } } + foreach (var _ in ..reader.ReadInt32()) + { + var key = reader.ReadInt32(); + var name = reader.ReadIshtarString(); + var cts = new List(); + + foreach (var count in ..reader.ReadInt32()) + { + var k = reader.ReadInt32(); + var kind = (VeinTypeParameterConstraint)reader.ReadInt32(); + + if (kind == VeinTypeParameterConstraint.BITTABLE) + cts.Add(new VeinBaseConstraintConstBittable()); + else if (kind == VeinTypeParameterConstraint.CLASS) + cts.Add(new VeinBaseConstraintConstClass()); + else if (kind == VeinTypeParameterConstraint.TYPE) + { + var type = reader.ReadTypeName(module); + cts.Add(new VeinBaseConstraintConstType(module.FindType(type, true))); + } + else if (kind == VeinTypeParameterConstraint.SIGNATURE) + { + var type = reader.ReadTypeName(module); + cts.Add(new VeinBaseConstraintConstSignature(module.FindType(type, true))); + } + else + throw new NotImplementedException(); + } + + module.generics_table.Add(key, new VeinTypeArg(name, cts)); + } + // restore unresolved types foreach (var @class in module.class_table) { @@ -244,16 +288,18 @@ public static ModuleReader Read(byte[] arr, IReadOnlyList deps, Func { if (method.ReturnType is not UnresolvedVeinClass) continue; - method.ReturnType = module.FindType(method.ReturnType.FullName, true); + method.Temp_ReplaceReturnType(module.FindType(method.ReturnType.FullName, true)); } foreach (var method in @class.Methods) { - foreach (var argument in method.Arguments) + foreach (var argument in method.Signature.Arguments) { - if (argument.Type is not UnresolvedVeinClass) + if (argument.IsGeneric) continue; - argument.Type = module.FindType(argument.Type.FullName, true); + if (argument.ComplexType.Class is not UnresolvedVeinClass) + continue; + argument.Temp_ReplaceType(module.FindType(argument.ComplexType.Class.FullName, true)); } } foreach (var field in @class.Fields) @@ -387,17 +433,19 @@ private static List ReadArguments(BinaryReader binary, ModuleRe foreach (var _ in ..binary.ReadInt32()) { var nIdx = binary.ReadInt32(); - var type = binary.ReadTypeName(module); - args.Add(new VeinArgumentRef + var isGeneric = binary.ReadBoolean(); + if (isGeneric) + { + var generic = binary.ReadGenericTypeName(module); + args.Add(new VeinArgumentRef(module.GetConstStringByIndex(nIdx), generic)); + } + else { - Name = module.GetConstStringByIndex(nIdx), - Type = module.FindType(type, true, false) - }); + var type = binary.ReadTypeName(module); + args.Add(new VeinArgumentRef(module.GetConstStringByIndex(nIdx), module.FindType(type, true, false))); + } } return args; } - public ModuleReader(VeinCore types) : base(".unnamed", types) - { - } } } diff --git a/runtime/ishtar.base/emit/TypeForwarder.cs b/runtime/ishtar.base/emit/TypeForwarder.cs index 8c8d5f87..ab30949e 100644 --- a/runtime/ishtar.base/emit/TypeForwarder.cs +++ b/runtime/ishtar.base/emit/TypeForwarder.cs @@ -9,87 +9,87 @@ public static void Indicate(VeinCore types, VeinClass clazz) { switch (clazz.FullName.NameWithNS) { - case "global::vein/lang/Aspect": + case "global::std/Aspect": clazz.TypeCode = VeinTypeCode.TYPE_CLASS; types.AspectClass = clazz; break; - case "global::vein/lang/Raw": + case "global::std/Raw": clazz.TypeCode = VeinTypeCode.TYPE_RAW; types.RawClass = clazz; break; - case "global::vein/lang/Object": + case "global::std/Object": clazz.TypeCode = VeinTypeCode.TYPE_OBJECT; types.ObjectClass = clazz; break; - case "global::vein/lang/ValueType": + case "global::std/ValueType": clazz.TypeCode = VeinTypeCode.TYPE_OBJECT; types.ValueTypeClass = clazz; break; - case "global::vein/lang/Array": + case "global::std/Array": clazz.TypeCode = VeinTypeCode.TYPE_ARRAY; types.ArrayClass = clazz; break; - case "global::vein/lang/Void": + case "global::std/Void": clazz.TypeCode = VeinTypeCode.TYPE_VOID; types.VoidClass = clazz; break; - case "global::vein/lang/Int64": + case "global::std/Int64": clazz.TypeCode = VeinTypeCode.TYPE_I8; types.Int64Class = clazz; break; - case "global::vein/lang/Int32": + case "global::std/Int32": clazz.TypeCode = VeinTypeCode.TYPE_I4; types.Int32Class = clazz; break; - case "global::vein/lang/Int16": + case "global::std/Int16": clazz.TypeCode = VeinTypeCode.TYPE_I2; types.Int16Class = clazz; break; - case "global::vein/lang/UInt64": + case "global::std/UInt64": clazz.TypeCode = VeinTypeCode.TYPE_U8; types.UInt64Class = clazz; break; - case "global::vein/lang/UInt32": + case "global::std/UInt32": clazz.TypeCode = VeinTypeCode.TYPE_U4; types.UInt32Class = clazz; break; - case "global::vein/lang/UInt16": + case "global::std/UInt16": clazz.TypeCode = VeinTypeCode.TYPE_U2; types.UInt16Class = clazz; break; - case "global::vein/lang/Boolean": + case "global::std/Boolean": clazz.TypeCode = VeinTypeCode.TYPE_BOOLEAN; types.BoolClass = clazz; break; - case "global::vein/lang/String": + case "global::std/String": clazz.TypeCode = VeinTypeCode.TYPE_STRING; types.StringClass = clazz; break; - case "global::vein/lang/Char": + case "global::std/Char": clazz.TypeCode = VeinTypeCode.TYPE_CHAR; types.CharClass = clazz; break; - case "global::vein/lang/Half": + case "global::std/Half": clazz.TypeCode = VeinTypeCode.TYPE_R2; types.HalfClass = clazz; break; - case "global::vein/lang/Float": + case "global::std/Float": clazz.TypeCode = VeinTypeCode.TYPE_R4; types.FloatClass = clazz; break; - case "global::vein/lang/Double": + case "global::std/Double": clazz.TypeCode = VeinTypeCode.TYPE_R8; types.DoubleClass = clazz; break; - case "global::vein/lang/Decimal": + case "global::std/Decimal": clazz.TypeCode = VeinTypeCode.TYPE_R16; types.DecimalClass = clazz; break; - case "global::vein/lang/Byte": + case "global::std/Byte": clazz.TypeCode = VeinTypeCode.TYPE_U1; types.ByteClass = clazz; break; - case "global::vein/lang/Exception": + case "global::std/Exception": clazz.TypeCode = VeinTypeCode.TYPE_CLASS; types.ExceptionClass = clazz; break; diff --git a/runtime/ishtar.base/emit/VeinModuleBuilder.cs b/runtime/ishtar.base/emit/VeinModuleBuilder.cs index 4340d74b..3dea961a 100644 --- a/runtime/ishtar.base/emit/VeinModuleBuilder.cs +++ b/runtime/ishtar.base/emit/VeinModuleBuilder.cs @@ -106,6 +106,20 @@ public int InternTypeName(QualityTypeName name) //logger.Information("TypeName '{name}' baked by index: {key}", name, key); return key; } + + /// + /// Intern TypeName constant into module storage and return TypeName index. + /// + /// + public int InternGenericTypeName(VeinTypeArg name) + { + if (name == null) + throw new ArgumentNullException(nameof(name)); + var key = _intern(generics_table, name); + + //logger.Information("TypeName '{name}' baked by index: {key}", name, key); + return key; + } /// /// Intern FieldName constant into module storage and return FieldName index. /// @@ -141,9 +155,6 @@ public byte[] BakeByteArray() binary.Write(vdx); binary.Write(OpCodes.SetVersion); - - - binary.Write(strings_table.Count); foreach (var (key, value) in strings_table) { @@ -202,6 +213,33 @@ public byte[] BakeByteArray() throw new NotSupportedException(); } } + + binary.Write(generics_table.Count); + foreach (var (i, generic) in generics_table) + { + binary.Write(i); + binary.WriteIshtarString(generic.Name); + + binary.Write(generic.Constraints.Count); + foreach (var constraint in generic.Constraints) + { + switch (constraint.Constraint) + { + case VeinTypeParameterConstraint.BITTABLE: + case VeinTypeParameterConstraint.CLASS: + break; + case VeinTypeParameterConstraint.TYPE when constraint is VeinBaseConstraintConstType t: + binary.WriteTypeName(t.classes.FullName, this); + break; + case VeinTypeParameterConstraint.SIGNATURE when constraint is VeinBaseConstraintConstSignature s: + binary.WriteTypeName(s.@interface.FullName, this); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } + var constBody = const_table.BakeByteArray(); binary.Write(constBody.Length); binary.Write(constBody); diff --git a/runtime/ishtar.base/emit/extensions/QualityTypeEx.cs b/runtime/ishtar.base/emit/extensions/QualityTypeEx.cs index 13630e7b..0777c1b1 100644 --- a/runtime/ishtar.base/emit/extensions/QualityTypeEx.cs +++ b/runtime/ishtar.base/emit/extensions/QualityTypeEx.cs @@ -9,6 +9,15 @@ namespace ishtar.emit.extensions public delegate nint TypeNameGetter(int typeIndex); public static class QualityTypeEx { + public static VeinComplexType ReadComplexType(this BinaryReader bin, VeinModule module) + { + var isGeneric = bin.ReadBoolean(); + if (isGeneric) + return bin.ReadGenericTypeName(module); + return module.FindType(bin.ReadTypeName(module), true); + } + + public static QualityTypeName ReadTypeName(this BinaryReader bin, VeinModule module) { var typeIndex = bin.ReadInt32(); @@ -17,6 +26,14 @@ public static QualityTypeName ReadTypeName(this BinaryReader bin, VeinModule mod throw new Exception($"TypeName by index '{typeIndex}' not found in '{module.Name}' module."); } + public static VeinTypeArg ReadGenericTypeName(this BinaryReader bin, VeinModule module) + { + var typeIndex = bin.ReadInt32(); + + return module.generics_table.GetValueOrDefault(typeIndex) ?? + throw new Exception($"VeinTypeArg by index '{typeIndex}' not found in '{module.Name}' module."); + } + public static nint ReadTypeName(this BinaryReader bin, TypeNameGetter getter) { var typeIndex = bin.ReadInt32(); @@ -31,6 +48,23 @@ public static void WriteTypeName(this BinaryWriter bin, QualityTypeName type, Ve bin.Write(key); } + public static void WriteComplexType(this BinaryWriter bin, VeinComplexType type, VeinModuleBuilder module) + { + bin.Write(type.IsGeneric); + + if (type.IsGeneric) + bin.WriteGenericTypeName(type, module); + else + bin.WriteTypeName(((VeinClass)type).FullName, module); + } + + public static void WriteGenericTypeName(this BinaryWriter bin, VeinTypeArg type, VeinModuleBuilder module) + { + var key = module.InternGenericTypeName(type); + + bin.Write(key); + } + public static void PutTypeName(this ILGenerator gen, QualityTypeName type) { Func getConst = gen._methodBuilder.moduleBuilder.InternTypeName; @@ -46,5 +80,20 @@ public static void PutTypeNameInto(this ILGenerator gen, QualityTypeName type, B var key = getConst(type); writer.Write(key); } + + + public static void WriteArguments(this BinaryWriter binary, VeinMethodSignature signature, VeinModuleBuilder module) + { + binary.Write(signature.ArgLength); + foreach (var argument in signature.Arguments) + { + binary.Write(module.InternString(argument.Name)); + binary.Write(argument.IsGeneric); + if (argument.IsGeneric) + binary.WriteGenericTypeName(argument.ComplexType.TypeArg, module); + else + binary.WriteTypeName(argument.ComplexType!.Class.FullName, module); + } + } } } diff --git a/runtime/ishtar.base/fs/IshtarAssembly.elf.cs b/runtime/ishtar.base/fs/IshtarAssembly.elf.cs index 68a3fb60..95126c8f 100644 --- a/runtime/ishtar.base/fs/IshtarAssembly.elf.cs +++ b/runtime/ishtar.base/fs/IshtarAssembly.elf.cs @@ -106,7 +106,7 @@ private static void AddCode(ElfFile file, byte[] il) }); file.Data.Write(il, 0, il.Length); - var vm_notes = Encoding.ASCII.GetBytes("insomnia"); + var vm_notes = "insomnia"u8.ToArray(); file.Sections.Add(new ElfSection { Name = file.Strings.SaveString(".note"), @@ -148,7 +148,7 @@ public class InsomniaAssemblyMetadata { public Version Version { get; set; } = new(1, 0, 0, 0); public DateTimeOffset Timestamp { get; set; } = DateTimeOffset.UtcNow; - public string TargetFramework { get; set; } = "ManaStandard,Version=v1.0"; + public string TargetFramework { get; set; } = "IshtarStandard,Version=v2.0"; public Dictionary OtherMeta { get; } = new(); } diff --git a/runtime/ishtar.generator/GeneratorContext.cs b/runtime/ishtar.generator/GeneratorContext.cs index e5fc426c..4de9a207 100644 --- a/runtime/ishtar.generator/GeneratorContext.cs +++ b/runtime/ishtar.generator/GeneratorContext.cs @@ -92,7 +92,7 @@ public ClassBuilder CreateHiddenType(string name) public (VeinArgumentRef, int index)? ResolveArgument(IdentifierExpression id) { - foreach (var (argument, index) in CurrentMethod.Arguments.Select((x, i) => (x, i))) + foreach (var (argument, index) in CurrentMethod.Signature.Arguments.Select((x, i) => (x, i))) { if (argument.Name.Equals(id.ExpressionString)) return (argument, index); @@ -101,7 +101,7 @@ public ClassBuilder CreateHiddenType(string name) } public (VeinArgumentRef, int index) GetCurrentArgument(IdentifierExpression id) { - foreach (var (argument, index) in CurrentMethod.Arguments.Select((x, i) => (x, i))) + foreach (var (argument, index) in CurrentMethod.Signature.Arguments.Select((x, i) => (x, i))) { if (argument.Name.Equals(id.ExpressionString)) return (argument, index); diff --git a/runtime/ishtar.generator/generators/operators.cs b/runtime/ishtar.generator/generators/operators.cs index 55f1b123..9d61e232 100644 --- a/runtime/ishtar.generator/generators/operators.cs +++ b/runtime/ishtar.generator/generators/operators.cs @@ -40,9 +40,11 @@ public static void EmitBinaryExpression(this ILGenerator gen, BinaryExpressionSy var name = $"op_{op}"; var args = new[] { left_type, right_type }; - var methodName = VeinMethodBase.GetFullName(name, args); var method = left_type.FindMethod(name, args); + + var methodName = VeinMethod.GetFullName(name, method.ReturnType, args); + if (method is null || !method.IsStatic || !method.IsSpecial) { context.LogError($"Operator '{op.GetSymbol()}' " + diff --git a/runtime/ishtar.generator/generators/types.cs b/runtime/ishtar.generator/generators/types.cs index f1ff9c99..b8bf69b1 100644 --- a/runtime/ishtar.generator/generators/types.cs +++ b/runtime/ishtar.generator/generators/types.cs @@ -3,6 +3,7 @@ namespace ishtar; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using vein.runtime; using vein.syntax; diff --git a/runtime/ishtar.vm/FFI/ForeignFunctionInterface.cs b/runtime/ishtar.vm/FFI/ForeignFunctionInterface.cs index 83942cc9..21558856 100644 --- a/runtime/ishtar.vm/FFI/ForeignFunctionInterface.cs +++ b/runtime/ishtar.vm/FFI/ForeignFunctionInterface.cs @@ -2,13 +2,19 @@ namespace ishtar; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; +using collections; using runtime; +using runtime.gc; using vein.runtime; public unsafe class ForeignFunctionInterface { public readonly VirtualMachine vm; - public Dictionary method_table { get; } = new(); + public NativeDictionary* methods { get; } = IshtarGC.AllocateDictionary(); + public Dictionary method_table { get; } = new(); + + private ulong _index; public ForeignFunctionInterface(VirtualMachine vm) { @@ -33,21 +39,25 @@ private void INIT() //B_NAPI.InitTable(this); } - public RuntimeIshtarMethod* Add(string name, MethodFlags flags, params (string name, VeinTypeCode type)[] args) - { - var method = vm.CreateInternalMethod( - VeinMethodBase.GetFullName(name, args.Select(x => (x.name, vm.Types->ByTypeCode(x.type)->Name))), flags, args); - method->Assert(method); - method_table.Add(method->Name, (nint)method); - return method; - } + public RuntimeIshtarMethod* Add(string name, MethodFlags flags, VeinTypeCode returnType, params (string name, VeinTypeCode type)[] args) + => Add(name, flags, vm.Types->ByTypeCode(returnType), args); public RuntimeIshtarMethod* Add(string name, MethodFlags flags, RuntimeIshtarClass* returnType, params (string name, VeinTypeCode type)[] args) { - var n = VeinMethodBase.GetFullName(name, args.Select(x => (x.name, vm.Types->ByTypeCode(x.type)->Name))); - var method = vm.CreateInternalMethod(n, flags, returnType, args); + _index++; + var arr = new RuntimeIshtarClass*[args.Length]; + + for (int index = 0; index < args.Length; index++) + { + var (_, type) = args[index]; + arr[index] = vm.Types->ByTypeCode(type); + } + + var method = vm.CreateInternalMethod( + RuntimeIshtarMethod.GetFullName(name, returnType, arr), flags, args); method->Assert(method); - method_table.Add(method->Name, (nint)method); + method_table.Add(method->Name, _index); + methods->Add(_index, method); return method; } @@ -96,7 +106,13 @@ public static void StaticTypeOf(CallFrame* current, IshtarObject** arg1, VeinTyp } public RuntimeIshtarMethod* GetMethod(string FullName) - => (RuntimeIshtarMethod*)method_table.GetValueOrDefault(FullName); + { + if (method_table.TryGetValue(FullName, out var idx)) + return methods->Get(idx); + throw new EntryPointNotFoundException(FullName); + } + + private RuntimeIshtarMethod* GetMethod(ulong idx) => methods->Get(idx); public static void LinkExternalNativeLibrary(string importModule, string fnName, @@ -110,10 +126,9 @@ public static void LinkExternalNativeLibrary(string importModule, string fnName, public void DisplayDefinedMapping() { - if (!vm.Config.HasFlag(SysFlag.DISPLAY_FFI_MAPPING)) return; + if (vm.Config.HasFlag(SysFlag.DISPLAY_FFI_MAPPING)) return; - foreach (var (key, value) in method_table) - vm.trace.println($"ffi map '{key}' -> 'sys::FFI/{((RuntimeIshtarClass*)value)->Name}'"); + foreach (var (key, value) in method_table) vm.trace.println($"ffi map '{key}' -> 'sys::FFI/{(GetMethod(value))->Name}'"); } } diff --git a/runtime/ishtar.vm/NativeExports.cs b/runtime/ishtar.vm/NativeExports.cs index fa8e2111..d953866f 100644 --- a/runtime/ishtar.vm/NativeExports.cs +++ b/runtime/ishtar.vm/NativeExports.cs @@ -1,5 +1,9 @@ namespace ishtar; +using System.Runtime.InteropServices; +using LLVMSharp.Interop; +using vein.runtime; + [ExcludeFromCodeCoverage] public static unsafe class NativeExports { @@ -8,6 +12,17 @@ public static void VM_INIT() var vm = VirtualMachine.Create("app"); } + //[UnmanagedCallersOnly] + //public static void execute_method(CallFrame** frame) + //{ + + //} + //[UnmanagedCallersOnly] + //public static void create_method(MarshaledString name, MethodFlags flags, RuntimeIshtarClass* returnType, RuntimeIshtarClass** args) + //{ + + //} + public static stackval* VM_EXECUTE_METHOD(VirtualMachine vm, Types.FrameRef* frame) { throw null; diff --git a/runtime/ishtar.vm/Properties/launchSettings.json b/runtime/ishtar.vm/Properties/launchSettings.json index 86794a74..e9e48555 100644 --- a/runtime/ishtar.vm/Properties/launchSettings.json +++ b/runtime/ishtar.vm/Properties/launchSettings.json @@ -6,9 +6,9 @@ "WSL": { "commandName": "WSL2" }, - "run test fast": { + "run std": { "commandName": "Project", - "commandLineArgs": "..\\..\\..\\..\\..\\..\\test\\ishtar_test\\std.wll --sys::log::use-console=1" + "commandLineArgs": "..\\..\\..\\..\\..\\..\\lib\\vein.std\\std\\bin\\std.wll --sys::log::use-console=1" }, "run external_test": { "commandName": "Project", diff --git a/runtime/ishtar.vm/VirtualMachine.cs b/runtime/ishtar.vm/VirtualMachine.cs index c3d16f8a..59daaa69 100644 --- a/runtime/ishtar.vm/VirtualMachine.cs +++ b/runtime/ishtar.vm/VirtualMachine.cs @@ -121,13 +121,6 @@ public void Dispose() public RuntimeIshtarMethod* DefineEmptySystemMethod(string name) => CreateInternalMethod(name, MethodFlags.Extern, TYPE_VOID.AsRuntimeClass(Types), Array.Empty()); - public RuntimeIshtarMethod* DefineEmptySystemMethod(string name, RuntimeIshtarClass* clazz) - { - var args = IshtarGC.AllocateList(); - args->Add(RuntimeMethodArgument.Create(Types, "i1", clazz)); - return InternalClass->DefineMethod(VeinMethodBase.GetFullName(name, new List<(string argName, string typeName)>() { ("i1", clazz->Name) }), TYPE_VOID.AsRuntimeClass(Types), - MethodFlags.Extern | MethodFlags.Private | MethodFlags.Special, args); - } public volatile NativeException CurrentException; @@ -706,40 +699,43 @@ void ForceFail(RuntimeIshtarClass* clazz) { var _a = method->Arguments->Get(i); // TODO, type eq validate --sp; -#if DEBUG - println($"@@@@<< {StringStorage.GetString(_a->Name, invocation)}: {_a->Type->FullName->NameWithNS}"); - if (Environment.GetCommandLineArgs().Contains("--sys::ishtar::skip-validate-args=1")) - { - method_args[y] = *sp; - continue; - } - var arg_class = _a->Type; - if (arg_class->Name is not "Object" and not "ValueType") - { - var sp_obj = IshtarMarshal.Boxing(invocation, sp); - - if (sp_obj == null) - continue; - - var sp_class = sp_obj->clazz; - - if (sp_class == null) - continue; - - if (sp_class->ID != arg_class->ID) - { - if (!sp_class->IsInner(arg_class)) - { - FastFail(TYPE_MISMATCH, - $"Argument '{StringStorage.GetString(_a->Name, invocation)}: {_a->Type->Name}'" + - $" is not matched for '{method->Name}' function.", - invocation); - break; - } - } - } -#endif - +//#if DEBUG +// if (_a->Type.IsGeneric) +// println($"@@@@<< {StringStorage.GetString(_a->Name, invocation)}: {StringStorage.GetString(_a->Type.TypeArg->Name, invocation)}"); +// else +// println($"@@@@<< {StringStorage.GetString(_a->Name, invocation)}: {_a->Type.Class->FullName->NameWithNS}"); + +// if (Config.CallOpCodeSkipValidateArgs) +// { +// method_args[y] = *sp; +// continue; +// } +// var arg_class = _a->Type; +// if (arg_class->Name is not "Object" and not "ValueType") +// { +// var sp_obj = IshtarMarshal.Boxing(invocation, sp); + +// if (sp_obj == null) +// continue; + +// var sp_class = sp_obj->clazz; + +// if (sp_class == null) +// continue; + +// if (sp_class->ID != arg_class->ID) +// { +// if (!sp_class->IsInner(arg_class)) +// { +// FastFail(TYPE_MISMATCH, +// $"Argument '{StringStorage.GetString(_a->Name, invocation)}: {_a->Type->Name}'" + +// $" is not matched for '{method->Name}' function.", +// invocation); +// break; +// } +// } +// } +//#endif method_args[y] = *sp; } diff --git a/runtime/ishtar.vm/__builtin/B_App.cs b/runtime/ishtar.vm/__builtin/B_App.cs index 9f0a912d..cf6385eb 100644 --- a/runtime/ishtar.vm/__builtin/B_App.cs +++ b/runtime/ishtar.vm/__builtin/B_App.cs @@ -62,13 +62,13 @@ public static unsafe class B_App public static void InitTable(ForeignFunctionInterface ffi) { - ffi.Add("@_get_os_value", Public | Static | Extern)-> + ffi.Add("@_get_os_value", Public | Static | Extern, TYPE_I4)-> AsNative((delegate*)&GetOSValue); - ffi.Add("@_exit", Public | Static | Extern, ("msg", TYPE_STRING), ("code", TYPE_I4))-> + ffi.Add("@_exit", Public | Static | Extern, TYPE_VOID, ("msg", TYPE_STRING), ("code", TYPE_I4))-> AsNative((delegate*)&Exit); - ffi.Add("@_switch_flag", Public | Static | Extern, ("key", TYPE_STRING), ("value", TYPE_BOOLEAN)) + ffi.Add("@_switch_flag", Public | Static | Extern, TYPE_VOID, ("key", TYPE_STRING), ("value", TYPE_BOOLEAN)) ->AsNative((delegate*)&SwitchFlag); } } diff --git a/runtime/ishtar.vm/__builtin/B_Field.cs b/runtime/ishtar.vm/__builtin/B_Field.cs index 5d0dd9ba..032d16ec 100644 --- a/runtime/ishtar.vm/__builtin/B_Field.cs +++ b/runtime/ishtar.vm/__builtin/B_Field.cs @@ -30,7 +30,7 @@ public static unsafe class B_Field } - internal static IshtarMetaClass ThisClass => IshtarMetaClass.Define("vein/lang", "Field"); + internal static IshtarMetaClass ThisClass => IshtarMetaClass.Define("std", "Field"); public static void InitTable(ForeignFunctionInterface ffi) diff --git a/runtime/ishtar.vm/__builtin/B_File.cs b/runtime/ishtar.vm/__builtin/B_File.cs index a3c0a038..e338c3b1 100644 --- a/runtime/ishtar.vm/__builtin/B_File.cs +++ b/runtime/ishtar.vm/__builtin/B_File.cs @@ -28,7 +28,7 @@ public static unsafe class B_File } - internal static IshtarMetaClass ThisClass => IshtarMetaClass.Define("vein/lang/fs", "File"); + internal static IshtarMetaClass ThisClass => IshtarMetaClass.Define("std/fs", "File"); //public static void InitTable(Dictionary table) => new RuntimeIshtarMethod("i_call_fs_File_info", Public | Static | Extern, diff --git a/runtime/ishtar.vm/__builtin/B_Function.cs b/runtime/ishtar.vm/__builtin/B_Function.cs index 36c67168..94f6f0a5 100644 --- a/runtime/ishtar.vm/__builtin/B_Function.cs +++ b/runtime/ishtar.vm/__builtin/B_Function.cs @@ -23,7 +23,7 @@ public static unsafe class B_Function } - internal static IshtarMetaClass ThisClass => IshtarMetaClass.Define("vein/lang", "Function"); + internal static IshtarMetaClass ThisClass => IshtarMetaClass.Define("std", "Function"); public static void InitTable(ForeignFunctionInterface ffi) diff --git a/runtime/ishtar.vm/__builtin/B_GC.cs b/runtime/ishtar.vm/__builtin/B_GC.cs index 3287f3b0..e1c05f75 100644 --- a/runtime/ishtar.vm/__builtin/B_GC.cs +++ b/runtime/ishtar.vm/__builtin/B_GC.cs @@ -1,6 +1,7 @@ namespace ishtar; using static vein.runtime.MethodFlags; +using static vein.runtime.VeinTypeCode; public static unsafe class B_GC { @@ -16,10 +17,10 @@ public static unsafe class B_GC public static void InitTable(ForeignFunctionInterface ffi) { - ffi.Add("i_call_GC_get_allocated", Public | Static | Extern)-> + ffi.Add("i_call_GC_get_allocated", Public | Static | Extern, TYPE_I8)-> AsNative((delegate*)&GetAllocatedBytes); - ffi.Add("i_call_GC_get_alive_objects", Public | Static | Extern)-> + ffi.Add("i_call_GC_get_alive_objects", Public | Static | Extern, TYPE_I8)-> AsNative((delegate*)&GetAliveObjects); } } diff --git a/runtime/ishtar.vm/__builtin/B_IEEEConsts.cs b/runtime/ishtar.vm/__builtin/B_IEEEConsts.cs index f35a1677..97d5bbd9 100644 --- a/runtime/ishtar.vm/__builtin/B_IEEEConsts.cs +++ b/runtime/ishtar.vm/__builtin/B_IEEEConsts.cs @@ -1,6 +1,7 @@ namespace ishtar { using static vein.runtime.MethodFlags; + using static vein.runtime.VeinTypeCode; public static unsafe class B_IEEEConsts { @@ -14,40 +15,40 @@ public static unsafe class B_IEEEConsts public static void InitTable(ForeignFunctionInterface ffi) { - ffi.Add("i_call_get_Half_NaN", Public | Static | Extern) + ffi.Add("i_call_get_Half_NaN", Public | Static | Extern, TYPE_R2) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Float_NaN", Public | Static | Extern) + ffi.Add("i_call_get_Float_NaN", Public | Static | Extern, TYPE_R4) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Decimal_NaN", Public | Static | Extern) + ffi.Add("i_call_get_Decimal_NaN", Public | Static | Extern, TYPE_R16) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Double_NaN", Public | Static | Extern) + ffi.Add("i_call_get_Double_NaN", Public | Static | Extern, TYPE_R8) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Half_Infinity", Public | Static | Extern) + ffi.Add("i_call_get_Half_Infinity", Public | Static | Extern, TYPE_R2) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Float_Infinity", Public | Static | Extern) + ffi.Add("i_call_get_Float_Infinity", Public | Static | Extern, TYPE_R4) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Decimal_Infinity", Public | Static | Extern) + ffi.Add("i_call_get_Decimal_Infinity", Public | Static | Extern, TYPE_R16) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Double_Infinity", Public | Static | Extern) + ffi.Add("i_call_get_Double_Infinity", Public | Static | Extern, TYPE_R8) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Half_NegativeInfinity", Public | Static | Extern) + ffi.Add("i_call_get_Half_NegativeInfinity", Public | Static | Extern, TYPE_R2) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Float_NegativeInfinity", Public | Static | Extern) + ffi.Add("i_call_get_Float_NegativeInfinity", Public | Static | Extern, TYPE_R4) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Decimal_NegativeInfinity", Public | Static | Extern) + ffi.Add("i_call_get_Decimal_NegativeInfinity", Public | Static | Extern, TYPE_R16) ->AsNative((delegate*)&getHalfNaN); - ffi.Add("i_call_get_Double_NegativeInfinity", Public | Static | Extern) + ffi.Add("i_call_get_Double_NegativeInfinity", Public | Static | Extern, TYPE_R8) ->AsNative((delegate*)&getHalfNaN); } diff --git a/runtime/ishtar.vm/__builtin/B_Out.cs b/runtime/ishtar.vm/__builtin/B_Out.cs index 95b61497..609327fd 100644 --- a/runtime/ishtar.vm/__builtin/B_Out.cs +++ b/runtime/ishtar.vm/__builtin/B_Out.cs @@ -65,12 +65,12 @@ public static unsafe class B_Out public static void InitTable(ForeignFunctionInterface ffi) { - ffi.Add("@_println", Public | Static | Extern, ("val", TYPE_OBJECT)) + ffi.Add("@_println", Public | Static | Extern, TYPE_VOID, ("val", TYPE_OBJECT)) ->AsNative((delegate*)&FPrintLn_Object); - ffi.Add("@_println", Public | Static | Extern, ("val", TYPE_I4)) + ffi.Add("@_println", Public | Static | Extern, TYPE_VOID, ("val", TYPE_I4)) ->AsNative((delegate*)&FPrintLn_Int32); - ffi.Add("@_readline", Public | Static | Extern, TYPE_STRING.AsRuntimeClass(ffi.vm.Types)) + ffi.Add("@_readline", Public | Static | Extern, TYPE_STRING.AsRuntimeClass(ffi.vm.Types)) ->AsNative((delegate*)&FReadLine); } } diff --git a/runtime/ishtar.vm/__builtin/B_String.cs b/runtime/ishtar.vm/__builtin/B_String.cs index af7e3d41..77fefd83 100644 --- a/runtime/ishtar.vm/__builtin/B_String.cs +++ b/runtime/ishtar.vm/__builtin/B_String.cs @@ -8,32 +8,32 @@ public static unsafe class B_String { public static void InitTable(ForeignFunctionInterface ffi) { - ffi.Add("i_call_String_Concat", Private | Static | Extern, + ffi.Add("i_call_String_Concat", Private | Static | Extern, TYPE_STRING, ("v1", TYPE_STRING), ("v2", TYPE_STRING)) ->AsNative((delegate*)&Concat) ; - ffi.Add("i_call_String_Equal", Private | Static | Extern, + ffi.Add("i_call_String_Equal", Private | Static | Extern, TYPE_BOOLEAN, ("v1", TYPE_STRING), ("v2", TYPE_STRING)) ->AsNative((delegate*)&StrEqual) ; - ffi.Add("i_call_String_Trim_Start", Private | Static | Extern, + ffi.Add("i_call_String_Trim_Start", Private | Static | Extern, TYPE_STRING, ("v1", TYPE_STRING)) ->AsNative((delegate*)&TrimStart) ; - ffi.Add("i_call_String_Trim_End", Private | Static | Extern, + ffi.Add("i_call_String_Trim_End", Private | Static | Extern, TYPE_STRING, ("v1", TYPE_STRING)) ->AsNative((delegate*)&TrimEnd) ; - ffi.Add("i_call_String_fmt", Private | Static | Extern, + ffi.Add("i_call_String_fmt", Private | Static | Extern, TYPE_STRING, ("template", TYPE_STRING), ("array", TYPE_ARRAY)) ->AsNative((delegate*)&Fmt) ; - ffi.Add("i_call_String_Contains", Private | Static | Extern, + ffi.Add("i_call_String_Contains", Private | Static | Extern, TYPE_BOOLEAN, ("v1", TYPE_STRING), ("v2", TYPE_STRING)) ->AsNative((delegate*)&Contains) ; diff --git a/runtime/ishtar.vm/__builtin/B_StringBuilder.cs b/runtime/ishtar.vm/__builtin/B_StringBuilder.cs index e258c98e..11c68469 100644 --- a/runtime/ishtar.vm/__builtin/B_StringBuilder.cs +++ b/runtime/ishtar.vm/__builtin/B_StringBuilder.cs @@ -85,7 +85,7 @@ public unsafe static class B_StringBuilder //return gc.ToIshtarObject(buffer->Value.ToString(), current); } - internal static IshtarMetaClass ThisClass => IshtarMetaClass.Define("vein/lang", "StringBuilder"); + internal static IshtarMetaClass ThisClass => IshtarMetaClass.Define("std", "StringBuilder"); public static void InitTable(ForeignFunctionInterface ffi) { diff --git a/runtime/ishtar.vm/__builtin/B_Threading.cs b/runtime/ishtar.vm/__builtin/B_Threading.cs index 8b292ba7..df823fb7 100644 --- a/runtime/ishtar.vm/__builtin/B_Threading.cs +++ b/runtime/ishtar.vm/__builtin/B_Threading.cs @@ -16,7 +16,7 @@ public static stackval createThread(stackval* args, int argsSize) public static void InitTable(ForeignFunctionInterface ffi) { - ffi.Add("_createThread", MethodFlags.Static) + ffi.Add("_createThread", MethodFlags.Static, VeinTypeCode.TYPE_VOID) ->AsNative(&createThread); } } diff --git a/runtime/ishtar.vm/__builtin/B_Type.cs b/runtime/ishtar.vm/__builtin/B_Type.cs index 515733dd..ea34fa5a 100644 --- a/runtime/ishtar.vm/__builtin/B_Type.cs +++ b/runtime/ishtar.vm/__builtin/B_Type.cs @@ -52,7 +52,7 @@ public static unsafe class B_Type return null; } - internal static IshtarMetaClass ThisClass => IshtarMetaClass.Define("vein/lang", "Type"); + internal static IshtarMetaClass ThisClass => IshtarMetaClass.Define("std", "Type"); public static void InitTable(ForeignFunctionInterface ffi) diff --git a/runtime/ishtar.vm/__builtin/mappings/FileInfoAllocator.cs b/runtime/ishtar.vm/__builtin/mappings/FileInfoAllocator.cs index 04d52adb..b84e8dcb 100644 --- a/runtime/ishtar.vm/__builtin/mappings/FileInfoAllocator.cs +++ b/runtime/ishtar.vm/__builtin/mappings/FileInfoAllocator.cs @@ -23,5 +23,5 @@ public unsafe class FileInfoAllocator : TransitAllocator //IshtarSync.EnterCriticalSection(ref @class.Owner.Interlocker.INIT_TYPE_BARRIER); } - public override VeinClass Type => IshtarMetaClass.Define("vein/lang/fs", "File"); + public override VeinClass Type => IshtarMetaClass.Define("std/fs", "File"); } diff --git a/runtime/ishtar.vm/runtime/KnowTypes.cs b/runtime/ishtar.vm/runtime/KnowTypes.cs index 438b5aa6..7b166964 100644 --- a/runtime/ishtar.vm/runtime/KnowTypes.cs +++ b/runtime/ishtar.vm/runtime/KnowTypes.cs @@ -14,7 +14,7 @@ public static class Reflection public static class Native { public static QualityTypeName NativeHandleTypeName = - new("std", nameof(NativeHandle), "global::vein/lang/native"); + new("std", nameof(NativeHandle), "global::std/native"); public static RuntimeIshtarClass* NativeHandle(CallFrame* frame) => findType(NativeHandleTypeName, frame); @@ -22,28 +22,28 @@ public static class Native public static QualityTypeName FileNotFoundFaultTypeName = - new("std", nameof(FileNotFoundFault), "global::vein/lang"); + new("std", nameof(FileNotFoundFault), "global::std"); public static RuntimeIshtarClass* FileNotFoundFault(CallFrame* frame) => findType(FileNotFoundFaultTypeName, frame); } - public static QualityTypeName TypeInfoTypeName = new("std", nameof(Type), "global::vein/lang"); - public static QualityTypeName FieldInfoTypeName = new("std", nameof(Field), "global::vein/lang"); - public static QualityTypeName FunctionInfoTypeName = new("std", nameof(Function), "global::vein/lang"); + public static QualityTypeName TypeInfoTypeName = new("std", nameof(Type), "global::std"); + public static QualityTypeName FieldInfoTypeName = new("std", nameof(Field), "global::std"); + public static QualityTypeName FunctionInfoTypeName = new("std", nameof(Function), "global::std"); - public static QualityTypeName NullPointerExceptionTypeName = new("std", "NullPointerException", "global::vein/lang"); - public static QualityTypeName IncorrectCastFaultTypeName = new("std", "IncorrectCastFault", "global::vein/lang"); + public static QualityTypeName NullPointerExceptionTypeName = new("std", "NullPointerException", "global::std"); + public static QualityTypeName IncorrectCastFaultTypeName = new("std", "IncorrectCastFault", "global::std"); public static QualityTypeName FreeImmortalObjectFaultTypeName = - new("std", nameof(FreeImmortalObjectFault), "global::vein/lang"); + new("std", nameof(FreeImmortalObjectFault), "global::std"); public static QualityTypeName TypeNotFoundFaultTypeName = - new("std", nameof(TypeNotFoundFault), "global::vein/lang/reflection"); + new("std", nameof(TypeNotFoundFault), "global::std/reflection"); public static QualityTypeName MultipleTypeFoundFaultTypeName = - new("std", nameof(MultipleTypeFoundFault), "global::vein/lang/reflection"); + new("std", nameof(MultipleTypeFoundFault), "global::std/reflection"); public static QualityTypeName PlatformIsNotSupportFaultTypeName = - new("std", nameof(PlatformIsNotSupportFault), "global::vein/lang"); - public static QualityTypeName IshatFault = new("std", nameof(IshatFault), "global::vein/lang"); + new("std", nameof(PlatformIsNotSupportFault), "global::std"); + public static QualityTypeName IshatFault = new("std", nameof(IshatFault), "global::std"); public static RuntimeIshtarClass* NullPointerException(CallFrame* frame) => findType(NullPointerExceptionTypeName, frame); diff --git a/runtime/ishtar.vm/runtime/gc/IshtarGC.cs b/runtime/ishtar.vm/runtime/gc/IshtarGC.cs index 838108c3..8e74c2b0 100644 --- a/runtime/ishtar.vm/runtime/gc/IshtarGC.cs +++ b/runtime/ishtar.vm/runtime/gc/IshtarGC.cs @@ -556,17 +556,15 @@ public void UnRegisterWeakLink(void** link, bool longLive) #region internal -#if !BOEHM_GC +#if BOEHM_GC private static readonly AllocatorBlock _allocator = new() { - alloc = &IshtarGC_Alloc, - alloc_primitives = &IshtarGC_AtomicAlloc, + alloc = &AllocateImmortal, + alloc_primitives = &AllocateImmortal, free = &IshtarGC_Free, realloc = &IshtarGC_Realloc }; - #else - private static readonly AllocatorBlock _allocator = new() { alloc = &NativeMemory_AllocZeroed, @@ -574,7 +572,6 @@ public void UnRegisterWeakLink(void** link, bool longLive) free = &NativeMemory_Free, realloc = &NativeMemory_Realloc }; - #endif diff --git a/runtime/ishtar.vm/runtime/jit/IshtarJIT.cs b/runtime/ishtar.vm/runtime/jit/IshtarJIT.cs index 679682ed..5d5de8b9 100644 --- a/runtime/ishtar.vm/runtime/jit/IshtarJIT.cs +++ b/runtime/ishtar.vm/runtime/jit/IshtarJIT.cs @@ -177,6 +177,9 @@ public void GenerateHeader(Assembler asm, int stackSize, nint procedure) public void* WrapNativeCall(IntPtr procedure, List Arguments, void* returnValue, VeinTypeCode returnType) { + if (Arguments.Any(x => x.IsGeneric)) + throw new NotSupportedException("generics is not support"); + var asm = AllocEmitter(); var stackOffset = 0; var desc = ConvertArgumentToDesc(Arguments); @@ -201,7 +204,7 @@ public void GenerateHeader(Assembler asm, int stackSize, nint procedure) for (var i = 0; i < desc.Count; i++) { var argInfo = desc[i]; - var atype = Arguments[i].Type.TypeCode; + var atype = Arguments[i].ComplexType.Class.TypeCode; if (argInfo.Instruction is x64_AssemblerStep.InstructionTarget.push) { @@ -453,22 +456,6 @@ public void GenerateHeader(Assembler asm, int stackSize, nint procedure) } - private TypeMarshalBox RemapToNative(VeinArgumentRef arg) - { - if (arg.Type.IsValueType) - return RemapValueTypeToNative(arg); - return new TypeMarshalBox((byte)sizeof(nint), arg.Type); - } - - - private TypeMarshalBox RemapValueTypeToNative(VeinArgumentRef arg) - { - var type = arg.Type; - var size = type.TypeCode.GetNativeSize(); - - return new TypeMarshalBox(size, type); - } - public void* WrapNativeCall_WithArg_Int32(void* procedure, long value) { var c = AllocEmitter(); diff --git a/runtime/ishtar.vm/runtime/vm/IshtarTypes.cs b/runtime/ishtar.vm/runtime/vm/IshtarTypes.cs index 52e5d41c..9b108d08 100644 --- a/runtime/ishtar.vm/runtime/vm/IshtarTypes.cs +++ b/runtime/ishtar.vm/runtime/vm/IshtarTypes.cs @@ -89,34 +89,34 @@ public readonly unsafe struct IshtarTypes( *module = new RuntimeIshtarModule(vault, "unnamed_types", module, new IshtarVersion(0, 0)); - var objectClass = r->create($"std%global::vein/lang/Object".L(), null, module, TYPE_OBJECT); - var valueTypeClass = r->create($"std%global::vein/lang/ValueType".L(), null, module, TYPE_OBJECT); + var objectClass = r->create($"std%global::std/Object".L(), null, module, TYPE_OBJECT); + var valueTypeClass = r->create($"std%global::std/ValueType".L(), null, module, TYPE_OBJECT); *r = new IshtarTypes( objectClass, valueTypeClass, - r->create($"std%global::vein/lang/Void".L(), valueTypeClass, module, TYPE_VOID), - r->create($"std%global::vein/lang/String".L(), objectClass, module, TYPE_STRING), - r->create($"std%global::vein/lang/Byte".L(), valueTypeClass, module, TYPE_U1), - r->create($"std%global::vein/lang/SByte".L(), valueTypeClass, module, TYPE_I1), - r->create($"std%global::vein/lang/Int16".L(), valueTypeClass, module, TYPE_I2), - r->create($"std%global::vein/lang/Int32".L(), valueTypeClass, module, TYPE_I4), - r->create($"std%global::vein/lang/Int64".L(), valueTypeClass, module, TYPE_I8), - r->create($"std%global::vein/lang/UInt16".L(), valueTypeClass, module, TYPE_U2), - r->create($"std%global::vein/lang/UInt32".L(), valueTypeClass, module, TYPE_U4), - r->create($"std%global::vein/lang/UInt64".L(), valueTypeClass,module, TYPE_U8), - r->create($"std%global::vein/lang/Half".L(), valueTypeClass, module, TYPE_R2), - r->create($"std%global::vein/lang/Float".L(), valueTypeClass, module, TYPE_R4), - r->create($"std%global::vein/lang/Double".L(), valueTypeClass, module, TYPE_R8), - r->create($"std%global::vein/lang/Decimal".L(), valueTypeClass, module, TYPE_R16), - r->create($"std%global::vein/lang/Boolean".L(), valueTypeClass, module, TYPE_BOOLEAN), - r->create($"std%global::vein/lang/Char".L(), valueTypeClass, module, TYPE_CHAR), - r->create($"std%global::vein/lang/Array".L(), objectClass, module, TYPE_ARRAY), - r->create($"std%global::vein/lang/Exception".L(), objectClass, module, TYPE_CLASS), - r->create($"std%global::vein/lang/Raw".L(), valueTypeClass, module, TYPE_RAW), - r->create($"std%global::vein/lang/Aspect".L(), objectClass, module, TYPE_CLASS), - r->create($"std%global::vein/lang/Function".L(), objectClass, module, TYPE_FUNCTION), - r->create($"std%global::vein/lang/Range".L(), objectClass, module, TYPE_CLASS) + r->create($"std%global::std/Void".L(), valueTypeClass, module, TYPE_VOID), + r->create($"std%global::std/String".L(), objectClass, module, TYPE_STRING), + r->create($"std%global::std/Byte".L(), valueTypeClass, module, TYPE_U1), + r->create($"std%global::std/SByte".L(), valueTypeClass, module, TYPE_I1), + r->create($"std%global::std/Int16".L(), valueTypeClass, module, TYPE_I2), + r->create($"std%global::std/Int32".L(), valueTypeClass, module, TYPE_I4), + r->create($"std%global::std/Int64".L(), valueTypeClass, module, TYPE_I8), + r->create($"std%global::std/UInt16".L(), valueTypeClass, module, TYPE_U2), + r->create($"std%global::std/UInt32".L(), valueTypeClass, module, TYPE_U4), + r->create($"std%global::std/UInt64".L(), valueTypeClass,module, TYPE_U8), + r->create($"std%global::std/Half".L(), valueTypeClass, module, TYPE_R2), + r->create($"std%global::std/Float".L(), valueTypeClass, module, TYPE_R4), + r->create($"std%global::std/Double".L(), valueTypeClass, module, TYPE_R8), + r->create($"std%global::std/Decimal".L(), valueTypeClass, module, TYPE_R16), + r->create($"std%global::std/Boolean".L(), valueTypeClass, module, TYPE_BOOLEAN), + r->create($"std%global::std/Char".L(), valueTypeClass, module, TYPE_CHAR), + r->create($"std%global::std/Array".L(), objectClass, module, TYPE_ARRAY), + r->create($"std%global::std/Exception".L(), objectClass, module, TYPE_CLASS), + r->create($"std%global::std/Raw".L(), valueTypeClass, module, TYPE_RAW), + r->create($"std%global::std/Aspect".L(), objectClass, module, TYPE_CLASS), + r->create($"std%global::std/Function".L(), objectClass, module, TYPE_FUNCTION), + r->create($"std%global::std/Range".L(), objectClass, module, TYPE_CLASS) ); r->Add(objectClass, false); r->Add(r->VoidClass, false); diff --git a/runtime/ishtar.vm/runtime/vm/RuntimeIshtarAlias.cs b/runtime/ishtar.vm/runtime/vm/RuntimeIshtarAlias.cs new file mode 100644 index 00000000..755fca5a --- /dev/null +++ b/runtime/ishtar.vm/runtime/vm/RuntimeIshtarAlias.cs @@ -0,0 +1,73 @@ +namespace ishtar; + +using System.Runtime.InteropServices; +using collections; +using runtime; +using runtime.gc; + +[StructLayout(LayoutKind.Explicit)] +public unsafe struct RuntimeIshtarAlias : IEq +{ + [FieldOffset(0)] + public AliasKind Kind; + [FieldOffset(1)] + public RuntimeIshtarAlias_Method Method; + [FieldOffset(1)] + public RuntimeIshtarAlias_Type Type; + + public static RuntimeIshtarAlias* CreateTypeAlias(RuntimeQualityTypeName* name, RuntimeIshtarClass* type) + { + var alias = IshtarGC.AllocateImmortal(); + + *alias = new RuntimeIshtarAlias(); + + alias->Kind = AliasKind.TYPE; + alias->Type.Class = type; + alias->Type.Name = name; + + return alias; + } + + public static RuntimeIshtarAlias* CreateMethodAlias(RuntimeQualityTypeName* name, RuntimeIshtarSignature* type) + { + var alias = IshtarGC.AllocateImmortal(); + + *alias = new RuntimeIshtarAlias(); + + alias->Kind = AliasKind.METHOD; + alias->Method.Method = type; + alias->Method.Name = name; + + return alias; + } + + public static void Free(RuntimeIshtarAlias* alias) => IshtarGC.FreeImmortal(alias); + public static bool Eq(RuntimeIshtarAlias* p1, RuntimeIshtarAlias* p2) + { + if (p1->Kind != p2->Kind) + return false; + if (p1->Kind == AliasKind.METHOD) + return RuntimeQualityTypeName.Eq(p1->Method.Name, p2->Method.Name); + if (p1->Kind == AliasKind.TYPE) + return RuntimeQualityTypeName.Eq(p1->Type.Name, p2->Type.Name); + return false; + } +} + +public enum AliasKind : byte +{ + TYPE, + METHOD +} + +public unsafe struct RuntimeIshtarAlias_Method +{ + public RuntimeQualityTypeName* Name; + public RuntimeIshtarSignature* Method; +} + +public unsafe struct RuntimeIshtarAlias_Type +{ + public RuntimeQualityTypeName* Name; + public RuntimeIshtarClass* Class; +} diff --git a/runtime/ishtar.vm/runtime/vm/RuntimeIshtarClass.cs b/runtime/ishtar.vm/runtime/vm/RuntimeIshtarClass.cs index cc444951..ac438d8b 100644 --- a/runtime/ishtar.vm/runtime/vm/RuntimeIshtarClass.cs +++ b/runtime/ishtar.vm/runtime/vm/RuntimeIshtarClass.cs @@ -11,11 +11,14 @@ namespace ishtar using static WNE; using runtime.gc; + + // ReSharper disable once TypeParameterCanBeVariant public interface ITransitionAlignment { TValue this[TKey key] { get; } } + // ReSharper disable once TypeParameterCanBeVariant public unsafe interface IUnsafeTransitionAlignment where TValue : unmanaged { TValue* this[TKey key] { get; } @@ -492,11 +495,17 @@ public void init_vtable(VirtualMachine vm, CallFrame* fr = null) public RuntimeIshtarMethod* GetEntryPoint() => Methods->FirstOrNull(x => { + if (x->IsSpecial) + return false; if (!x->IsStatic) return false; + if (x->IsExtern) + return false; + if (x->ReturnType->TypeCode != TYPE_VOID) + return false; if (x->ArgLength > 0) return false; - if (!x->Name.Equals("master()")) + if (!x->RawName.Equals("master")) return false; return true; }); diff --git a/runtime/ishtar.vm/runtime/vm/RuntimeIshtarMethod.cs b/runtime/ishtar.vm/runtime/vm/RuntimeIshtarMethod.cs index f2d77ba3..cab57423 100644 --- a/runtime/ishtar.vm/runtime/vm/RuntimeIshtarMethod.cs +++ b/runtime/ishtar.vm/runtime/vm/RuntimeIshtarMethod.cs @@ -5,27 +5,25 @@ namespace ishtar using collections; using emit; using runtime.gc; + using LLVMSharp; - public unsafe struct RuntimeMethodArgument : IEq, IDisposable + public unsafe struct RuntimeMethodArgument( + RuntimeComplexType type, + InternedString* name, + RuntimeMethodArgument* self) + : IEq, IDisposable { - public RuntimeMethodArgument(RuntimeIshtarClass* type, InternedString* name, RuntimeMethodArgument* self) - { - Type = type; - Name = name; - Self = self; - } - public const string THIS_ARGUMENT = ""; - public RuntimeIshtarClass* Type { get; private set; } - public InternedString* Name { get; private set; } - public RuntimeMethodArgument* Self { get; private set; } + public RuntimeComplexType Type { get; private set; } = type; + public InternedString* Name { get; private set; } = name; + public RuntimeMethodArgument* Self { get; private set; } = self; public void Dispose() { - Type = null; + Type = default; Name = null; Self = null; } @@ -80,7 +78,7 @@ public void Dispose() return lst; } - public static RuntimeMethodArgument* Create(IshtarTypes* types, string name, RuntimeIshtarClass* type) + public static RuntimeMethodArgument* Create(IshtarTypes* types, string name, RuntimeComplexType type) { var a = IshtarGC.AllocateImmortal(); @@ -92,13 +90,168 @@ public void Dispose() public void ReplaceType(RuntimeIshtarClass* clazz) { VirtualMachine.Assert(clazz is not null, WNE.TYPE_LOAD, "[arg] Replacing type is nullptr"); - - if (Type->IsUnresolved) + if (Type.IsGeneric) return; + if (Type.Class->IsUnresolved) Type = clazz; } public static bool Eq(RuntimeMethodArgument* p1, RuntimeMethodArgument* p2) => InternedString.Eq(p1->Name, p2->Name) && RuntimeIshtarClass.Eq(p1->Type, p2->Type); } + + public readonly unsafe struct RuntimeIshtarTypeArg( + InternedString* id, + InternedString* name, + NativeList* constraints) + : IEq + { + public readonly InternedString* Id = id; + public readonly InternedString* Name = name; + public readonly NativeList* Constraints = constraints; + + + public static bool Eq(RuntimeIshtarTypeArg* p1, RuntimeIshtarTypeArg* p2) + { + if (p1 is null || p2 is null) + throw null; + return InternedString.Eq(p1->Id, p2->Id); + } + + public static RuntimeIshtarTypeArg* Allocate(InternedString* Name, + NativeList* constraints) + { + var type = IshtarGC.AllocateImmortal(); + + *type = new RuntimeIshtarTypeArg(CreateId(Name, constraints), Name, constraints); + + return type; + } + + public static void Free(RuntimeIshtarTypeArg* typeArg) + => IshtarGC.FreeImmortal(typeArg); + + + // TODO + private static InternedString* CreateId(InternedString* Name, + NativeList* constraints) + { + var rawName = StringStorage.GetStringUnsafe(Name); + constraints->ForEach(x => + { + if (x->Kind == VeinTypeParameterConstraint.BITTABLE) + rawName += "[bittable]"; + else if (x->Kind == VeinTypeParameterConstraint.CLASS) + rawName += "[class]"; + else if (x->Kind == VeinTypeParameterConstraint.SIGNATURE || x->Kind == VeinTypeParameterConstraint.TYPE) + rawName += $"[{x->Type->FullName->NameWithNS}]"; + }); + + return StringStorage.Intern(rawName); + } + } + + public unsafe struct IshtarParameterConstraint : IEquatable, IEq + { + public VeinTypeParameterConstraint Kind; + public RuntimeIshtarClass* Type; // when TYPE or SIGNATURE + + public bool Equals(IshtarParameterConstraint other) => Kind == other.Kind && RuntimeIshtarClass.Eq(other.Type, Type); + + public static bool Eq(IshtarParameterConstraint* p1, IshtarParameterConstraint* p2) + { + if (p1 is null || p2 is null) + throw null; + return p1->Kind == p2->Kind && RuntimeIshtarClass.Eq(p1->Type, p2->Type); + } + + public static IshtarParameterConstraint* CreateBittable() + { + var e = IshtarGC.AllocateImmortal(); + *e = new IshtarParameterConstraint(); + e->Kind = VeinTypeParameterConstraint.BITTABLE; + return e; + } + public static IshtarParameterConstraint* CreateClass() + { + var e = IshtarGC.AllocateImmortal(); + *e = new IshtarParameterConstraint(); + e->Kind = VeinTypeParameterConstraint.CLASS; + return e; + } + public static IshtarParameterConstraint* CreateSignature(RuntimeIshtarClass* @interface) + { + var e = IshtarGC.AllocateImmortal(); + *e = new IshtarParameterConstraint(); + e->Kind = VeinTypeParameterConstraint.SIGNATURE; + e->Type = @interface; + return e; + } + + public static IshtarParameterConstraint* CreateType(RuntimeIshtarClass* type) + { + var e = IshtarGC.AllocateImmortal(); + *e = new IshtarParameterConstraint(); + e->Kind = VeinTypeParameterConstraint.TYPE; + e->Type = type; + return e; + } + } + + + + public readonly unsafe struct RuntimeComplexType + { + private readonly RuntimeIshtarTypeArg* _typeArg; + private readonly RuntimeIshtarClass* _class; + + public RuntimeComplexType(RuntimeIshtarClass* @class) => _class = @class; + + public RuntimeComplexType(RuntimeIshtarTypeArg* typeArg) => _typeArg = typeArg; + + public bool IsGeneric => _typeArg is not null; + + public RuntimeIshtarTypeArg* TypeArg => _typeArg; + public RuntimeIshtarClass* Class => _class; + + + public static implicit operator RuntimeComplexType(RuntimeIshtarClass* cpx) => new(cpx); + public static implicit operator RuntimeComplexType(RuntimeIshtarTypeArg* cpx) => new(cpx); + + + public static implicit operator RuntimeIshtarClass*(RuntimeComplexType cpx) + { + if (cpx.IsGeneric) + throw new NotSupportedException($"Trying summon non generic vein type, but complex type is generic"); + return cpx._class; + } + + public static implicit operator RuntimeIshtarTypeArg*(RuntimeComplexType cpx) + { + if (cpx.IsGeneric) + throw new NotSupportedException($"Trying summon generic type, but complex type is non generic vein type"); + return cpx._typeArg; + } + } + + public unsafe struct RuntimeIshtarSignature( + RuntimeComplexType returnType, + NativeList* arguments) + { + public RuntimeComplexType ReturnType = returnType; + public readonly NativeList* Arguments = arguments; + + + public static RuntimeIshtarSignature* Allocate(RuntimeComplexType returnType, + NativeList* arguments) + { + var sig = IshtarGC.AllocateImmortal(); + + *sig = new RuntimeIshtarSignature(returnType, arguments); + + return sig; + } + + public static void Free(RuntimeIshtarSignature* sig) => IshtarGC.FreeImmortal(sig); + } public unsafe struct RuntimeIshtarMethod : INamed, IEq, IDisposable { @@ -118,13 +271,14 @@ public unsafe struct RuntimeIshtarMethod : INamed, IEq, IDi public string Name => StringStorage.GetStringUnsafe(_name); public string RawName => StringStorage.GetStringUnsafe(_rawName); public MethodFlags Flags { get; private set; } - public RuntimeIshtarClass* ReturnType { get; private set; } + public RuntimeIshtarClass* ReturnType => Signature->ReturnType; public RuntimeIshtarClass* Owner { get; private set; } public int ArgLength => Arguments->Count; - public NativeList* Arguments { get; private set; } + public NativeList* Arguments => Signature->Arguments; public NativeList* Aspects { get; private set; } + public RuntimeIshtarSignature* Signature { get; private set; } public void ForceSetAsAsync() { @@ -141,14 +295,15 @@ public void Dispose() if (Header is not null) IshtarGC.FreeImmortal(Header); - Arguments->ForEach(x => x->Dispose()); - Arguments->ForEach(IshtarGC.FreeImmortal); + (Arguments)->ForEach(x => x->Dispose()); + (Arguments)->ForEach(IshtarGC.FreeImmortal); Aspects->Clear(); - Arguments->Clear(); + (Arguments)->Clear(); + RuntimeIshtarSignature.Free(Signature); IshtarGC.FreeList(Aspects); IshtarGC.FreeList(Arguments); _self = null; - Arguments = null; + Signature = null; Aspects = null; } @@ -178,9 +333,9 @@ public void Assert(RuntimeIshtarMethod* @ref) internal void ReplaceReturnType(RuntimeIshtarClass* type) { VirtualMachine.Assert(type is not null, WNE.TYPE_LOAD, "Replacing type is nullptr"); - VirtualMachine.Assert(ReturnType->IsUnresolved, WNE.TYPE_LOAD, "Replace returnType is possible only if type already unresolved"); + VirtualMachine.Assert((ReturnType)->IsUnresolved, WNE.TYPE_LOAD, "Replace returnType is possible only if type already unresolved"); - ReturnType = type; + Signature->ReturnType = type; } private static readonly Dictionary DiagnosticCtorTraces = new(); @@ -194,17 +349,17 @@ internal RuntimeIshtarMethod(string name, MethodFlags flags, RuntimeIshtarClass* { this = default; _self = self; - Arguments = IshtarGC.AllocateList(); + var arguments = IshtarGC.AllocateList(); Aspects = IshtarGC.AllocateList(); _name = StringStorage.Intern(name); _rawName = StringStorage.Intern(name.Split('(').First()); Flags = flags; - ReturnType = returnType; Owner = owner; foreach (var argument in args) - Arguments->Add(argument); + arguments->Add(argument); _ctor_called = true; DiagnosticCtorTraces[(nint)self] = Environment.StackTrace; + Signature = RuntimeIshtarSignature.Allocate(returnType, arguments); } internal RuntimeIshtarMethod(string name, MethodFlags flags, RuntimeIshtarClass* returnType, RuntimeIshtarClass* owner, RuntimeIshtarMethod* self, @@ -212,17 +367,17 @@ internal RuntimeIshtarMethod(string name, MethodFlags flags, RuntimeIshtarClass* { this = default; _self = self; - Arguments = IshtarGC.AllocateList(); + var arguments = IshtarGC.AllocateList(); Aspects = IshtarGC.AllocateList(); _name = StringStorage.Intern(name); _rawName = StringStorage.Intern(name.Split('(').First()); Flags = flags; - ReturnType = returnType; Owner = owner; if (args->Count != 0) - Arguments->AddRange(args); + arguments->AddRange(args); _ctor_called = true; DiagnosticCtorTraces[(nint)self] = Environment.StackTrace; + Signature = RuntimeIshtarSignature.Allocate(returnType, arguments); } public void SetILCode(uint* code, uint size) @@ -266,5 +421,87 @@ public static bool Eq(RuntimeIshtarMethod* p1, RuntimeIshtarMethod* p2) return p1->Name.Equals(p2->Name) && RuntimeIshtarClass.Eq(p1->Owner, p2->Owner) && p1->ArgLength == p2->ArgLength; } + + + + // TODO remove fucking using .NET types + + public static string GetFullName(string name, RuntimeComplexType* returnType, IEnumerable args) + { + static string ToTemplateString(RuntimeComplexType* t) => t->IsGeneric + ? $"µ{StringStorage.GetStringUnsafe(t->TypeArg->Name)}" + : t->Class->FullName->ToString(); + return $"{name}({string.Join(',', args.Select(x => $"{x.ToTemplateString()}"))}) -> {ToTemplateString(returnType)}"; + } + + public static string GetFullName(string name, RuntimeComplexType* returnType, NativeList* args) + { + static string ToTemplateString(RuntimeComplexType* t) => t->IsGeneric + ? $"µ{StringStorage.GetStringUnsafe(t->TypeArg->Name)}" + : t->Class->FullName->ToString(); + + var str = new List(); + + args->ForEach(x => + { + var data = x->Type; + str.Add(ToTemplateString(&data)); + }); + + return $"{name}({string.Join(',', str)}) -> {ToTemplateString(returnType)}"; + } + + public static string GetFullName(string name, RuntimeIshtarClass* returnType, NativeList* args) + { + static string ToTemplateString(RuntimeComplexType* t) => t->IsGeneric + ? $"µ{StringStorage.GetStringUnsafe(t->TypeArg->Name)}" + : t->Class->FullName->ToString(); + + var str = new List(); + + args->ForEach(x => + { + if (!NotThis(x)) + return; + + var data = x->Type; + str.Add(ToTemplateString(&data)); + }); + + return $"{name}({string.Join(',', str)}) -> {returnType->FullName->ToString()}"; + } + + public static string GetFullName(string name, RuntimeIshtarClass* returnType, IEnumerable args) + => $"{name}({string.Join(',', args.Where(NotThis).Select(x => $"{x.ToTemplateString()}"))}) -> {returnType->FullName->ToString()}"; + + public static string GetFullName(string name, RuntimeIshtarClass* returnType, RuntimeIshtarClass*[] args) + { + var stw = new List(); + + foreach (var @class in args) + stw.Add($"{@class->FullName->ToString()}"); + + return $"{name}({string.Join(',', stw)}) -> {returnType->FullName->ToString()}"; + } + + public static string GetFullName(string name, RuntimeComplexType* returnType, RuntimeIshtarClass*[] args) + { + static string ToTemplateString(RuntimeComplexType* t) => t->IsGeneric ? + $"µ{StringStorage.GetStringUnsafe(t->TypeArg->Name)}" : + t->Class->FullName->NameWithNS; + + var stw = new List(); + + foreach (var @class in args) + stw.Add($"{@class->FullName->ToString()}"); + + return $"{name}({string.Join(',', stw)}) -> {ToTemplateString(returnType)}"; + } + + private static bool NotThis(RuntimeMethodArgument* @ref) => + !StringStorage.GetStringUnsafe(@ref->Name).Equals(VeinArgumentRef.THIS_ARGUMENT); + private static bool NotThis(VeinArgumentRef @ref) => + !@ref.Name.Equals(VeinArgumentRef.THIS_ARGUMENT); + // end TODO } } diff --git a/runtime/ishtar.vm/runtime/vm/RuntimeIshtarModule.cs b/runtime/ishtar.vm/runtime/vm/RuntimeIshtarModule.cs index 96d80afe..3cbf1c0b 100644 --- a/runtime/ishtar.vm/runtime/vm/RuntimeIshtarModule.cs +++ b/runtime/ishtar.vm/runtime/vm/RuntimeIshtarModule.cs @@ -9,12 +9,12 @@ namespace ishtar.runtime; using System.Diagnostics; using System.IO; using System.Linq; -using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using vein.exceptions; using vein.extensions; using vein.reflection; using vein.runtime; +using static StringStorage; public unsafe struct RuntimeIshtarModule : IEq, IDisposable { @@ -25,6 +25,9 @@ public unsafe struct RuntimeIshtarModule : IEq, IDisposable public IshtarVersion Version { get; internal set; } + + public NativeList* alias_table { get; private set; } + = IshtarGC.AllocateList(); public NativeList* class_table { get; private set; } = IshtarGC.AllocateList(); public NativeList* deps_table { get; private set; } @@ -34,6 +37,8 @@ public unsafe struct RuntimeIshtarModule : IEq, IDisposable public NativeDictionary* types_table { get; private set; } = IshtarGC.AllocateDictionary(); + public NativeDictionary* generics_table { get; private set; } + = IshtarGC.AllocateDictionary(); public NativeDictionary* fields_table { get; private set; } = IshtarGC.AllocateDictionary(); @@ -55,11 +60,15 @@ public void Dispose() aspects_table->ForEach(x => x->Dispose()); aspects_table->ForEach(IshtarGC.FreeImmortal); + alias_table->ForEach(RuntimeIshtarAlias.Free); + generics_table->ForEach((x, y) => RuntimeIshtarTypeArg.Free(y)); types_table->Clear(); class_table->Clear(); deps_table->Clear(); aspects_table->Clear(); + alias_table->Clear(); + generics_table->Clear(); IshtarGC.FreeDictionary(types_table); IshtarGC.FreeDictionary(fields_table); @@ -67,6 +76,8 @@ public void Dispose() IshtarGC.FreeList(class_table); IshtarGC.FreeList(deps_table); IshtarGC.FreeList(aspects_table); + IshtarGC.FreeList(alias_table); + IshtarGC.FreeDictionary(generics_table); WeakRef.Free(Vault); @@ -76,6 +87,8 @@ public void Dispose() types_table = null; fields_table = null; string_table = null; + alias_table = null; + generics_table = null; _self = null; _name = null; Vault = null; @@ -96,13 +109,13 @@ public RuntimeIshtarModule(AppVault vault, string name, RuntimeIshtarModule* sel _self = self; Vault = WeakRef.Create(vault); Version = version; - _name = StringStorage.Intern(name); + _name = Intern(name); } public string Name { - get => StringStorage.GetStringUnsafe(_name); - set => _name = StringStorage.Intern(value); + get => GetStringUnsafe(_name); + set => _name = Intern(value); } @@ -273,7 +286,7 @@ public string Name VirtualMachine.GlobalPrintln($"read string: [{key}] '{value}'"); - module->string_table->Add(key, StringStorage.Intern(value)); + module->string_table->Add(key, Intern(value)); } module->Name = module->GetConstStringByIndex(idx); @@ -345,6 +358,59 @@ public string Name //throw new ClassAlreadyDefined($"Class '{clazz->FullName->ToString()}' already defined in '{module->Name}' module"); } + foreach (var _ in ..reader.ReadInt32()) + { + var key = reader.ReadInt32(); + var name = reader.ReadTypeName(module); + var isType = reader.ReadBoolean(); + + if (isType) + { + var typename = reader.ReadTypeName(module); + var type = module->FindType(typename, true, true); + + module->alias_table->Add(RuntimeIshtarAlias.CreateTypeAlias(name, type)); + } + else + { + var retType = reader.ReadComplexType(module); + var args = ReadArguments(reader, module); + var sig = RuntimeIshtarSignature.Allocate(retType, args); + module->alias_table->Add(RuntimeIshtarAlias.CreateMethodAlias(name, sig)); + } + } + // read generics + foreach (var _ in ..reader.ReadInt32()) + { + var key = reader.ReadInt32(); + var name = reader.ReadIshtarString(); + var cts = IshtarGC.AllocateList(); + + foreach (var count in ..reader.ReadInt32()) + { + var k = reader.ReadInt32(); + var kind = (VeinTypeParameterConstraint)reader.ReadInt32(); + + if (kind == VeinTypeParameterConstraint.BITTABLE) + cts->Add(IshtarParameterConstraint.CreateBittable()); + else if (kind == VeinTypeParameterConstraint.CLASS) + cts->Add(IshtarParameterConstraint.CreateClass()); + else if (kind == VeinTypeParameterConstraint.TYPE) + { + var type = reader.ReadTypeName(module); + cts->Add(IshtarParameterConstraint.CreateType(module->FindType(type, true, true))); + } + else if (kind == VeinTypeParameterConstraint.SIGNATURE) + { + var type = reader.ReadTypeName(module); + cts->Add(IshtarParameterConstraint.CreateType(module->FindType(type, true, true))); + } + else + throw new NotImplementedException(); + } + module->generics_table->Add(key, RuntimeIshtarTypeArg.Allocate(Intern(name), cts)); + } + // restore unresolved types module->class_table->ForEach(@class => { var parent = @class->Parent; @@ -373,10 +439,12 @@ public string Name if (method->Arguments->Length == 0) return; method->Arguments->ForEach(arg => { - if (!arg->Type->IsUnresolved) + if (arg->Type.IsGeneric) + return; + if (!arg->Type.Class->IsUnresolved) return; - VirtualMachine.GlobalPrintln($"resolve method.arg[]: [{arg->Type->FullName->NameWithNS}] "); - arg->ReplaceType(module->FindType(arg->Type->FullName, true, true)); + VirtualMachine.GlobalPrintln($"resolve method.arg[]: [{arg->Type.Class->FullName->NameWithNS}] "); + arg->ReplaceType(module->FindType(arg->Type.Class->FullName, true, true)); }); }); @@ -389,6 +457,9 @@ public string Name }); }); + + + foreach (var body in deferClassBodies) { var clazz = body.Clazz; @@ -454,7 +525,7 @@ public static void FillConstStorage(RuntimeConstStorage* storage, byte[] arr, Ca var value = bin.ReadIshtarString(); var fn = IshtarGC.AllocateImmortal(); - *fn = new RuntimeFieldName(StringStorage.Intern(fullname)); + *fn = new RuntimeFieldName(Intern(fullname)); stackval a = IshtarMarshal.LegacyBoxing(frame, type_code, value); @@ -488,7 +559,7 @@ public static void DistributionAspects(RuntimeIshtarModule* module) var class_eq = (RuntimeIshtarClass* x, InternedString* clazz) => { - return x->Name.Equals(StringStorage.GetStringUnsafe(clazz)); + return x->Name.Equals(GetStringUnsafe(clazz)); }; module->aspects_table->ForEach(aspect => @@ -517,7 +588,7 @@ public static void DistributionAspects(RuntimeIshtarModule* module) @class->Aspects->Add(aspect); } else - module->vm.println($"Aspect '{aspect->Name}': class '{StringStorage.GetStringUnsafe(classAspect.ClassName)}' not found."); + module->vm.println($"Aspect '{aspect->Name}': class '{GetStringUnsafe(classAspect.ClassName)}' not found."); break; } case AspectTarget.Method: @@ -530,16 +601,16 @@ public static void DistributionAspects(RuntimeIshtarModule* module) if (@class is null) { - module->vm.println($"Aspect '{aspect->Name}': method '{StringStorage.GetStringUnsafe(ma.ClassName)}/{StringStorage.GetStringUnsafe(ma.MethodName)}' not found. [no class found]"); + module->vm.println($"Aspect '{aspect->Name}': method '{GetStringUnsafe(ma.ClassName)}/{GetStringUnsafe(ma.MethodName)}' not found. [no class found]"); return; } - var method = @class->Methods->FirstOrNull(m => m->Name.Equals(StringStorage.GetStringUnsafe(ma.MethodName))); + var method = @class->Methods->FirstOrNull(m => m->Name.Equals(GetStringUnsafe(ma.MethodName))); if (method is not null) method->Aspects->Add(aspect); else { var methods = @class->Methods->ToList(); - module->vm.println($"Aspect '{aspect->Name}': method '{StringStorage.GetStringUnsafe(ma.ClassName)}/{StringStorage.GetStringUnsafe(ma.MethodName)}' not found."); + module->vm.println($"Aspect '{aspect->Name}': method '{GetStringUnsafe(ma.ClassName)}/{GetStringUnsafe(ma.MethodName)}' not found."); } break; } @@ -553,14 +624,14 @@ public static void DistributionAspects(RuntimeIshtarModule* module) if (@class is null) { - module->vm.println($"Aspect '{aspect->Name}': field '{StringStorage.GetStringUnsafe(fa.ClassName)}/{StringStorage.GetStringUnsafe(fa.FieldName)}' not found. [no class found]"); + module->vm.println($"Aspect '{aspect->Name}': field '{GetStringUnsafe(fa.ClassName)}/{GetStringUnsafe(fa.FieldName)}' not found. [no class found]"); return; } - var field = @class->Fields->FirstOrNull(m => m->Name.Equals(StringStorage.GetStringUnsafe(fa.FieldName))); + var field = @class->Fields->FirstOrNull(m => m->Name.Equals(GetStringUnsafe(fa.FieldName))); if (field is not null) field->Aspects->Add(aspect); else - module->vm.println($"Aspect '{aspect->Name}': field '{StringStorage.GetStringUnsafe(fa.ClassName)}/{StringStorage.GetStringUnsafe(fa.FieldName)}' not found."); + module->vm.println($"Aspect '{aspect->Name}': field '{GetStringUnsafe(fa.ClassName)}/{GetStringUnsafe(fa.FieldName)}' not found."); break; } } @@ -662,6 +733,9 @@ public List DecodeField(BinaryReader binary, RuntimeIshtarC using var mem = new MemoryStream(arr); using var binary = new BinaryReader(mem); var idx = binary.ReadInt32(); + var methodName = ishtarModule->GetConstStringByIndex(idx); + + var flags = (MethodFlags)binary.ReadInt16(); var bodysize = binary.ReadInt32(); var stacksize = binary.ReadByte(); @@ -670,7 +744,6 @@ public List DecodeField(BinaryReader binary, RuntimeIshtarC var args = ReadArguments(binary, ishtarModule); var body = binary.ReadBytes(bodysize); - var methodName = ishtarModule->GetConstStringByIndex(idx); var returnType = ishtarModule->FindType(retType, true, false); var mth = @class->DefineMethod(methodName, returnType, flags, args); @@ -694,7 +767,7 @@ public List DecodeField(BinaryReader binary, RuntimeIshtarC public string GetConstStringByIndex(int index) { if (string_table->TryGetValue(index, out var value)) - return StringStorage.GetStringUnsafe(value); + return GetStringUnsafe(value); throw new AggregateException($"String by index '{index}' not found in module '{Name}'."); } @@ -744,20 +817,12 @@ public void LinkFFIMethod(RuntimeIshtarMethod* method) return; } - var importTarget = StringStorage.GetString((InternedString*)aspect->Arguments->Get(0)->Value.data.p, sys_frame); - var importFn = StringStorage.GetString((InternedString*)aspect->Arguments->Get(1)->Value.data.p, sys_frame); + var importTarget = GetString((InternedString*)aspect->Arguments->Get(0)->Value.data.p, sys_frame); + var importFn = GetString((InternedString*)aspect->Arguments->Get(1)->Value.data.p, sys_frame); if (importTarget == InternalTarget) { - var args = new List<(string argName, string typeName)>(); - - - method->Arguments->ForEach(x => - { - args.Add((StringStorage.GetStringUnsafe(x->Name), x->Type->Name)); - }); - - name = VeinMethodBase.GetFullName(importFn, args); + name = RuntimeIshtarMethod.GetFullName(importFn, method->ReturnType, method->Arguments); LinkInternalNative(name, method); return; } @@ -776,12 +841,11 @@ private void LinkInternalNative(string name, RuntimeIshtarMethod* method) if (m is null) { + vm.FFI.DisplayDefinedMapping(); vm.FastFail(WNE.TYPE_LOAD, method->RawName != name ? $"Extern '{method->Name} -> {name}' method not found in native mapping." : $"Extern '{method->Name}' method not found in native mapping.", sys_frame); - - vm.FFI.DisplayDefinedMapping(); return; } @@ -876,14 +940,18 @@ internal static void ConstructIL(RuntimeIshtarMethod* method, byte[] body, short private static NativeList* ReadArguments(BinaryReader binary, RuntimeIshtarModule* ishtarModule) { var args = IshtarGC.AllocateList(); - foreach (var _ in ..binary.ReadInt32()) + var size = binary.ReadInt32(); + foreach (var _ in ..size) { var nIdx = binary.ReadInt32(); - var type = binary.ReadTypeName(ishtarModule); + var isGeneric = binary.ReadBoolean(); + RuntimeComplexType argType = isGeneric ? + binary.ReadGenericTypeName(ishtarModule) : + ishtarModule->FindType(binary.ReadTypeName(ishtarModule), true, false); var a = RuntimeMethodArgument.Create(ishtarModule->vm.Types, ishtarModule->GetConstStringByIndex(nIdx), - ishtarModule->FindType(type, true, false)); + argType); args->Add(a); } return args; @@ -903,13 +971,30 @@ public static unsafe class QualityTypeEx { var typeIndex = bin.ReadInt32(); - if (!module->types_table->TryGetValue(typeIndex, out var result)) throw new Exception($"TypeName by index '{typeIndex}' not found in '{module->Name}' module."); return result; } + public static RuntimeComplexType ReadComplexType(this BinaryReader bin, RuntimeIshtarModule* module) + { + var isGeneric = bin.ReadBoolean(); + if (isGeneric) + return bin.ReadGenericTypeName(module); + return module->FindType(bin.ReadTypeName(module), true, true); + } + + public static RuntimeIshtarTypeArg* ReadGenericTypeName(this BinaryReader bin, RuntimeIshtarModule* module) + { + var typeIndex = bin.ReadInt32(); + + if (module->generics_table->TryGetValue(typeIndex, out var result)) + return result; + + throw new Exception($"RuntimeIshtarTypeArg by index '{typeIndex}' not found in '{module->Name}' module."); + } + public static NativeList* ToNative(this List types) where T : unmanaged, IEq { var t = IshtarGC.AllocateList(types.Count); @@ -1023,7 +1108,7 @@ public unsafe struct RuntimeAspect : IEq, IDisposable public AspectTarget Target { get; } - private string _debugString => $"[{StringStorage.GetStringUnsafe(_name)}] {Target}"; + private string _debugString => $"[{GetStringUnsafe(_name)}] {Target}"; public NativeList* Arguments { get; } = IshtarGC.AllocateList(); @@ -1031,7 +1116,7 @@ public void Dispose() { if (_self is null) return; - var n = StringStorage.GetStringUnsafe(_name); + var n = GetStringUnsafe(_name); VirtualMachine.GlobalPrintln($"@@@@ Disposed aspect '{n}'"); _name = null; Union = default; @@ -1049,8 +1134,8 @@ public void Dispose() public string Name { - get => StringStorage.GetStringUnsafe(_name); - set => _name = StringStorage.Intern(value); + get => GetStringUnsafe(_name); + set => _name = Intern(value); } @@ -1070,11 +1155,11 @@ public RuntimeAspect(string name, NativeList* args, Aspec { static AspectTarget getTarget(FieldName name) { - if (name.fullName.Contains("/method/")) + if (name.fullName.Contains($"{Aspect.ASPECT_METADATA_DIVIDER}method{Aspect.ASPECT_METADATA_DIVIDER}")) return AspectTarget.Method; - if (name.fullName.Contains("/field/")) + if (name.fullName.Contains($"{Aspect.ASPECT_METADATA_DIVIDER}field{Aspect.ASPECT_METADATA_DIVIDER}")) return AspectTarget.Field; - if (name.fullName.Contains("/class/")) + if (name.fullName.Contains($"{Aspect.ASPECT_METADATA_DIVIDER}class{Aspect.ASPECT_METADATA_DIVIDER}")) return AspectTarget.Class; throw new UnknownAspectTargetException(name); @@ -1083,11 +1168,11 @@ static AspectTarget getTarget(FieldName name) - var asp_methods = data->RawGetWithFilter(x => x->Class.Contains("aspect/") && x->Class.Contains("/method/")) + var asp_methods = data->RawGetWithFilter(x => x->Class.Contains($"aspect{Aspect.ASPECT_METADATA_DIVIDER}") && x->Class.Contains($"{Aspect.ASPECT_METADATA_DIVIDER}method{Aspect.ASPECT_METADATA_DIVIDER}")) .Select(x => (*((RuntimeFieldName*)x.field),x.obj)).ToList(); - var asp_fields = data->RawGetWithFilter(x => x->Class.Contains("aspect/") && x->Class.Contains("/field/")) + var asp_fields = data->RawGetWithFilter(x => x->Class.Contains($"aspect{Aspect.ASPECT_METADATA_DIVIDER}") && x->Class.Contains($"{Aspect.ASPECT_METADATA_DIVIDER}field{Aspect.ASPECT_METADATA_DIVIDER}")) .Select(x => (*((RuntimeFieldName*)x.field),x.obj)).ToList(); - var asp_class = data->RawGetWithFilter(x => x->Class.Contains("aspect/") && x->Class.Contains("/class/") && !x->Class.Contains("/method/") && !x->Class.Contains("/field/")) + var asp_class = data->RawGetWithFilter(x => x->Class.Contains($"aspect{Aspect.ASPECT_METADATA_DIVIDER}") && x->Class.Contains($"{Aspect.ASPECT_METADATA_DIVIDER}class{Aspect.ASPECT_METADATA_DIVIDER}") && !x->Class.Contains($"{Aspect.ASPECT_METADATA_DIVIDER}method{Aspect.ASPECT_METADATA_DIVIDER}") && !x->Class.Contains($"{Aspect.ASPECT_METADATA_DIVIDER}field{Aspect.ASPECT_METADATA_DIVIDER}")) .Select(x => (*((RuntimeFieldName*)x.field),x.obj)).ToList(); @@ -1095,25 +1180,25 @@ static AspectTarget getTarget(FieldName name) // rly shit var groupClasses = asp_class.GroupBy(x => - x.Item1.Fullname.Replace("aspect/", "") - .Replace("/class", "") + x.Item1.Fullname.Replace($"aspect{Aspect.ASPECT_METADATA_DIVIDER}", "") + .Replace($"{Aspect.ASPECT_METADATA_DIVIDER}class", "") .Split('.').First()); var groupMethods = asp_methods.GroupBy(x => - x.Item1.Fullname.Replace("aspect/", "") - .Replace("/class", "") - .Replace("/method", "") + x.Item1.Fullname.Replace($"aspect{Aspect.ASPECT_METADATA_DIVIDER}", "") + .Replace($"{Aspect.ASPECT_METADATA_DIVIDER}class", "") + .Replace($"{Aspect.ASPECT_METADATA_DIVIDER}method", "") .Split('.').First()); var groupFields = asp_fields.GroupBy(x => - x.Item1.Fullname.Replace("aspect/", "") - .Replace("/class", "") - .Replace("/field", "") + x.Item1.Fullname.Replace($"aspect{Aspect.ASPECT_METADATA_DIVIDER}", "") + .Replace($"{Aspect.ASPECT_METADATA_DIVIDER}class", "") + .Replace($"{Aspect.ASPECT_METADATA_DIVIDER}field", "") .Split('.').First()); foreach (var groupClass in groupClasses) { var lst = groupClass.ToList(); - var aspectName = groupClass.Key.Split('/').First(); - var aspectClass = groupClass.Key.Split('/').Last(); + var aspectName = groupClass.Key.Split(Aspect.ASPECT_METADATA_DIVIDER).First(); + var aspectClass = groupClass.Key.Split(Aspect.ASPECT_METADATA_DIVIDER).Last(); var args = IshtarGC.AllocateList(lst.Count); @@ -1130,7 +1215,7 @@ static AspectTarget getTarget(FieldName name) *asp = new RuntimeAspect(aspectName, args, AspectTarget.Class, asp); - asp->Union.ClassAspect.ClassName = StringStorage.Intern(aspectClass); + asp->Union.ClassAspect.ClassName = Intern(aspectClass); if (aspects->FirstOrNull(x => RuntimeAspect.Eq(x, asp)) is not null) { @@ -1142,9 +1227,9 @@ static AspectTarget getTarget(FieldName name) foreach (var groupMethod in groupMethods) { var lst = groupMethod.ToList(); - var aspectName = groupMethod.Key.Split('/')[0]; - var aspectClass = groupMethod.Key.Split('/')[1]; - var aspectMethod = groupMethod.Key.Split('/')[2]; + var aspectName = groupMethod.Key.Split(Aspect.ASPECT_METADATA_DIVIDER)[0]; + var aspectClass = groupMethod.Key.Split(Aspect.ASPECT_METADATA_DIVIDER)[1]; + var aspectMethod = groupMethod.Key.Split(Aspect.ASPECT_METADATA_DIVIDER)[2]; var args = IshtarGC.AllocateList(lst.Count); var asp = IshtarGC.AllocateImmortal(); @@ -1159,8 +1244,8 @@ static AspectTarget getTarget(FieldName name) } *asp = new RuntimeAspect(aspectName, args, AspectTarget.Method, asp); - asp->Union.MethodAspect.ClassName = StringStorage.Intern(aspectClass); - asp->Union.MethodAspect.MethodName = StringStorage.Intern(aspectMethod); + asp->Union.MethodAspect.ClassName = Intern(aspectClass); + asp->Union.MethodAspect.MethodName = Intern(aspectMethod); aspects->Add(asp); @@ -1168,9 +1253,9 @@ static AspectTarget getTarget(FieldName name) foreach (var groupMethod in groupFields) { var lst = groupMethod.ToList(); - var aspectName = groupMethod.Key.Split('/')[0]; - var aspectClass = groupMethod.Key.Split('/')[1]; - var aspectField = groupMethod.Key.Split('/')[2]; + var aspectName = groupMethod.Key.Split(Aspect.ASPECT_METADATA_DIVIDER)[0]; + var aspectClass = groupMethod.Key.Split(Aspect.ASPECT_METADATA_DIVIDER)[1]; + var aspectField = groupMethod.Key.Split(Aspect.ASPECT_METADATA_DIVIDER)[2]; var args = IshtarGC.AllocateList(lst.Count); @@ -1186,8 +1271,8 @@ static AspectTarget getTarget(FieldName name) } *asp = new RuntimeAspect(aspectName, args, AspectTarget.Field, asp); - asp->Union.FieldAspect.ClassName = StringStorage.Intern(aspectClass); - asp->Union.FieldAspect.FieldName = StringStorage.Intern(aspectField); + asp->Union.FieldAspect.ClassName = Intern(aspectClass); + asp->Union.FieldAspect.FieldName = Intern(aspectField); aspects->Add(asp); } diff --git a/runtime/ishtar.vm/vm.switch.cs b/runtime/ishtar.vm/vm.switch.cs index 21c00d48..068d1102 100644 --- a/runtime/ishtar.vm/vm.switch.cs +++ b/runtime/ishtar.vm/vm.switch.cs @@ -42,6 +42,7 @@ public bool HasFlag(SysFlag flag) public bool UseDebugAllocator => Has("has_debug_allocator"); public bool DisabledFinalization => Has("has_disabled_finalization"); + public bool CallOpCodeSkipValidateArgs => Has("skip-validate-args"); //--sys::ishtar::skip-validate-args=1 #endregion diff --git a/test/vc_test/Features/GenericDocumentFeature.cs b/test/vc_test/Features/GenericDocumentFeature.cs index bb3c7348..3fef8f32 100644 --- a/test/vc_test/Features/GenericDocumentFeature.cs +++ b/test/vc_test/Features/GenericDocumentFeature.cs @@ -7,43 +7,46 @@ public class GenericDocumentFeature [Test] public void test1() { - Syntax.CompilationUnit.ParseVein( - """ - #space "test" - #use "vein/lang" - - struct App { - public test2(): void - { - for (let i = 55; i++; i != 500) { - Out.print("hello world!"); + Assert.Throws(() => + { + Syntax.CompilationUnit.ParseVein( + """ + #space "test" + #use "vein/lang" + + struct App { + public test2(): void + { + for (let i = 55; i++; i != 500) { + Out.print("hello world!"); + } } - } - public test1(): void { - fail null; - } - - public test1(): void { - let b = "asdads" + "gfdfg"; - } - - public static master(): void { - Out.print(Fib(15)); - } - - public static Fib(n: i32): i32 - { - if (n < 2) + public test1(): void { + fail null; + } + + public test1(): void { + let b = "asdads" + "gfdfg"; + } + + public static master(): void { + Out.print(Fib(15)); + } + + public static Fib(n: i32): i32 { - return n; + if (n < 2) + { + return n; + } + auto a = Fib(n - 1); + auto b = Fib(n - 2) + return a + b; } - auto a = Fib(n - 1); - auto b = Fib(n - 2) - return a + b; } - } - """ - ); + """ + ); + }, "Semicolon required"); } [Test] @@ -118,7 +121,7 @@ public static Fib(n: i32): i32 return n; } auto a = Fib(n - 1); - auto b = Fib(n - 2) + auto b = Fib(n - 2); return a + b; } } diff --git a/test/vc_test/Features/GenericFeatureTest.cs b/test/vc_test/Features/GenericFeatureTest.cs new file mode 100644 index 00000000..93d7dbeb --- /dev/null +++ b/test/vc_test/Features/GenericFeatureTest.cs @@ -0,0 +1,67 @@ +namespace veinc_test.Features; + +public class GenericFeatureTest : TestContext +{ + [Theory] + [TestCase("class", "")] + [TestCase("struct", "")] + [TestCase("interface", "")] + [TestCase("class", "", "when T1 is i32")] + public void DeclarationCanDeclareMethods(string keyword, string generics, string extended = "") + { + var cd = Syntax.ClassDeclaration.Parse($"[special] {keyword} Program{generics} {extended} {{ [special] main(): void {{}} }}"); + Assert.True(cd.Methods.Any()); + Assert.AreEqual("Program", cd.Identifier.ToString()); + Assert.IsTrue(cd.Aspects.Single().IsSpecial); + + var md = cd.Methods.Single(); + Assert.AreEqual("void", md.ReturnType.Identifier.ToString().ToLower()); + Assert.AreEqual("main", md.Identifier.ToString()); + Assert.IsTrue(md.Aspects.Single().IsSpecial); + Assert.False(md.Parameters.Any()); + + Assert.Throws(() => Syntax.ClassDeclaration.ParseVein($" class Test{generics} {{ void Main }}")); + Assert.Throws(() => Syntax.ClassDeclaration.ParseVein($"class Foo{generics} {{ int main() }}")); + } + + + [Test] + public void GenericConstraintParserTest() + { + var cd = Syntax.GenericConstraintParser.ParseVein("when T is i32"); + Assert.NotZero(cd.Count); + var c = cd.First(); + + Assert.AreEqual(c.GenericIndex.Typeword.Identifier.ExpressionString, "T"); + Assert.AreEqual(c.Constraint.Typeword.Identifier.ExpressionString, "i32"); + } + + [Test] + public void ManyGenericConstraintParserTest() + { + var cd = Syntax.GenericConstraintParser.ParseVein("when T is i32, T1 is bool"); + Assert.NotZero(cd.Count); + var c = cd.First(); + + Assert.AreEqual(c.GenericIndex.Typeword.Identifier.ExpressionString, "T"); + Assert.AreEqual(c.Constraint.Typeword.Identifier.ExpressionString, "i32"); + } + + + [Test] + public void GenericsDeclarationParser() + { + var cd = Syntax.GenericsDeclarationParser.ParseVein(""); + Assert.NotZero(cd.Count); + var c = cd.First(); + } + + [Test] + public void ManyGenericsDeclarationParser() + { + var cd = Syntax.GenericsDeclarationParser.ParseVein(""); + Assert.NotZero(cd.Count); + var c = cd.First(); + } + +}