Skip to content

Commit

Permalink
[cpp] native inside of class.
Browse files Browse the repository at this point in the history
Close #168
  • Loading branch information
pfusik committed Jul 12, 2024
1 parent 98770e0 commit 9115d96
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 37 deletions.
10 changes: 9 additions & 1 deletion AST.fu
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ public abstract class FuScope : FuSymbol
{
protected Dictionary<string, FuSymbol#>() Dict;
internal FuSymbol!? First = null;
FuSymbol!? Last;
internal FuSymbol!? Last = null;

public int Count() => this.Dict.Count;

Expand Down Expand Up @@ -966,6 +966,14 @@ public class FuNative : FuSymbol
public override int GetLocLength() => 6;
public override bool CompletesNormally() => true;
public override void AcceptStatement(FuVisitor! visitor) { visitor.VisitNative(this); }
public FuMember? GetFollowingMember()
{
for (FuSymbol? symbol = this.Next; symbol != null; symbol = symbol.Next) {
if (symbol is FuMember member)
return member;
}
return null;
}
}

class FuReturn : FuScope
Expand Down
19 changes: 14 additions & 5 deletions GenCpp.fu
Original file line number Diff line number Diff line change
Expand Up @@ -1780,7 +1780,8 @@ public class GenCpp : GenCCpp
{
bool constructor = GetConstructorVisibility(klass) == visibility;
bool destructor = visibility == FuVisibility.Public && (klass.HasSubclasses || klass.AddsVirtualMethods());
if (!constructor && !destructor && !HasMembersOfVisibility(klass, visibility))
bool trailingNative = visibility == FuVisibility.Private && klass.Last is FuNative; // assuming private members are emitted last
if (!constructor && !destructor && !trailingNative && !HasMembersOfVisibility(klass, visibility))
return;

Write(visibilityKeyword);
Expand Down Expand Up @@ -1818,17 +1819,20 @@ public class GenCpp : GenCCpp
}

