Skip to content

Commit

Permalink
touch up, operator version, method calls work
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Jul 14, 2023
1 parent d2393d0 commit 26fd815
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 41 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,39 @@ jobs:

- name: run tests
run: nimble tests

docs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: jiro4989/setup-nim-action@v1

- name: install nimbleutils
run: nimble install -y https://github.com/metagn/nimbleutils@#HEAD

- name: install dependencies
run: nimble install -y

- name: compile docs
run: nimble docs

- name: move to subfolder
run: |
mkdir pages
mv docs pages/
cd pages
git init
git add -A
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git commit -m 'deploy'
- name: push to branch
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: gh-pages
force: true
directory: ./pages/
if: github.event_name != 'pull_request'
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,56 @@ proc foo(a, b, c: int) =
echo "b: ", b
echo "c: ", c
# regular call:
foo.spread:
1
c = 3
b = 2
spread foo(1): # limitation: can't call with dot syntax for calls
# operator version:
...foo:
1
c = 3
b = 2
# operator allows inline version with `do`:
let a = 1 + (...min do:
2
3)
assert a == 3
# method call syntax:
spread 1.foo:
c = 3
b = 2
spread 1.foo(2):
c = 3
# arrays:
const arr = [].spread:
1
2
3
assert arr == [1, 2, 3]
# table constructors:
let tab = {:}.spread:
"a" = 1 # constructors convert = in a statement to :
_("b": 2, "c": 3) # all arguments of _ are spread directly
assert tab == {"a": 1, "b": 2, "c": 3}
# object or tuple constructors need a single `_: _``:
type Foo = object
a, b, c: int
# to spread object or tuple constructors without any arguments, include a single _: _
let obj = spread Foo(_: _):
a = 1
c = 3
b = 2
assert obj = Foo(a: 1, b: 2, c: 3)
assert obj == Foo(a: 1, b: 2, c: 3)
```
4 changes: 2 additions & 2 deletions spread.nimble
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Package

version = "0.1.0"
version = "0.2.0"
author = "metagn"
description = "macro for spreading blocks into call parameters/collections"
license = "MIT"
Expand All @@ -25,7 +25,7 @@ task docs, "build docs for all modules":
task tests, "run tests for multiple backends and defines":
when declared(runTests):
runTests(
backends = {c, #[js]#},
backends = {c, js, nims},
)
else:
echo "tests task not implemented, need nimbleutils"
62 changes: 62 additions & 0 deletions src/spread.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,53 @@
import macros

macro spread*(call: untyped, args: varargs[untyped]): untyped =
## macro for providing call arguments or collection literal elements with
## block syntax
runnableExamples:
proc foo(a, b, c: int) =
echo "a: ", a
echo "b: ", b
echo "c: ", c

# regular call:
foo.spread:
1
c = 3
b = 2

# method call syntax:
spread 1.foo:
c = 3
b = 2

spread 1.foo(2):
c = 3

# arrays:
const arr = [].spread:
1
2
3

assert arr == [1, 2, 3]

# table constructors:
let tab = {:}.spread:
"a" = 1 # constructors convert = in a statement to :
_("b": 2, "c": 3) # all arguments of _ are spread directly

assert tab == {"a": 1, "b": 2, "c": 3}

# object or tuple constructors need a single `_: _``:
type Foo = object
a, b, c: int

let obj = spread Foo(_: _):
a = 1
c = 3
b = 2

assert obj == Foo(a: 1, b: 2, c: 3)
let colonKinds = {nnkBracket, nnkPar, nnkCurly,
nnkTupleConstr, nnkTableConstr, nnkObjConstr}
result =
Expand All @@ -24,3 +71,18 @@ macro spread*(call: untyped, args: varargs[untyped]): untyped =
result.add(arg[1..^1])
else:
result.add(arg)

template `...`*(call: untyped, args: varargs[untyped]): untyped =
## operator version of `spread`
runnableExamples:
...foo:
1
c = 3
b = 2

# allows inline version with `do`:
let a = 1 + (...min do:
2
3)
assert a == 3
spread(call, args)
36 changes: 0 additions & 36 deletions tests/test1.nim

This file was deleted.

59 changes: 59 additions & 0 deletions tests/test_spread.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import spread

block:
proc foo(a, b, c: int): string = $(a, b, c)

block:
# regular call:
let x = foo.spread:
a = 1
c = 3
b = 2
doAssert x == "(1, 2, 3)"

# method call syntax:
let y = spread 1.foo:
c = 3
b = 2
let z = spread 1.foo(2):
c = 3
doAssert x == y and y == z

block:
# operator version:
let a = ...foo:
1
c = 3
b = 2
doAssert a == "(1, 2, 3)"

# operator allows inline version with `do`:
let b = 1 + (...min do:
2
3)
doAssert b == 3

block:
# array constructor:
const arr = [].spread:
1
2
3
doAssert arr == [1, 2, 3]

# table constructor
let tab = spread {:}:
"a" = 1 # constructors convert = in a statement to :
_("b": 2, "c": 3) # all arguments of _ are spread directly
doAssert tab == {"a": 1, "b": 2, "c": 3}

block:
# object or tuple constructors
type Foo = object
a, b, c: int
let obj = spread Foo(_: _):
a = 1
c = 3
b = 2
doAssert obj == Foo(a: 1, b: 2, c: 3)

0 comments on commit 26fd815

Please sign in to comment.