Skip to content

Commit

Permalink
Introduce IValidatable
Browse files Browse the repository at this point in the history
  • Loading branch information
burdoto committed Feb 25, 2023
1 parent 09ecfe4 commit 7e145c1
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 4 deletions.
7 changes: 7 additions & 0 deletions kscr-compiler/AbstractVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@

namespace KScr.Compiler;

public interface IValidatable
{
void Validate();
}

public abstract class AbstractVisitor<T> : KScrParserBaseVisitor<T>
{
protected AbstractVisitor(CompilerRuntime vm, CompilerContext ctx)
Expand All @@ -27,6 +32,8 @@ protected AbstractVisitor(CompilerRuntime vm, CompilerContext ctx)

protected override bool ShouldVisitNextChild(IRuleNode node, T currentResult)
{
if (currentResult is IValidatable validatable)
validatable.Validate();
return currentResult == null;
}

Expand Down
58 changes: 54 additions & 4 deletions kscr-compiler/NodeCompiler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
Expand All @@ -14,7 +15,7 @@

namespace KScr.Compiler;

public abstract class SourceNode : AbstractVisitor<SourceNode>
public abstract class SourceNode : AbstractVisitor<SourceNode>, IValidatable
{
public readonly List<SourceNode> Nodes = new();

Expand Down Expand Up @@ -57,6 +58,8 @@ public static int RevisitRec(IEnumerable<SourceNode> nodes, bool rec = false)
Log<CompilerRuntime>.At(LogLevel.Debug, $"Revisited {c} members");
return c;
}

public abstract void Validate();
}

public class PackageNode : SourceNode
Expand Down Expand Up @@ -103,7 +106,9 @@ public int ReadPackages()
try
{
var dir = new DirectoryInfo(sub);
Nodes.Add(ForPackage(vm, ctx, dir, Package));
var node = ForPackage(vm, ctx, dir, Package);
node.Validate();
Nodes.Add(node);
c++;
}
catch (CompilerException cex)
Expand Down Expand Up @@ -134,7 +139,9 @@ public int ReadFiles()
try
{
var file = new FileInfo(sub);
Nodes.Add(new FileNode(vm, ctx, this, file));
var node = new FileNode(vm, ctx, this, file);
node.Validate();
Nodes.Add(node);
c++;
}
catch (CompilerException cex)
Expand All @@ -154,6 +161,7 @@ public static int ReadClassesRec(IEnumerable<SourceNode> nodes)
if (node is FileNode fn)
c += fn.ReadClass();
c += ReadClassesRec(node.Nodes);
node.Validate();
}
catch (CompilerException cex)
{
Expand All @@ -162,6 +170,13 @@ public static int ReadClassesRec(IEnumerable<SourceNode> nodes)

return c;
}

public override void Validate()
{
if (!Package.FullName.All(c => !char.IsLetter(c) || char.IsLower(c)))
throw new CompilerException(RuntimeBase.SystemSrcPos, CompilerErrorMessage.InvalidName,
"package", Package.FullName, "must be lowercase");
}
}

public class FileNode : SourceNode
Expand Down Expand Up @@ -224,6 +239,32 @@ public MemberNode CreateClassNode()
Member = Cls
};
}

public override void Validate()
{
// 1 validate constructors using all superconstructors
if (Cls.DeclaredMembers.ContainsKey(Method.ConstructorName))
{
var ctor = (Cls.DeclaredMembers[Method.ConstructorName] as Method)!;
foreach (var error in Cls.Superclasses
.Where(cls => cls.Name is not "object" and not "void")
.Where(cls => !ctor.SuperCalls.Any(spr => spr.Arg.StartsWith(cls.CanonicalName)))
.Select(missing => new CompilerException(ctor.SourceLocation,
CompilerErrorMessage.ClassSuperTypeNotCalled, Cls, missing)))
vm.CompilerErrors.Add(error);
}

// 2 validate class abstract or all abstract members implemented
if (!Cls.IsAbstract())
foreach (var error in ((IClass)Cls).InheritedMembers
.Where(ModifierMethods.IsAbstract)
.Where(mem => ((IClass)Cls).ClassMembers.All(x => x.Name != mem.Name))
.Select(missing => new CompilerException(Cls.SourceLocation,
CompilerErrorMessage.ClassAbstractMemberNotImplemented, Cls, missing)))
vm.CompilerErrors.Add(error);

// 3 validate used type parameters
}
}

public class MemberNode : SourceNode
Expand All @@ -250,7 +291,9 @@ public int ReadMembers()
foreach (var mem in cls.member())
try
{
Nodes.Add(Visit(mem));
var node = Visit(mem);
node.Validate();
Nodes.Add(node);
c++;
}
catch (CompilerException cex)
Expand Down Expand Up @@ -412,4 +455,11 @@ private Core.System.Class ContainingClass()
return cls;
return Parent!.ContainingClass();
}

public override void Validate()
{
// 1 validate overriding member is constructor or matches supermember footprint

// 2 validate used type parameters
}
}

0 comments on commit 7e145c1

Please sign in to comment.