Skip to content

Commit 895ca9f

Browse files
committed
[collection] Change PriorityQueue to separate element and priority.
Like .NET, unlike C++/Java/Python.
1 parent 1b2288d commit 895ca9f

File tree

11 files changed

+648
-319
lines changed

11 files changed

+648
-319
lines changed

AST.fu

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public enum FuId
6767
TypeParam0,
6868
TypeParam0NotFinal,
6969
TypeParam0Predicate,
70+
TypeParam1,
7071
SByteRange,
7172
ByteRange,
7273
ShortRange,
@@ -1561,6 +1562,7 @@ public class FuSystem : FuScope
15611562
internal FuType# VoidType = new FuType { Id = FuId.VoidType, Name = "void" };
15621563
internal FuType# NullType = new FuType { Id = FuId.NullType, Name = "null", Nullable = true };
15631564
FuType# TypeParam0 = new FuType { Id = FuId.TypeParam0, Name = "T" };
1565+
FuType# TypeParam1 = new FuType { Id = FuId.TypeParam1, Name = "T" };
15641566
internal FuIntegerType# IntType = new FuIntegerType { Id = FuId.IntType, Name = "int" };
15651567
FuRangeType# UIntType = FuRangeType.New(0, int.MaxValue);
15661568
internal FuIntegerType# NIntType = new FuIntegerType { Id = FuId.NIntType, Name = "nint" };
@@ -1762,9 +1764,9 @@ public class FuSystem : FuScope
17621764
stackClass.AddMethod(TypeParam0, FuId.StackPeek, "Peek", false);
17631765
stackClass.AddMethod(VoidType, FuId.StackPush, "Push", true, FuVar.New(TypeParam0, "value"));
17641766
stackClass.AddMethod(TypeParam0, FuId.StackPop, "Pop", true);
1765-
FuClass! priorityQueueClass = AddCollection(FuId.PriorityQueueClass, "PriorityQueue", 1, FuId.PriorityQueueClear, FuId.PriorityQueueCount);
1767+
FuClass! priorityQueueClass = AddCollection(FuId.PriorityQueueClass, "PriorityQueue", 2, FuId.PriorityQueueClear, FuId.PriorityQueueCount);
17661768
priorityQueueClass.AddMethod(TypeParam0, FuId.PriorityQueueDequeue, "Dequeue", true);
1767-
priorityQueueClass.AddMethod(VoidType, FuId.PriorityQueueEnqueue, "Enqueue", true, FuVar.New(TypeParam0, "value"));
1769+
priorityQueueClass.AddMethod(VoidType, FuId.PriorityQueueEnqueue, "Enqueue", true, FuVar.New(TypeParam0, "element"), FuVar.New(TypeParam1, "priority"));
17681770
priorityQueueClass.AddMethod(TypeParam0, FuId.PriorityQueuePeek, "Peek", false);
17691771
AddSet(FuId.HashSetClass, "HashSet", FuId.HashSetAdd, FuId.HashSetClear, FuId.HashSetContains, FuId.HashSetCount, FuId.HashSetRemove);
17701772
AddSet(FuId.SortedSetClass, "SortedSet", FuId.SortedSetAdd, FuId.SortedSetClear, FuId.SortedSetContains, FuId.SortedSetCount, FuId.SortedSetRemove);

GenCpp.fu

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
public class GenCpp : GenCCpp
2222
{
23+
bool HasPriorityQueue;
2324
bool UsingStringViewLiterals;
2425
bool HasEnumFlags;
2526
bool NumberTryParse;
@@ -233,13 +234,12 @@ public class GenCpp : GenCCpp
233234
cppType = "stack";
234235
break;
235236
case FuId.PriorityQueueClass:
237+
this.HasPriorityQueue = true;
236238
Include("queue");
237-
Write("std::priority_queue<");
238-
WriteType(elementType, false);
239-
Write(", std::vector<");
240-
WriteType(elementType, false);
241-
Write(">, std::greater<");
239+
Write("std::priority_queue<FuPriorityQueueEntry<");
242240
WriteType(elementType, false);
241+
Write(", ");
242+
WriteType(klass.TypeArg1, false);
243243
Write(">>");
244244
return;
245245
case FuId.HashSetClass:
@@ -548,7 +548,7 @@ public class GenCpp : GenCCpp
548548
obj.Accept(this, priority);
549549
}
550550

