Skip to content

Commit

Permalink
Derive INew methods while parsing classes to allow calling them from …
Browse files Browse the repository at this point in the history
…inside of methods
  • Loading branch information
CloakerSmoker committed May 21, 2024
1 parent ef702d1 commit 049153b
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 49 deletions.
Binary file modified build/freebsd_compiler.elf
Binary file not shown.
Binary file modified build/linux_compiler.elf
Binary file not shown.
Binary file modified build/windows_compiler.exe
Binary file not shown.
99 changes: 50 additions & 49 deletions src/compiler/Parser.rlx
Original file line number Diff line number Diff line change
Expand Up @@ -1451,7 +1451,7 @@ struct ParserState {
declare Type ParseBitsAsType()
declare void ParseBitsFields(TypeInfo*, i16, i16)

define i16 ParseNestedStruct(TypeInfo* ForType, i8 IsUnaligned, i16 NextFieldOffset) {
define i16 ParseNestedStruct(TypeInfo* ForType, i8 IsUnaligned, i16 NextFieldOffset, void(void*, TypeInfo*, FunctionDefine*) OnMethod) {
HashMap* Fields := ForType~>Fields
HashMap* Methods := ForType~>Methods
HashMap* StaticMethods := ForType~>StaticMethods
Expand Down Expand Up @@ -1496,7 +1496,11 @@ struct ParserState {
MethodContainer := StaticMethods
}

this->ParseFunctionDefinition(MethodContainer, MethodKeyword, ThisType, !IsStaticMethod)
FunctionDefine* Method := this->ParseFunctionDefinition(MethodContainer, MethodKeyword, ThisType, !IsStaticMethod)

if (OnMethod != null) {
OnMethod(this, ForType, Method)
}

; Ignore commas after methods, they aren't actually needed for parsing
this->NextTokenMatches(TOKEN_TYPE_PUNCTUATION, PUNCTUATION_COMMA)
Expand All @@ -1515,7 +1519,7 @@ struct ParserState {

if (InUnion && this->NextTokenMatches(TOKEN_TYPE_KEYWORD, KEYWORD_STRUCT)) {
this->Consume(TOKEN_TYPE_PUNCTUATION, PUNCTUATION_OPEN_BRACE, "Expected '{' to open nested struct")
i16 FieldSize := this->ParseNestedStruct(ForType, IsUnaligned, NextFieldOffset) - TotalSize
i16 FieldSize := this->ParseNestedStruct(ForType, IsUnaligned, NextFieldOffset, OnMethod) - TotalSize
}
else if (this->NextTokenMatches(TOKEN_TYPE_KEYWORD, KEYWORD_BITS)) {
Type BackingType := this->ParseBitsAsType()
Expand Down Expand Up @@ -1612,16 +1616,20 @@ struct ParserState {
return TotalSize
}

define void ParseStructFields(TypeInfo* ForType, i8 IsUnaligned) {
define void ParseStructFields(TypeInfo* ForType, i8 IsUnaligned, void(void*, TypeInfo*, FunctionDefine*) OnMethod) {
PointerArray* FieldsInOrder := PointerArray:New()
ForType->FieldsInOrder := FieldsInOrder

this->CurrentNamespace->DefineEntry("self", ForType)
i16 TotalSize := this->ParseNestedStruct(ForType, IsUnaligned, ForType->Size)
i16 TotalSize := this->ParseNestedStruct(ForType, IsUnaligned, ForType->Size, OnMethod)
this->CurrentNamespace->DeleteEntry("self")

ForType->Size := TotalSize
}

define void ParseStructFields(TypeInfo* ForType, i8 IsUnaligned) {
this->ParseStructFields(ForType, IsUnaligned, null)
}

define void ParseStructDefinition() {
TypeInfo* NewType := this->ParseCustomTypeName(TYPE_KIND_STRUCTURE)
Expand Down Expand Up @@ -2199,6 +2207,42 @@ struct ParserState {
this->AddClassInterface(ContainerType, InterfaceName~>Context, InterfaceType, IsDerived)
}

define void OnClassMethodDefined(TypeInfo* ForType, FunctionDefine* Current) {
ClassInfo* Info := ForType->ClassInfo
InterfaceImplementationInfo* INewImplementation := Info->Interfaces->GetPointer(this->INewType)

if (INewImplementation) {
if (Current->IsMethod = FUNCTION_IS_METHOD) {
Current->CallCount := 2

i32 ParameterCount := Current->ParameterCount - 1
Type* ParameterTypes := Alloc(ParameterCount * #Type)

for (i32 Index := 0, Index < ParameterCount, Index++) {
VariableInfo* OriginalParameter := Current->Parameters[Index + 1]

ParameterTypes[Index] := OriginalParameter->Type
}

FunctionDefine* DerivedWrapper := this->MakeDerivedMethod(Current~>Context, "New", ForType->AsPointer(1), ParameterCount, ParameterTypes)

DerivedWrapper->IsMethod := FUNCTION_IS_DERIVED_METHOD
DerivedWrapper->MethodOfTypeName := ForType->Name

DerivedWrapper->DerivedImplementationInfo := INewImplementation
DerivedWrapper->WrappedNewMethod := Current

HashMapElement* Last := ForType~>StaticMethods->Get("New")

if (Last) {
DerivedWrapper->Next := Last->Value
}

ForType~>StaticMethods->Set("New", DerivedWrapper)
}
}
}

define void ParseClass() {
TypeInfo* NewType := this->ParseCustomTypeName(TYPE_KIND_STRUCTURE)

Expand Down Expand Up @@ -2255,7 +2299,7 @@ struct ParserState {
}
}

this->ParseStructFields(NewType, false)
this->ParseStructFields(NewType, false, &self.OnClassMethodDefined)

HashMap* Methods := NewType~>Methods
i32 Count := Info->InterfacesInOrder->Count()
Expand Down Expand Up @@ -2331,49 +2375,6 @@ struct ParserState {
ImplementationMethod->CallCount := 2
}
}

InterfaceImplementationInfo* INewImplementation := Info->Interfaces->GetPointer(this->INewType)

if (INewImplementation) {
HashMapElement* Element := NewType~>Methods->Get("New")

if (Element) {
FunctionDefine* Current := Element->Value

while (Current) {
if (Current->IsMethod = FUNCTION_IS_METHOD) {
Current->CallCount := 2

i32 ParameterCount := Current->ParameterCount - 1
Type* ParameterTypes := Alloc(ParameterCount * #Type)

for (i32 Index := 0, Index < ParameterCount, Index++) {
VariableInfo* OriginalParameter := Current->Parameters[Index + 1]

ParameterTypes[Index] := OriginalParameter->Type
}

FunctionDefine* DerivedWrapper := this->MakeDerivedMethod(Current~>Context, "New", NewType->AsPointer(1), ParameterCount, ParameterTypes)

DerivedWrapper->IsMethod := FUNCTION_IS_DERIVED_METHOD
DerivedWrapper->MethodOfTypeName := NewType->Name

DerivedWrapper->DerivedImplementationInfo := INewImplementation
DerivedWrapper->WrappedNewMethod := Current

HashMapElement* Last := NewType~>StaticMethods->Get("New")

if (Last) {
DerivedWrapper->Next := Last->Value
}

NewType~>StaticMethods->Set("New", DerivedWrapper)
}

Current := Current->Next
}
}
}

NewType->IsIncomplete := false
}
Expand Down

0 comments on commit 049153b

Please sign in to comment.