# # # The Nim Compiler # (c) Copyright 2015 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # ## This module implements the 'implies' relation for guards. import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer, idents, saturate, modulegraphs, options, lineinfos, int128 const someEq = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc, mEqStr, mEqSet, mEqCString} # set excluded here as the semantics are vastly different: someLe = {mLeI, mLeF64, mLeU, mLeEnum, mLeCh, mLeB, mLePtr, mLeStr} someLt = {mLtI, mLtF64, mLtU, mLtEnum, mLtCh, mLtB, mLtPtr, mLtStr} someLen = {mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq} someIn = {mInSet} someHigh = {mHigh} # we don't list unsigned here because wrap around semantics suck for # proving anything: someAdd = {mAddI, mAddF64, mSucc} someSub = {mSubI, mSubF64, mPred} someMul = {mMulI, mMulF64} someDiv = {mDivI, mDivF64} someMod = {mModI} someMax = {mMaxI} someMin = {mMinI} someBinaryOp = someAdd+someSub+someMul+someMax+someMin proc isValue(n: PNode): bool = n.kind in {nkCharLit..nkNilLit} proc isLocation(n: PNode): bool = not n.isValue proc isLet(n: PNode): bool = if n.kind == nkSym: if n.sym.kind in {skLet, skTemp, skForVar}: result = true elif n.sym.kind == skParam and skipTypes(n.sym.typ, abstractInst).kind != tyVar: result = true proc isVar(n: PNode): bool = n.kind == nkSym and n.sym.kind in {skResult, skVar} and {sfAddrTaken} * n.sym.flags == {} proc isLetLocation(m: PNode, isApprox: bool): bool = # consider: 'n[].kind' --> we really need to support 1 deref op even if this # is technically wrong due to aliasing :-( We could introduce "soft" facts # for this; this would still be very useful for warnings and also nicely # solves the 'var' problems. For now we fix this by requiring much more # restrictive expressions for the 'not nil' checking. var n = m var derefs = 0 while true: case n.kind of nkDotExpr, nkCheckedFieldExpr, nkObjUpConv, nkObjDownConv: n = n[0] of nkDerefExpr, nkHiddenDeref: n = n[0] inc derefs of nkBracketExpr: if isConstExpr(n[1]) or isLet(n[1]) or isConstExpr(n[1].skipConv): n = n[0] else: return of nkHiddenStdConv, nkHiddenSubConv, nkConv: n = n[1] else: break result = n.isLet and derefs <= ord(isApprox) if not result and isApprox: result = isVar(n) proc interestingCaseExpr*(m: PNode): bool = isLetLocation(m, true) type Operators* = object opNot, opContains, opLe, opLt, opAnd, opOr, opIsNil, opEq: PSym opAdd, opSub, opMul, opDiv, opLen: PSym proc initOperators*(g: ModuleGraph): Operators = result.opLe = createMagic(g, "<=", mLeI) result.opLt = createMagic(g, "<", mLtI) result.opAnd = createMagic(g, "and", mAnd) result.opOr = createMagic(g, "or", mOr) result.opIsNil = createMagic(g, "isnil", mIsNil) result.opEq = createMagic(g, "==", mEqI) result.opAdd = createMagic(g, "+", mAddI) result.opSub = createMagic(g, "-", mSubI) result.opMul = createMagic(g, "*", mMulI) result.opDiv = createMagic(g, "div", mDivI) result.opLen = createMagic(g, "len", mLengthSeq) result.opNot = createMagic(g, "not", mNot) result.opContains = createMagic(g, "contains", mInSet) proc swapArgs(fact: PNode, newOp: PSym): PNode = result = newNodeI(nkCall, fact.info, 3) result[0] = newSymNode(newOp) result[1] = fact[2] result[2] = fact[1] proc neg(n: PNode; o: Operators): PNode = if n == nil: return nil case n.getMagic of mNot: result = n[1] of someLt: # not (a < b) == a >= b == b <= a result = swapArgs(n, o.opLe) of someLe: result = swapArgs(n, o.opLt) of mInSet: if n[1].kind != nkCurly: return nil let t = n[2].typ.skipTypes(abstractInst) result = newNodeI(nkCall, n.info, 3) result[0] = n[0] result[2] = n[2] if t.kind == tyEnum: var s = newNodeIT(nkCurly, n.info, n[1].typ) for e in t.n: let eAsNode = newIntNode(nkIntLit, e.sym.position) if not inSet(n[1], eAsNode): s.add eAsNode result[1] = s #elif t.kind notin {tyString, tySequence} and lengthOrd(t) < 1000: # result[1] = complement(n[1]) else: # not ({2, 3, 4}.contains(x)) x != 2 and x != 3 and x != 4 # XXX todo result = nil of mOr: # not (a or b) --> not a and not b let a = n[1].neg(o) b = n[2].neg(o) if a != nil and b != nil: result = newNodeI(nkCall, n.info, 3) result[0] = newSymNode(o.opAnd) result[1] = a result[2] = b elif a != nil: result = a elif b != nil: result = b else: # leave not (a == 4) as it is result = newNodeI(nkCall, n.info, 2) result[0] = newSymNode(o.opNot) result[1] = n proc buildCall(op: PSym; a: PNode): PNode = result = newNodeI(nkCall, a.info, 2) result[0] = newSymNode(op) result[1] = a proc buildCall(op: PSym; a, b: PNode): PNode = result = newNodeI(nkInfix, a.info, 3) result[0] = newSymNode(op) result[1] = a result[2] = b proc `|+|`(a, b: PNode): PNode = result = copyNode(a) if a.kind in {nkCharLit..nkUInt64Lit}: result.intVal = a.intVal |+| b.intVal else: result.floatVal = a.floatVal + b.floatVal proc `|-|`(a, b: PNode): PNode = result = copyNode(a) if a.kind in {nkCharLit..nkUInt64Lit}: result.intVal = a.intVal |-| b.intVal else: result.floatVal = a.floatVal - b.floatVal proc `|*|`(a, b: PNode): PNode = result = copyNode(a) if a.kind in {nkCharLit..nkUInt64Lit}: result.intVal = a.intVal |*| b.intVal else: result.floatVal = a.floatVal * b.floatVal proc `|div|`(a, b: PNode): PNode = result = copyNode(a) if a.kind in {nkCharLit..nkUInt64Lit}: result.intVal = a.intVal div b.intVal else: result.floatVal = a.floatVal / b.floatVal proc negate(a, b, res: PNode; o: Operators): PNode = if b.kind in {nkCharLit..nkUInt64Lit} and b.intVal != low(BiggestInt): var b = copyNode(b) b.intVal = -b.intVal if a.kind in {nkCharLit..nkUInt64Lit}: b.intVal = b.intVal |+| a.intVal result = b else: result = buildCall(o.opAdd, a, b) elif b.kind in {nkFloatLit..nkFloat64Lit}: var b = copyNode(b) b.floatVal = -b.floatVal result = buildCall(o.opAdd, a, b) else: result = res proc zero(): PNode = nkIntLit.newIntNode(0) proc one(): PNode = nkIntLit.newIntNode(1) proc minusOne(): PNode = nkIntLit.newIntNode(-1) proc lowBound*(conf: ConfigRef; x: PNode): PNode = result = nkIntLit.newIntNode(firstOrd(conf, x.typ)) result.info = x.info proc highBound*(conf: ConfigRef; x: PNode; o: Operators): PNode = let typ = x.typ.skipTypes(abstractInst) result = if typ.kind == tyArray: nkIntLit.newIntNode(lastOrd(conf, typ)) elif typ.kind == tySequence and x.kind == nkSym and x.sym.kind == skConst: nkIntLit.newIntNode(x.sym.ast.len-1) else: o.opAdd.buildCall(o.opLen.buildCall(x), minusOne()) result.info = x.info proc reassociation(n: PNode; o: Operators): PNode = result = n # (foo+5)+5 --> foo+10; same for '*' case result.getMagic of someAdd: if result[2].isValue and result[1].getMagic in someAdd and result[1][2].isValue: result = o.opAdd.buildCall(result[1][1], result[1][2] |+| result[2]) if result[2].intVal == 0: result = result[1] of someMul: if result[2].isValue and result[1].getMagic in someMul and result[1][2].isValue: result = o.opMul.buildCall(result[1][1], result[1][2] |*| result[2]) if result[2].intVal == 1: result = result[1] elif result[2].intVal == 0: result = zero() else: discard proc pred(n: PNode): PNode = if n.kind in {nkCharLit..nkUInt64Lit} and n.intVal != low(BiggestInt): result = copyNode(n) dec result.intVal else: result = n proc buildLe*(o: Operators; a, b: PNode): PNode = result = o.opLe.buildCall(a, b) proc canon*(n: PNode; o: Operators): PNode = if n.safeLen >= 1: result = shallowCopy(n) for i in 0.. (foo + 4) + 2 of someHigh: # high == len+(-1) result = o.opAdd.buildCall(o.opLen.buildCall(result[1]), minusOne()) of someSub: # x - 4 --> x + (-4) result = negate(result[1], result[2], result, o) of someLen: result[0] = o.opLen.newSymNode of someLt - {mLtF64}: # x < y same as x <= y-1: let y = n[2].canon(o) let p = pred(y) let minus = if p != y: p else: o.opAdd.buildCall(y, minusOne()).canon(o) result = o.opLe.buildCall(n[1].canon(o), minus) else: discard result = skipConv(result) result = reassociation(result, o) # most important rule: (x-4) <= a.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module ranger.gui.defaultui</title>
</head><body bgcolor="#f0f0f8">

<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="ranger.html"><font color="#ffffff">ranger</font></a>.<a href="ranger.gui.html"><font color="#ffffff">gui</font></a>.defaultui</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/ranger/ranger/gui/defaultui.py">/home/hut/ranger/ranger/gui/defaultui.py</a></font></td></tr></table>
    <p><tt>#&nbsp;Copyright&nbsp;(c)&nbsp;2009,&nbsp;2010&nbsp;hut&nbsp;&lt;hut@lavabit.com&gt;<br>
#<br>
#&nbsp;Permission&nbsp;to&nbsp;use,&nbsp;copy,&nbsp;modify,&nbsp;and/or&nbsp;distribute&nbsp;this&nbsp;software&nbsp;for&nbsp;any<br>
#&nbsp;purpose&nbsp;with&nbsp;or&nbsp;without&nbsp;fee&nbsp;is&nbsp;hereby&nbsp;granted,&nbsp;provided&nbsp;that&nbsp;the&nbsp;above<br>
#&nbsp;copyright&nbsp;notice&nbsp;and&nbsp;this&nbsp;permission&nbsp;notice&nbsp;appear&nbsp;in&nbsp;all&nbsp;copies.<br>
#<br>
#&nbsp;THE&nbsp;SOFTWARE&nbsp;IS&nbsp;PROVIDED&nbsp;"AS&nbsp;IS"&nbsp;AND&nbsp;THE&nbsp;AUTHOR&nbsp;DISCLAIMS&nbsp;ALL&nbsp;WARRANTIES<br>
#&nbsp;WITH&nbsp;REGARD&nbsp;TO&nbsp;THIS&nbsp;SOFTWARE&nbsp;INCLUDING&nbsp;ALL&nbsp;IMPLIED&nbsp;WARRANTIES&nbsp;OF<br>
#&nbsp;MERCHANTABILITY&nbsp;AND&nbsp;FITNESS.&nbsp;IN&nbsp;NO&nbsp;EVENT&nbsp;SHALL&nbsp;THE&nbsp;AUTHOR&nbsp;BE&nbsp;LIABLE&nbsp;FOR<br>
#&nbsp;ANY&nbsp;SPECIAL,&nbsp;DIRECT,&nbsp;INDIRECT,&nbsp;OR&nbsp;CONSEQUENTIAL&nbsp;DAMAGES&nbsp;OR&nbsp;ANY&nbsp;DAMAGES<br>
#&nbsp;WHATSOEVER&nbsp;RESULTING&nbsp;FROM&nbsp;LOSS&nbsp;OF&nbsp;USE,&nbsp;DATA&nbsp;OR&nbsp;PROFITS,&nbsp;WHETHER&nbsp;IN&nbsp;AN<br>
#&nbsp;ACTION&nbsp;OF&nbsp;CONTRACT,&nbsp;NEGLIGENCE&nbsp;OR&nbsp;OTHER&nbsp;TORTIOUS&nbsp;ACTION,&nbsp;ARISING&nbsp;OUT&nbsp;OF<br>
#&nbsp;OR&nbsp;IN&nbsp;CONNECTION&nbsp;WITH&nbsp;THE&nbsp;USE&nbsp;OR&nbsp;PERFORMANCE&nbsp;OF&nbsp;THIS&nbsp;SOFTWARE.</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
    
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="ranger.gui.ui.html#UI">ranger.gui.ui.UI</a>(<a href="ranger.gui.displayable.html#DisplayableContainer">ranger.gui.displayable.DisplayableContainer</a>)
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="ranger.gui.defaultui.html#DefaultUI">DefaultUI</a>
</font></dt></dl>
</dd>
</dl>
 <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="DefaultUI">class <strong>DefaultUI</strong></a>(<a href="ranger.gui.ui.html#UI">ranger.gui.ui.UI</a>)</font></td></tr>
    
<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl><dt>Method resolution order:</dt>
<dd><a href="ranger.gui.defaultui.html#DefaultUI">DefaultUI</a></dd>
<dd><a href="ranger.gui.ui.html#UI">ranger.gui.ui.UI</a></dd>
<dd><a href="ranger.gui.displayable.html#DisplayableContainer">ranger.gui.displayable.DisplayableContainer</a></dd>
<dd><a href="ranger.gui.displayable.html#Displayable">ranger.gui.displayable.Displayable</a></dd>
<dd><a href="ranger.shared.html#EnvironmentAware">ranger.s