Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User defined classes #478

Open
wants to merge 109 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
0c3f5ca
Syntax
Kuinox Aug 18, 2024
c2ebad1
wip
Kuinox Aug 25, 2024
451df51
wip
Kuinox Sep 8, 2024
6c1f7d5
wip
Kuinox Sep 14, 2024
56e59d2
Merge remote-tracking branch 'origin/main' into userdefined-classes-3
Kuinox Sep 15, 2024
43adfa0
wip
Kuinox Sep 16, 2024
a0cab5b
wip
Kuinox Sep 16, 2024
616ad18
yes there is no message commit because it will get squashed
Kuinox Sep 17, 2024
8b6c184
progress.
Kuinox Sep 18, 2024
c1b941e
binding & symbols works.
Kuinox Sep 19, 2024
242d9b8
wip
Kuinox Sep 23, 2024
991e13d
wip
Kuinox Sep 28, 2024
73e6a15
fix
Kuinox Sep 30, 2024
231feb2
wip
Kuinox Oct 2, 2024
a839616
updated SyntaxFactory.
Kuinox Oct 3, 2024
0521fa4
ps swap.
Kuinox Oct 3, 2024
3c63845
use field keyword.
Kuinox Oct 3, 2024
ca84c41
wip
Kuinox Oct 5, 2024
23c9817
Merge remote-tracking branch 'origin/userdefined-classes-3' into user…
Kuinox Oct 5, 2024
0476eac
wip
Kuinox Oct 5, 2024
940f5f8
starting to implementing this.
Kuinox Oct 7, 2024
929d875
fix
Kuinox Oct 8, 2024
4d404ab
wip
Kuinox Oct 8, 2024
c7673ef
wip
Kuinox Oct 9, 2024
da57abc
wip
Kuinox Oct 14, 2024
2d3aaa9
Fixed MetadataCodegen
Kuinox Oct 14, 2024
712558b
Fix some codegen
Kuinox Oct 14, 2024
568c527
some progress.
Kuinox Oct 17, 2024
d798797
wip
Kuinox Oct 17, 2024
5f22300
wip
Kuinox Oct 20, 2024
abd2580
wip
Kuinox Oct 21, 2024
c25ca7f
Make constructor generate (but incorrectly)
Kuinox Oct 22, 2024
71f8162
constructor have a special name.
Kuinox Oct 23, 2024
67b98dc
it work.
Kuinox Oct 23, 2024
f4f5e0f
ok there is a few bugs remaining
Kuinox Oct 23, 2024
a6d119d
tests cleanup.
Kuinox Oct 24, 2024
2c93d54
remove debug dll dump
Kuinox Oct 24, 2024
1a0a5b7
Merge branch 'main' into userdefined-classes-3
Kuinox Oct 26, 2024
a2a35db
wip fixing tests.
Kuinox Oct 26, 2024
2ff6b99
fixed special name logic
Kuinox Oct 27, 2024
f7539df
self review
Kuinox Oct 27, 2024
8035ae4
Some pr feedback.
Kuinox Oct 27, 2024
fb297e0
Removed unused field ir model.
Kuinox Oct 27, 2024
56fd7f4
Type => Class, + ran namespace simplification.
Kuinox Oct 27, 2024
0922f74
using cleanup.
Kuinox Oct 27, 2024
5fe55ad
some pr feedback.
Kuinox Oct 28, 2024
cb8465a
more pr feedback
Kuinox Oct 28, 2024
c24b819
wip
Kuinox Oct 28, 2024
ce72219
Added error on this resolution.
Kuinox Oct 29, 2024
4de8931
Update src/Draco.Compiler/Internal/OptimizingIr/Model/Class.cs
Kuinox Oct 29, 2024
a18510d
Update src/Draco.Compiler/Internal/Syntax/Syntax.xml
Kuinox Oct 29, 2024
5db5309
Update src/Draco.Compiler/Internal/OptimizingIr/Model/Procedure.cs
Kuinox Oct 29, 2024
2bdf4ac
Added tests for illegal this.
Kuinox Oct 30, 2024
14a8df1
Merge branch 'main' into userdefined-classes-3
LPeter1997 Oct 30, 2024
4b83f01
Update Syntax.xml
LPeter1997 Oct 30, 2024
e20a311
Builds
LPeter1997 Oct 30, 2024
d696448
Update Parser.cs
LPeter1997 Oct 30, 2024
e3dd5d0
Update Parser.cs
LPeter1997 Oct 30, 2024
81a95ab
Update Parser.cs
LPeter1997 Oct 30, 2024
261b076
Update Lexer.cs
LPeter1997 Oct 30, 2024
541f941
Yeeted unit
LPeter1997 Oct 30, 2024
d6f7b4e
Update ConstructorFunctionSymbol.cs
LPeter1997 Oct 31, 2024
dafd12c
Update SyntaxErrors.cs
LPeter1997 Oct 31, 2024
883abbe
Update Lexer.cs
LPeter1997 Oct 31, 2024
1990d06
Cleaned up syntax naming
LPeter1997 Oct 31, 2024
ae6d486
Syntax fixup
LPeter1997 Oct 31, 2024
1d0e05f
Parser done
LPeter1997 Oct 31, 2024
e987b77
Some PR feedback.
Kuinox Nov 1, 2024
fbbffa9
Update DefaultConstructorSymbol.cs
LPeter1997 Nov 2, 2024
0cd287e
Update SourceThisParameterSymbol.cs
LPeter1997 Nov 2, 2024
35e0a51
Simplification
LPeter1997 Nov 2, 2024
bb06a72
More simplification
LPeter1997 Nov 2, 2024
7072883
Placed additional symbols into respective class
LPeter1997 Nov 2, 2024
9482eba
Update SyntaxFactory.cs
LPeter1997 Nov 3, 2024
6f3ae69
Update ErrorThisParameterSymbol.cs
LPeter1997 Nov 3, 2024
5c49194
Update ErrorThisParameterSymbol.cs
LPeter1997 Nov 3, 2024
312be23
Tweaks
LPeter1997 Nov 3, 2024
5d32842
Update SemanticModel.cs
LPeter1997 Nov 3, 2024
37c5f9a
Update Binder_Expression.cs
LPeter1997 Nov 3, 2024
a32b6c7
Update SourceClassSymbol.cs
LPeter1997 Nov 3, 2024
ff3636c
Update ClassBinder.cs
LPeter1997 Nov 3, 2024
3178f1b
Update ClassBinder.cs
LPeter1997 Nov 3, 2024
91db04d
Simplified
LPeter1997 Nov 3, 2024
498fd58
Update BinderCache.cs
LPeter1997 Nov 3, 2024
b10833e
Update MetadataCodegen.cs
LPeter1997 Nov 7, 2024
8d7c65b
Update MetadataCodegen.cs
LPeter1997 Nov 7, 2024
f46bb86
Update ModelExtensions.cs
LPeter1997 Nov 7, 2024
06dad34
Update Procedure.cs
LPeter1997 Nov 7, 2024
01ae05d
Removed parent relationships
LPeter1997 Nov 7, 2024
27f3e2f
Update MetadataCodegen.cs
LPeter1997 Nov 7, 2024
2155163
Update IClass.cs
LPeter1997 Nov 7, 2024
3a8e650
Update Module.cs
LPeter1997 Nov 7, 2024
b21515f
Rename
LPeter1997 Nov 7, 2024
cca9b52
Reorder, rename
LPeter1997 Nov 11, 2024
3842497
Fixed errors
LPeter1997 Nov 11, 2024
05793a9
Update ParserTests.cs
LPeter1997 Nov 11, 2024
f054f7b
Update CompilingCodeTests.cs
LPeter1997 Nov 11, 2024
0d44315
Update ConstructorFunctionSymbol.cs
LPeter1997 Nov 11, 2024
50bc7fb
Made class props work
LPeter1997 Nov 11, 2024
fc64a4d
Update SourceClassSymbol.cs
LPeter1997 Nov 11, 2024
4a7df1a
Update MetadataCodegen.cs
LPeter1997 Nov 11, 2024
3d8db0c
Slight fixes
LPeter1997 Nov 11, 2024
f0526b6
Fix
LPeter1997 Nov 12, 2024
d418c40
Codegen and IR fix
LPeter1997 Nov 12, 2024
02ed123
Update MetadataCodegen.cs
LPeter1997 Nov 13, 2024
3429e63
Update MetadataCodegen.cs
LPeter1997 Nov 13, 2024
a42b49f
Update MetadataCodegen.cs
LPeter1997 Nov 13, 2024
4e71a87
Update MetadataCodegen.cs
LPeter1997 Nov 13, 2024
a6a5d9e
Update MetadataCodegen.cs
LPeter1997 Nov 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/Draco.Chr/Constraints/PropagationHistory.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Draco.Chr.Rules;
Expand Down
1 change: 0 additions & 1 deletion src/Draco.Compiler.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.CommandLine;
using System.CommandLine.Parsing;
using System.IO;
using System.Linq;
using Draco.Compiler.Api;
Expand Down
48 changes: 48 additions & 0 deletions src/Draco.Compiler.Tests/EndToEnd/CompilingCodeTests.cs
Kuinox marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -999,4 +999,52 @@ func outer(x: int32): int32 {

Assert.Equal(3, result);
}

[Fact]
public void ClassHelloWorld()
{
var assembly = CompileToAssembly("""
import System.Console;

class Foo {
func bar() {
WriteLine("Hello, World!");
}
}
""");

var stringWriter = new StringWriter();
_ = Invoke<object?>(assembly: assembly, stdout: stringWriter, methodName: "bar", moduleName: "FreeFunctions.Foo");

Assert.Equal($"Hello, World!{Environment.NewLine}", stringWriter.ToString(), ignoreLineEndingDifferences: true);
}

[Fact]
public void InstanceField()
{
var assembly = CompileToAssembly("""
import System.Console;

func bar(): int32 {
var foo = Foo();
foo.increment();
return foo.get();
}

class Foo {
field var i: int32;

public func increment(this) {
this.i += 1;
}

public func get(this): int32 {
return this.i;
}
}
""");

var value = Invoke<int>(assembly: assembly, methodName: "bar");
Assert.Equal(1, value);
}
}
8 changes: 4 additions & 4 deletions src/Draco.Compiler.Tests/Services/CodeCompletionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ public void TestLocalCompletionGlobalVariable()
{
// TODO: Can we get rid of all this filtering by filtering in the completion service?
var completions = GetCompletionWords("""
val global = 5;
val globalVar = 5;
func main(){
var local = gl|
}
""");

AssertCompletions(completions, "global");
AssertCompletions(completions, "globalVar");
}

