Skip to content

Instantly share code, notes, and snippets.

@michaelsbradleyjr
Last active June 11, 2023 16:22
Show Gist options
  • Save michaelsbradleyjr/91c9283cc7bcfee8736c7e94f88a1c97 to your computer and use it in GitHub Desktop.
Save michaelsbradleyjr/91c9283cc7bcfee8736c7e94f88a1c97 to your computer and use it in GitHub Desktop.
# module a
import std/[macros, typetraits]
type
ModelName = distinct string
Spec*[T] = object
model: ModelName
Machine*[T] = object
data*: T
Void* = object
func `$`*(x: ModelName): string =
x.string
func init*(T: typedesc[Void]): T =
T()
macro spec*(): auto =
result = quote do:
Spec[Void](model: ModelName(Void.name))
macro spec*(T: typedesc): auto =
result = quote do:
Spec[`T`](model: ModelName(`T`.name))
func compile*[T](spec: Spec[T]): Machine[T] =
mixin init
Machine[T](data: T.init)
# module b
# import ./a
type MyData* = object
x: string
func init*(T: typedesc[MyData], x: string): T =
T(x: x)
func init*(T: typedesc[MyData]): T =
T(x: "default")
const spec1a = spec()
let spec1b = spec()
const machine1a = spec1a.compile
let machine1b = spec1b.compile
echo ""
echo spec1a
echo ""
echo spec1b
echo ""
echo machine1a
echo ""
echo machine1b
echo ""
const spec2a = MyData.spec
let spec2b = MyData.spec
const machine2a = spec2a.compile
let machine2b = spec2b.compile
echo spec2a
echo ""
echo spec2b
echo ""
echo machine2a
echo ""
echo machine2b
echo ""
# output
# ----------------------
# (model: Void)
#
# (model: Void)
#
# (data: ())
#
# (data: ())
#
# (model: MyData)
#
# (model: MyData)
#
# (data: (x: "default"))
#
# (data: (x: "default"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment