Last active
December 30, 2022 13:25
-
-
Save flaviut/b59ccbb3a1a71e79c686 to your computer and use it in GitHub Desktop.
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 macros | |
proc procToLambda(input: PNimrodNode): PNimrodNode {.compiletime.} = | |
# Ident !"foo" | |
# Empty | |
# Empty | |
# FormalParams | |
# Ident retType | |
# IdentDefs | |
# ... | |
# Pragma | |
# ... | |
# Empty | |
# StmtList | |
# ... | |
expectKind(input, nnkProcDef) | |
expectLen(input, 7) | |
result = newNimNode(nnkLambda) | |
result.add(newEmptyNode()) # name | |
result.add(newEmptyNode()) | |
result.add(newEmptyNode()) | |
result.add(input[3]) # params | |
result.add(newEmptyNode()) # pragmas | |
result.add(newEmptyNode()) | |
result.add(input[6]) # body | |
proc callchainToProc(input, templat: PNimrodNode): PNimrodNode {.compiletime.} = | |
expectKind(templat, nnkProcDef) | |
var params: seq[PNimrodNode] = @[] | |
# FormalParams | |
# Ident retTypeName | |
# (IdentDefs | |
# (Ident paramName)* | |
# Ident typeName | |
# Empty)* | |
for i in 1.. <len(templat[3]): | |
let nextDefs = templat[3][i] | |
expectKind(nextDefs, nnkIdentDefs) | |
for pi in 0..(len(nextDefs)-3): | |
params.add(nextDefs[pi]) | |
let resultCall = newCall(input, params) | |
result = copyNimTree(templat) | |
result[6] = quote do: | |
return `resultCall` | |
macro decorate*(vals: openarray[expr], input: stmt): stmt = | |
result = procToLambda(input) | |
for i in 0.. <len(vals): # Wrap the proc in each of the decorators | |
result = newCall(vals[i], result) | |
result = callchainToProc(result, input) |
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 decorators | |
proc timesTwo(input: proc(parm1: string): int): proc(p: string): int = | |
return proc (p: string): int = | |
return input(p) * 2 | |
proc plusTwo(input: proc(parm1: string): int): proc(p: string): int = | |
return proc (p: string): int = | |
return input(p) + 2 | |
proc foo(parm1: string): int {.decorate: [timesTwo, plusTwo].} = | |
return 2 | |
echo foo("") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment