Merge branch 'master' of github.com:Araq/Nimrod

This commit is contained in:
Araq 2012-09-15 00:21:29 +02:00
commit 04e4aa328b
2 changed files with 43 additions and 75 deletions

View file

@ -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( template print(name, value: expr): stmt =
op[0], op[1], op[2], when compiles(string($value)):
op.lineinfo, checkpoint(name & " was " & $value)
op.toStrLit,
op[1].toStrLit,
op[2].toStrLit,
op[1].kind notin nnkLiterals,
op[2].kind notin nnkLiterals))
result = rewriteBinaryOp(conditions[1]) proc inspectArgs(exp: PNimrodNode) =
for i in 1 .. <exp.len:
if exp[i].kind notin nnkLiterals:
inc counter
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
of nnkCall, nnkCommand: case checked.kind
proc rewriteCall(op: PNimrodNode): PNimrodNode = of nnkCallKinds:
template rewrite(call, lineInfoLit: expr, expLit: string, template rewrite(call, lineInfoLit: expr, callLit: string,
argAssgs, argPrintOuts: stmt): stmt = argAssgs, argPrintOuts: stmt): stmt =
block: block:
argAssgs argAssgs
if not call: if not call:
checkpoint(lineInfoLit & ": Check failed: " & expLit) checkpoint(lineInfoLit & ": Check failed: " & callLit)
argPrintOuts argPrintOuts
fail()
template asgn(a, value: expr): stmt =
let a = value
template print(name, value: expr): stmt =
checkpoint(name & " was " & $value)
var
argsAsgns = newNimNode(nnkStmtList)
argsPrintOuts = newNimNode(nnkStmtList)
opStr = op.toStrLit
for i in 1 .. <op.len:
if op[i].kind notin nnkLiterals:
# TODO: print only types that are printable
var arg = newIdentNode(":param" & ($i))
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()
let e = conditions[1] var checkedStr = checked.toStrLit
result = getAst(rewrite(e, e.lineinfo, e.toStrLit)) inspectArgs(checked)
result = getAst(rewrite(checked, checked.lineinfo, checkedStr, argsAsgns, argsPrintOuts))
of nnkStmtList:
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:

View file

@ -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))