From 214426d870e2a31acb1590d8d23c970b95b45781 Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Sat, 15 Oct 2022 18:59:49 +0200 Subject: [PATCH 1/9] first implementation --- .../KScr/Compiler/Class/ClassMemberVisitor.cs | 28 +++++++++++++++++-- kscr-core/Bytecode/Method.cs | 14 ++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs b/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs index eea693a..fa289f8 100644 --- a/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs +++ b/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs @@ -1,6 +1,9 @@ -using KScr.Antlr; +using System.Collections.Generic; +using System.Linq; +using KScr.Antlr; using KScr.Core; using KScr.Core.Bytecode; +using KScr.Core.Exception; using KScr.Core.Model; namespace KScr.Compiler.Class; @@ -32,9 +35,28 @@ public override IClassMember VisitMemCtor(KScrParser.MemCtorContext memCtor) Body = VisitMemberCode(context.memberBlock()), CatchFinally = memCtor.catchBlocks() == null ? null : VisitCatchBlocks(memCtor.catchBlocks()) }; + List paramSymbols = new(); foreach (var param in context.parameters().parameter()) - ctor.Parameters.Add(new MethodParameter - { Name = param.idPart().GetText(), Type = VisitTypeInfo(param.type()) }); + { + var parameter = new MethodParameter + { Name = param.idPart().GetText(), Type = VisitTypeInfo(param.type()) }; + ctor.Parameters.Add(parameter); + paramSymbols.Add(ctx.RegisterSymbol(parameter.Name, parameter.Type, SymbolType.Parameter)); + } + foreach (var super in context.subConstructorCalls().subConstructorCall()) + { + var superType = ctx.FindType(vm, super.type().GetText())!; + ctor.SuperCalls.Add(new StatementComponent() + { + Type = StatementComponentType.Code, + CodeType = BytecodeType.ConstructorCall, + Arg = superType.FullDetailedName, + SubStatement = VisitArguments(super.arguments()) + }); + } + if (!paramSymbols.All(ctx.UnregisterSymbol)) + throw new FatalException("Could not unregister all ctor parameter symbols"); + return ctor; } diff --git a/kscr-core/Bytecode/Method.cs b/kscr-core/Bytecode/Method.cs index 3134a9d..fdfc78d 100644 --- a/kscr-core/Bytecode/Method.cs +++ b/kscr-core/Bytecode/Method.cs @@ -84,6 +84,7 @@ public Method(SourcefilePosition sourceLocation, Class parent, string name, ITyp } public List Parameters { get; } = new(); + public List SuperCalls { get; } = new(); public ITypeInfo ReturnType { get; } public override string FullName => @@ -99,6 +100,19 @@ public override Stack Invoke(RuntimeBase vm, Stack stack, IObject? target = null throw new FatalException("Missing invocation target for non-static method " + Name); stack.StepInto(vm, SourceLocation, target, this, stack => { + if (Name == ConstructorName) + { + // pre-handle super calls + foreach (var superCall in SuperCalls) + { + var superType = vm.FindType(superCall.Arg!)!; + var superCtor = superType.DeclaredMembers[ConstructorName]; + if ((superCall.SubStatement!.CodeType & BytecodeType.ParameterExpression) == 0) + throw new FatalException("Invalid supercall: Missing parameter expression"); + var args = superCall.SubStatement.Evaluate(vm, stack.Output(Del))[Del]!; + superCtor.Invoke(vm, stack, target, args: args.AsArray(vm, stack)); + } + } for (var i = 0; i < Math.Min(Parameters.Count, args.Length); i++) vm.PutLocal(stack, Parameters[i].Name, args[i]); Body.Evaluate(vm, stack); From 4e0ca4f6d1572866464d9a3624f997975178dc85 Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Sat, 15 Oct 2022 19:16:45 +0200 Subject: [PATCH 2/9] create test scenario --- KScr.NET.sln | 5 ++- kscr-compiler/KScr/Compiler/NodeCompiler.cs | 4 +-- kscr-system/kscr-system.csproj | 4 +-- kscr-system/src-todo/time/Date.kscr | 31 ---------------- kscr-system/src-todo/time/DateTime.kscr | 4 --- kscr-system/src-todo/time/Time.kscr | 36 ------------------- kscr-system/src/time/Date.kscr | 35 ++++++++++++++++++ kscr-system/src/time/DateTime.kscr | 10 ++++++ kscr-system/src/time/Time.kscr | 40 +++++++++++++++++++++ 9 files changed, 93 insertions(+), 76 deletions(-) delete mode 100644 kscr-system/src-todo/time/Date.kscr delete mode 100644 kscr-system/src-todo/time/DateTime.kscr delete mode 100644 kscr-system/src-todo/time/Time.kscr create mode 100644 kscr-system/src/time/Date.kscr create mode 100644 kscr-system/src/time/DateTime.kscr create mode 100644 kscr-system/src/time/Time.kscr diff --git a/KScr.NET.sln b/KScr.NET.sln index 6eb7df1..1bcad43 100644 --- a/KScr.NET.sln +++ b/KScr.NET.sln @@ -84,7 +84,10 @@ Global File = Build std & Execute.run.xml File = Compile & Run.run.xml File = Test Install.run.xml - File = Test Sandbox.run.xml + File = Test Build - dependencies.run.xml + File = Test Build - info.run.xml + File = Test Build - build.run.xml + File = Test Build - run.run.xml EndGlobalSection GlobalSection(NestedProjects) = preSolution {8F75C3E7-3788-47DA-8313-4C7051D5D342} = {BCE9FFFF-7A44-4FFF-A877-A1C5076A2847} diff --git a/kscr-compiler/KScr/Compiler/NodeCompiler.cs b/kscr-compiler/KScr/Compiler/NodeCompiler.cs index 7eef991..f92e90c 100644 --- a/kscr-compiler/KScr/Compiler/NodeCompiler.cs +++ b/kscr-compiler/KScr/Compiler/NodeCompiler.cs @@ -34,6 +34,7 @@ public static MemberNode ForBaseClass(CompilerRuntime vm, CompilerContext ctx, F if (decl.classDecl().Length != 1) throw new NotImplementedException("Unable to load more than one class from source file " + file.FullName); var cls = pkg.Package.GetOrCreateClass(vm, info.Name, info.Modifier, info.ClassType)!; + ctx = new CompilerContext { Parent = ctx, Class = cls, Imports = vm.FindClassImports(decl.imports()) }; var kls = decl.classDecl(0); try { @@ -48,8 +49,7 @@ public static MemberNode ForBaseClass(CompilerRuntime vm, CompilerContext ctx, F ctx.DropContext(); } - return new MemberNode(vm, - new CompilerContext { Parent = ctx, Class = cls, Imports = vm.FindClassImports(decl.imports()) }, pkg) + return new MemberNode(vm, ctx, pkg) { MemberContext = kls, Member = cls diff --git a/kscr-system/kscr-system.csproj b/kscr-system/kscr-system.csproj index 76ee3cb..b7b498f 100644 --- a/kscr-system/kscr-system.csproj +++ b/kscr-system/kscr-system.csproj @@ -16,11 +16,11 @@ - + - + diff --git a/kscr-system/src-todo/time/Date.kscr b/kscr-system/src-todo/time/Date.kscr deleted file mode 100644 index fe203b1..0000000 --- a/kscr-system/src-todo/time/Date.kscr +++ /dev/null @@ -1,31 +0,0 @@ -package org.comroid.kscr.time; - -public class Date { - private static final Map interns = new Trie(); - public final int Year; - public final int Month; - public final int Day; - - public Date(int year, int month, int day) { - return getInternal(year, month, day); - } - - @Convert - public Date(str date) { - int[] split = date.split("-") >> int::parse; - return new Date(split[0], split[1], split[2]); - } - - public str toString(short variant) { - return toString(Year, Month, Day); - } - - @Trie.Key - private static str toString(int year, int month, int day) { - return $"{Year}-{Month}-{Day}"; - } - - private static Date getInternal(int year, int month, int day) { - return interns.getOrCreate(Year, Month, Day); - } -} diff --git a/kscr-system/src-todo/time/DateTime.kscr b/kscr-system/src-todo/time/DateTime.kscr deleted file mode 100644 index 5cd14c2..0000000 --- a/kscr-system/src-todo/time/DateTime.kscr +++ /dev/null @@ -1,4 +0,0 @@ -package org.comroid.kscr.time; - -public final class DateTime extends Date, Time { -} diff --git a/kscr-system/src-todo/time/Time.kscr b/kscr-system/src-todo/time/Time.kscr deleted file mode 100644 index 669a1ff..0000000 --- a/kscr-system/src-todo/time/Time.kscr +++ /dev/null @@ -1,36 +0,0 @@ -package org.comroid.kscr.time; - -public class Time { - private static final Map interns = new Trie(); - public final int Hour; - public final int Minute; - public final int? Second; - public final int? Millisecond; - - public Time(int hour, int minute, int second?, int millisecond?) { - return getInternal(hour, minute, second, millisecond); - } - - @Convert - public Time(str time) { - int[] split = time.split("[:.]") >> int::parse; - return new Time(split[0], split[1], split[2], split[3]); - } - - public str toString(short variant) { - return toString(Hour, Minute, Second, Millisecond); - } - - @Trie.Key - private static str toString(int hour, int minute, int second?, int millisecond?) { - str txt = $"{Hour}:{Minute}"; - Second ?> txt += "." + Second; - Millisecond ?> txt += "." + Millisecond; - return txt; - - } - - private static Time getInternal(int hour, int minute, int second?, int millisecond?) { - return interns.getOrCreate(hour, minute, second, millisecond); - } -} diff --git a/kscr-system/src/time/Date.kscr b/kscr-system/src/time/Date.kscr new file mode 100644 index 0000000..8fb9539 --- /dev/null +++ b/kscr-system/src/time/Date.kscr @@ -0,0 +1,35 @@ +package org.comroid.kscr.time; + +public class Date { + public Date(int days) { + stdio <<- "Date is " + days + "days" + endl; + } + + //private static final Map interns = new Trie(); + //public final int Year; + //public final int Month; + //public final int Day; +// + //public Date(int year, int month, int day) { + // return getInternal(year, month, day); + //} +// + //@Convert + //public Date(str date) { + // int[] split = date.split("-") >> int::parse; + // return new Date(split[0], split[1], split[2]); + //} +// + //public str toString(short variant) { + // return toString(Year, Month, Day); + //} +// + //@Trie.Key + //private static str toString(int year, int month, int day) { + // return $"{Year}-{Month}-{Day}"; + //} +// + //private static Date getInternal(int year, int month, int day) { + // return interns.getOrCreate(Year, Month, Day); + //} +} diff --git a/kscr-system/src/time/DateTime.kscr b/kscr-system/src/time/DateTime.kscr new file mode 100644 index 0000000..b3045aa --- /dev/null +++ b/kscr-system/src/time/DateTime.kscr @@ -0,0 +1,10 @@ +package org.comroid.kscr.time; + +import org.comroid.kscr.time.Date; +import org.comroid.kscr.time.Time; + +public final class DateTime extends Date, Time { + public DateTime(int days, int seconds) : Date(days), Time(seconds) { + stdio <<- "DateTime is " + days + ":" + seconds + endl; + } +} diff --git a/kscr-system/src/time/Time.kscr b/kscr-system/src/time/Time.kscr new file mode 100644 index 0000000..b58e8bb --- /dev/null +++ b/kscr-system/src/time/Time.kscr @@ -0,0 +1,40 @@ +package org.comroid.kscr.time; + +public class Time { + public Time(int seconds) { + stdio <<- "Time is " + seconds + "secs" + endl; + } + + //private static final Map interns = new Trie(); + //public final int Hour; + //public final int Minute; + //public final int? Second; + //public final int? Millisecond; +// + //public Time(int hour, int minute, int second?, int millisecond?) { + // return getInternal(hour, minute, second, millisecond); + //} +// + //@Convert + //public Time(str time) { + // int[] split = time.split("[:.]") >> int::parse; + // return new Time(split[0], split[1], split[2], split[3]); + //} +// + //public str toString(short variant) { + // return toString(Hour, Minute, Second, Millisecond); + //} +// + //@Trie.Key + //private static str toString(int hour, int minute, int second?, int millisecond?) { + // str txt = $"{Hour}:{Minute}"; + // Second ?> txt += "." + Second; + // Millisecond ?> txt += "." + Millisecond; + // return txt; + // + //} +// + //private static Time getInternal(int hour, int minute, int second?, int millisecond?) { + // return interns.getOrCreate(hour, minute, second, millisecond); + //} +} From 373d293d793225bc95b4f574346136a94983093b Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Wed, 19 Oct 2022 20:38:59 +0200 Subject: [PATCH 3/9] introduce FileNode --- KScr.NET.sln | 5 +- .../KScr/Compiler/AbstractVisitor.cs | 4 +- .../KScr/Compiler/Class/ClassMemberVisitor.cs | 2 +- .../KScr/Compiler/Class/ClassVisitor.cs | 4 +- .../KScr/Compiler/Code/CodeblockVisitor.cs | 2 +- .../KScr/Compiler/Code/ExpressionVisitor.cs | 2 +- .../KScr/Compiler/Code/StatementVisitor.cs | 2 +- .../KScr/Compiler/Code/TypeInfoVisitor.cs | 2 +- .../KScr/Compiler/CompilerRuntime.cs | 2 +- kscr-compiler/KScr/Compiler/NodeCompiler.cs | 150 +++++++++++------- 10 files changed, 108 insertions(+), 67 deletions(-) diff --git a/KScr.NET.sln b/KScr.NET.sln index 1bcad43..6eb7df1 100644 --- a/KScr.NET.sln +++ b/KScr.NET.sln @@ -84,10 +84,7 @@ Global File = Build std & Execute.run.xml File = Compile & Run.run.xml File = Test Install.run.xml - File = Test Build - dependencies.run.xml - File = Test Build - info.run.xml - File = Test Build - build.run.xml - File = Test Build - run.run.xml + File = Test Sandbox.run.xml EndGlobalSection GlobalSection(NestedProjects) = preSolution {8F75C3E7-3788-47DA-8313-4C7051D5D342} = {BCE9FFFF-7A44-4FFF-A877-A1C5076A2847} diff --git a/kscr-compiler/KScr/Compiler/AbstractVisitor.cs b/kscr-compiler/KScr/Compiler/AbstractVisitor.cs index 308550d..23af3c0 100644 --- a/kscr-compiler/KScr/Compiler/AbstractVisitor.cs +++ b/kscr-compiler/KScr/Compiler/AbstractVisitor.cs @@ -16,13 +16,13 @@ namespace KScr.Compiler; public abstract class AbstractVisitor : KScrParserBaseVisitor { - protected AbstractVisitor(RuntimeBase vm, CompilerContext ctx) + protected AbstractVisitor(CompilerRuntime vm, CompilerContext ctx) { this.vm = vm; this.ctx = ctx; } - protected RuntimeBase vm { get; } + protected CompilerRuntime vm { get; } protected CompilerContext ctx { get; } protected ITypeInfo? RequestedType { get; init; } diff --git a/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs b/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs index fa289f8..a1f3aec 100644 --- a/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs +++ b/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs @@ -10,7 +10,7 @@ namespace KScr.Compiler.Class; public class ClassMemberVisitor : AbstractVisitor { - public ClassMemberVisitor(RuntimeBase vm, CompilerContext ctx) : base(vm, ctx) + public ClassMemberVisitor(CompilerRuntime vm, CompilerContext ctx) : base(vm, ctx) { } diff --git a/kscr-compiler/KScr/Compiler/Class/ClassVisitor.cs b/kscr-compiler/KScr/Compiler/Class/ClassVisitor.cs index cd84308..0a1681c 100644 --- a/kscr-compiler/KScr/Compiler/Class/ClassVisitor.cs +++ b/kscr-compiler/KScr/Compiler/Class/ClassVisitor.cs @@ -8,7 +8,7 @@ namespace KScr.Compiler.Class; public class ClassInfoVisitor : AbstractVisitor { - public ClassInfoVisitor(RuntimeBase vm, CompilerContext ctx) : base(vm, ctx) + public ClassInfoVisitor(CompilerRuntime vm, CompilerContext ctx) : base(vm, ctx) { } @@ -28,7 +28,7 @@ public override ClassInfo VisitClassDecl(KScrParser.ClassDeclContext context) public class ClassVisitor : AbstractVisitor { - public ClassVisitor(RuntimeBase vm, CompilerContext ctx) : base(vm, ctx) + public ClassVisitor(CompilerRuntime vm, CompilerContext ctx) : base(vm, ctx) { } diff --git a/kscr-compiler/KScr/Compiler/Code/CodeblockVisitor.cs b/kscr-compiler/KScr/Compiler/Code/CodeblockVisitor.cs index 7802776..83037d3 100644 --- a/kscr-compiler/KScr/Compiler/Code/CodeblockVisitor.cs +++ b/kscr-compiler/KScr/Compiler/Code/CodeblockVisitor.cs @@ -8,7 +8,7 @@ namespace KScr.Compiler.Code; public class CodeblockVisitor : AbstractVisitor { - public CodeblockVisitor(RuntimeBase vm, CompilerContext ctx) : base(vm, ctx) + public CodeblockVisitor(CompilerRuntime vm, CompilerContext ctx) : base(vm, ctx) { } diff --git a/kscr-compiler/KScr/Compiler/Code/ExpressionVisitor.cs b/kscr-compiler/KScr/Compiler/Code/ExpressionVisitor.cs index c4dda92..6ce2950 100644 --- a/kscr-compiler/KScr/Compiler/Code/ExpressionVisitor.cs +++ b/kscr-compiler/KScr/Compiler/Code/ExpressionVisitor.cs @@ -10,7 +10,7 @@ namespace KScr.Compiler.Code; public class ExpressionVisitor : AbstractVisitor { - public ExpressionVisitor(RuntimeBase vm, CompilerContext ctx) : base(vm, ctx) + public ExpressionVisitor(CompilerRuntime vm, CompilerContext ctx) : base(vm, ctx) { } diff --git a/kscr-compiler/KScr/Compiler/Code/StatementVisitor.cs b/kscr-compiler/KScr/Compiler/Code/StatementVisitor.cs index 2c86f1a..ef1c757 100644 --- a/kscr-compiler/KScr/Compiler/Code/StatementVisitor.cs +++ b/kscr-compiler/KScr/Compiler/Code/StatementVisitor.cs @@ -8,7 +8,7 @@ namespace KScr.Compiler.Code; public class StatementVisitor : AbstractVisitor { - public StatementVisitor(RuntimeBase vm, CompilerContext ctx) : base(vm, ctx) + public StatementVisitor(CompilerRuntime vm, CompilerContext ctx) : base(vm, ctx) { } diff --git a/kscr-compiler/KScr/Compiler/Code/TypeInfoVisitor.cs b/kscr-compiler/KScr/Compiler/Code/TypeInfoVisitor.cs index bdaaba6..4ed68c2 100644 --- a/kscr-compiler/KScr/Compiler/Code/TypeInfoVisitor.cs +++ b/kscr-compiler/KScr/Compiler/Code/TypeInfoVisitor.cs @@ -10,7 +10,7 @@ namespace KScr.Compiler.Code; public class TypeInfoVisitor : AbstractVisitor { - public TypeInfoVisitor(RuntimeBase vm, CompilerContext ctx) : base(vm, ctx) + public TypeInfoVisitor(CompilerRuntime vm, CompilerContext ctx) : base(vm, ctx) { } diff --git a/kscr-compiler/KScr/Compiler/CompilerRuntime.cs b/kscr-compiler/KScr/Compiler/CompilerRuntime.cs index 6ea5d74..a516e87 100644 --- a/kscr-compiler/KScr/Compiler/CompilerRuntime.cs +++ b/kscr-compiler/KScr/Compiler/CompilerRuntime.cs @@ -32,7 +32,7 @@ public void CompileSource(string source, string? basePackage = null) var decl = MakeFileDecl(src); ctx = new CompilerContext { Parent = ctx, Class = FindClassInfo(src), Imports = FindClassImports(decl.imports()) }; - node = SourceNode.ForBaseClass(this, ctx, src, new PackageNode(this, ctx, src.DirectoryName!, pkg)); + node = new FileNode(this, ctx, new PackageNode(this, ctx, src.DirectoryName!, pkg), src).CreateClassNode(); var mc = (node as MemberNode)!.ReadMembers(); Debug.WriteLine($"[NodeCompiler] Loaded {mc} members"); } diff --git a/kscr-compiler/KScr/Compiler/NodeCompiler.cs b/kscr-compiler/KScr/Compiler/NodeCompiler.cs index f92e90c..2f42da7 100644 --- a/kscr-compiler/KScr/Compiler/NodeCompiler.cs +++ b/kscr-compiler/KScr/Compiler/NodeCompiler.cs @@ -16,7 +16,7 @@ public abstract class SourceNode : AbstractVisitor { public readonly List Nodes = new(); - protected SourceNode(RuntimeBase vm, CompilerContext ctx) : base(vm, ctx) + protected SourceNode(CompilerRuntime vm, CompilerContext ctx) : base(vm, ctx) { } @@ -27,35 +27,6 @@ public static PackageNode ForPackage(CompilerRuntime vm, CompilerContext ctx, Di return new PackageNode(vm, new CompilerContext { Parent = ctx, Package = pkg }, dir.FullName, pkg); } - public static MemberNode ForBaseClass(CompilerRuntime vm, CompilerContext ctx, FileInfo file, PackageNode pkg) - { - var info = vm.FindClassInfo(file); - var decl = vm.MakeFileDecl(file); - if (decl.classDecl().Length != 1) - throw new NotImplementedException("Unable to load more than one class from source file " + file.FullName); - var cls = pkg.Package.GetOrCreateClass(vm, info.Name, info.Modifier, info.ClassType)!; - ctx = new CompilerContext { Parent = ctx, Class = cls, Imports = vm.FindClassImports(decl.imports()) }; - var kls = decl.classDecl(0); - try - { - ctx.PushContext(cls); - foreach (var type in kls.objectExtends()?.type() ?? new KScrParser.TypeContext[] { }) - cls.DeclaredSuperclasses.Add(ctx.FindType(vm, type.GetText())!.AsClassInstance(vm)); - foreach (var type in kls.objectImplements()?.type() ?? new KScrParser.TypeContext[] { }) - cls.DeclaredInterfaces.Add(ctx.FindType(vm, type.GetText())!.AsClassInstance(vm)); - } - finally - { - ctx.DropContext(); - } - - return new MemberNode(vm, ctx, pkg) - { - MemberContext = kls, - Member = cls - }; - } - public static int RevisitRec(IEnumerable nodes, bool rec = false) { var c = 0; @@ -69,6 +40,8 @@ public static int RevisitRec(IEnumerable nodes, bool rec = false) .Select(x => x.RevisitCode()) .Sum(); else c += mem.RevisitCode(); + else if (node is FileNode fil) + c += RevisitRec(fil.Nodes, true); else throw new FatalException("Invalid Node to revisit: " + node); if (!rec) @@ -82,7 +55,7 @@ public class PackageNode : SourceNode public readonly Package Package; public readonly string Path; - public PackageNode(RuntimeBase vm, CompilerContext ctx, string path, Package package) : base(vm, ctx) + public PackageNode(CompilerRuntime vm, CompilerContext ctx, string path, Package package) : base(vm, ctx) { Path = path; Package = package; @@ -90,13 +63,27 @@ public PackageNode(RuntimeBase vm, CompilerContext ctx, string path, Package pac public void Read() { - int pc, cc = pc = 0; + int pc, fc, mc = fc = pc = 0; pc += ReadPackages(); - pc += ReadPackagesRec(Nodes, ref cc); + pc += ReadPackageMembersRec(Nodes); + fc += ReadFilesRec(Nodes); + mc += ReadClassesRec(Nodes); Debug.WriteLine($"[NodeCompiler] Loaded {pc} packages"); - Debug.WriteLine($"[NodeCompiler] Loaded {cc} classes"); - Debug.WriteLine($"[NodeCompiler] Loaded {pc + cc} nodes"); + Debug.WriteLine($"[NodeCompiler] Loaded {fc} files"); + Debug.WriteLine($"[NodeCompiler] Loaded {mc} members"); + Debug.WriteLine($"[NodeCompiler] Loaded {pc + fc + mc} nodes"); + } + + public static int ReadPackageMembersRec(IEnumerable nodes) + { + int c = 0; + foreach (var node in nodes.Where(x => x is PackageNode).Cast()) + { + c += node.ReadPackages(); + c += ReadPackageMembersRec(node.Nodes); + } + return c; } public int ReadPackages() @@ -105,48 +92,105 @@ public int ReadPackages() foreach (var sub in Directory.EnumerateDirectories(Path)) { var dir = new DirectoryInfo(sub); - Nodes.Add(ForPackage(vm as CompilerRuntime ?? throw new FatalException("Invalid Runtime"), ctx, dir, - Package)); + Nodes.Add(ForPackage(vm, ctx, dir, Package)); c++; } - return c; } - public static int ReadPackagesRec(IEnumerable nodes, ref int cc) + private static int ReadFilesRec(IEnumerable nodes) { - var c = 0; + int c = 0; foreach (var node in nodes.Where(x => x is PackageNode).Cast()) { - c += node.ReadPackages(); - c += ReadPackagesRec(node.Nodes, ref cc); - cc += node.ReadClasses(); + c += node.ReadFiles(); + c += ReadFilesRec(node.Nodes); } - return c; } - public int ReadClasses() + public int ReadFiles() { - var c = 0; - foreach (var sub in Directory.EnumerateFiles(Path, '*' + RuntimeBase.SourceFileExt, - SearchOption.TopDirectoryOnly)) + int c = 0; + foreach (var sub in Directory.EnumerateFiles(Path, '*' + RuntimeBase.SourceFileExt, SearchOption.TopDirectoryOnly)) { var file = new FileInfo(sub); - var classNode = ForBaseClass(vm as CompilerRuntime ?? throw new FatalException("Invalid Runtime"), ctx, - file, this); - classNode.ReadMembers(); - Nodes.Add(classNode); + Nodes.Add(new FileNode(vm, ctx, this, file)); c++; } + return c; + } + + public static int ReadClassesRec(IEnumerable nodes) + { + int c = 0; + foreach (var node in nodes) + { + if (node is FileNode fn) + c += fn.ReadClass(); + c += ReadClassesRec(node.Nodes); + } + return c; + } +} +public class FileNode : SourceNode +{ + public PackageNode Pkg { get; } + public FileInfo File { get; } + public ClassInfo ClassInfo { get; } + public KScrParser.FileContext Decl { get; } + public List Imports { get; } + public Core.Std.Class Cls { get; } + + public FileNode(CompilerRuntime vm, CompilerContext ctx, PackageNode pkg, FileInfo file) : base(vm, ctx) + { + this.Pkg = pkg; + this.File = file; + this.ClassInfo = vm.FindClassInfo(file); + this.Decl = vm.MakeFileDecl(File); + this.Imports = vm.FindClassImports(Decl.imports()); + this.Cls = Pkg.Package.GetOrCreateClass(vm, ClassInfo.Name, ClassInfo.Modifier, ClassInfo.ClassType)!; + } + + public int ReadClass() + { + var classNode = CreateClassNode(); + var c = classNode.ReadMembers(); + Nodes.Add(classNode); return c; } + + public MemberNode CreateClassNode() + { + if (Decl.classDecl().Length != 1) + throw new NotImplementedException("Unable to load more than one class from source file " + File.FullName); + var ctx = new CompilerContext { Parent = this.ctx, Class = Cls, Imports = this.Imports }; + var kls = Decl.classDecl(0); + try + { + ctx.PushContext(Cls); + foreach (var type in kls.objectExtends()?.type() ?? new KScrParser.TypeContext[] { }) + Cls.DeclaredSuperclasses.Add(ctx.FindType(vm, type.GetText())!.AsClassInstance(vm)); + foreach (var type in kls.objectImplements()?.type() ?? new KScrParser.TypeContext[] { }) + Cls.DeclaredInterfaces.Add(ctx.FindType(vm, type.GetText())!.AsClassInstance(vm)); + } + finally + { + ctx.DropContext(); + } + + return new MemberNode(vm, ctx, Pkg) + { + MemberContext = kls, + Member = Cls + }; + } } public class MemberNode : SourceNode { - public MemberNode(RuntimeBase vm, CompilerContext ctx, PackageNode pkg, MemberNode? parent = null) : base(vm, ctx) + public MemberNode(CompilerRuntime vm, CompilerContext ctx, PackageNode pkg, MemberNode? parent = null) : base(vm, ctx) { Pkg = pkg; Parent = parent; From 929c7a083ac413346f084dc443bf7c8fbe13f80a Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Wed, 19 Oct 2022 20:54:21 +0200 Subject: [PATCH 4/9] remove outdated duplicate code Update NodeCompiler.cs --- .../KScr/Compiler/AbstractVisitor.cs | 13 -- .../KScr/Compiler/Class/ClassMemberVisitor.cs | 145 ------------------ .../KScr/Compiler/Class/ClassVisitor.cs | 31 ---- kscr-compiler/KScr/Compiler/NodeCompiler.cs | 11 ++ 4 files changed, 11 insertions(+), 189 deletions(-) delete mode 100644 kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs diff --git a/kscr-compiler/KScr/Compiler/AbstractVisitor.cs b/kscr-compiler/KScr/Compiler/AbstractVisitor.cs index 23af3c0..c19d696 100644 --- a/kscr-compiler/KScr/Compiler/AbstractVisitor.cs +++ b/kscr-compiler/KScr/Compiler/AbstractVisitor.cs @@ -72,19 +72,6 @@ protected TypeParameter VisitTypeParameter(KScrParser.GenericTypeDefContext gtd) return new TypeParameter(name, spec, target.AsClassInstance(vm)) { DefaultValue = def }; } - protected IClassMember VisitClassMember(KScrParser.MemberContext member) - { - return member.RuleIndex switch - { - KScrParser.RULE_methodDecl or KScrParser.RULE_constructorDecl or KScrParser.RULE_initDecl - or KScrParser.RULE_propertyDecl or KScrParser.RULE_member - => new ClassMemberVisitor(vm, ctx).Visit(member), - KScrParser.RULE_classDecl => new ClassVisitor(vm, ctx).Visit(member), - _ => throw new ArgumentOutOfRangeException(nameof(member.RuleIndex), member.RuleIndex, - "Invalid Rule for member: " + member) - }; - } - protected ExecutableCode VisitCode(ParserRuleContext? code) { return code == null ? new ExecutableCode() : new CodeblockVisitor(vm, ctx).Visit(code); diff --git a/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs b/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs deleted file mode 100644 index a1f3aec..0000000 --- a/kscr-compiler/KScr/Compiler/Class/ClassMemberVisitor.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using KScr.Antlr; -using KScr.Core; -using KScr.Core.Bytecode; -using KScr.Core.Exception; -using KScr.Core.Model; - -namespace KScr.Compiler.Class; - -public class ClassMemberVisitor : AbstractVisitor -{ - public ClassMemberVisitor(CompilerRuntime vm, CompilerContext ctx) : base(vm, ctx) - { - } - - public override IClassMember VisitMemInit(KScrParser.MemInitContext memInit) - { - var context = memInit.initDecl(); - return new Method(ToSrcPos(context), ctx.Class!.AsClass(vm), Method.StaticInitializerName, - Core.Std.Class.VoidType, MemberModifier.Private | MemberModifier.Static) - { - Body = VisitMemberCode(context.memberBlock()), - CatchFinally = memInit.catchBlocks() == null ? null : VisitCatchBlocks(memInit.catchBlocks()) - }; - } - - public override IClassMember VisitMemCtor(KScrParser.MemCtorContext memCtor) - { - var context = memCtor.constructorDecl(); - var cls = ctx.Class!.AsClass(vm); - var mod = VisitModifiers(context.modifiers()) | MemberModifier.Static; - var ctor = new Method(ToSrcPos(context), cls, Method.ConstructorName, cls, mod) - { - Body = VisitMemberCode(context.memberBlock()), - CatchFinally = memCtor.catchBlocks() == null ? null : VisitCatchBlocks(memCtor.catchBlocks()) - }; - List paramSymbols = new(); - foreach (var param in context.parameters().parameter()) - { - var parameter = new MethodParameter - { Name = param.idPart().GetText(), Type = VisitTypeInfo(param.type()) }; - ctor.Parameters.Add(parameter); - paramSymbols.Add(ctx.RegisterSymbol(parameter.Name, parameter.Type, SymbolType.Parameter)); - } - foreach (var super in context.subConstructorCalls().subConstructorCall()) - { - var superType = ctx.FindType(vm, super.type().GetText())!; - ctor.SuperCalls.Add(new StatementComponent() - { - Type = StatementComponentType.Code, - CodeType = BytecodeType.ConstructorCall, - Arg = superType.FullDetailedName, - SubStatement = VisitArguments(super.arguments()) - }); - } - if (!paramSymbols.All(ctx.UnregisterSymbol)) - throw new FatalException("Could not unregister all ctor parameter symbols"); - - return ctor; - } - - public override IClassMember VisitMemMtd(KScrParser.MemMtdContext memMtd) - { - var context = memMtd.methodDecl(); - var name = context.idPart().GetText(); - var type = VisitTypeInfo(context.type()); - var mod = VisitModifiers(context.modifiers()); - var mtd = new Method(ToSrcPos(context), ctx.Class!.AsClass(vm), name, type, mod) - { - Body = VisitMemberCode(context.memberBlock()), - CatchFinally = memMtd.catchBlocks() == null ? null : VisitCatchBlocks(memMtd.catchBlocks()) - }; - foreach (var param in context.parameters().parameter()) - mtd.Parameters.Add(new MethodParameter - { Name = param.idPart().GetText(), Type = VisitTypeInfo(param.type()) }); - return mtd; - } - - public override IClassMember VisitMemIdx(KScrParser.MemIdxContext memIdx) - { - var context = memIdx.indexerMemberDecl(); - var type = VisitTypeInfo(context.type()); - var mod = VisitModifiers(context.modifiers()); - var idx = new Property(ToSrcPos(context), ctx.Class!.AsClass(vm), Method.IndexerName, type, mod); - return new PropBlockVisitor(this, idx).Visit(context.propBlock()); - } - - public override IClassMember VisitPropertyDecl(KScrParser.PropertyDeclContext context) - { - var name = context.idPart().GetText(); - var type = VisitTypeInfo(context.type()); - var mod = VisitModifiers(context.modifiers()); - var prop = new Property(ToSrcPos(context), ctx.Class!.AsClass(vm), name, type, mod); - return new PropBlockVisitor(this, prop).Visit(context.propBlock()); - } - - private sealed class PropBlockVisitor : KScrParserBaseVisitor - { - private readonly ClassMemberVisitor _parent; - private readonly Property _prop; - - public PropBlockVisitor(ClassMemberVisitor parent, Property prop) - { - _parent = parent; - _prop = prop; - } - - public override Property VisitPropComputed(KScrParser.PropComputedContext context) - { - _prop.Getter = _parent.VisitMemberCode(context.memberBlock()); - _prop.Gettable = true; - return _prop; - } - - public override Property VisitPropAccessors(KScrParser.PropAccessorsContext context) - { - _prop.Gettable = (_prop.Getter = _parent.VisitMemberCode(context.propGetter())) != null; - if (context.propSetter() is { } setter) - _prop.Settable = (_prop.Setter = _parent.VisitMemberCode(setter)) != null; - if (context.propInit() is { } init) - _prop.Inittable = (_prop.Initter = _parent.VisitMemberCode(init)) != null; - return _prop; - } - - public override Property VisitPropFieldStyle(KScrParser.PropFieldStyleContext context) - { - if (context.Start.Type == KScrLexer.ASSIGN && context.expr() is { } expr) - { - var initter = new ExecutableCode(); - var stmt = new Statement - { - Type = StatementComponentType.Expression, - CodeType = BytecodeType.Expression - }; - stmt.Main.Add(_parent.VisitExpression(expr)); - initter.Main.Add(stmt); - _prop.Inittable = (_prop.Initter = initter) != null; - } - - _prop.Gettable = _prop.Settable = true; - return _prop; - } - } -} \ No newline at end of file diff --git a/kscr-compiler/KScr/Compiler/Class/ClassVisitor.cs b/kscr-compiler/KScr/Compiler/Class/ClassVisitor.cs index 0a1681c..8638e29 100644 --- a/kscr-compiler/KScr/Compiler/Class/ClassVisitor.cs +++ b/kscr-compiler/KScr/Compiler/Class/ClassVisitor.cs @@ -26,37 +26,6 @@ public override ClassInfo VisitClassDecl(KScrParser.ClassDeclContext context) } } -public class ClassVisitor : AbstractVisitor -{ - public ClassVisitor(CompilerRuntime vm, CompilerContext ctx) : base(vm, ctx) - { - } - - private Core.Std.Class cls => ctx.Class!.AsClass(vm); - - public override Core.Std.Class VisitClassDecl(KScrParser.ClassDeclContext context) - { - if (context.genericTypeDefs() is { } defs) - foreach (var genTypeDef in defs.genericTypeDef()) - if (cls.TypeParameters.All(x => x.Name != genTypeDef.idPart().GetText())) - cls.TypeParameters.Add(VisitTypeParameter(genTypeDef)); - if (context.objectExtends() is { } ext) - foreach (var extendsType in ext.type()) - cls.DeclaredSuperclasses.Add(VisitTypeInfo(extendsType).AsClassInstance(vm)); - if (context.objectImplements() is { } impl) - foreach (var implementsType in impl.type()) - cls.DeclaredInterfaces.Add(VisitTypeInfo(implementsType).AsClassInstance(vm)); - - foreach (var each in context.member()) - { - var member = VisitClassMember(each); - cls.DeclaredMembers[member.Name] = member; - } - - return cls; - } -} - public class ModifierVisitor : KScrParserBaseVisitor { public override MemberModifier VisitModPublic(KScrParser.ModPublicContext context) diff --git a/kscr-compiler/KScr/Compiler/NodeCompiler.cs b/kscr-compiler/KScr/Compiler/NodeCompiler.cs index 2f42da7..bd04fdb 100644 --- a/kscr-compiler/KScr/Compiler/NodeCompiler.cs +++ b/kscr-compiler/KScr/Compiler/NodeCompiler.cs @@ -260,6 +260,17 @@ public override SourceNode VisitConstructorDecl(KScrParser.ConstructorDeclContex Type = VisitTypeInfo(param.type()), Name = param.idPart().GetText() }); + foreach (var super in context.subConstructorCalls()?.subConstructorCall() ?? Array.Empty()) + { + var superType = ctx.FindType(vm, super.type().GetText())!; + ctor.SuperCalls.Add(new StatementComponent() + { + Type = StatementComponentType.Code, + CodeType = BytecodeType.ConstructorCall, + Arg = superType.FullDetailedName, + SubStatement = VisitArguments(super.arguments()) + }); + } return new MemberNode(vm, ctx, Pkg, this) { MemberContext = context, From af53976aafb5c482fc9c02d359c48d987f8ef94a Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Wed, 19 Oct 2022 20:54:33 +0200 Subject: [PATCH 5/9] fix binaryop mutation --- grammar/KScrParser.g4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammar/KScrParser.g4 b/grammar/KScrParser.g4 index fa3b554..41e6c17 100644 --- a/grammar/KScrParser.g4 +++ b/grammar/KScrParser.g4 @@ -113,7 +113,7 @@ indexerDecl: LSQUAR type idPart (COMMA type idPart)* RSQUAR; indexerExpr: LSQUAR expr (COMMA expr)* RSQUAR; cast: LPAREN type COLON expr RPAREN; declaration: type idPart (ASSIGN expr)?; -mutation: binaryop? ASSIGN expr; +mutation: (binaryop | binaryop_late)? ASSIGN expr; call: idPart arguments; ctorCall: NEW type arguments; newArray: NEW type indexerExpr; From d45198beff9abc2928d272990ee63da65247e256 Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Wed, 19 Oct 2022 20:54:43 +0200 Subject: [PATCH 6/9] Update kscr-compiler.csproj --- kscr-compiler/kscr-compiler.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kscr-compiler/kscr-compiler.csproj b/kscr-compiler/kscr-compiler.csproj index 9affb91..ed1dd54 100644 --- a/kscr-compiler/kscr-compiler.csproj +++ b/kscr-compiler/kscr-compiler.csproj @@ -16,11 +16,11 @@ - + - + From e11d020d9061cf984fad245bbbd91d26b38bdc94 Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Wed, 19 Oct 2022 21:04:24 +0200 Subject: [PATCH 7/9] do save supercalls for constructors --- kscr-bytecode/Adapter/BytecodeAdapterV0_10.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kscr-bytecode/Adapter/BytecodeAdapterV0_10.cs b/kscr-bytecode/Adapter/BytecodeAdapterV0_10.cs index 3dc20af..f23ddad 100644 --- a/kscr-bytecode/Adapter/BytecodeAdapterV0_10.cs +++ b/kscr-bytecode/Adapter/BytecodeAdapterV0_10.cs @@ -139,6 +139,8 @@ protected override void WriteMethod(Stream stream, StringCache strings, Method m Write(stream, strings, mtd.ReturnType.FullDetailedName); Write(stream, strings, mtd.SourceLocation); Write(stream, strings, mtd.Parameters.ToArray()); + if (mtd.Name == Method.ConstructorName) + Write(stream, strings, mtd.SuperCalls.ToArray()); Write(stream, strings, mtd.Body); } @@ -158,9 +160,14 @@ protected override Method ReadMethod(RuntimeBase vm, Stream stream, StringCache returnType = vm.FindType(ReadString(stream, strings)); srcPos = Load(vm, strings, stream, pkg, cls); var parameters = ReadArray(vm, stream, strings, pkg, cls); + StatementComponent[]? supers = name == Method.ConstructorName + ? ReadArray(vm, stream, strings, pkg, cls) + : null; var body = Load(vm, strings, stream, pkg, cls); var mtd = new Method(srcPos, cls!, name, returnType, mod) { Body = body }; mtd.Parameters.AddRange(parameters); + if (supers != null) + mtd.SuperCalls.AddRange(supers); return mtd; } From 5f62b3701c7587666d5b225d0bc998b840dd31c3 Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Wed, 19 Oct 2022 21:04:45 +0200 Subject: [PATCH 8/9] init ctor variables before superctor evaluation --- kscr-core/Bytecode/Method.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kscr-core/Bytecode/Method.cs b/kscr-core/Bytecode/Method.cs index fdfc78d..570f454 100644 --- a/kscr-core/Bytecode/Method.cs +++ b/kscr-core/Bytecode/Method.cs @@ -100,6 +100,8 @@ public override Stack Invoke(RuntimeBase vm, Stack stack, IObject? target = null throw new FatalException("Missing invocation target for non-static method " + Name); stack.StepInto(vm, SourceLocation, target, this, stack => { + for (var i = 0; i < Math.Min(Parameters.Count, args.Length); i++) + vm.PutLocal(stack, Parameters[i].Name, args[i]); if (Name == ConstructorName) { // pre-handle super calls @@ -113,8 +115,6 @@ public override Stack Invoke(RuntimeBase vm, Stack stack, IObject? target = null superCtor.Invoke(vm, stack, target, args: args.AsArray(vm, stack)); } } - for (var i = 0; i < Math.Min(Parameters.Count, args.Length); i++) - vm.PutLocal(stack, Parameters[i].Name, args[i]); Body.Evaluate(vm, stack); if (stack.State != State.Return && Name != ConstructorName && ReturnType.Name != "void") throw new FatalException("Invalid state after method: " + stack.State); From 57fad336a50a5d93238860d11fbb0fb2355932c2 Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Wed, 19 Oct 2022 21:04:57 +0200 Subject: [PATCH 9/9] add polymorphism test code --- examples/PrintNumbers.kscr | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/PrintNumbers.kscr b/examples/PrintNumbers.kscr index 7f06c94..b667a40 100644 --- a/examples/PrintNumbers.kscr +++ b/examples/PrintNumbers.kscr @@ -2,6 +2,7 @@ package org.comroid.kscr.test; import org.comroid.kscr.core.Throwable; import org.comroid.kscr.core.Sequencable; +import org.comroid.kscr.time.DateTime; public class PrintNumbers implements Throwable { public static int StackSize => 64; @@ -23,6 +24,7 @@ public class PrintNumbers implements Throwable { // stdio <<- "first argument is:" + args[0] + endl // <<- "args array is " + args + endl; public static void main() { + DateTime datetime = new DateTime(3, 4); int[] xy = new int[6]; stdio <<- "array size is " + xy.length() + endl;