551-
void WritePop!(FuExpr obj, FuPriority parent, int p, string front)
551+
void WritePop!(FuExpr obj, FuPriority parent, int p, string front, string frontSuffix = "")
552552
{
553553
if (parent == FuPriority.Statement) {
554554
StartMethodCall(obj);
@@ -569,6 +569,7 @@ public class GenCpp : GenCCpp
569569
WriteChar(p);
570570
WriteChar('.');
571571
Write(front);
572+
Write(frontSuffix);
572573
Write("(); ");
573574
WriteChar(p);
574575
Write(".pop(); return ");
@@ -1013,15 +1014,13 @@ public class GenCpp : GenCCpp
10131014
WritePop(obj, parent, 'q', "front");
10141015
break;
10151016
case FuId.QueueEnqueue:
1016-
case FuId.PriorityQueueEnqueue:
10171017
WriteMethodCall(obj, "push", args[0]);
10181018
break;
10191019
case FuId.QueuePeek:
10201020
StartMethodCall(obj);
10211021
Write("front()");
10221022
break;
10231023
case FuId.StackPeek:
1024-
case FuId.PriorityQueuePeek:
10251024
StartMethodCall(obj);
10261025
Write("top()");
10271026
break;
@@ -1032,7 +1031,14 @@ public class GenCpp : GenCCpp
10321031
WriteCollectionMethod(obj, "push", args);
10331032
break;
10341033
case FuId.PriorityQueueDequeue:
1035-
WritePop(obj, parent, 'q', "top");
1034+
WritePop(obj, parent, 'q', "top", "().get");
1035+
break;
1036+
case FuId.PriorityQueueEnqueue:
1037+
WriteMethodCall(obj, "emplace", args[0], args[1]);
1038+
break;
1039+
case FuId.PriorityQueuePeek:
1040+
StartMethodCall(obj);
1041+
Write("top().get()");
10361042
break;
10371043
case FuId.HashSetAdd:
10381044
case FuId.SortedSetAdd:
@@ -2042,6 +2048,7 @@ public class GenCpp : GenCCpp
20422048
{
20432049
this.WrittenClasses.Clear();
20442050
this.InHeaderFile = true;
2051+
this.HasPriorityQueue = false;
20452052
this.UsingStringViewLiterals = false;
20462053
this.HasEnumFlags = false;
20472054
this.NumberTryParse = false;
@@ -2179,7 +2186,21 @@ public class GenCpp : GenCCpp
21792186
}
21802187
WriteNewLine();
21812188
WriteLine("#endif");
2182-
2189+
}
2190+
if (this.HasPriorityQueue) {
2191+
WriteLine("template <class TElement, class TPriority>");
2192+
WriteLine("class FuPriorityQueueEntry");
2193+
OpenBlock();
2194+
WriteLine("TPriority priority;");
2195+
WriteLine("TElement element;");
2196+
this.Indent--;
2197+
WriteLine("public:");
2198+
this.Indent++;
2199+
WriteLine("FuPriorityQueueEntry(const TElement &element, const TPriority &priority) : priority(priority), element(element) {}");
2200+
WriteLine("const TElement &get() const { return element; }");
2201+
WriteLine("bool operator<(const FuPriorityQueueEntry &that) const { return that.priority < priority; }");
2202+
this.Indent--;
2203+
WriteLine("};");
21832204
}
21842205
CloseStringWriter();
21852206
CloseFile();

GenCs.fu

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,13 +251,6 @@ public class GenCs : GenTyped
251251
WriteElementType(klass.GetElementType());
252252
break;
253253
case FuId.PriorityQueueClass:
254-
Include("System.Collections.Generic");
255-
Write("PriorityQueue<");
256-
WriteType(klass.GetElementType(), false);
257-
Write(", ");
258-
WriteType(klass.GetElementType(), false);
259-
WriteChar('>');
260-
break;
261254
case FuId.DictionaryClass:
262255
case FuId.SortedDictionaryClass:
263256
Include("System.Collections.Generic");
@@ -584,9 +577,6 @@ public class GenCs : GenTyped
584577
WriteCoercedArgs(method, args);
585578
Write(", null)");
586579
break;
587-
case FuId.PriorityQueueEnqueue:
588-
WriteMethodCall(obj, "Enqueue", args[0], args[0]); // FIXME: side effect
589-
break;
590580
case FuId.DictionaryAdd:
591581
WritePostfix(obj, ".Add(");
592582
args[0].Accept(this, FuPriority.Argument);

GenJava.fu

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class GenJava : GenTyped
2222
{
2323
string OutputFile;
2424
string Namespace;
25+
bool HasPriorityQueue;
2526

2627
protected override string GetTargetName() => "Java";
2728

@@ -315,7 +316,13 @@ public class GenJava : GenTyped
315316
WriteCollectionType("Stack", klass.GetElementType());
316317
break;
317318
case FuId.PriorityQueueClass:
318-
WriteCollectionType("PriorityQueue", klass.GetElementType());
319+
this.HasPriorityQueue = true;
320+
Include("java.util.PriorityQueue");
321+
Write("PriorityQueue<FuPriorityQueueEntry<");
322+
WriteJavaType(klass.TypeArg0, false, true);
323+
Write(", ");
324+
WriteJavaType(klass.TypeArg1, false, true);
325+
Write(">>");
319326
break;
320327
case FuId.HashSetClass:
321328
WriteCollectionType("HashSet", klass.GetElementType());
@@ -792,17 +799,27 @@ public class GenJava : GenTyped
792799
Write(").sort(null)");
793800
break;
794801
case FuId.QueueDequeue:
795-
case FuId.PriorityQueueDequeue:
796802
WritePostfix(obj, ".remove()");
797803
break;
798804
case FuId.QueueEnqueue:
799-
case FuId.PriorityQueueEnqueue:
800805
WriteMethodCall(obj, "add", args[0]);
801806
break;
802807
case FuId.QueuePeek:
803-
case FuId.PriorityQueuePeek:
804808
WritePostfix(obj, ".element()");
805809
break;
810+
case FuId.PriorityQueueDequeue:
811+
WritePostfix(obj, ".remove().get()");
812+
break;
813+
case FuId.PriorityQueueEnqueue:
814+
WritePostfix(obj, ".add(new FuPriorityQueueEntry(");
815+
args[0].Accept(this, FuPriority.Argument);
816+
Write(", ");
817+
args[1].Accept(this, FuPriority.Argument);
818+
Write("))");
819+
break;
820+
case FuId.PriorityQueuePeek:
821+
WritePostfix(obj, ".element().get()");
822+
break;
806823
case FuId.DictionaryAdd:
807824
WritePostfix(obj, ".put(");
808825
args[0].Accept(this, FuPriority.Argument);
@@ -1475,14 +1492,41 @@ public class GenJava : GenTyped
14751492
CloseFile();
14761493
}
14771494

1495+
void WritePriorityQueue!()
1496+
{
1497+
CreateJavaFile("FuPriorityQueueEntry");
1498+
WriteLine("class FuPriorityQueueEntry<TElement, TPriority extends Comparable<TPriority>>");
1499+
WriteLine("\timplements Comparable<FuPriorityQueueEntry<TElement, TPriority>>");
1500+
OpenBlock();
1501+
WriteLine("private final TElement element;");
1502+
WriteLine("private final TPriority priority;");
1503+
WriteNewLine();
1504+
WriteLine("public FuPriorityQueueEntry(TElement element, TPriority priority)");
1505+
OpenBlock();
1506+
WriteLine("this.element = element;");
1507+
WriteLine("this.priority = priority;");
1508+
CloseBlock();
1509+
WriteNewLine();
1510+
WriteLine("public TElement get()");
1511+
OpenBlock();
1512+
WriteLine("return element;");
1513+
CloseBlock();
1514+
WriteNewLine();
1515+
WriteLine("public int compareTo(FuPriorityQueueEntry<TElement, TPriority> o)");
1516+
OpenBlock();
1517+
WriteLine("return priority.compareTo(o.priority);");
1518+
CloseBlock();
1519+
CloseBlock();
1520+
CloseFile();
1521+
}
1522+
14781523
void WriteResources!()
14791524
{
14801525
CreateJavaFile("FuResource");
14811526
WriteLine("import java.io.DataInputStream;");
14821527
WriteLine("import java.io.IOException;");
14831528
WriteNewLine();
1484-
Write("class FuResource");
1485-
WriteNewLine();
1529+
WriteLine("class FuResource");
14861530
OpenBlock();
14871531
WriteLine("static byte[] getByteArray(String name, int length)");
14881532
OpenBlock();
@@ -1514,7 +1558,10 @@ public class GenJava : GenTyped
15141558
{
15151559
this.OutputFile = outputFile;
15161560
this.Namespace = namespace;
1561+
this.HasPriorityQueue = false;
15171562
WriteTypes(program);
1563+
if (this.HasPriorityQueue)
1564+
WritePriorityQueue();
15181565
if (program.Resources.Count > 0)
15191566
WriteResources();
15201567
}

GenPy.fu

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,11 @@ public class GenPy : GenPySwift
317317
WriteCollectionTypeAnnotation("collections.deque", klass);
318318
break;
319319
case FuId.PriorityQueueClass:
320-
WriteCollectionTypeAnnotation("list", klass);
320+
Write("list[tuple[");
321+
WriteTypeAnnotation(klass.TypeArg1);
322+
Write(", ");
323+
WriteTypeAnnotation(klass.TypeArg0);
324+
Write("]]");
321325
break;
322326
case FuId.HashSetClass:
323327
case FuId.SortedSetClass:
@@ -973,19 +977,29 @@ public class GenPy : GenPySwift
973977
WriteListAppend(obj, args);
974978
break;
975979
case FuId.QueuePeek:
976-
case FuId.PriorityQueuePeek:
977980
WritePostfix(obj, "[0]");
978981
break;
979982
case FuId.PriorityQueueClear:
980983
WritePostfix(obj, ".clear()");
981984
break;
982-
case FuId.PriorityQueueEnqueue:
985+
case FuId.PriorityQueueDequeue:
983986
Include("heapq");
984-
WriteCall("heapq.heappush", obj, args[0]);
987+
Write("heapq.heappop(");
988+
obj.Accept(this, FuPriority.Argument);
989+
Write(")[1]");
985990
break;
986-
case FuId.PriorityQueueDequeue:
991+
case FuId.PriorityQueueEnqueue:
987992
Include("heapq");
988-
WriteCall("heapq.heappop", obj);
993+
Write("heapq.heappush(");
994+
obj.Accept(this, FuPriority.Argument);
995+
Write(", (");
996+
args[1].Accept(this, FuPriority.Argument);
997+
Write(", ");
998+
args[0].Accept(this, FuPriority.Argument);
999+
Write("))");
1000+
break;
1001+
case FuId.PriorityQueuePeek:
1002+
WritePostfix(obj, "[0][1]");
9891003
break;
9901004
case FuId.DictionaryAdd:
9911005
WriteDictionaryAdd(obj, args);

Sema.fu

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,10 +1271,16 @@ public class FuSema
12711271

12721272
FuType# EvalType(FuClassType generic, FuType# type)
12731273
{
1274-
if (type.Id == FuId.TypeParam0)
1274+
switch (type.Id) {
1275+
case FuId.TypeParam0:
12751276
return generic.TypeArg0;
1276-
if (type.Id == FuId.TypeParam0NotFinal)
1277+
case FuId.TypeParam0NotFinal:
12771278
return generic.TypeArg0.IsFinal() ? null : generic.TypeArg0;
1279+
case FuId.TypeParam1:
1280+
return generic.TypeArg1;
1281+
default:
1282+
break;
1283+
}
12781284
if (type is FuClassType collection && collection.Class.TypeParameterCount == 1 && collection.TypeArg0.Id == FuId.TypeParam0) {
12791285
FuClassType# result = type is FuReadWriteClassType ? new FuReadWriteClassType() : new FuClassType();
12801286
result.Class = collection.Class;

0 commit comments

Comments
 (0)