# # # The Nimrod Compiler # (c) Copyright 2012 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # # # included from cgen.nim proc leftAppearsOnRightSide(le, ri: PNode): bool = if le != nil: for i in 1 .. 1: app(pl, ", ") # beware of 'result = p(result)'. We may need to allocate a temporary: if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri): # Great, we can use 'd': if d.k == locNone: getTemp(p, typ.sons[0], d) elif d.k notin {locExpr, locTemp} and not hasNoInit(ri): # reset before pass as 'result' var: resetLoc(p, d) app(pl, addrLoc(d)) appf(pl, ");$n") line(p, cpsStmts, pl) else: var tmp: TLoc getTemp(p, typ.sons[0], tmp) app(pl, addrLoc(tmp)) appf(pl, ");$n") line(p, cpsStmts, pl) genAssignment(p, d, tmp, {}) # no need for deep copying else: app(pl, ")") if d.k == locNone: getTemp(p, typ.sons[0], d) assert(d.t != nil) # generate an assignment to d: var list: TLoc initLoc(list, locCall, d.t, OnUnknown) list.r = pl genAssignment(p, d, list, {}) # no need for deep copying else: appf(pl, ");$n") line(p, cpsStmts, pl) proc isInCurrentFrame(p: BProc, n: PNode): bool = # checks if `n` is an expression that refers to the current frame; # this does not work reliably because of forwarding + inlining can break it case n.kind of nkSym: if n.sym.kind in {skVar, skResult, skTemp, skLet} and p.prc != nil: result = p.prc.id == n.sym.owner.id of nkDotExpr, nkBracketExpr: if skipTypes(n.sons[0].typ, abstractInst).kind notin {tyVar,tyPtr,tyRef}: result = isInCurrentFrame(p, n.sons[0]) of nkHiddenStdConv, nkHiddenSubConv, nkConv: result = isInCurrentFrame(p, n.sons[1]) of nkHiddenDeref, nkDerefExpr: # what about: var x = addr(y); callAsOpenArray(x[])? # *shrug* ``addr`` is unsafe anyway. result = false of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr: result = isInCurrentFrame(p, n.sons[0]) else: nil proc openArrayLoc(p: BProc, n: PNode): PRope = var a: TLoc initLocExpr(p, n, a) case skipTypes(a.t, abstractVar).kind of tyOpenArray, tyVarargs: result = ropef("$1, $1Len0", [rdLoc(a)]) of tyString, tySequence: if skipTypes(n.typ, abstractInst).kind == tyVar: result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField()]) else: result = ropef("$1->data, $1->$2", [a.rdLoc, lenField()]) of tyArray, tyArrayConstr: result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]) else: InternalError("openArrayLoc: " & typeToString(a.t)) proc genArgStringToCString(p: BProc, n: PNode): PRope {.inline.} = var a: TLoc initLocExpr(p, n.sons[0], a) result = ropef("$1->data", [a.rdLoc]) proc genArg(p: BProc, n: PNode, param: PSym): PRope = var a: TLoc if n.kind == nkStringToCString: result = genArgStringToCString(p, n) elif skipTypes(param.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: var n = if n.kind != nkHiddenAddr: n else: n.sons[0] result = openArrayLoc(p, n) elif ccgIntroducedPtr(param): initLocExpr(p, n, a) result = addrLoc(a) else: initLocExpr(p, n, a) result = rdLoc(a) proc genArgNoParam(p: BProc, n: PNode): PRope = var a: TLoc if n.kind == nkStringToCString: result = genArgStringToCString(p, n) else: initLocExpr(p, n, a) result = rdLoc(a) proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) = var op: TLoc # this is a hotspot in the compiler initLocExpr(p, ri.sons[0], op) var params: PRope # getUniqueType() is too expensive here: var typ = skipTypes(ri.sons[0].typ, abstractInst) assert(typ.kind == tyProc) var length = sonsLen(ri) for i in countup(1, length - 1): assert(sonsLen(typ) == sonsLen(typ.n)) if ri.sons[i].typ.isCompileTimeOnly: continue if params !=
discard """
output: ""
"""
import threadpool, os

var chan: Channel[int]

chan.