Merge branch 'master' of github.com:Araq/Nimrod
This commit is contained in:
commit
04e4aa328b
2 changed files with 43 additions and 75 deletions
|
|
@ -93,88 +93,58 @@ template fail* =
|
||||||
checkpoints = @[]
|
checkpoints = @[]
|
||||||
|
|
||||||
macro check*(conditions: stmt): stmt {.immediate.} =
|
macro check*(conditions: stmt): stmt {.immediate.} =
|
||||||
let conditions = callsite()
|
let checked = callsite()[1]
|
||||||
|
|
||||||
case conditions.kind
|
var
|
||||||
of nnkCall, nnkCommand, nnkMacroStmt:
|
argsAsgns = newNimNode(nnkStmtList)
|
||||||
case conditions[1].kind
|
argsPrintOuts = newNimNode(nnkStmtList)
|
||||||
of nnkInfix:
|
counter = 0
|
||||||
proc rewriteBinaryOp(op: PNimrodNode): PNimrodNode =
|
|
||||||
template rewrite(op, left, right, lineInfoLit: expr, opLit,
|
|
||||||
leftLit, rightLit: string, printLhs, printRhs: bool): stmt =
|
|
||||||
block:
|
|
||||||
var
|
|
||||||
lhs = left
|
|
||||||
rhs = right
|
|
||||||
|
|
||||||
if not `op`(lhs, rhs):
|
template asgn(a, value: expr): stmt =
|
||||||
checkpoint(lineInfoLit & ": Check failed: " & opLit)
|
let a = value
|
||||||
when printLhs: checkpoint(" " & leftLit & " was " & $lhs)
|
|
||||||
when printRhs: checkpoint(" " & rightLit & " was " & $rhs)
|
|
||||||
fail()
|
|
||||||
|
|
||||||
result = getAst(rewrite(
|
|
||||||
op[0], op[1], op[2],
|
|
||||||
op.lineinfo,
|
|
||||||
op.toStrLit,
|
|
||||||
op[1].toStrLit,
|
|
||||||
op[2].toStrLit,
|
|
||||||
op[1].kind notin nnkLiterals,
|
|
||||||
op[2].kind notin nnkLiterals))
|
|
||||||
|
|
||||||
result = rewriteBinaryOp(conditions[1])
|
|
||||||
|
|
||||||
of nnkCall, nnkCommand:
|
template print(name, value: expr): stmt =
|
||||||
proc rewriteCall(op: PNimrodNode): PNimrodNode =
|
when compiles(string($value)):
|
||||||
template rewrite(call, lineInfoLit: expr, expLit: string,
|
checkpoint(name & " was " & $value)
|
||||||
argAssgs, argPrintOuts: stmt): stmt =
|
|
||||||
block:
|
|
||||||
argAssgs
|
|
||||||
if not call:
|
|
||||||
checkpoint(lineInfoLit & ": Check failed: " & expLit)
|
|
||||||
argPrintOuts
|
|
||||||
fail()
|
|
||||||
|
|
||||||
template asgn(a, value: expr): stmt =
|
proc inspectArgs(exp: PNimrodNode) =
|
||||||
let a = value
|
for i in 1 .. <exp.len:
|
||||||
|
if exp[i].kind notin nnkLiterals:
|
||||||
template print(name, value: expr): stmt =
|
inc counter
|
||||||
checkpoint(name & " was " & $value)
|
var arg = newIdentNode(":p" & ($counter))
|
||||||
|
var argStr = exp[i].toStrLit
|
||||||
|
if exp[i].kind in nnkCallKinds: inspectArgs(exp[i])
|
||||||
|
argsAsgns.add getAst(asgn(arg, exp[i]))
|
||||||
|
argsPrintOuts.add getAst(print(argStr, arg))
|
||||||
|
exp[i] = arg
|
||||||
|
|
||||||
var
|
case checked.kind
|
||||||
argsAsgns = newNimNode(nnkStmtList)
|
of nnkCallKinds:
|
||||||
argsPrintOuts = newNimNode(nnkStmtList)
|
template rewrite(call, lineInfoLit: expr, callLit: string,
|
||||||
opStr = op.toStrLit
|
argAssgs, argPrintOuts: stmt): stmt =
|
||||||
|
block:
|
||||||
for i in 1 .. <op.len:
|
argAssgs
|
||||||
if op[i].kind notin nnkLiterals:
|
if not call:
|
||||||
# TODO: print only types that are printable
|
checkpoint(lineInfoLit & ": Check failed: " & callLit)
|
||||||
var arg = newIdentNode(":param" & ($i))
|
argPrintOuts
|
||||||
argsAsgns.add getAst(asgn(arg, op[i]))
|
|
||||||
argsPrintOuts.add getAst(print(op[i].toStrLit, arg))
|
|
||||||
op[i] = arg
|
|
||||||
|
|
||||||
result = getAst(rewrite(op, op.lineinfo, opStr, argsAsgns, argsPrintOuts))
|
|
||||||
|
|
||||||
result = rewriteCall(conditions[1])
|
|
||||||
|
|
||||||
of nnkStmtList:
|
|
||||||
result = newNimNode(nnkStmtList)
|
|
||||||
for i in countup(0, conditions[1].len - 1):
|
|
||||||
result.add(newCall(!"check", conditions[1][i]))
|
|
||||||
|
|
||||||
else:
|
|
||||||
template rewrite(Exp, lineInfoLit: expr, expLit: string): stmt =
|
|
||||||
if not Exp:
|
|
||||||
checkpoint(lineInfoLit & ": Check failed: " & expLit)
|
|
||||||
fail()
|
fail()
|
||||||
|
|
||||||
|
var checkedStr = checked.toStrLit
|
||||||
|
inspectArgs(checked)
|
||||||
|
result = getAst(rewrite(checked, checked.lineinfo, checkedStr, argsAsgns, argsPrintOuts))
|
||||||
|
|
||||||
let e = conditions[1]
|
of nnkStmtList:
|
||||||
result = getAst(rewrite(e, e.lineinfo, e.toStrLit))
|
result = newNimNode(nnkStmtList)
|
||||||
|
for i in countup(0, checked.len - 1):
|
||||||
|
result.add(newCall(!"check", checked[i]))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
var ast = conditions.treeRepr
|
template rewrite(Exp, lineInfoLit: expr, expLit: string): stmt =
|
||||||
error conditions.lineinfo & ": Malformed check statement:\n" & ast
|
if not Exp:
|
||||||
|
checkpoint(lineInfoLit & ": Check failed: " & expLit)
|
||||||
|
fail()
|
||||||
|
|
||||||
|
result = getAst(rewrite(checked, checked.lineinfo, checked.toStrLit))
|
||||||
|
|
||||||
template require*(conditions: stmt): stmt {.immediate, dirty.} =
|
template require*(conditions: stmt): stmt {.immediate, dirty.} =
|
||||||
block:
|
block:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
var s = @[]
|
|
||||||
|
|
||||||
proc `*` *(a, b: seq[int]): seq[int] =
|
proc `*` *(a, b: seq[int]): seq[int] =
|
||||||
# allocate a new sequence:
|
# allocate a new sequence:
|
||||||
newSeq(result, len(a))
|
newSeq(result, len(a))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue