Skip to content

Commit

Permalink
nimpretty
Browse files Browse the repository at this point in the history
  • Loading branch information
rotu committed Jul 11, 2022
1 parent 7d5e13c commit 355c6ff
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 63 deletions.
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 16 additions & 3 deletions records.nimble
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
# Package
import os

# Package
version = "0.1.0"
author = "dan"
description = "Dan's magic records library"
license = "MIT"
srcDir = "src"
binDir = "build"
requires "nim >= 1.6.6"

task style, "enforce code style":
var paths: seq[string]
for path in listFiles(thisDir()):
if splitFile(path).ext == ".nimble":
paths.add(path)

# Dependencies
for dir in ["src", "tests"]:
for path in walkDirRec(thisDir()):
if splitFile(path).ext == ".nim":
paths.add(path)

requires "nim >= 1.6.6"
echo ("prettying ", repr(paths))
for path in paths:
exec "nimpretty " & path
30 changes: 15 additions & 15 deletions src/records.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,44 @@ type KeySet = HashSet[string]
# proc union *(s1:KeySet, s2:KeySet):KeySet =
# union(toHashSet(s1), toHashSet(s2)).toSeq

type Record[T:tuple] = object
type Record[T: tuple] = object
data: T

proc toRecord*[T:tuple](x:T): auto =
proc toRecord*[T: tuple](x: T): auto =
let sorted = sortFields(x)
Record[typeof(sorted)](data: sorted)

proc toTuple*[T:tuple](x:Record[T]): T =
proc toTuple*[T: tuple](x: Record[T]): T =
x.data

proc `==`*[T1,T2](t1:Record[T1], t2:Record[T2]): bool =
for x1,x2 in fields(t1.data,t2.data):
proc `==`*[T1, T2](t1: Record[T1], t2: Record[T2]): bool =
for x1, x2 in fields(t1.data, t2.data):
if x1 != x2:
return false
return false
true

proc keyset*[T](): KeySet =
tupleKeys[T]().toHashSet

proc keyset*[T](t:Record[T]): KeySet =
proc keyset*[T](t: Record[T]): KeySet =
keyset[T]()

proc `[]`*[T](r:Record[T], key:static string): auto =
proc `[]`*[T](r: Record[T], key: static string): auto =
get[T](r, key)

proc get *[T](r:Record[T], key:static string): auto =
proc get *[T](r: Record[T], key: static string): auto =
r.data[key]

proc merge *[T1,T2](r1:Record[T1], r2:Record[T2]): auto =
proc merge *[T1, T2](r1: Record[T1], r2: Record[T2]): auto =
toRecord(concat(r1.data, r2.data))

proc `&` *[T1,T2](r1:Record[T1], r2:Record[T2]): auto =
proc `&` *[T1, T2](r1: Record[T1], r2: Record[T2]): auto =
merge(r1, r2)

proc proj*[T](r:Record[T], keys:static KeySet): auto =
proc proj*[T](r: Record[T], keys: static KeySet): auto =
toRecord(toTuple(r).project(keys.toSeq()))

# proc macroSchemaFromTupleTypeImpl(ttype: NimNode):Table[string, NimNode] =
# proc macroSchemaFromTupleTypeImpl(ttype: NimNode):Table[string, NimNode] =
# expectKind(ttype, nnkTupleTy)
# for f in ttype.children:
# expectKind(f, nnkIdentDefs)
Expand Down Expand Up @@ -85,7 +85,7 @@ proc proj*[T](r:Record[T], keys:static KeySet): auto =
# macro dumpType(x: typed): untyped =
# newLit(x.getType.lispRepr)

# macro dumpSameType(x:typed, y:typed):untyped =
# macro dumpSameType(x:typed, y:typed):untyped =
# newLit(sameType(x,y))

