Last active
October 30, 2025 20:28
-
-
Save planetis-m/ef5baf6ae8fabcfc503d8e5fae271c1e to your computer and use it in GitHub Desktop.
Demonstration examples for nimony
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import std / [syncio, tables, hashes, intsets, assertions] | |
| type | |
| Point = object | |
| x, y: int | |
| Drawable = concept | |
| proc draw(p: Self) | |
| proc draw(p: Point) = | |
| echo "Point(", p.x, ", ", p.y, ")" | |
| proc process[T: Drawable](item: T) = | |
| item.draw() | |
| # Use openArray with converter from array | |
| proc sumCoords(a: openArray[Point]): int = | |
| for p in a: | |
| result += p.x + p.y | |
| # Table usage | |
| var t = initTable[string, int]() | |
| t["alpha"] = 42 | |
| assert t.contains("alpha") | |
| assert (try: t["alpha"] except: -1) == 42 | |
| # IntSet usage | |
| var s = initIntSet() | |
| s.incl 100 | |
| assert s.contains(100) | |
| # Case of string | |
| proc handleCmd(cmd: string) = | |
| case cmd | |
| of "draw": | |
| let p = Point(x: 10, y: 20) | |
| process(p) | |
| of "sum": | |
| let pts = [Point(x: 1, y: 2), Point(x: 3, y: 4)] | |
| echo "Sum: ", sumCoords(pts) | |
| else: | |
| echo "Unknown command" | |
| # Main | |
| handleCmd("draw") | |
| handleCmd("sum") | |
| handleCmd("unknown") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import std/[syncio, hashes, tables] | |
| # Sorting over openArray[int] | |
| proc sort(a: var openArray[int]) = | |
| var n = a.len | |
| while true: | |
| var swapped = false | |
| var i = 0 | |
| while i < n-1: | |
| if a[i] > a[i+1]: | |
| swap a[i], a[i+1] | |
| swapped = true | |
| inc i | |
| dec n | |
| if not swapped: break | |
| # Case on string | |
| proc dispatch(x: string) = | |
| case x | |
| of "foo": echo "foo" | |
| of "bar": echo "bar" | |
| else: echo "unknown" | |
| # Tables | |
| proc demoTable() = | |
| var t = initTable[int, int]() | |
| t[123] = 321 | |
| echo "len = ", t.len | |
| try: | |
| inc t[123] | |
| echo "t[123] = ", t[123] # expected 322 | |
| except: | |
| discard | |
| # Main | |
| var x = [3, 2, 1, 6, 7, 4, 5] | |
| sort x | |
| for i in 0..<x.len: | |
| echo x[i] | |
| dispatch("foo") | |
| dispatch("other") | |
| demoTable() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import std/[syncio] | |
| # Template lowered by the plugin to a literal 256-element array expression. | |
| template buildPopcountLut(): untyped {.plugin: "poplut".} | |
| # Generate the LUT at compile time (plugin produces the bracket literal). | |
| let PopLut: array[256, int] = buildPopcountLut() | |
| proc refPopcnt(x: int): int = | |
| # Reference implementation using bit sampling. | |
| var u = cast[uint64](x) | |
| var c = 0 | |
| for i in 0..<64: | |
| c += int((u shr i) and 1'u64) | |
| c | |
| proc popcntFast(x: int): int = | |
| # Use 8 lookups into PopLut (byte-wise). | |
| var u = cast[uint64](x) | |
| var s = 0 | |
| let mask = 0xFF'u64 | |
| for k in 0..7: | |
| s += PopLut[int((u shr (k * 8)) and mask)] | |
| s | |
| proc main = | |
| echo "LUT size: ", PopLut.len | |
| echo "PopLut[13] = ", PopLut[13] # expected 3 | |
| for n in [0, 1, 2, 3, 13, 255, 256, 1023, 65535, -1]: | |
| let a = popcntFast(n) | |
| let b = refPopcnt(n) | |
| echo n, " -> fast=", a, " ref=", b | |
| main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import std/[math, syncio] | |
| type | |
| # Base of the hierarchy | |
| Shape = ref object of RootObj | |
| Circle = ref object of Shape | |
| r: float | |
| Rect = ref object of Shape | |
| w, h: float | |
| Triangle = ref object of Shape | |
| base, height: float | |
| # Dynamic dispatch entry points | |
| method area(s: Shape): float {.base.} = 0.0 | |
| method describe(s: Shape) = | |
| echo "Shape area=", area(s) | |
| # Overrides | |
| method area(c: Circle): float = PI * c.r * c.r | |
| method describe(c: Circle) = | |
| echo "Circle r=", c.r, " area=", area(c) | |
| method area(r: Rect): float = r.w * r.h | |
| method describe(r: Rect) = | |
| echo "Rect ", r.w, "x", r.h, " area=", area(r) | |
| method area(t: Triangle): float = (t.base * t.height) / 2.0 | |
| method describe(t: Triangle) = | |
| echo "Triangle base=", t.base, " height=", t.height, " area=", area(t) | |
| # Use base-static type to demonstrate dynamic dispatch. | |
| proc show(s: Shape) = | |
| describe s | |
| proc addArea(total: var float; s: Shape) = | |
| total += area(s) | |
| proc main = | |
| # Polymorphic container with mixed dynamic types | |
| var shapes: seq[Shape] = @[ | |
| Circle(r: 3.0).Shape, | |
| Rect(w: 4.0, h: 5.0), | |
| Triangle(base: 10.0, height: 2.0), | |
| Circle(r: 1.5) | |
| ] | |
| var total = 0.0 | |
| var nCircles = 0 | |
| var nRects = 0 | |
| for s in shapes: | |
| s.describe() # dynamic dispatch | |
| total += area(s) # dynamic dispatch | |
| if s of Circle: inc nCircles | |
| elif s of Rect: inc nRects | |
| echo "total area=", total | |
| echo "circles=", nCircles, " rects=", nRects | |
| main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import std/[syncio, rawthreads] | |
| type | |
| Work = object | |
| start: int # 3 or 5 | |
| stop: int # inclusive upper bound | |
| step: int # 4 | |
| counter: int | |
| iterator countup(a, b, step: int): int = | |
| var x = a | |
| while x <= b: | |
| yield x | |
| inc x, step | |
| proc isPrime(n: int): bool = | |
| if n < 2: return false | |
| if n == 2: return true | |
| if (n and 1) == 0: return false | |
| for d in countup(3, n, 2): | |
| if d * d > n: break | |
| if n mod d == 0: return false | |
| true | |
| proc worker(arg: pointer) {.nimcall.} = | |
| let w = cast[ptr Work](arg) | |
| echo "worker tid=", getThreadId() | |
| for n in countup(w.start, w.stop, w.step): | |
| if isPrime(n): | |
| inc w.counter | |
| proc main = | |
| echo "main tid=", getThreadId() | |
| const limit = 20_000_000 | |
| var w0 = Work(start: 3, stop: limit, step: 4, counter: 0) # 3,7,11,... | |
| var w1 = Work(start: 5, stop: limit, step: 4, counter: 0) # 5,9,13,... | |
| var t0, t1: RawThread | |
| try: | |
| create(t0, worker, addr w0) | |
| create(t1, worker, addr w1) | |
| except: | |
| quit("Failed to start threads!") | |
| join t0 | |
| join t1 | |
| let primeCount = 1 + w0.counter + w1.counter # sum the separate counts plus prime 2 | |
| echo "primes in 1..", limit, " = ", primeCount | |
| main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import nimonyplugins | |
| # Compute popcount (Hamming weight) for 0..255 at plugin compile/run time. | |
| proc popc8(i: int): int = | |
| var v = i | |
| var c = 0 | |
| while v != 0: | |
| v = v and (v - 1) # clear lowest set bit | |
| inc c | |
| c | |
| proc tr(n: Node): Tree = | |
| # Transform: buildPopcountLut() ==> [pc0, pc1, ..., pc255] | |
| result = createTree() | |
| let info = n.info | |
| result.withTree BracketX, info: | |
| for i in 0..<256: | |
| result.addIntLit popc8(i), info | |
| var inp = loadTree() | |
| saveTree tr(beginRead inp) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment