Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
kekyo committed Apr 30, 2024
1 parent 1501f4b commit 3b4e673
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 38 deletions.
81 changes: 53 additions & 28 deletions chibild/chibild.core/Generating/CodeGenerator_Emit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ private void AddFundamentalAttributes(
TargetFramework? targetFramework,
bool? disableJITOptimization)
{
// TODO: Use context instead of delayed looking up.
var context = new LookupContext(
this.targetModule,
null,
Expand Down Expand Up @@ -164,11 +165,10 @@ private void AddFundamentalAttributes(
}

private void AssignEntryPoint(
ModuleDefinition targetModule,
string entryPointSymbol)
{
// Priority search for a module type.
var startup = targetModule.Types.
var startup = this.targetModule.Types.
First(t => t.FullName == "<Module>").
Methods.
FirstOrDefault(m =>
Expand All @@ -178,7 +178,7 @@ private void AssignEntryPoint(
// Entire search when not found.
if (startup == null)
{
startup = targetModule.Types.
startup = this.targetModule.Types.
Where(type => type.IsClass).
SelectMany(type => type.Methods).
FirstOrDefault(m =>
Expand All @@ -189,7 +189,7 @@ private void AssignEntryPoint(
// Inject startup code when declared.
if (startup != null)
{
targetModule.EntryPoint = startup;
this.targetModule.EntryPoint = startup;
this.logger.Information($"Found entry point.");
}
else
Expand Down Expand Up @@ -277,8 +277,10 @@ MethodBody GetInitializerBody(TypeDefinition type)
return cctor.Body;
}

this.fileScopedInitializerBody = new(() => GetInitializerBody(this.fileScopedType.Value));
this.dataInitializerBody = new(() => GetInitializerBody(this.dataType.Value));
this.fileScopedInitializerBody = new(() =>
GetInitializerBody(this.fileScopedType.Value));
this.dataInitializerBody = new(() =>
GetInitializerBody(this.dataType.Value));
}

public TypeDefinition GetFileScopedType() =>
Expand All @@ -301,45 +303,60 @@ public Mono.Collections.Generic.Collection<Instruction> GetDataInitializerBody()
}

private void EmitMembers(
ObjectInputFragment fragment,
ModuleDefinition targetModule)
ObjectInputFragment fragment)
{
var holder = new TypeDefinitionHolder(fragment, targetModule);
var holder = new TypeDefinitionHolder(
fragment,
this.targetModule);

///////////////////////////////////////////////////

foreach (var enumeration in fragment.GetDeclaredEnumerations(true))
{
holder.GetFileScopedType().NestedTypes.Add(enumeration);
holder.GetFileScopedType().
NestedTypes.
Add(enumeration);
}

foreach (var structure in fragment.GetDeclaredStructures(true))
{
holder.GetFileScopedType().NestedTypes.Add(structure);
holder.GetFileScopedType().
NestedTypes.
Add(structure);
}

foreach (var function in fragment.GetDeclaredFunctions(true))
{
holder.GetFileScopedType().Methods.Add(function);
holder.GetFileScopedType().
Methods.
Add(function);
}

foreach (var variable in fragment.GetDeclaredVariables(true))
{
holder.GetFileScopedType().Fields.Add(variable);
holder.GetFileScopedType().
Fields.
Add(variable);
}

foreach (var constant in fragment.GetDeclaredConstants(true))
{
holder.GetFileScopedType().Fields.Add(constant);
holder.GetFileScopedType().
Fields.
Add(constant);
}

foreach (var initializer in fragment.GetDeclaredInitializer(true).Reverse())
{
holder.GetFileScopedType().Methods.Insert(0, initializer);
holder.GetFileScopedType().
Methods.
Insert(0, initializer);

// Insert type initializer caller.
var instructions = holder.GetFileScopedInitializerBody();
instructions.Insert(0, Instruction.Create(OpCodes.Call, initializer));
instructions.Insert(
0,
Instruction.Create(OpCodes.Call, initializer));
}

///////////////////////////////////////////////////
Expand All @@ -356,26 +373,36 @@ private void EmitMembers(

foreach (var function in fragment.GetDeclaredFunctions(false))
{
holder.GetTextType().Methods.Add(function);
holder.GetTextType().
Methods.
Add(function);
}

foreach (var variable in fragment.GetDeclaredVariables(false))
{
holder.GetDataType().Fields.Add(variable);
holder.GetDataType().
Fields.
Add(variable);
}

foreach (var constant in fragment.GetDeclaredConstants(false))
{
holder.GetRDataType().Fields.Add(constant);
holder.GetRDataType().
Fields.
Add(constant);
}

foreach (var initializer in fragment.GetDeclaredInitializer(false).Reverse())
{
holder.GetDataType().Methods.Insert(0, initializer);
holder.GetDataType().
Methods.
Insert(0, initializer);

// Insert type initializer caller.
var instructions = holder.GetDataInitializerBody();
instructions.Insert(0, Instruction.Create(OpCodes.Call, initializer));
instructions.Insert(
0,
Instruction.Create(OpCodes.Call, initializer));
}

///////////////////////////////////////////////////
Expand All @@ -385,7 +412,9 @@ private void EmitMembers(

foreach (var function in fragment.GetDeclaredModuleFunctions())
{
moduleType.Methods.Add(function);
moduleType.
Methods.
Add(function);
}
}

Expand Down Expand Up @@ -430,9 +459,7 @@ public bool Emit(
foreach (var fragment in inputFragments.
OfType<ObjectInputFragment>())
{
this.EmitMembers(
fragment,
this.targetModule);
this.EmitMembers(fragment);
}

// Apply all delayed looking up (types).
Expand Down Expand Up @@ -480,9 +507,7 @@ public bool Emit(
// Assign entry point when set producing executable.
if (entryPointSymbol != null)
{
this.AssignEntryPoint(
this.targetModule,
entryPointSymbol);
this.AssignEntryPoint(entryPointSymbol);
}

// (Completed all CIL implementations in this place.)
Expand Down
11 changes: 4 additions & 7 deletions chibild/chibild.core/Generating/TypeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,14 @@
//
/////////////////////////////////////////////////////////////////////////////////////

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using chibicc.toolchain.Parsing;
using chibicc.toolchain.Tokenizing;
using Mono.Cecil;
using Mono.Cecil.Rocks;
using ParameterAttributes = Mono.Cecil.ParameterAttributes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace chibild.Generating;

Expand Down
3 changes: 1 addition & 2 deletions toolchain.common/Parsing/CilParser_VariableDirective.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
//
/////////////////////////////////////////////////////////////////////////////////////

using chibicc.toolchain.Internal;
using chibicc.toolchain.Tokenizing;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using chibicc.toolchain.Internal;

namespace chibicc.toolchain.Parsing;

Expand Down
2 changes: 1 addition & 1 deletion toolchain.common/Parsing/TypeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public static bool TryParse(Token token, out TypeNode typeNode)
}

var ((returnNode, name), lastParameters) = nodeStack.Pop();
if (parameters.LastOrDefault() is (_, "...", _))
if (parameters.LastOrDefault() is (TypeIdentityNode("...", _), _, _))
{
currentNode = new FunctionSignatureNode(
returnNode,
Expand Down

0 comments on commit 3b4e673

Please sign in to comment.