for (FuSymbol? symbol = klass.First; symbol != null; symbol = symbol.Next) {
if (!(symbol is FuMember member) || member.Visibility != visibility || member.Id == FuId.Main)
continue;
switch (member) {
switch (symbol) {
case FuConst konst:
if (konst.Visibility != visibility)
continue;
WriteDoc(konst.Documentation);
WriteConst(konst);
break;
case FuField field:
WriteField(field);
if (field.Visibility == visibility)
WriteField(field);
break;
case FuMethod method:
if (method.Visibility != visibility || method.Id == FuId.Main)
continue;
WriteMethodDoc(method);
switch (method.CallType) {
case FuCallType.Static:
Expand Down Expand Up @@ -1858,6 +1862,11 @@ public class GenCpp : GenCCpp
}
WriteCharLine(';');
break;
case FuNative nat:
FuMember? followingMember = nat.GetFollowingMember();
if (visibility == (followingMember != null ? followingMember.Visibility : FuVisibility.Private))
VisitNative(nat);
break;
default:
assert false;
}
Expand Down
34 changes: 26 additions & 8 deletions libfut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1977,6 +1977,15 @@ void FuNative::acceptStatement(FuVisitor * visitor) const
visitor->visitNative(this);
}

const FuMember * FuNative::getFollowingMember() const
{
for (const FuSymbol * symbol = this->next; symbol != nullptr; symbol = symbol->next) {
if (const FuMember *member = dynamic_cast<const FuMember *>(symbol))
return member;
}
return nullptr;
}

int FuReturn::getLocLength() const
{
return 6;
Expand Down Expand Up @@ -15221,7 +15230,8 @@ void GenCpp::writeDeclarations(const FuClass * klass, FuVisibility visibility, s
{
bool constructor = getConstructorVisibility(klass) == visibility;
bool destructor = visibility == FuVisibility::public_ && (klass->hasSubclasses || klass->addsVirtualMethods());
if (!constructor && !destructor && !hasMembersOfVisibility(klass, visibility))
bool trailingNative = visibility == FuVisibility::private_ && dynamic_cast<const FuNative *>(klass->last);
if (!constructor && !destructor && !trailingNative && !hasMembersOfVisibility(klass, visibility))
return;
write(visibilityKeyword);
writeCharLine(':');
Expand Down Expand Up @@ -15255,16 +15265,19 @@ void GenCpp::writeDeclarations(const FuClass * klass, FuVisibility visibility, s
writeLine("() = default;");
}
for (const FuSymbol * symbol = klass->first; symbol != nullptr; symbol = symbol->next) {
const FuMember * member;
if (!(member = dynamic_cast<const FuMember *>(symbol)) || member->visibility != visibility || member->id == FuId::main)
continue;
if (const FuConst *konst = dynamic_cast<const FuConst *>(member)) {
if (const FuConst *konst = dynamic_cast<const FuConst *>(symbol)) {
if (konst->visibility != visibility)
continue;
writeDoc(konst->documentation.get());
writeConst(konst);
}
else if (const FuField *field = dynamic_cast<const FuField *>(member))
writeField(field);
else if (const FuMethod *method = dynamic_cast<const FuMethod *>(member)) {
else if (const FuField *field = dynamic_cast<const FuField *>(symbol)) {
if (field->visibility == visibility)
writeField(field);
}
else if (const FuMethod *method = dynamic_cast<const FuMethod *>(symbol)) {
if (method->visibility != visibility || method->id == FuId::main)
continue;
writeMethodDoc(method);
switch (method->callType) {
case FuCallType::static_:
Expand Down Expand Up @@ -15294,6 +15307,11 @@ void GenCpp::writeDeclarations(const FuClass * klass, FuVisibility visibility, s
}
writeCharLine(';');
}
else if (const FuNative *nat = dynamic_cast<const FuNative *>(symbol)) {
const FuMember * followingMember = nat->getFollowingMember();
if (visibility == (followingMember != nullptr ? followingMember->visibility : FuVisibility::private_))
visitNative(nat);
}
else
std::abort();
}
Expand Down
30 changes: 24 additions & 6 deletions libfut.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,7 @@ public abstract class FuScope : FuSymbol

internal FuSymbol First = null;

FuSymbol Last;
internal FuSymbol Last = null;

public int Count() => this.Dict.Count;

Expand Down Expand Up @@ -2484,6 +2484,15 @@ public override void AcceptStatement(FuVisitor visitor)
{
visitor.VisitNative(this);
}

public FuMember GetFollowingMember()
{
for (FuSymbol symbol = this.Next; symbol != null; symbol = symbol.Next) {
if (symbol is FuMember member)
return member;
}
return null;
}
}

class FuReturn : FuScope
Expand Down Expand Up @@ -15571,7 +15580,8 @@ void WriteDeclarations(FuClass klass, FuVisibility visibility, string visibility
{
bool constructor = GetConstructorVisibility(klass) == visibility;
bool destructor = visibility == FuVisibility.Public && (klass.HasSubclasses || klass.AddsVirtualMethods());
if (!constructor && !destructor && !HasMembersOfVisibility(klass, visibility))
bool trailingNative = visibility == FuVisibility.Private && klass.Last is FuNative;
if (!constructor && !destructor && !trailingNative && !HasMembersOfVisibility(klass, visibility))
return;
Write(visibilityKeyword);
WriteCharLine(':');
Expand Down Expand Up @@ -15605,17 +15615,20 @@ void WriteDeclarations(FuClass klass, FuVisibility visibility, string visibility
WriteLine("() = default;");
}
for (FuSymbol symbol = klass.First; symbol != null; symbol = symbol.Next) {
if (!(symbol is FuMember member) || member.Visibility != visibility || member.Id == FuId.Main)
continue;
switch (member) {
switch (symbol) {
case FuConst konst:
if (konst.Visibility != visibility)
continue;
WriteDoc(konst.Documentation);
WriteConst(konst);
break;
case FuField field:
WriteField(field);
if (field.Visibility == visibility)
WriteField(field);
break;
case FuMethod method:
if (method.Visibility != visibility || method.Id == FuId.Main)
continue;
WriteMethodDoc(method);
switch (method.CallType) {
case FuCallType.Static:
Expand Down Expand Up @@ -15645,6 +15658,11 @@ void WriteDeclarations(FuClass klass, FuVisibility visibility, string visibility
}
WriteCharLine(';');
break;
case FuNative nat:
FuMember followingMember = nat.GetFollowingMember();
if (visibility == (followingMember != null ? followingMember.Visibility : FuVisibility.Private))
VisitNative(nat);
break;
default:
throw new NotImplementedException();
}
Expand Down
4 changes: 2 additions & 2 deletions libfut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -734,8 +734,7 @@ class FuScope : public FuSymbol
void addToList(std::shared_ptr<FuSymbol> symbol);
public:
FuSymbol * first = nullptr;
private:
FuSymbol * last;
FuSymbol * last = nullptr;
};

class FuAggregateInitializer : public FuExpr
Expand Down Expand Up @@ -1109,6 +1108,7 @@ class FuNative : public FuSymbol
int getLocLength() const override;
bool completesNormally() const override;
void acceptStatement(FuVisitor * visitor) const override;
const FuMember * getFollowingMember() const;
public:
std::string content;
};
Expand Down
47 changes: 33 additions & 14 deletions libfut.js
Original file line number Diff line number Diff line change
Expand Up @@ -1610,7 +1610,7 @@ export class FuScope extends FuSymbol
{
dict = {};
first = null;
#last;
last = null;

count()
{
Expand Down Expand Up @@ -1638,8 +1638,8 @@ export class FuScope extends FuSymbol
if (this.first == null)
this.first = symbol;
else
this.#last.next = symbol;
this.#last = symbol;
this.last.next = symbol;
this.last = symbol;
}

add(symbol)
Expand Down Expand Up @@ -2541,6 +2541,16 @@ export class FuNative extends FuSymbol
{
visitor.visitNative(this);
}

getFollowingMember()
{
for (let symbol = this.next; symbol != null; symbol = symbol.next) {
let member;
if ((member = symbol) instanceof FuMember)
return member;
}
return null;
}
}

class FuReturn extends FuScope
Expand Down Expand Up @@ -16060,7 +16070,8 @@ export class GenCpp extends GenCCpp
{
let constructor = GenCpp.#getConstructorVisibility(klass) == visibility;
let destructor = visibility == FuVisibility.PUBLIC && (klass.hasSubclasses || klass.addsVirtualMethods());
if (!constructor && !destructor && !GenCpp.#hasMembersOfVisibility(klass, visibility))
let trailingNative = visibility == FuVisibility.PRIVATE && klass.last instanceof FuNative;
if (!constructor && !destructor && !trailingNative && !GenCpp.#hasMembersOfVisibility(klass, visibility))
return;
this.write(visibilityKeyword);
this.writeCharLine(58);
Expand Down Expand Up @@ -16094,20 +16105,22 @@ export class GenCpp extends GenCCpp
this.writeLine("() = default;");
}
for (let symbol = klass.first; symbol != null; symbol = symbol.next) {
let member;
if (!((member = symbol) instanceof FuMember) || member.visibility != visibility || member.id == FuId.MAIN)
continue;
if (member instanceof FuConst) {
const konst = member;
if (symbol instanceof FuConst) {
const konst = symbol;
if (konst.visibility != visibility)
continue;
this.writeDoc(konst.documentation);
this.writeConst(konst);
}
else if (member instanceof FuField) {
const field = member;
this.writeField(field);
else if (symbol instanceof FuField) {
const field = symbol;
if (field.visibility == visibility)
this.writeField(field);
}
else if (member instanceof FuMethod) {
const method = member;
else if (symbol instanceof FuMethod) {
const method = symbol;
if (method.visibility != visibility || method.id == FuId.MAIN)
continue;
this.writeMethodDoc(method);
switch (method.callType) {
case FuCallType.STATIC:
Expand Down Expand Up @@ -16137,6 +16150,12 @@ export class GenCpp extends GenCCpp
}
this.writeCharLine(59);
}
else if (symbol instanceof FuNative) {
const nat = symbol;
let followingMember = nat.getFollowingMember();
if (visibility == (followingMember != null ? followingMember.visibility : FuVisibility.PRIVATE))
this.visitNative(nat);
}
else
throw new Error();
}
Expand Down
12 changes: 11 additions & 1 deletion test/NativeMember.fu
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public class Test
var ok = true
}
#else
//FAIL: cpp TODO
native {
bool ok = true;
}
Expand All @@ -43,6 +42,17 @@ public class Test
native {
result = o.ok;
}
#if CPP
native {
result &= o.trailing;
}
#endif
return result;
}

#if CPP
native {
bool trailing = true;
}
#endif
}

0 comments on commit 9115d96

Please sign in to comment.