mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 20:04:18 +00:00
patterns for 'importcpp' (still undocumented)
This commit is contained in:
@@ -110,8 +110,7 @@ proc openArrayLoc(p: BProc, n: PNode): PRope =
|
||||
result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])
|
||||
else: internalError("openArrayLoc: " & typeToString(a.t))
|
||||
|
||||
proc genArgStringToCString(p: BProc,
|
||||
n: PNode): PRope {.inline.} =
|
||||
proc genArgStringToCString(p: BProc, n: PNode): PRope {.inline.} =
|
||||
var a: TLoc
|
||||
initLocExpr(p, n.sons[0], a)
|
||||
result = ropef("$1->data", [a.rdLoc])
|
||||
@@ -218,40 +217,105 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||
else:
|
||||
genCallPattern()
|
||||
|
||||
proc genCppArg(p: BProc; ri: PNode; i: int; typ: PType): PRope =
|
||||
if i < sonsLen(typ):
|
||||
# 'var T' is 'T&' in C++. This means we ignore the request of
|
||||
# any nkHiddenAddr when it's a 'var T'.
|
||||
assert(typ.n.sons[i].kind == nkSym)
|
||||
if typ.sons[i].kind == tyVar and ri.sons[i].kind == nkHiddenAddr:
|
||||
result = genArgNoParam(p, ri.sons[i][0])
|
||||
else:
|
||||
result = genArg(p, ri.sons[i], typ.n.sons[i].sym)
|
||||
else:
|
||||
result = genArgNoParam(p, ri.sons[i])
|
||||
|
||||
proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): PRope =
|
||||
var i = 0
|
||||
var j = 1
|
||||
while i < pat.len:
|
||||
case pat[i]
|
||||
of '@':
|
||||
result.app genCppArg(p, ri, j, typ)
|
||||
for k in j+1 .. < ri.len:
|
||||
result.app(~", ")
|
||||
result.app genCppArg(p, ri, k, typ)
|
||||
inc i
|
||||
of '#':
|
||||
if pat[i+1] in {'+', '@'}:
|
||||
let ri = ri[j]
|
||||
if ri.kind in nkCallKinds:
|
||||
let typ = skipTypes(ri.sons[0].typ, abstractInst)
|
||||
if pat[i+1] == '+': result.app genArgNoParam(p, ri.sons[0])
|
||||
result.app(~"(")
|
||||
result.app genCppArg(p, ri, 1, typ)
|
||||
for k in j+1 .. < ri.len:
|
||||
result.app(~", ")
|
||||
result.app genCppArg(p, ri, k, typ)
|
||||
result.app(~")")
|
||||
else:
|
||||
localError(ri.info, "call expression expected for C++ pattern")
|
||||
inc i
|
||||
else:
|
||||
result.app genCppArg(p, ri, j, typ)
|
||||
if pat[i+1] == '.':
|
||||
let param = typ.n.sons[j].sym
|
||||
if skipTypes(param.typ, {tyGenericInst}).kind == tyPtr: result.app(~"->")
|
||||
else: result.app(~".")
|
||||
inc i
|
||||
inc j
|
||||
of '\'':
|
||||
inc i
|
||||
let stars = i
|
||||
while pat[i] == '*': inc i
|
||||
if pat[i] in Digits:
|
||||
let j = pat[i].ord - '0'.ord
|
||||
var t = typ.sons[j]
|
||||
for k in 1..i-stars:
|
||||
if t != nil and t.len > 0: t = t.elemType
|
||||
if t == nil: result.app(~"void")
|
||||
else: result.app(getTypeDesc(p.module, t))
|
||||
else:
|
||||
result.app(toRope($pat[i]))
|
||||
inc i
|
||||
|
||||
proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||
var op, a: TLoc
|
||||
initLocExpr(p, ri.sons[0], op)
|
||||
var pl: PRope = nil
|
||||
# getUniqueType() is too expensive here:
|
||||
var typ = skipTypes(ri.sons[0].typ, abstractInst)
|
||||
assert(typ.kind == tyProc)
|
||||
var length = sonsLen(ri)
|
||||
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||
|
||||
var param = typ.n.sons[1].sym
|
||||
if typ.sons[1].kind == tyVar and ri.sons[1].kind == nkHiddenAddr:
|
||||
app(pl, genArgNoParam(p, ri.sons[1][0]))
|
||||
else:
|
||||
app(pl, genArg(p, ri.sons[1], param))
|
||||
|
||||
if skipTypes(param.typ, {tyGenericInst}).kind == tyPtr: app(pl, ~"->")
|
||||
else: app(pl, ~".")
|
||||
app(pl, op.r)
|
||||
var params: PRope
|
||||
for i in countup(2, length - 1):
|
||||
if params != nil: params.app(~", ")
|
||||
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||
if i < sonsLen(typ):
|
||||
# 'var T' is 'T&' in C++. This means we ignore the request of
|
||||
# any nkHiddenAddr when it's a 'var T'.
|
||||
assert(typ.n.sons[i].kind == nkSym)
|
||||
if typ.sons[i].kind == tyVar and ri.sons[i].kind == nkHiddenAddr:
|
||||
app(params, genArgNoParam(p, ri.sons[i][0]))
|
||||
else:
|
||||
app(params, genArg(p, ri.sons[i], typ.n.sons[i].sym))
|
||||
# don't call 'ropeToStr' here for efficiency:
|
||||
let pat = ri.sons[0].sym.loc.r.data
|
||||
internalAssert pat != nil
|
||||
if pat.contains({'#', '(', '@', '\''}):
|
||||
var pl = genPatternCall(p, ri, pat, typ)
|
||||
# simpler version of 'fixupCall' that works with the pl+params combination:
|
||||
var typ = skipTypes(ri.sons[0].typ, abstractInst)
|
||||
if typ.sons[0] != nil:
|
||||
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:
|
||||
app(params, genArgNoParam(p, ri.sons[i]))
|
||||
fixupCall(p, le, ri, d, pl, params)
|
||||
app(pl, ~";$n")
|
||||
line(p, cpsStmts, pl)
|
||||
else:
|
||||
var pl: PRope = nil
|
||||
var param = typ.n.sons[1].sym
|
||||
app(pl, genCppArg(p, ri, 1, typ))
|
||||
if skipTypes(param.typ, {tyGenericInst}).kind == tyPtr: app(pl, ~"->")
|
||||
else: app(pl, ~".")
|
||||
app(pl, op.r)
|
||||
var params: PRope
|
||||
for i in countup(2, length - 1):
|
||||
if params != nil: params.app(~", ")
|
||||
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||
app(params, genCppArg(p, ri, i, typ))
|
||||
fixupCall(p, le, ri, d, pl, params)
|
||||
|
||||
proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
|
||||
# generates a crappy ObjC call
|
||||
|
||||
@@ -141,7 +141,7 @@ proc elemType*(t: PType): PType =
|
||||
case t.kind
|
||||
of tyGenericInst, tyDistinct: result = elemType(lastSon(t))
|
||||
of tyArray, tyArrayConstr: result = t.sons[1]
|
||||
else: result = t.sons[0]
|
||||
else: result = t.lastSon
|
||||
assert(result != nil)
|
||||
|
||||
proc skipGeneric(t: PType): PType =
|
||||
|
||||
Reference in New Issue
Block a user