# # # The Nimrod Compiler # (c) Copyright 2013 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 const someEq = {mEqI, mEqI64, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc, mEqUntracedRef, mEqStr, mEqSet, mEqCString} # set excluded here as the semantics are vastly different: someLe = {mLeI, mLeI64, mLeF64, mLeU, mLeU64, mLeEnum, mLeCh, mLeB, mLePtr, mLeStr} someLt = {mLtI, mLtI64, mLtF64, mLtU, mLtU64, mLtEnum, mLtCh, mLtB, mLtPtr, mLtStr} someLen = {mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq} someIn = {mInRange, mInSet} 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 {sfGlobal, 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.sons[0] of nkDerefExpr, nkHiddenDeref: n = n.sons[0] inc derefs of nkBracketExpr: if isConstExpr(n.sons[1]) or isLet(n.sons[1]): n = n.sons[0] else: return of nkHiddenStdConv, nkHiddenSubConv, nkConv: n = n.sons[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) proc getMagicOp(name: string, m: TMagic): PSym = result = newSym(skProc, getIdent(name), nil, unknownLineInfo()) result.magic = m let opLe = getMagicOp("<=", mLeI) opLt = getMagicOp("<", mLtI) opAnd = getMagicOp("and", mAnd) opOr = getMagicOp("or", mOr) opNot = getMagicOp("not", mNot) opIsNil = getMagicOp("isnil", mIsNil) opContains = getMagicOp("contains", mInSet) opEq = getMagicOp("==", mEqI) proc swapArgs(fact: PNode, newOp: PSym): PNode = result = newNodeI(nkCall, fact.info, 3) result.sons[0] = newSymNode(newOp) result.sons[1] = fact.sons[2] result.sons[2] = fact.sons[1] proc neg(n: PNode): PNode = if n == nil: return nil case n.getMagic of mNot: result = n.sons[1] of someLt: # not (a < b) == a >= b == b <= a result = swapArgs(n, opLe) of someLe: result = swapArgs(n, opLt) of mInSet: if n.sons[1].kind != nkCurly: return nil let t = n.sons[2].typ.skipTypes(abstractInst) result = newNodeI(nkCall, n.info, 3) result.sons[0] = n.sons[0] result.sons[2] = n.sons[2] if t.kind == tyEnum: var s
#!/bin/sh
# This file is only for flatpak.
DIRECTORY="$(dirname "$0")"
RUN_COMMAND='./pong $@'
cd "$DIRECTORY"/../Pong && $RUN_COMMAND