# type Foo = object
Expand Down Expand Up @@ -119,4 +119,4 @@ proc proj*[T](r:Record[T], keys:static KeySet): auto =
# echo "----"
# echo dumpTypeImpl(1)
# echo dumpTypeInst(1)
# echo dumpType(1)
# echo dumpType(1)
34 changes: 17 additions & 17 deletions src/records/tupleops.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import std/tables
import std/algorithm
import macros

macro concat*(t1:tuple,t2:tuple): untyped =
macro concat*(t1: tuple, t2: tuple): untyped =
let fields = collect:
for arg in [t1,t2]:
for arg in [t1, t2]:
expectKind(arg.getTypeImpl(), {nnkTupleConstr, nnkTupleTy})
for i, d in pairs(arg.getTypeImpl):
case kind(d):
Expand All @@ -20,33 +20,33 @@ macro concat*(t1:tuple,t2:tuple): untyped =
newTree(nnkDotExpr, arg, prop)
)
else:
error("Unexpected field kind: `" & $kind(d) & "`")
error("Unexpected field kind: `" & $kind(d) & "`")
newEmptyNode()
newTree(nnkTupleConstr, fields)

proc `&` *(t1:tuple, t2:tuple):auto =
proc `&` *(t1: tuple, t2: tuple): auto =
concat(t1, t2)


proc tupleKeys*[T:tuple](): seq[string] =
proc tupleKeys*[T: tuple](): seq[string] =
result = static:
collect:
for c in getTypeImpl(T).children:
expectKind(c, nnkIdentDefs)
c[0].repr

proc tupleKeys*(t:tuple): seq[string] =
tupleKeys[typeof(t)]()

proc getFieldNames*[T:tuple](): seq[string] =
proc tupleKeys*(t: tuple): seq[string] =
tupleKeys[typeof(t)]()

proc getFieldNames*[T: tuple](): seq[string] =
macro getFieldNamesImpl(): seq[string] =
newLit:
collect:
for f in T.getTypeImpl.children:
f[0].repr()
getFieldNamesImpl()

proc proj*[T:tuple](t:T, tags:static[seq[string]]): tuple =
proc proj*[T: tuple](t: T, tags: static[seq[string]]): tuple =
## Rearrange/select named fields from a named tuple,
## returning a new named tuple
macro projImpl(): tuple =
Expand All @@ -58,7 +58,7 @@ proc proj*[T:tuple](t:T, tags:static[seq[string]]): tuple =
))
projImpl()

proc proj*[T:tuple](t:T, ixes:static[seq[Ordinal]]) =
proc proj*[T: tuple](t: T, ixes: static[seq[Ordinal]]) =
## Rearrange/select named fields from a positional tuple,
## returning a new positional tuple
macro projImpl(): tuple =
Expand All @@ -68,25 +68,25 @@ proc proj*[T:tuple](t:T, ixes:static[seq[Ordinal]]) =
projImpl()

# order fields alphabetically
proc sortFields*[T:tuple](arg: T):tuple =
const fields = sorted(getFieldNames[T]())
proc sortFields*[T: tuple](arg: T): tuple =
const fields = sorted(getFieldNames[T]())
proj(arg, fields)

converter reshuffle*[T1:tuple, T2:tuple](x: T1): T2 =
converter reshuffle*[T1: tuple, T2: tuple](x: T1): T2 =
for name, v1, v2 in fieldPairs(x, result):
v2 = v1

macro assignFromImpl(dest: var object|tuple; src: tuple): untyped =
var res = newNimNode(nnkStmtList)
for n in src.getTypeImpl:
expectKind(n,nnkIdentDefs)
res.add(newAssignment(newDotExpr(dest,n[0]), newDotExpr(src,n[0])))
expectKind(n, nnkIdentDefs)
res.add(newAssignment(newDotExpr(dest, n[0]), newDotExpr(src, n[0])))
res

proc `<~` *(dest: var (tuple | object); src: tuple) =
assignFromImpl(dest, src)

