Closed ghost closed 7 months ago
It looks like delphi sets are just wrappers for 256-bit bitmasks, so they shouldn't be too bad to port. Something like this would probably work:
struct DelphiSet (mask 4 ulong) {
func insert(value ubyte) {
memory *ubyte = &this.mask as *ubyte
memory[value / 8] |= 1 << (value % 8)
}
func remove(value ubyte) {
memory *ubyte = &this.mask as *ubyte
memory[value / 8] &= ~(1 << (value % 8))
}
func contains(value ubyte) bool {
memory *ubyte = &this.mask as *ubyte
return (memory[value / 8] & (1 << (value % 8))) != 0
}
func insert(value $T~__flat_enum__) {
this.insert(value as ubyte)
}
func remove(value $T~__flat_enum__) {
this.remove(value as ubyte)
}
func contains(value $T~__flat_enum__) bool {
return this.contains(value as ubyte)
}
}
import basics
enum Fruit (APPLE, BANANA, ORANGE)
func main {
set DelphiSet
printf("[!] Adding 13\n")
set.insert(13ub)
printf("[!] Adding Fruit::APPLE\n")
set.insert(Fruit::APPLE)
printf(" set.contains(Fruit::APPLE) = %b\n", set.contains(Fruit::APPLE))
printf(" set.contains(Fruit::BANANA) = %b\n", set.contains(Fruit::BANANA))
printf(" set.contains(13ub) = %b\n", set.contains(13ub))
printf("[!] Removing Fruit::APPLE\n")
set.remove(Fruit::APPLE)
printf(" set.contains(Fruit::APPLE) = %b\n", set.contains(Fruit::APPLE))
printf(" set.contains(Fruit::BANANA) = %b\n", set.contains(Fruit::BANANA))
printf(" set.contains(13ub) = %b\n", set.contains(13ub))
printf("[!] Adding Fruit::BANANA\n")
set.insert(Fruit::BANANA)
printf(" set.contains(Fruit::APPLE) = %b\n", set.contains(Fruit::APPLE))
printf(" set.contains(Fruit::BANANA) = %b\n", set.contains(Fruit::BANANA))
printf(" set.contains(13ub) = %b\n", set.contains(13ub))
printf("[!] Removing 13ub\n")
set.remove(13ub)
printf(" set.contains(Fruit::APPLE) = %b\n", set.contains(Fruit::APPLE))
printf(" set.contains(Fruit::BANANA) = %b\n", set.contains(Fruit::BANANA))
printf(" set.contains(13ub) = %b\n", set.contains(13ub))
}
And if you need easy construction without declaring a variable, one way to do it would be like:
func empty() DelphiSet {
set DelphiSet
return set
}
import basics
func main {
doSomething(empty() ~> DelphiSet)
}
func doSomething(set DelphiSet) {
another_set DelphiSet = empty() ~> DelphiSet
}
The ~>
operator can be used to request a specific return type which is how this style can work
It's to help porting of Delphi code.