add 2020 and some cleanup
This commit is contained in:
20
2020/lib/loader.nim
Normal file
20
2020/lib/loader.nim
Normal file
@ -0,0 +1,20 @@
|
||||
import streams, strutils
|
||||
|
||||
|
||||
func getFileName(daynum: int, suffix: string = ""): string =
|
||||
if daynum < 10:
|
||||
result = "0"
|
||||
result = "data/" & result & $daynum & suffix & ".txt"
|
||||
|
||||
|
||||
proc loadStrings*(daynum: int, suffix: string = ""): seq[string] =
|
||||
var s = openFileStream(getFileName(daynum, suffix))
|
||||
for line in s.lines():
|
||||
result.add(line)
|
||||
|
||||
|
||||
proc loadInts*(daynum: int): seq[int] =
|
||||
var s = openFileStream(getFileName(daynum))
|
||||
for line in s.lines():
|
||||
let n = parseInt(line)
|
||||
result.add(n)
|
44
2020/lib/util.nim
Normal file
44
2020/lib/util.nim
Normal file
@ -0,0 +1,44 @@
|
||||
import std/macros
|
||||
|
||||
|
||||
macro `<-`*(lhs: untyped, rhs: untyped): untyped =
|
||||
# ensure that the left-hand side is a valid bracket expression e.g. [a, b, c]
|
||||
let errmsg = "Invalid syntax for unpack operator: " & lhs.toStrLit().strVal()
|
||||
if lhs.kind != nnkBracket:
|
||||
error(errmsg, lhs)
|
||||
for name in lhs:
|
||||
if name.kind != nnkIdent:
|
||||
error(errmsg, lhs)
|
||||
|
||||
# the result will be a check to ensure no index defects, followed by assignment statements
|
||||
result = newNimNode(nnkStmtList, lineInfoFrom = lhs)
|
||||
|
||||
# first add a check to ensure that the container being unpacked has enough values
|
||||
# this has to be done at runtime, since it's potentially unknown at compile time
|
||||
let numIdents = lhs.len
|
||||
let strRepr = lhs.toStrLit().strVal() & " <- " & rhs.toStrLit().strVal()
|
||||
let lenCheck = quote do:
|
||||
if `rhs`.len < `numIdents`:
|
||||
raise newException(ValueError, "Not enough values to unpack: \"" & `strRepr` & "\"")
|
||||
result.add(lenCheck)
|
||||
|
||||
var assign_from = rhs
|
||||
# if the right-hand side is an expression, it might
|
||||
# be expensive, so we save it to a temp variable
|
||||
if rhs.kind != nnkIdent:
|
||||
# repoint assign_src so that we end up using a temp variable
|
||||
# instead of repeating the original expression a bunch of times
|
||||
assign_from = ident("unpack_tmp_src")
|
||||
# e.g. "let unpack_tmp_src = somestring.split()"
|
||||
let declare_assign_src = newLetStmt(assign_from, rhs)
|
||||
result.add(declare_assign_src)
|
||||
|
||||
# finally, inject the actual assignments
|
||||
for i, name in lhs:
|
||||
let assignment = quote do:
|
||||
# expanded to e.g. "let a = someseq[0]"
|
||||
let `name` = `assign_from`[`i`]
|
||||
result.add(assignment)
|
||||
|
||||
|
||||
proc showAddr*[T](x: T) = echo cast[uint64](unsafeAddr x)
|
Reference in New Issue
Block a user