proc `=~` *(dest:var(tuple); src:tuple) =
proc `=~` *(dest: var(tuple); src: tuple) =
static:
assert sorted(tupleKeys(dest)) == sorted(tupleKeys(src))
dest <~ src
16 changes: 8 additions & 8 deletions tests/testRecords.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ import sugar
import records

test "canmakerecord":
let mytuple = (x:1, y:2)
let mytuple = (x: 1, y: 2)
var p = (mytuple).toRecord
check p == p
# check callAll(f) == n

test "keyset":
let x = toRecord((a:1,b:2))
let y = toRecord((b:1,a:6))
let x = toRecord((a: 1, b: 2))
let y = toRecord((b: 1, a: 6))
check keyset(x) == keyset(y)

test "union order varies":
let x = (a:1).toRecord
let y = (b:2).toRecord
let z = (c:3).toRecord
let x = (a: 1).toRecord
let y = (b: 2).toRecord
let z = (c: 3).toRecord

check(x.merge(y).merge(z) == z.merge(x).merge(y))
check ( x & y == y & x)
check (x & y == y & x)
40 changes: 20 additions & 20 deletions tests/testTuple.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,50 @@ import std/sequtils
import macros

# test "call":
# proc fn(a:string, b:string, c:string) =
# proc fn(a:string, b:string, c:string) =
# check a=="a"
# check b=="b"
# check c=="c"

# call(fn,("a","b"),(c:"c"))

test "fieldnames":
let x=(a:1,b:2)
let x = (a: 1, b: 2)
type T = typeof(x)
check getFieldNames[typeof(x)]() == @["a", "b"]
check getFieldNames[T]() == @["a", "b"]
check getFieldNames[tuple[b:int,a:string]]() == @["b", "a"]
check getFieldNames[tuple[b: int, a: string]]() == @["b", "a"]

test "sortfields":
let x=(a:1,b:2,c:3)
let x = (a: 1, b: 2, c: 3)
check sortFields(x) == x
check sortFields((x:1,a:2)) == (a:2,x:1)
check sortFields((x: 1, a: 2)) == (a: 2, x: 1)

test "assignfrom":
var dest=(x:1,y:2)
var src=(x:3)
var dest = (x: 1, y: 2)
var src = (x: 3)
dest <~ src

test "tuplecat1":
check concat((),()) == ()
check concat((), ()) == ()

type Person = tuple[nam: string, age: int]
type Person2 = tuple[ssn: string]
let x = (1,2,3)
let y = (4,5,6)
let x = (1, 2, 3)
let y = (4, 5, 6)

check concat(x,y) == (1,2,3,4,5,6)
check concat(x, y) == (1, 2, 3, 4, 5, 6)

var t:Person = ("foo", 3)
let t2:Person2 = ("123453456",)
check concat(t,t2) == (nam:"foo", age: 3, ssn:"123453456")
var t: Person = ("foo", 3)
let t2: Person2 = ("123453456", )
check concat(t, t2) == (nam: "foo", age: 3, ssn: "123453456")
let empty = ()
const otherempty = ()
check concat(empty, otherempty) == ()

let nums1 = (1,"b",3)
let nums1 = (1, "b", 3)
echo "concatting"
check concat(nums1, nums1) == (1,"b",3,1,"b",3)
check concat(nums1, nums1) == (1, "b", 3, 1, "b", 3)


# test "tuplecat":
Expand All @@ -72,10 +72,10 @@ test "tuplecat1":


test "test sort":
let z = (x:1)
let z = (x: 1)
check sortFields(z) == z
let b = (x:1, y:2, w:"w")
check sortFields(b) == (w:"w",x:1,y:2)
let b = (x: 1, y: 2, w: "w")
check sortFields(b) == (w: "w", x: 1, y: 2)
# check tupleKeys(b) == ['x','y','w']
# check tupleKeys(sortFields(b)) == ['w','x','y']

Expand Down

0 comments on commit 355c6ff

Please sign in to comment.