Skip to content

Instantly share code, notes, and snippets.

@planetis-m
Last active October 30, 2025 20:28
Show Gist options
  • Select an option

  • Save planetis-m/ef5baf6ae8fabcfc503d8e5fae271c1e to your computer and use it in GitHub Desktop.

Select an option

Save planetis-m/ef5baf6ae8fabcfc503d8e5fae271c1e to your computer and use it in GitHub Desktop.
Demonstration examples for nimony
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")
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()
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()
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()
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()
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