[Fact]
Expand Down Expand Up @@ -78,11 +78,11 @@ func main(){
public void TestGlobalCompletionGlobalVariable()
{
var completions = GetCompletionWords("""
val global = 5;
val globalVar = 5;
val x = gl|
""");

AssertCompletions(completions, "global");
AssertCompletions(completions, "globalVar");
}

[Fact]
Expand Down
37 changes: 35 additions & 2 deletions src/Draco.Compiler.Tests/Syntax/ParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1957,7 +1957,7 @@ func foo(@Attr2("this is a parameter") x: int32) {}
this.T(TokenKind.ParenOpen);
this.N<SeparatedSyntaxList<ParameterSyntax>>();
{
this.N<ParameterSyntax>();
this.N<NormalParameterSyntax>();
{
this.N<SyntaxList<AttributeSyntax>>();
this.N<AttributeSyntax>();
Expand Down Expand Up @@ -2088,7 +2088,7 @@ func foo(x: List<>) {}
this.T(TokenKind.ParenOpen);
this.N<SeparatedSyntaxList<ParameterSyntax>>();
{
this.N<ParameterSyntax>();
this.N<NormalParameterSyntax>();
{
this.T(TokenKind.Identifier, "x");
this.T(TokenKind.Colon);
Expand All @@ -2113,4 +2113,37 @@ func foo(x: List<>) {}
}
}
}

[Fact]
public void TestClassDeclaration()
{
this.ParseDeclaration("""
class Foo {
}
""");

this.N<ClassDeclarationSyntax>();
{
this.T(TokenKind.KeywordClass);
this.T(TokenKind.Identifier, "Foo");
this.N<BlockClassBodySyntax>();
}
}

[Fact]
public void TestValueClassDeclaration()
{
this.ParseDeclaration("""
value class Foo {
}
""");

this.N<ClassDeclarationSyntax>();
{
this.T(TokenKind.KeywordValue);
this.T(TokenKind.KeywordClass);
this.T(TokenKind.Identifier, "Foo");
this.N<BlockClassBodySyntax>();
}
}
}
11 changes: 10 additions & 1 deletion src/Draco.Compiler/Api/Semantics/SemanticModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
Expand Down Expand Up @@ -194,6 +193,16 @@ public ImmutableArray<ISymbol> GetAllAccessibleSymbols(SyntaxNode? node)
.SingleOrDefault(sym => sym.DeclaringSyntax == syntax);
return symbol;
}
case SourceClassSymbol classSymbol:
{
// Could be the class itself
if (classSymbol.DeclaringSyntax == syntax) return containingSymbol;

// Search for the corresponding syntax
var symbol = classSymbol.Members
.SingleOrDefault(sym => sym.DeclaringSyntax == syntax);
return symbol;
}
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public ImmutableArray<CompletionItem> GetCompletions(SemanticModel semanticModel
// Type expression
NameTypeSyntax => CompletionContext.Type,
// Parameter name declaration
ParameterSyntax => CompletionContext.None,
NormalParameterSyntax => CompletionContext.None,
// Global declaration
UnexpectedDeclarationSyntax => CompletionContext.Declaration,
// Declaring identifier
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;

Expand Down
88 changes: 75 additions & 13 deletions src/Draco.Compiler/Api/Syntax/SyntaxFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ public static SeparatedSyntaxList<ParameterSyntax> ParameterList(params Paramete
public static ParameterSyntax Parameter(string name, TypeSyntax type) =>
Parameter([], name, type);
public static ParameterSyntax Parameter(IEnumerable<AttributeSyntax> attributes, string name, TypeSyntax type) =>
Parameter(SyntaxList(attributes), null, Identifier(name), Colon, type);
NormalParameter(SyntaxList(attributes), null, Identifier(name), Colon, type);
public static ParameterSyntax VariadicParameter(string name, TypeSyntax type) =>
Parameter(SyntaxList<AttributeSyntax>(), Ellipsis, Identifier(name), Colon, type);
NormalParameter(SyntaxList<AttributeSyntax>(), Ellipsis, Identifier(name), Colon, type);

public static SeparatedSyntaxList<GenericParameterSyntax> GenericParameterList(IEnumerable<GenericParameterSyntax> parameters) =>
SeparatedSyntaxList(Comma, parameters);
Expand Down Expand Up @@ -173,64 +173,126 @@ public static VariableDeclarationSyntax ValDeclaration(
string name,
TypeSyntax? type = null,
ExpressionSyntax? value = null) =>
VariableDeclaration([], null, false, false, name, type, value);
VariableDeclaration(
attributes: [], null,
isGlobal: false,
isField: false,
isMutable: false,
name: name,
type: type,
value: value);

public static VariableDeclarationSyntax VarDeclaration(
string name,
TypeSyntax? type = null,
ExpressionSyntax? value = null) =>
VariableDeclaration([], null, false, true, name, type, value);
ExpressionSyntax? value = null) => VariableDeclaration(
attributes: [],
visibility: null,
isGlobal: false,
isField: false,
isMutable: true,
name: name,
type: type,
value: value);

public static VariableDeclarationSyntax FieldValDeclaration(
string name,
TypeSyntax? type = null,
ExpressionSyntax? value = null) =>
VariableDeclaration([], null, true, false, name, type, value);
ExpressionSyntax? value = null) => VariableDeclaration(
attributes: [],
visibility: null,
isGlobal: false,
isField: true,
isMutable: false,
name: name,
type: type,
value: value);

