Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuinox committed Sep 28, 2024
1 parent 242d9b8 commit 991e13d
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/Draco.Compiler.Tests/EndToEnd/CodeExecutionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Draco.Compiler.Tests.TestUtilities;

namespace Draco.Compiler.Tests.EndToEnd;

[Collection(nameof(NoParallelizationCollectionDefinition))]
public class CodeExecutionTests
{
[Fact]
public void ClassHelloWorld()
{
var assembly = CompileToAssembly("""
import System.Console;

func main() {
WriteLine("Hello, World!");
}

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

var stringWriter = new StringWriter();
_ = Invoke<object?>(assembly: assembly, stdout: stringWriter);

Assert.Equal($"Hello, World!{Environment.NewLine}", stringWriter.ToString(), ignoreLineEndingDifferences: true);
}
}
4 changes: 4 additions & 0 deletions src/Draco.Compiler/Internal/Binding/BinderCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ internal sealed class BinderCache(Compilation compilation)
/// <returns>The binder for <paramref name="syntax"/>.</returns>
public Binder GetBinder(SyntaxNode syntax)
{
if(syntax is ClassDeclarationSyntax )
{

}
var scopeDefiningAncestor = BinderFacts.GetScopeDefiningAncestor(syntax);
Debug.Assert(scopeDefiningAncestor is not null);

Expand Down
89 changes: 89 additions & 0 deletions src/Draco.Compiler/Internal/Codegen/MetadataCodegen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public static void Generate(
private readonly Dictionary<Symbol, MemberReferenceHandle> intrinsicReferenceHandles = [];
private readonly AssemblyReferenceHandle systemRuntimeReference;
private readonly TypeReferenceHandle systemObjectReference;
private readonly TypeReferenceHandle systemValueTypeReference;

private MetadataCodegen(Compilation compilation, IAssembly assembly, CodegenFlags flags)
{
Expand All @@ -120,6 +121,11 @@ private MetadataCodegen(Compilation compilation, IAssembly assembly, CodegenFlag
assembly: this.systemRuntimeReference,
@namespace: "System",
name: "Object");

this.systemValueTypeReference = this.GetOrAddTypeReference(
assembly: this.systemRuntimeReference,
@namespace: "System",
name: "ValueType");
}

private void WriteModuleAndAssemblyDefinition()
Expand Down Expand Up @@ -648,6 +654,89 @@ private BlobHandle EncodeAttributeSignature(AttributeInstance attribute)
});
}

private TypeDefinitionHandle EncodeClass(
IType type,
TypeDefinitionHandle? parent,
ref int fieldIndex,
ref int procIndex
)
{
var startFieldIndex = fieldIndex;
var startProcIndex = procIndex;

var visibility = (type.Symbol.Visibility, parent) switch
{
(Api.Semantics.Visibility.Public, not null) => TypeAttributes.NestedPublic,
(Api.Semantics.Visibility.Public, null) => TypeAttributes.Public,
(_, not null) => TypeAttributes.NestedAssembly,
(_, null) => TypeAttributes.NotPublic,
};

var attributes = visibility | TypeAttributes.Class | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit | TypeAttributes.Sealed;

if (type.Symbol.IsValueType) attributes |= TypeAttributes.SequentialLayout; // AutoLayout = 0.

var createdClass = this.AddTypeDefinition(
attributes,
null,
type.Name,
type.Symbol.IsValueType ? this.systemValueTypeReference : this.systemObjectReference,
fieldList: MetadataTokens.FieldDefinitionHandle(startFieldIndex),
methodList: MetadataTokens.MethodDefinitionHandle(startProcIndex)
);

// Procedures
foreach (var proc in type.Methods.Values)
{
var handle = this.EncodeProcedure(proc);
++procIndex;

// Todo: properties
}

// Fields
foreach (var field in type.Fields)
{
this.EncodeField(field.Key);
++fieldIndex;
}

// If this is a valuetype without fields, we add .pack 0 and .size 1
if (type.Symbol.IsValueType && type.Fields.Count == 0)
{
this.MetadataBuilder.AddTypeLayout(
type: createdClass,
packingSize: 0,
size: 1);
}

// If this isn't top level module, we specify nested relationship
if (parent is not null) this.MetadataBuilder.AddNestedType(createdClass, parent.Value);

return createdClass;
}

private FieldDefinitionHandle EncodeField(FieldSymbol field)
{
var visibility = field.Visibility switch
{
Api.Semantics.Visibility.Public => FieldAttributes.Public,
Api.Semantics.Visibility.Internal => FieldAttributes.Assembly,
Api.Semantics.Visibility.Private => FieldAttributes.Private,
_ => throw new IndexOutOfRangeException(nameof(field.Visibility)),
};
var mutability = field.IsMutable ? default : FieldAttributes.InitOnly;

// Definition
return this.AddFieldDefinition(
attributes: visibility | mutability,
name: field.Name,
signature: this.EncodeFieldSignature(field));
}

private BlobHandle EncodeFieldSignature(FieldSymbol field) =>
this.EncodeBlob(e => this.EncodeSignatureType(e.Field().Type(), field.Type));

private IEnumerable<TypeSymbol> ScalarConstantTypes => [
this.WellKnownTypes.SystemSByte,
this.WellKnownTypes.SystemInt16,
Expand Down
5 changes: 5 additions & 0 deletions src/Draco.Compiler/Internal/OptimizingIr/Model/IType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ namespace Draco.Compiler.Internal.OptimizingIr.Model;

internal interface IType
{
/// <summary>
/// The symbol of this type.
/// </summary>
public TypeSymbol Symbol { get; }

/// <summary>
/// The name of this type.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions src/Draco.Compiler/Internal/Syntax/Lexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ Unit TakeWithText(TokenKind tokenKind, int length)
{
"and" => TokenKind.KeywordAnd,
"class" => TokenKind.KeywordClass,
"global" => TokenKind.KeywordGlobal,
"else" => TokenKind.KeywordElse,
"false" => TokenKind.KeywordFalse,
"for" => TokenKind.KeywordFor,
Expand Down

0 comments on commit 991e13d

Please sign in to comment.