public static VariableDeclarationSyntax FieldVarDeclaration(
string name,
TypeSyntax? type = null,
ExpressionSyntax? value = null) =>
VariableDeclaration([], null, true, true, name, type, value);
ExpressionSyntax? value = null) => VariableDeclaration(
attributes: [],
visibility: null,
isGlobal: false,
isField: true,
isMutable: true,
name: name,
type: type,
value: value);

public static VariableDeclarationSyntax ValDeclaration(
Visibility? visibility,
string name,
TypeSyntax? type = null,
ExpressionSyntax? value = null) =>
VariableDeclaration([], visibility, false, false, name, type, value);
VariableDeclaration(
attributes: [],
visibility: visibility,
isGlobal: false,
isField: false,
isMutable: false,
name: name,
type: type,
value: value);

public static VariableDeclarationSyntax VarDeclaration(
Visibility? visibility,
string name,
TypeSyntax? type = null,
ExpressionSyntax? value = null) =>
VariableDeclaration([], visibility, false, true, name, type, value);
VariableDeclaration(
attributes: [],
visibility: visibility,
isGlobal: false,
isField: false,
isMutable: true,
name: name,
type: type,
value: value);

public static VariableDeclarationSyntax FieldValDeclaration(
Visibility? visibility,
string name,
TypeSyntax? type = null,
ExpressionSyntax? value = null) =>
VariableDeclaration([], visibility, true, false, name, type, value);
VariableDeclaration(
attributes: [],
visibility: visibility,
isGlobal: false,
isField: true,
isMutable: false,
name: name,
type: type,
value: value);

public static VariableDeclarationSyntax FieldVarDeclaration(
Visibility? visibility,
string name,
TypeSyntax? type = null,
ExpressionSyntax? value = null) =>
VariableDeclaration([], visibility, true, true, name, type, value);
VariableDeclaration(
attributes: [],
visibility: visibility,
isGlobal: false,
isField: true,
isMutable: true,
name: name,
type: type,
value: value);

public static VariableDeclarationSyntax VariableDeclaration(
IEnumerable<AttributeSyntax> attributes,
Visibility? visibility,
bool isGlobal,
bool isField,
bool isMutable,
string name,
TypeSyntax? type = null,
ExpressionSyntax? value = null) => VariableDeclaration(
attributes,
Visibility(visibility),
isGlobal ? TokenKind.KeywordGlobal : null,
isField ? TokenKind.KeywordField : null,
isMutable ? TokenKind.KeywordVar : TokenKind.KeywordVal,
name,
Expand Down
2 changes: 1 addition & 1 deletion src/Draco.Compiler/Api/Syntax/SyntaxFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ _ when IsMissing(node) => false,
ModuleDeclarationSyntax md => !IsMissing(md.CloseBrace),
ImportDeclarationSyntax id => !IsMissing(id.Semicolon),
FunctionDeclarationSyntax fd => IsCompleteEntry(fd.Body),
ParameterSyntax p => IsCompleteEntry(p.Type),
NormalParameterSyntax p => IsCompleteEntry(p.Type),
BlockFunctionBodySyntax bfb => !IsMissing(bfb.CloseBrace),
InlineFunctionBodySyntax ifb => !IsMissing(ifb.Semicolon),
LabelDeclarationSyntax ld => !IsMissing(ld.Colon),
Expand Down
2 changes: 1 addition & 1 deletion src/Draco.Compiler/Api/Syntax/SyntaxHighlighter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ or TokenKind.BracketOpen
private static IEnumerable<HighlightFragment> Identifier(SyntaxToken token, SemanticModel? semanticModel)
{
// Make a guess based on syntax
if (token.Parent is ParameterSyntax param && param.Name.Equals(token))
if (token.Parent is NormalParameterSyntax param && param.Name.Equals(token))
{
return Fragment(token, SyntaxColoring.ParameterName);
}
Expand Down
16 changes: 15 additions & 1 deletion src/Draco.Compiler/Internal/Binding/BinderCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public Binder GetBinder(SyntaxNode syntax)
CompilationUnitSyntax cu => this.BuildCompilationUnitBinder(cu),
ScriptEntrySyntax entry => this.BuildScriptEntryBinder(entry),
ModuleDeclarationSyntax mo => this.BuildModuleBinder(mo),
FunctionDeclarationSyntax decl => this.BuildFunctionDeclarationBinder(decl),
FunctionDeclarationSyntax funcDecl => this.BuildFunctionDeclarationBinder(funcDecl),
ClassDeclarationSyntax classDecl => this.BuildClassDeclarationBinder(classDecl),
FunctionBodySyntax body => this.BuildFunctionBodyBinder(body),
BlockExpressionSyntax block => this.BuildLocalBinder(block),
WhileExpressionSyntax loop => this.BuildLoopBinder(loop),
Expand Down Expand Up @@ -94,6 +95,19 @@ private FunctionBinder BuildFunctionDeclarationBinder(FunctionDeclarationSyntax
return new FunctionBinder(binder, functionSymbol);
}

private ClassBinder BuildClassDeclarationBinder(ClassDeclarationSyntax syntax)
{
Debug.Assert(syntax.Parent is not null);
var binder = this.GetBinder(syntax.Parent);
// Search for the function in the parents container
// For that we unwrap from the injected import layer(s)
var parent = UnwrapFromImportBinder(binder);
var classSymbol = parent.DeclaredSymbols
.OfType<SourceClassSymbol>()
.First(member => member.DeclaringSyntax == syntax); // should we shove that in a helper ?
return new ClassBinder(binder, classSymbol);
Kuinox marked this conversation as resolved.
Show resolved Hide resolved
}

private Binder BuildFunctionBodyBinder(FunctionBodySyntax syntax)
{
Debug.Assert(syntax.Parent is not null);
Expand Down
Loading
Loading