Merge branch 'devel' into gcbugfix
This commit is contained in:
commit
373a79b28a
127 changed files with 1341 additions and 612 deletions
|
|
@ -459,7 +459,7 @@ type
|
||||||
|
|
||||||
tfNeedsInit, # type constains a "not nil" constraint somewhere or some
|
tfNeedsInit, # type constains a "not nil" constraint somewhere or some
|
||||||
# other type so that it requires inititalization
|
# other type so that it requires inititalization
|
||||||
tfHasShared, # type constains a "shared" constraint modifier somewhere
|
tfVarIsPtr, # 'var' type is translated like 'ptr' even in C++ mode
|
||||||
tfHasMeta, # type contains "wildcard" sub-types such as generic params
|
tfHasMeta, # type contains "wildcard" sub-types such as generic params
|
||||||
# or other type classes
|
# or other type classes
|
||||||
tfHasGCedMem, # type contains GC'ed memory
|
tfHasGCedMem, # type contains GC'ed memory
|
||||||
|
|
@ -522,7 +522,7 @@ const
|
||||||
skError* = skUnknown
|
skError* = skUnknown
|
||||||
|
|
||||||
# type flags that are essential for type equality:
|
# type flags that are essential for type equality:
|
||||||
eqTypeFlags* = {tfIterator, tfShared, tfNotNil}
|
eqTypeFlags* = {tfIterator, tfShared, tfNotNil, tfVarIsPtr}
|
||||||
|
|
||||||
type
|
type
|
||||||
TMagic* = enum # symbols that require compiler magic:
|
TMagic* = enum # symbols that require compiler magic:
|
||||||
|
|
@ -1348,7 +1348,7 @@ proc isGCedMem*(t: PType): bool {.inline.} =
|
||||||
|
|
||||||
proc propagateToOwner*(owner, elem: PType) =
|
proc propagateToOwner*(owner, elem: PType) =
|
||||||
const HaveTheirOwnEmpty = {tySequence, tySet}
|
const HaveTheirOwnEmpty = {tySequence, tySet}
|
||||||
owner.flags = owner.flags + (elem.flags * {tfHasShared, tfHasMeta})
|
owner.flags = owner.flags + (elem.flags * {tfHasMeta})
|
||||||
if tfNotNil in elem.flags:
|
if tfNotNil in elem.flags:
|
||||||
if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvokation}:
|
if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvokation}:
|
||||||
owner.flags.incl tfNotNil
|
owner.flags.incl tfNotNil
|
||||||
|
|
@ -1359,9 +1359,6 @@ proc propagateToOwner*(owner, elem: PType) =
|
||||||
if owner.kind in HaveTheirOwnEmpty: discard
|
if owner.kind in HaveTheirOwnEmpty: discard
|
||||||
else: owner.flags.incl tfNeedsInit
|
else: owner.flags.incl tfNeedsInit
|
||||||
|
|
||||||
if tfShared in elem.flags:
|
|
||||||
owner.flags.incl tfHasShared
|
|
||||||
|
|
||||||
if elem.isMetaType:
|
if elem.isMetaType:
|
||||||
owner.flags.incl tfHasMeta
|
owner.flags.incl tfHasMeta
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -130,8 +130,8 @@ proc skipConvAndClosure*(n: PNode): PNode =
|
||||||
proc sameValue*(a, b: PNode): bool =
|
proc sameValue*(a, b: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkCharLit..nkInt64Lit:
|
of nkCharLit..nkUInt64Lit:
|
||||||
if b.kind in {nkCharLit..nkInt64Lit}: result = a.intVal == b.intVal
|
if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkFloatLit..nkFloat64Lit:
|
||||||
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
|
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
|
|
@ -145,13 +145,13 @@ proc leValue*(a, b: PNode): bool =
|
||||||
# a <= b?
|
# a <= b?
|
||||||
result = false
|
result = false
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkCharLit..nkInt64Lit:
|
of nkCharLit..nkUInt32Lit:
|
||||||
if b.kind in {nkCharLit..nkInt64Lit}: result = a.intVal <= b.intVal
|
if b.kind in {nkCharLit..nkUInt32Lit}: result = a.intVal <= b.intVal
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkFloatLit..nkFloat64Lit:
|
||||||
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal <= b.floatVal
|
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal <= b.floatVal
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if b.kind in {nkStrLit..nkTripleStrLit}: result = a.strVal <= b.strVal
|
if b.kind in {nkStrLit..nkTripleStrLit}: result = a.strVal <= b.strVal
|
||||||
else:
|
else:
|
||||||
# don't raise an internal error for 'nimrod check':
|
# don't raise an internal error for 'nimrod check':
|
||||||
#InternalError(a.info, "leValue")
|
#InternalError(a.info, "leValue")
|
||||||
discard
|
discard
|
||||||
|
|
|
||||||
|
|
@ -124,8 +124,8 @@ proc genArgStringToCString(p: BProc, n: PNode): PRope {.inline.} =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, n.sons[0], a)
|
initLocExpr(p, n.sons[0], a)
|
||||||
result = ropef("$1->data", [a.rdLoc])
|
result = ropef("$1->data", [a.rdLoc])
|
||||||
|
|
||||||
proc genArg(p: BProc, n: PNode, param: PSym): PRope =
|
proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): PRope =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
if n.kind == nkStringToCString:
|
if n.kind == nkStringToCString:
|
||||||
result = genArgStringToCString(p, n)
|
result = genArgStringToCString(p, n)
|
||||||
|
|
@ -138,7 +138,15 @@ proc genArg(p: BProc, n: PNode, param: PSym): PRope =
|
||||||
elif p.module.compileToCpp and param.typ.kind == tyVar and
|
elif p.module.compileToCpp and param.typ.kind == tyVar and
|
||||||
n.kind == nkHiddenAddr:
|
n.kind == nkHiddenAddr:
|
||||||
initLocExprSingleUse(p, n.sons[0], a)
|
initLocExprSingleUse(p, n.sons[0], a)
|
||||||
result = rdLoc(a)
|
# if the proc is 'importc'ed but not 'importcpp'ed then 'var T' still
|
||||||
|
# means '*T'. See posix.nim for lots of examples that do that in the wild.
|
||||||
|
let callee = call.sons[0]
|
||||||
|
if callee.kind == nkSym and
|
||||||
|
{sfImportC, sfInfixCall, sfCompilerProc} * callee.sym.flags == {sfImportC} and
|
||||||
|
{lfHeader, lfNoDecl} * callee.sym.loc.flags != {}:
|
||||||
|
result = addrLoc(a)
|
||||||
|
else:
|
||||||
|
result = rdLoc(a)
|
||||||
else:
|
else:
|
||||||
initLocExprSingleUse(p, n, a)
|
initLocExprSingleUse(p, n, a)
|
||||||
result = rdLoc(a)
|
result = rdLoc(a)
|
||||||
|
|
@ -166,7 +174,7 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||||
if params != nil: app(params, ~", ")
|
if params != nil: app(params, ~", ")
|
||||||
if i < sonsLen(typ):
|
if i < sonsLen(typ):
|
||||||
assert(typ.n.sons[i].kind == nkSym)
|
assert(typ.n.sons[i].kind == nkSym)
|
||||||
app(params, genArg(p, ri.sons[i], typ.n.sons[i].sym))
|
app(params, genArg(p, ri.sons[i], typ.n.sons[i].sym, ri))
|
||||||
else:
|
else:
|
||||||
app(params, genArgNoParam(p, ri.sons[i]))
|
app(params, genArgNoParam(p, ri.sons[i]))
|
||||||
fixupCall(p, le, ri, d, op.r, params)
|
fixupCall(p, le, ri, d, op.r, params)
|
||||||
|
|
@ -192,7 +200,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
|
||||||
assert(sonsLen(typ) == sonsLen(typ.n))
|
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||||
if i < sonsLen(typ):
|
if i < sonsLen(typ):
|
||||||
assert(typ.n.sons[i].kind == nkSym)
|
assert(typ.n.sons[i].kind == nkSym)
|
||||||
app(pl, genArg(p, ri.sons[i], typ.n.sons[i].sym))
|
app(pl, genArg(p, ri.sons[i], typ.n.sons[i].sym, ri))
|
||||||
else:
|
else:
|
||||||
app(pl, genArgNoParam(p, ri.sons[i]))
|
app(pl, genArgNoParam(p, ri.sons[i]))
|
||||||
if i < length - 1: app(pl, ~", ")
|
if i < length - 1: app(pl, ~", ")
|
||||||
|
|
@ -295,7 +303,7 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): PRope =
|
||||||
if x.typ.kind == tyPtr:
|
if x.typ.kind == tyPtr:
|
||||||
result = genArgNoParam(p, x)
|
result = genArgNoParam(p, x)
|
||||||
result.app("->")
|
result.app("->")
|
||||||
elif x.kind in {nkHiddenDeref, nkDerefExpr}:
|
elif x.kind in {nkHiddenDeref, nkDerefExpr} and x[0].typ.kind == tyPtr:
|
||||||
result = genArgNoParam(p, x[0])
|
result = genArgNoParam(p, x[0])
|
||||||
result.app("->")
|
result.app("->")
|
||||||
else:
|
else:
|
||||||
|
|
@ -424,12 +432,12 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
|
||||||
assert(sonsLen(typ) == sonsLen(typ.n))
|
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||||
|
|
||||||
if length > 1:
|
if length > 1:
|
||||||
app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym))
|
app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri))
|
||||||
app(pl, ~" ")
|
app(pl, ~" ")
|
||||||
app(pl, op.r)
|
app(pl, op.r)
|
||||||
if length > 2:
|
if length > 2:
|
||||||
app(pl, ~": ")
|
app(pl, ~": ")
|
||||||
app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym))
|
app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri))
|
||||||
for i in countup(3, length-1):
|
for i in countup(3, length-1):
|
||||||
assert(sonsLen(typ) == sonsLen(typ.n))
|
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||||
if i >= sonsLen(typ):
|
if i >= sonsLen(typ):
|
||||||
|
|
@ -439,7 +447,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
|
||||||
app(pl, ~" ")
|
app(pl, ~" ")
|
||||||
app(pl, param.name.s)
|
app(pl, param.name.s)
|
||||||
app(pl, ~": ")
|
app(pl, ~": ")
|
||||||
app(pl, genArg(p, ri.sons[i], param))
|
app(pl, genArg(p, ri.sons[i], param, ri))
|
||||||
if typ.sons[0] != nil:
|
if typ.sons[0] != nil:
|
||||||
if isInvalidReturnType(typ.sons[0]):
|
if isInvalidReturnType(typ.sons[0]):
|
||||||
if sonsLen(ri) > 1: app(pl, ~" ")
|
if sonsLen(ri) > 1: app(pl, ~" ")
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,9 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope =
|
||||||
else:
|
else:
|
||||||
result = toRope("NIM_NIL")
|
result = toRope("NIM_NIL")
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if skipTypes(ty, abstractVarRange).kind == tyString:
|
if n.strVal.isNil:
|
||||||
|
result = ropecg(p.module, "((#NimStringDesc*) NIM_NIL)", [])
|
||||||
|
elif skipTypes(ty, abstractVarRange).kind == tyString:
|
||||||
var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
|
var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
|
||||||
if id == gBackendId:
|
if id == gBackendId:
|
||||||
# string literal not found in the cache:
|
# string literal not found in the cache:
|
||||||
|
|
@ -664,7 +666,8 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
|
|
||||||
proc isCppRef(p: BProc; typ: PType): bool {.inline.} =
|
proc isCppRef(p: BProc; typ: PType): bool {.inline.} =
|
||||||
result = p.module.compileToCpp and
|
result = p.module.compileToCpp and
|
||||||
skipTypes(typ, abstractInst).kind == tyVar
|
skipTypes(typ, abstractInst).kind == tyVar and
|
||||||
|
tfVarIsPtr notin skipTypes(typ, abstractInst).flags
|
||||||
|
|
||||||
proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
|
proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
|
||||||
let mt = mapType(e.sons[0].typ)
|
let mt = mapType(e.sons[0].typ)
|
||||||
|
|
@ -677,12 +680,14 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
|
||||||
else:
|
else:
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExprSingleUse(p, e.sons[0], a)
|
initLocExprSingleUse(p, e.sons[0], a)
|
||||||
case skipTypes(a.t, abstractInst).kind
|
let typ = skipTypes(a.t, abstractInst)
|
||||||
|
case typ.kind
|
||||||
of tyRef:
|
of tyRef:
|
||||||
d.s = OnHeap
|
d.s = OnHeap
|
||||||
of tyVar:
|
of tyVar:
|
||||||
d.s = OnUnknown
|
d.s = OnUnknown
|
||||||
if p.module.compileToCpp:
|
if tfVarIsPtr notin typ.flags and p.module.compileToCpp and
|
||||||
|
e.kind == nkHiddenDeref:
|
||||||
putIntoDest(p, d, e.typ, rdLoc(a))
|
putIntoDest(p, d, e.typ, rdLoc(a))
|
||||||
return
|
return
|
||||||
of tyPtr:
|
of tyPtr:
|
||||||
|
|
@ -923,6 +928,7 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
L: TLabel
|
L: TLabel
|
||||||
tmp: TLoc
|
tmp: TLoc
|
||||||
getTemp(p, e.typ, tmp) # force it into a temp!
|
getTemp(p, e.typ, tmp) # force it into a temp!
|
||||||
|
inc p.splitDecls
|
||||||
expr(p, e.sons[1], tmp)
|
expr(p, e.sons[1], tmp)
|
||||||
L = getLabel(p)
|
L = getLabel(p)
|
||||||
if m == mOr:
|
if m == mOr:
|
||||||
|
|
@ -935,6 +941,7 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
|
||||||
d = tmp
|
d = tmp
|
||||||
else:
|
else:
|
||||||
genAssignment(p, d, tmp, {}) # no need for deep copying
|
genAssignment(p, d, tmp, {}) # no need for deep copying
|
||||||
|
dec p.splitDecls
|
||||||
|
|
||||||
proc genEcho(p: BProc, n: PNode) =
|
proc genEcho(p: BProc, n: PNode) =
|
||||||
# this unusal way of implementing it ensures that e.g. ``echo("hallo", 45)``
|
# this unusal way of implementing it ensures that e.g. ``echo("hallo", 45)``
|
||||||
|
|
@ -945,7 +952,7 @@ proc genEcho(p: BProc, n: PNode) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
for i in countup(0, n.len-1):
|
for i in countup(0, n.len-1):
|
||||||
initLocExpr(p, n.sons[i], a)
|
initLocExpr(p, n.sons[i], a)
|
||||||
appf(args, ", ($1)->data", [rdLoc(a)])
|
appf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)])
|
||||||
linefmt(p, cpsStmts, "printf($1$2);$n",
|
linefmt(p, cpsStmts, "printf($1$2);$n",
|
||||||
makeCString(repeatStr(n.len, "%s") & tnl), args)
|
makeCString(repeatStr(n.len, "%s") & tnl), args)
|
||||||
|
|
||||||
|
|
@ -2168,7 +2175,7 @@ proc genConstExpr(p: BProc, n: PNode): PRope =
|
||||||
var cs: TBitSet
|
var cs: TBitSet
|
||||||
toBitSet(n, cs)
|
toBitSet(n, cs)
|
||||||
result = genRawSetData(cs, int(getSize(n.typ)))
|
result = genRawSetData(cs, int(getSize(n.typ)))
|
||||||
of nkBracket, nkPar, nkClosure:
|
of nkBracket, nkPar, nkClosure, nkObjConstr:
|
||||||
var t = skipTypes(n.typ, abstractInst)
|
var t = skipTypes(n.typ, abstractInst)
|
||||||
if t.kind == tySequence:
|
if t.kind == tySequence:
|
||||||
result = genConstSeq(p, n, t)
|
result = genConstSeq(p, n, t)
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ proc genSingleVar(p: BProc, a: PNode) =
|
||||||
registerGcRoot(p, v)
|
registerGcRoot(p, v)
|
||||||
else:
|
else:
|
||||||
let imm = isAssignedImmediately(a.sons[2])
|
let imm = isAssignedImmediately(a.sons[2])
|
||||||
if imm and p.module.compileToCpp:
|
if imm and p.module.compileToCpp and p.splitDecls == 0:
|
||||||
# C++ really doesn't like things like 'Foo f; f = x' as that invokes a
|
# C++ really doesn't like things like 'Foo f; f = x' as that invokes a
|
||||||
# parameterless constructor followed by an assignment operator. So we
|
# parameterless constructor followed by an assignment operator. So we
|
||||||
# generate better code here:
|
# generate better code here:
|
||||||
|
|
@ -253,16 +253,7 @@ proc genConstStmt(p: BProc, t: PNode) =
|
||||||
elif c.typ.kind in ConstantDataTypes and lfNoDecl notin c.loc.flags and
|
elif c.typ.kind in ConstantDataTypes and lfNoDecl notin c.loc.flags and
|
||||||
c.ast.len != 0:
|
c.ast.len != 0:
|
||||||
if not emitLazily(c): requestConstImpl(p, c)
|
if not emitLazily(c): requestConstImpl(p, c)
|
||||||
when false:
|
|
||||||
# generate the data:
|
|
||||||
fillLoc(c.loc, locData, c.typ, mangleName(c), OnUnknown)
|
|
||||||
if sfImportc in c.flags:
|
|
||||||
appf(p.module.s[cfsData], "extern NIM_CONST $1 $2;$n",
|
|
||||||
[getTypeDesc(p.module, c.typ), c.loc.r])
|
|
||||||
else:
|
|
||||||
appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
|
|
||||||
[getTypeDesc(p.module, c.typ), c.loc.r, genConstExpr(p, c.ast)])
|
|
||||||
|
|
||||||
proc genIf(p: BProc, n: PNode, d: var TLoc) =
|
proc genIf(p: BProc, n: PNode, d: var TLoc) =
|
||||||
#
|
#
|
||||||
# { if (!expr1) goto L1;
|
# { if (!expr1) goto L1;
|
||||||
|
|
@ -286,17 +277,22 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
|
||||||
let it = n.sons[i]
|
let it = n.sons[i]
|
||||||
if it.len == 2:
|
if it.len == 2:
|
||||||
when newScopeForIf: startBlock(p)
|
when newScopeForIf: startBlock(p)
|
||||||
initLocExpr(p, it.sons[0], a)
|
initLocExprSingleUse(p, it.sons[0], a)
|
||||||
lelse = getLabel(p)
|
lelse = getLabel(p)
|
||||||
inc(p.labels)
|
inc(p.labels)
|
||||||
lineFF(p, cpsStmts, "if (!$1) goto $2;$n",
|
lineF(p, cpsStmts, "if (!$1) goto $2;$n",
|
||||||
"br i1 $1, label %LOC$3, label %$2$nLOC$3: $n",
|
[rdLoc(a), lelse])
|
||||||
[rdLoc(a), lelse, toRope(p.labels)])
|
|
||||||
when not newScopeForIf: startBlock(p)
|
when not newScopeForIf: startBlock(p)
|
||||||
expr(p, it.sons[1], d)
|
if p.module.compileToCpp:
|
||||||
|
# avoid "jump to label crosses initialization" error:
|
||||||
|
app(p.s(cpsStmts), "{")
|
||||||
|
expr(p, it.sons[1], d)
|
||||||
|
app(p.s(cpsStmts), "}")
|
||||||
|
else:
|
||||||
|
expr(p, it.sons[1], d)
|
||||||
endBlock(p)
|
endBlock(p)
|
||||||
if sonsLen(n) > 1:
|
if sonsLen(n) > 1:
|
||||||
lineFF(p, cpsStmts, "goto $1;$n", "br label %$1$n", [lend])
|
lineF(p, cpsStmts, "goto $1;$n", [lend])
|
||||||
fixLabel(p, lelse)
|
fixLabel(p, lelse)
|
||||||
elif it.len == 1:
|
elif it.len == 1:
|
||||||
startBlock(p)
|
startBlock(p)
|
||||||
|
|
@ -355,7 +351,7 @@ proc genReturnStmt(p: BProc, t: PNode) =
|
||||||
# consume it before we return.
|
# consume it before we return.
|
||||||
var safePoint = p.finallySafePoints[p.finallySafePoints.len-1]
|
var safePoint = p.finallySafePoints[p.finallySafePoints.len-1]
|
||||||
linefmt(p, cpsStmts, "if ($1.status != 0) #popCurrentException();$n", safePoint)
|
linefmt(p, cpsStmts, "if ($1.status != 0) #popCurrentException();$n", safePoint)
|
||||||
lineFF(p, cpsStmts, "goto BeforeRet;$n", "br label %BeforeRet$n", [])
|
lineF(p, cpsStmts, "goto BeforeRet;$n", [])
|
||||||
|
|
||||||
proc genComputedGoto(p: BProc; n: PNode) =
|
proc genComputedGoto(p: BProc; n: PNode) =
|
||||||
# first pass: Generate array of computed labels:
|
# first pass: Generate array of computed labels:
|
||||||
|
|
|
||||||
|
|
@ -27,17 +27,7 @@ proc isKeyword(w: PIdent): bool =
|
||||||
|
|
||||||
proc mangleName(s: PSym): PRope =
|
proc mangleName(s: PSym): PRope =
|
||||||
result = s.loc.r
|
result = s.loc.r
|
||||||
if result == nil:
|
if result == nil:
|
||||||
if gCmd == cmdCompileToLLVM:
|
|
||||||
case s.kind
|
|
||||||
of skProc, skMethod, skConverter, skConst, skIterators:
|
|
||||||
result = ~"@"
|
|
||||||
of skVar, skForVar, skResult, skLet:
|
|
||||||
if sfGlobal in s.flags: result = ~"@"
|
|
||||||
else: result = ~"%"
|
|
||||||
of skTemp, skParam, skType, skEnumField, skModule:
|
|
||||||
result = ~"%"
|
|
||||||
else: internalError(s.info, "mangleName")
|
|
||||||
when oKeepVariableNames:
|
when oKeepVariableNames:
|
||||||
let keepOrigName = s.kind in skLocalVars - {skForVar} and
|
let keepOrigName = s.kind in skLocalVars - {skForVar} and
|
||||||
{sfFromGeneric, sfGlobal, sfShadowed, sfGenSym} * s.flags == {} and
|
{sfFromGeneric, sfGlobal, sfShadowed, sfGenSym} * s.flags == {} and
|
||||||
|
|
@ -103,13 +93,11 @@ proc typeName(typ: PType): PRope =
|
||||||
else: ~"TY"
|
else: ~"TY"
|
||||||
|
|
||||||
proc getTypeName(typ: PType): PRope =
|
proc getTypeName(typ: PType): PRope =
|
||||||
if (typ.sym != nil) and ({sfImportc, sfExportc} * typ.sym.flags != {}) and
|
if typ.sym != nil and {sfImportc, sfExportc} * typ.sym.flags != {}:
|
||||||
(gCmd != cmdCompileToLLVM):
|
|
||||||
result = typ.sym.loc.r
|
result = typ.sym.loc.r
|
||||||
else:
|
else:
|
||||||
if typ.loc.r == nil:
|
if typ.loc.r == nil:
|
||||||
typ.loc.r = if gCmd != cmdCompileToLLVM: con(typ.typeName, typ.id.toRope)
|
typ.loc.r = con(typ.typeName, typ.id.toRope)
|
||||||
else: con([~"%", typ.typeName, typ.id.toRope])
|
|
||||||
result = typ.loc.r
|
result = typ.loc.r
|
||||||
if result == nil: internalError("getTypeName: " & $typ.kind)
|
if result == nil: internalError("getTypeName: " & $typ.kind)
|
||||||
|
|
||||||
|
|
@ -200,9 +188,6 @@ const
|
||||||
"N_SYSCALL", # this is probably not correct for all platforms,
|
"N_SYSCALL", # this is probably not correct for all platforms,
|
||||||
# but one can #define it to what one wants
|
# but one can #define it to what one wants
|
||||||
"N_INLINE", "N_NOINLINE", "N_FASTCALL", "N_CLOSURE", "N_NOCONV"]
|
"N_INLINE", "N_NOINLINE", "N_FASTCALL", "N_CLOSURE", "N_NOCONV"]
|
||||||
CallingConvToStrLLVM: array[TCallingConvention, string] = ["fastcc $1",
|
|
||||||
"stdcall $1", "ccc $1", "safecall $1", "syscall $1", "$1 alwaysinline",
|
|
||||||
"$1 noinline", "fastcc $1", "ccc $1", "$1"]
|
|
||||||
|
|
||||||
proc cacheGetType(tab: TIdTable, key: PType): PRope =
|
proc cacheGetType(tab: TIdTable, key: PType): PRope =
|
||||||
# returns nil if we need to declare this type
|
# returns nil if we need to declare this type
|
||||||
|
|
@ -284,23 +269,23 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
|
||||||
# this fixes the 'sort' bug:
|
# this fixes the 'sort' bug:
|
||||||
if param.typ.kind == tyVar: param.loc.s = OnUnknown
|
if param.typ.kind == tyVar: param.loc.s = OnUnknown
|
||||||
# need to pass hidden parameter:
|
# need to pass hidden parameter:
|
||||||
appff(params, ", NI $1Len$2", ", @NI $1Len$2", [param.loc.r, j.toRope])
|
appf(params, ", NI $1Len$2", [param.loc.r, j.toRope])
|
||||||
inc(j)
|
inc(j)
|
||||||
arr = arr.sons[0]
|
arr = arr.sons[0]
|
||||||
if (t.sons[0] != nil) and isInvalidReturnType(t.sons[0]):
|
if (t.sons[0] != nil) and isInvalidReturnType(t.sons[0]):
|
||||||
var arr = t.sons[0]
|
var arr = t.sons[0]
|
||||||
if params != nil: app(params, ", ")
|
if params != nil: app(params, ", ")
|
||||||
app(params, getTypeDescAux(m, arr, check))
|
app(params, getTypeDescAux(m, arr, check))
|
||||||
if (mapReturnType(t.sons[0]) != ctArray) or (gCmd == cmdCompileToLLVM):
|
if (mapReturnType(t.sons[0]) != ctArray):
|
||||||
app(params, "*")
|
app(params, "*")
|
||||||
appff(params, " Result", " @Result", [])
|
appf(params, " Result", [])
|
||||||
if t.callConv == ccClosure and declareEnvironment:
|
if t.callConv == ccClosure and declareEnvironment:
|
||||||
if params != nil: app(params, ", ")
|
if params != nil: app(params, ", ")
|
||||||
app(params, "void* ClEnv")
|
app(params, "void* ClEnv")
|
||||||
if tfVarargs in t.flags:
|
if tfVarargs in t.flags:
|
||||||
if params != nil: app(params, ", ")
|
if params != nil: app(params, ", ")
|
||||||
app(params, "...")
|
app(params, "...")
|
||||||
if params == nil and gCmd != cmdCompileToLLVM: app(params, "void)")
|
if params == nil: app(params, "void)")
|
||||||
else: app(params, ")")
|
else: app(params, ")")
|
||||||
params = con("(", params)
|
params = con("(", params)
|
||||||
|
|
||||||
|
|
@ -505,8 +490,9 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
# but determining when this needs to be done is hard. We should split
|
# but determining when this needs to be done is hard. We should split
|
||||||
# C type generation into an analysis and a code generation phase somehow.
|
# C type generation into an analysis and a code generation phase somehow.
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyRef, tyPtr, tyVar:
|
of tyRef, tyPtr, tyVar:
|
||||||
let star = if t.kind == tyVar and compileToCpp(m): "&" else: "*"
|
var star = if t.kind == tyVar and tfVarIsPtr notin typ.flags and
|
||||||
|
compileToCpp(m): "&" else: "*"
|
||||||
var et = t.lastSon
|
var et = t.lastSon
|
||||||
var etB = et.skipTypes(abstractInst)
|
var etB = et.skipTypes(abstractInst)
|
||||||
if etB.kind in {tyArrayConstr, tyArray, tyOpenArray, tyVarargs}:
|
if etB.kind in {tyArrayConstr, tyArray, tyOpenArray, tyVarargs}:
|
||||||
|
|
@ -514,6 +500,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
# ``var set[char]`` in `getParamTypeDesc`
|
# ``var set[char]`` in `getParamTypeDesc`
|
||||||
et = elemType(etB)
|
et = elemType(etB)
|
||||||
etB = et.skipTypes(abstractInst)
|
etB = et.skipTypes(abstractInst)
|
||||||
|
star[0] = '*'
|
||||||
case etB.kind
|
case etB.kind
|
||||||
of tyObject, tyTuple:
|
of tyObject, tyTuple:
|
||||||
if isImportedCppType(etB) and et.kind == tyGenericInst:
|
if isImportedCppType(etB) and et.kind == tyGenericInst:
|
||||||
|
|
@ -529,7 +516,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
# no restriction! We have a forward declaration for structs
|
# no restriction! We have a forward declaration for structs
|
||||||
let x = getUniqueType(etB)
|
let x = getUniqueType(etB)
|
||||||
let name = getTypeForward(m, x)
|
let name = getTypeForward(m, x)
|
||||||
result = con(name, "**")
|
result = con(name, "*" & star)
|
||||||
idTablePut(m.typeCache, t, result)
|
idTablePut(m.typeCache, t, result)
|
||||||
pushType(m, x)
|
pushType(m, x)
|
||||||
else:
|
else:
|
||||||
|
|
@ -677,7 +664,7 @@ proc genProcHeader(m: BModule, prc: PSym): PRope =
|
||||||
rettype, params: PRope
|
rettype, params: PRope
|
||||||
genCLineDir(result, prc.info)
|
genCLineDir(result, prc.info)
|
||||||
# using static is needed for inline procs
|
# using static is needed for inline procs
|
||||||
if gCmd != cmdCompileToLLVM and lfExportLib in prc.loc.flags:
|
if lfExportLib in prc.loc.flags:
|
||||||
if m.isHeaderFile:
|
if m.isHeaderFile:
|
||||||
result.app "N_LIB_IMPORT "
|
result.app "N_LIB_IMPORT "
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -25,15 +25,6 @@ when options.hasTinyCBackend:
|
||||||
var
|
var
|
||||||
generatedHeader: BModule
|
generatedHeader: BModule
|
||||||
|
|
||||||
proc ropeff(cformat, llvmformat: string, args: varargs[PRope]): PRope =
|
|
||||||
if gCmd == cmdCompileToLLVM: result = ropef(llvmformat, args)
|
|
||||||
else: result = ropef(cformat, args)
|
|
||||||
|
|
||||||
proc appff(dest: var PRope, cformat, llvmformat: string,
|
|
||||||
args: varargs[PRope]) =
|
|
||||||
if gCmd == cmdCompileToLLVM: appf(dest, llvmformat, args)
|
|
||||||
else: appf(dest, cformat, args)
|
|
||||||
|
|
||||||
proc addForwardedProc(m: BModule, prc: PSym) =
|
proc addForwardedProc(m: BModule, prc: PSym) =
|
||||||
m.forwardedProcs.add(prc)
|
m.forwardedProcs.add(prc)
|
||||||
inc(gForwardedProcsCounter)
|
inc(gForwardedProcsCounter)
|
||||||
|
|
@ -137,79 +128,8 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
|
||||||
if i - 1 >= start:
|
if i - 1 >= start:
|
||||||
app(result, substr(frmt, start, i - 1))
|
app(result, substr(frmt, start, i - 1))
|
||||||
|
|
||||||
const compileTimeRopeFmt = false
|
template rfmt(m: BModule, fmt: string, args: varargs[PRope]): expr =
|
||||||
|
ropecg(m, fmt, args)
|
||||||
when compileTimeRopeFmt:
|
|
||||||
import macros
|
|
||||||
|
|
||||||
type TFmtFragmentKind = enum
|
|
||||||
ffSym,
|
|
||||||
ffLit,
|
|
||||||
ffParam
|
|
||||||
|
|
||||||
type TFragment = object
|
|
||||||
case kind: TFmtFragmentKind
|
|
||||||
of ffSym, ffLit:
|
|
||||||
value: string
|
|
||||||
of ffParam:
|
|
||||||
intValue: int
|
|
||||||
|
|
||||||
iterator fmtStringFragments(s: string): tuple[kind: TFmtFragmentKind,
|
|
||||||
value: string,
|
|
||||||
intValue: int] =
|
|
||||||
# This is a bit less featured version of the ropecg's algorithm
|
|
||||||
# (be careful when replacing ropecg calls)
|
|
||||||
var
|
|
||||||
i = 0
|
|
||||||
length = s.len
|
|
||||||
|
|
||||||
while i < length:
|
|
||||||
var start = i
|
|
||||||
case s[i]
|
|
||||||
of '$':
|
|
||||||
let n = s[i+1]
|
|
||||||
case n
|
|
||||||
of '$':
|
|
||||||
inc i, 2
|
|
||||||
of '0'..'9':
|
|
||||||
# XXX: use the new case object construction syntax when it's ready
|
|
||||||
yield (kind: ffParam, value: "", intValue: n.ord - ord('1'))
|
|
||||||
inc i, 2
|
|
||||||
start = i
|
|
||||||
else:
|
|
||||||
inc i
|
|
||||||
of '#':
|
|
||||||
inc i
|
|
||||||
var j = i
|
|
||||||
while s[i] in IdentChars: inc i
|
|
||||||
yield (kind: ffSym, value: substr(s, j, i-1), intValue: 0)
|
|
||||||
start = i
|
|
||||||
else: discard
|
|
||||||
|
|
||||||
while i < length:
|
|
||||||
if s[i] != '$' and s[i] != '#': inc i
|
|
||||||
else: break
|
|
||||||
|
|
||||||
if i - 1 >= start:
|
|
||||||
yield (kind: ffLit, value: substr(s, start, i-1), intValue: 0)
|
|
||||||
|
|
||||||
macro rfmt(m: BModule, fmt: static[string], args: varargs[PRope]): expr =
|
|
||||||
## Experimental optimized rope-formatting operator
|
|
||||||
## The run-time code it produces will be very fast, but will it speed up
|
|
||||||
## the compilation of nimrod itself or will the macro execution time
|
|
||||||
## offset the gains?
|
|
||||||
result = newCall(bindSym"ropeConcat")
|
|
||||||
for frag in fmtStringFragments(fmt):
|
|
||||||
case frag.kind
|
|
||||||
of ffSym:
|
|
||||||
result.add(newCall(bindSym"cgsym", m, newStrLitNode(frag.value)))
|
|
||||||
of ffLit:
|
|
||||||
result.add(newCall(bindSym"~", newStrLitNode(frag.value)))
|
|
||||||
of ffParam:
|
|
||||||
result.add(args[frag.intValue])
|
|
||||||
else:
|
|
||||||
template rfmt(m: BModule, fmt: string, args: varargs[PRope]): expr =
|
|
||||||
ropecg(m, fmt, args)
|
|
||||||
|
|
||||||
proc appcg(m: BModule, c: var PRope, frmt: TFormatStr,
|
proc appcg(m: BModule, c: var PRope, frmt: TFormatStr,
|
||||||
args: varargs[PRope]) =
|
args: varargs[PRope]) =
|
||||||
|
|
@ -242,24 +162,14 @@ proc lineCg(p: BProc, s: TCProcSection, frmt: TFormatStr,
|
||||||
args: varargs[PRope]) =
|
args: varargs[PRope]) =
|
||||||
app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
|
app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
|
||||||
|
|
||||||
when compileTimeRopeFmt:
|
proc linefmt(p: BProc, s: TCProcSection, frmt: TFormatStr,
|
||||||
template linefmt(p: BProc, s: TCProcSection, frmt: TFormatStr,
|
args: varargs[PRope]) =
|
||||||
args: varargs[PRope]) =
|
app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
|
||||||
line(p, s, rfmt(p.module, frmt, args))
|
|
||||||
else:
|
|
||||||
proc linefmt(p: BProc, s: TCProcSection, frmt: TFormatStr,
|
|
||||||
args: varargs[PRope]) =
|
|
||||||
app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
|
|
||||||
|
|
||||||
proc appLineCg(p: BProc, r: var PRope, frmt: TFormatStr,
|
proc appLineCg(p: BProc, r: var PRope, frmt: TFormatStr,
|
||||||
args: varargs[PRope]) =
|
args: varargs[PRope]) =
|
||||||
app(r, indentLine(p, ropecg(p.module, frmt, args)))
|
app(r, indentLine(p, ropecg(p.module, frmt, args)))
|
||||||
|
|
||||||
proc lineFF(p: BProc, s: TCProcSection, cformat, llvmformat: string,
|
|
||||||
args: varargs[PRope]) =
|
|
||||||
if gCmd == cmdCompileToLLVM: lineF(p, s, llvmformat, args)
|
|
||||||
else: lineF(p, s, cformat, args)
|
|
||||||
|
|
||||||
proc safeLineNm(info: TLineInfo): int =
|
proc safeLineNm(info: TLineInfo): int =
|
||||||
result = toLinenumber(info)
|
result = toLinenumber(info)
|
||||||
if result < 0: result = 0 # negative numbers are not allowed in #line
|
if result < 0: result = 0 # negative numbers are not allowed in #line
|
||||||
|
|
@ -267,8 +177,8 @@ proc safeLineNm(info: TLineInfo): int =
|
||||||
proc genCLineDir(r: var PRope, filename: string, line: int) =
|
proc genCLineDir(r: var PRope, filename: string, line: int) =
|
||||||
assert line >= 0
|
assert line >= 0
|
||||||
if optLineDir in gOptions:
|
if optLineDir in gOptions:
|
||||||
appff(r, "$N#line $2 $1$N", "; line $2 \"$1\"$n",
|
appf(r, "$N#line $2 $1$N",
|
||||||
[toRope(makeSingleLineCString(filename)), toRope(line)])
|
[toRope(makeSingleLineCString(filename)), toRope(line)])
|
||||||
|
|
||||||
proc genCLineDir(r: var PRope, info: TLineInfo) =
|
proc genCLineDir(r: var PRope, info: TLineInfo) =
|
||||||
genCLineDir(r, info.toFullPath, info.safeLineNm)
|
genCLineDir(r, info.toFullPath, info.safeLineNm)
|
||||||
|
|
@ -443,29 +353,6 @@ proc deinitGCFrame(p: BProc): PRope =
|
||||||
if p.gcFrameId > 0:
|
if p.gcFrameId > 0:
|
||||||
result = ropecg(p.module,
|
result = ropecg(p.module,
|
||||||
"if (((NU)&GCFRAME) < 4096) #nimGCFrame(&GCFRAME);$n")
|
"if (((NU)&GCFRAME) < 4096) #nimGCFrame(&GCFRAME);$n")
|
||||||
|
|
||||||
proc cstringLit(p: BProc, r: var PRope, s: string): PRope =
|
|
||||||
if gCmd == cmdCompileToLLVM:
|
|
||||||
inc(p.module.labels)
|
|
||||||
inc(p.labels)
|
|
||||||
result = ropef("%LOC$1", [toRope(p.labels)])
|
|
||||||
appf(p.module.s[cfsData], "@C$1 = private constant [$2 x i8] $3$n",
|
|
||||||
[toRope(p.module.labels), toRope(len(s)), makeLLVMString(s)])
|
|
||||||
appf(r, "$1 = getelementptr [$2 x i8]* @C$3, %NI 0, %NI 0$n",
|
|
||||||
[result, toRope(len(s)), toRope(p.module.labels)])
|
|
||||||
else:
|
|
||||||
result = makeCString(s)
|
|
||||||
|
|
||||||
proc cstringLit(m: BModule, r: var PRope, s: string): PRope =
|
|
||||||
if gCmd == cmdCompileToLLVM:
|
|
||||||
inc(m.labels, 2)
|
|
||||||
result = ropef("%MOC$1", [toRope(m.labels - 1)])
|
|
||||||
appf(m.s[cfsData], "@MOC$1 = private constant [$2 x i8] $3$n",
|
|
||||||
[toRope(m.labels), toRope(len(s)), makeLLVMString(s)])
|
|
||||||
appf(r, "$1 = getelementptr [$2 x i8]* @MOC$3, %NI 0, %NI 0$n",
|
|
||||||
[result, toRope(len(s)), toRope(m.labels)])
|
|
||||||
else:
|
|
||||||
result = makeCString(s)
|
|
||||||
|
|
||||||
proc allocParam(p: BProc, s: PSym) =
|
proc allocParam(p: BProc, s: PSym) =
|
||||||
assert(s.kind == skParam)
|
assert(s.kind == skParam)
|
||||||
|
|
@ -507,7 +394,7 @@ proc localVarDecl(p: BProc; s: PSym): PRope =
|
||||||
result = ropef(s.cgDeclFrmt, result, s.loc.r)
|
result = ropef(s.cgDeclFrmt, result, s.loc.r)
|
||||||
|
|
||||||
proc assignLocalVar(p: BProc, s: PSym) =
|
proc assignLocalVar(p: BProc, s: PSym) =
|
||||||
#assert(s.loc.k == locNone) // not yet assigned
|
#assert(s.loc.k == locNone) # not yet assigned
|
||||||
# this need not be fullfilled for inline procs; they are regenerated
|
# this need not be fullfilled for inline procs; they are regenerated
|
||||||
# for each module that uses them!
|
# for each module that uses them!
|
||||||
let decl = localVarDecl(p, s).con(";" & tnl)
|
let decl = localVarDecl(p, s).con(";" & tnl)
|
||||||
|
|
@ -553,13 +440,11 @@ proc assignGlobalVar(p: BProc, s: PSym) =
|
||||||
{optStackTrace, optEndb}:
|
{optStackTrace, optEndb}:
|
||||||
appcg(p.module, p.module.s[cfsDebugInit],
|
appcg(p.module, p.module.s[cfsDebugInit],
|
||||||
"#dbgRegisterGlobal($1, &$2, $3);$n",
|
"#dbgRegisterGlobal($1, &$2, $3);$n",
|
||||||
[cstringLit(p, p.module.s[cfsDebugInit],
|
[makeCString(normalize(s.owner.name.s & '.' & s.name.s)),
|
||||||
normalize(s.owner.name.s & '.' & s.name.s)),
|
|
||||||
s.loc.r, genTypeInfo(p.module, s.typ)])
|
s.loc.r, genTypeInfo(p.module, s.typ)])
|
||||||
|
|
||||||
proc assignParam(p: BProc, s: PSym) =
|
proc assignParam(p: BProc, s: PSym) =
|
||||||
assert(s.loc.r != nil)
|
assert(s.loc.r != nil)
|
||||||
if sfAddrTaken in s.flags and gCmd == cmdCompileToLLVM: allocParam(p, s)
|
|
||||||
localDebugInfo(p, s)
|
localDebugInfo(p, s)
|
||||||
|
|
||||||
proc fillProcLoc(sym: PSym) =
|
proc fillProcLoc(sym: PSym) =
|
||||||
|
|
@ -653,7 +538,6 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
|
||||||
let isCall = isGetProcAddr(lib)
|
let isCall = isGetProcAddr(lib)
|
||||||
var extname = sym.loc.r
|
var extname = sym.loc.r
|
||||||
if not isCall: loadDynamicLib(m, lib)
|
if not isCall: loadDynamicLib(m, lib)
|
||||||
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
|
|
||||||
var tmp = mangleDynLibProc(sym)
|
var tmp = mangleDynLibProc(sym)
|
||||||
sym.loc.r = tmp # from now on we only need the internal name
|
sym.loc.r = tmp # from now on we only need the internal name
|
||||||
sym.typ.sym = nil # generate a new name
|
sym.typ.sym = nil # generate a new name
|
||||||
|
|
@ -669,7 +553,7 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
|
||||||
params.app(", ")
|
params.app(", ")
|
||||||
let load = ropef("\t$1 = ($2) ($3$4));$n",
|
let load = ropef("\t$1 = ($2) ($3$4));$n",
|
||||||
[tmp, getTypeDesc(m, sym.typ),
|
[tmp, getTypeDesc(m, sym.typ),
|
||||||
params, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))])
|
params, makeCString(ropeToStr(extname))])
|
||||||
var last = lastSon(n)
|
var last = lastSon(n)
|
||||||
if last.kind == nkHiddenStdConv: last = last.sons[1]
|
if last.kind == nkHiddenStdConv: last = last.sons[1]
|
||||||
internalAssert(last.kind == nkStrLit)
|
internalAssert(last.kind == nkStrLit)
|
||||||
|
|
@ -684,10 +568,8 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
|
||||||
appcg(m, m.s[cfsDynLibInit],
|
appcg(m, m.s[cfsDynLibInit],
|
||||||
"\t$1 = ($2) #nimGetProcAddr($3, $4);$n",
|
"\t$1 = ($2) #nimGetProcAddr($3, $4);$n",
|
||||||
[tmp, getTypeDesc(m, sym.typ),
|
[tmp, getTypeDesc(m, sym.typ),
|
||||||
lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))])
|
lib.name, makeCString(ropeToStr(extname))])
|
||||||
appff(m.s[cfsVars], "$2 $1;$n",
|
appf(m.s[cfsVars], "$2 $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)])
|
||||||
"$1 = linkonce global $2 zeroinitializer$n",
|
|
||||||
[sym.loc.r, getTypeDesc(m, sym.loc.t)])
|
|
||||||
|
|
||||||
proc varInDynamicLib(m: BModule, sym: PSym) =
|
proc varInDynamicLib(m: BModule, sym: PSym) =
|
||||||
var lib = sym.annex
|
var lib = sym.annex
|
||||||
|
|
@ -700,7 +582,7 @@ proc varInDynamicLib(m: BModule, sym: PSym) =
|
||||||
appcg(m, m.s[cfsDynLibInit],
|
appcg(m, m.s[cfsDynLibInit],
|
||||||
"$1 = ($2*) #nimGetProcAddr($3, $4);$n",
|
"$1 = ($2*) #nimGetProcAddr($3, $4);$n",
|
||||||
[tmp, getTypeDesc(m, sym.typ),
|
[tmp, getTypeDesc(m, sym.typ),
|
||||||
lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))])
|
lib.name, makeCString(ropeToStr(extname))])
|
||||||
appf(m.s[cfsVars], "$2* $1;$n",
|
appf(m.s[cfsVars], "$2* $1;$n",
|
||||||
[sym.loc.r, getTypeDesc(m, sym.loc.t)])
|
[sym.loc.r, getTypeDesc(m, sym.loc.t)])
|
||||||
|
|
||||||
|
|
@ -723,13 +605,13 @@ proc cgsym(m: BModule, name: string): PRope =
|
||||||
rawMessage(errSystemNeeds, name)
|
rawMessage(errSystemNeeds, name)
|
||||||
result = sym.loc.r
|
result = sym.loc.r
|
||||||
|
|
||||||
proc generateHeaders(m: BModule) =
|
proc generateHeaders(m: BModule) =
|
||||||
app(m.s[cfsHeaders], tnl & "#include \"nimbase.h\"" & tnl)
|
app(m.s[cfsHeaders], tnl & "#include \"nimbase.h\"" & tnl)
|
||||||
var it = PStrEntry(m.headerFiles.head)
|
var it = PStrEntry(m.headerFiles.head)
|
||||||
while it != nil:
|
while it != nil:
|
||||||
if it.data[0] notin {'\"', '<'}:
|
if it.data[0] notin {'\"', '<'}:
|
||||||
appf(m.s[cfsHeaders], "$N#include \"$1\"$N", [toRope(it.data)])
|
appf(m.s[cfsHeaders], "$N#include \"$1\"$N", [toRope(it.data)])
|
||||||
else:
|
else:
|
||||||
appf(m.s[cfsHeaders], "$N#include $1$N", [toRope(it.data)])
|
appf(m.s[cfsHeaders], "$N#include $1$N", [toRope(it.data)])
|
||||||
it = PStrEntry(it.next)
|
it = PStrEntry(it.next)
|
||||||
|
|
||||||
|
|
@ -802,16 +684,17 @@ proc genProcAux(m: BModule, prc: PSym) =
|
||||||
app(generatedProc, initGCFrame(p))
|
app(generatedProc, initGCFrame(p))
|
||||||
if optStackTrace in prc.options:
|
if optStackTrace in prc.options:
|
||||||
app(generatedProc, p.s(cpsLocals))
|
app(generatedProc, p.s(cpsLocals))
|
||||||
var procname = cstringLit(p, generatedProc, prc.name.s)
|
var procname = makeCString(prc.name.s)
|
||||||
app(generatedProc, initFrame(p, procname, prc.info.quotedFilename))
|
app(generatedProc, initFrame(p, procname, prc.info.quotedFilename))
|
||||||
else:
|
else:
|
||||||
app(generatedProc, p.s(cpsLocals))
|
app(generatedProc, p.s(cpsLocals))
|
||||||
if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM):
|
if optProfiler in prc.options:
|
||||||
# invoke at proc entry for recursion:
|
# invoke at proc entry for recursion:
|
||||||
appcg(p, cpsInit, "\t#nimProfile();$n", [])
|
appcg(p, cpsInit, "\t#nimProfile();$n", [])
|
||||||
|
if p.beforeRetNeeded: app(generatedProc, "{")
|
||||||
app(generatedProc, p.s(cpsInit))
|
app(generatedProc, p.s(cpsInit))
|
||||||
app(generatedProc, p.s(cpsStmts))
|
app(generatedProc, p.s(cpsStmts))
|
||||||
if p.beforeRetNeeded: app(generatedProc, ~"\tBeforeRet: ;$n")
|
if p.beforeRetNeeded: app(generatedProc, ~"\t}BeforeRet: ;$n")
|
||||||
app(generatedProc, deinitGCFrame(p))
|
app(generatedProc, deinitGCFrame(p))
|
||||||
if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
|
if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
|
||||||
app(generatedProc, returnStmt)
|
app(generatedProc, returnStmt)
|
||||||
|
|
@ -831,7 +714,6 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
||||||
not containsOrIncl(m.declaredThings, sym.id):
|
not containsOrIncl(m.declaredThings, sym.id):
|
||||||
app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
|
app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
|
||||||
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
|
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
|
||||||
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
|
|
||||||
elif not containsOrIncl(m.declaredProtos, sym.id):
|
elif not containsOrIncl(m.declaredProtos, sym.id):
|
||||||
var header = genProcHeader(m, sym)
|
var header = genProcHeader(m, sym)
|
||||||
if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
|
if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
|
||||||
|
|
@ -929,21 +811,17 @@ proc addIntTypes(result: var PRope) {.inline.} =
|
||||||
|
|
||||||
proc getCopyright(cfile: string): PRope =
|
proc getCopyright(cfile: string): PRope =
|
||||||
if optCompileOnly in gGlobalOptions:
|
if optCompileOnly in gGlobalOptions:
|
||||||
result = ropeff("/* Generated by Nim Compiler v$1 */$N" &
|
result = ropef("/* Generated by Nim Compiler v$1 */$N" &
|
||||||
"/* (c) 2015 Andreas Rumpf */$N" &
|
"/* (c) 2015 Andreas Rumpf */$N" &
|
||||||
"/* The generated code is subject to the original license. */$N",
|
"/* The generated code is subject to the original license. */$N",
|
||||||
"; Generated by Nim Compiler v$1$N" &
|
[toRope(VersionAsString)])
|
||||||
"; (c) 2012 Andreas Rumpf$N", [toRope(VersionAsString)])
|
|
||||||
else:
|
else:
|
||||||
result = ropeff("/* Generated by Nim Compiler v$1 */$N" &
|
result = ropef("/* Generated by Nim Compiler v$1 */$N" &
|
||||||
"/* (c) 2015 Andreas Rumpf */$N" &
|
"/* (c) 2015 Andreas Rumpf */$N" &
|
||||||
"/* The generated code is subject to the original license. */$N" &
|
"/* The generated code is subject to the original license. */$N" &
|
||||||
"/* Compiled for: $2, $3, $4 */$N" &
|
"/* Compiled for: $2, $3, $4 */$N" &
|
||||||
"/* Command for C compiler:$n $5 */$N",
|
"/* Command for C compiler:$n $5 */$N",
|
||||||
"; Generated by Nim Compiler v$1$N" &
|
[toRope(VersionAsString),
|
||||||
"; (c) 2015 Andreas Rumpf$N" &
|
|
||||||
"; Compiled for: $2, $3, $4$N" &
|
|
||||||
"; Command for LLVM compiler:$N $5$N", [toRope(VersionAsString),
|
|
||||||
toRope(platform.OS[targetOS].name),
|
toRope(platform.OS[targetOS].name),
|
||||||
toRope(platform.CPU[targetCPU].name),
|
toRope(platform.CPU[targetCPU].name),
|
||||||
toRope(extccomp.CC[extccomp.cCompiler].name),
|
toRope(extccomp.CC[extccomp.cCompiler].name),
|
||||||
|
|
@ -1094,13 +972,11 @@ proc registerModuleToMain(m: PSym) =
|
||||||
var
|
var
|
||||||
init = m.getInitName
|
init = m.getInitName
|
||||||
datInit = m.getDatInitName
|
datInit = m.getDatInitName
|
||||||
appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
|
appf(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N", [init])
|
||||||
"declare void $1() noinline$N", [init])
|
appf(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N", [datInit])
|
||||||
appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
|
|
||||||
"declare void $1() noinline$N", [datInit])
|
|
||||||
if sfSystemModule notin m.flags:
|
if sfSystemModule notin m.flags:
|
||||||
appff(mainDatInit, "\t$1();$N", "call void ()* $1$n", [datInit])
|
appf(mainDatInit, "\t$1();$N", [datInit])
|
||||||
let initCall = ropeff("\t$1();$N", "call void ()* $1$n", [init])
|
let initCall = ropef("\t$1();$N", [init])
|
||||||
if sfMainModule in m.flags:
|
if sfMainModule in m.flags:
|
||||||
app(mainModInit, initCall)
|
app(mainModInit, initCall)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1108,8 +984,7 @@ proc registerModuleToMain(m: PSym) =
|
||||||
|
|
||||||
proc genInitCode(m: BModule) =
|
proc genInitCode(m: BModule) =
|
||||||
var initname = getInitName(m.module)
|
var initname = getInitName(m.module)
|
||||||
var prc = ropeff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
|
var prc = ropef("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N", [initname])
|
||||||
"define void $1() noinline {$n", [initname])
|
|
||||||
if m.typeNodes > 0:
|
if m.typeNodes > 0:
|
||||||
appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
|
appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
|
||||||
[m.typeNodesName, toRope(m.typeNodes)])
|
[m.typeNodesName, toRope(m.typeNodes)])
|
||||||
|
|
@ -1130,7 +1005,7 @@ proc genInitCode(m: BModule) =
|
||||||
# declare it nevertheless:
|
# declare it nevertheless:
|
||||||
m.frameDeclared = true
|
m.frameDeclared = true
|
||||||
if not m.preventStackTrace:
|
if not m.preventStackTrace:
|
||||||
var procname = cstringLit(m.initProc, prc, m.module.name.s)
|
var procname = makeCString(m.module.name.s)
|
||||||
app(prc, initFrame(m.initProc, procname, m.module.info.quotedFilename))
|
app(prc, initFrame(m.initProc, procname, m.module.info.quotedFilename))
|
||||||
else:
|
else:
|
||||||
app(prc, ~"\tTFrame F; F.len = 0;$N")
|
app(prc, ~"\tTFrame F; F.len = 0;$N")
|
||||||
|
|
@ -1151,8 +1026,8 @@ proc genInitCode(m: BModule) =
|
||||||
app(prc, deinitGCFrame(m.initProc))
|
app(prc, deinitGCFrame(m.initProc))
|
||||||
appf(prc, "}$N$N")
|
appf(prc, "}$N$N")
|
||||||
|
|
||||||
prc.appff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
|
prc.appf("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
|
||||||
"define void $1() noinline {$n", [getDatInitName(m.module)])
|
[getDatInitName(m.module)])
|
||||||
|
|
||||||
for i in cfsTypeInit1..cfsDynLibInit:
|
for i in cfsTypeInit1..cfsDynLibInit:
|
||||||
app(prc, genSectionStart(i))
|
app(prc, genSectionStart(i))
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,9 @@ type
|
||||||
maxFrameLen*: int # max length of frame descriptor
|
maxFrameLen*: int # max length of frame descriptor
|
||||||
module*: BModule # used to prevent excessive parameter passing
|
module*: BModule # used to prevent excessive parameter passing
|
||||||
withinLoop*: int # > 0 if we are within a loop
|
withinLoop*: int # > 0 if we are within a loop
|
||||||
|
splitDecls*: int # > 0 if we are in some context for C++ that
|
||||||
|
# requires 'T x = T()' to become 'T x; x = T()'
|
||||||
|
# (yes, C++ is weird like that)
|
||||||
gcFrameId*: Natural # for the GC stack marking
|
gcFrameId*: Natural # for the GC stack marking
|
||||||
gcFrameType*: PRope # the struct {} we put the GC markers into
|
gcFrameType*: PRope # the struct {} we put the GC markers into
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo)
|
||||||
|
|
||||||
const
|
const
|
||||||
HelpMessage = "Nim Compiler Version $1 (" & CompileDate & ") [$2: $3]\n" &
|
HelpMessage = "Nim Compiler Version $1 (" & CompileDate & ") [$2: $3]\n" &
|
||||||
"Copyright (c) 2006-2014 by Andreas Rumpf\n"
|
"Copyright (c) 2006-2015 by Andreas Rumpf\n"
|
||||||
|
|
||||||
const
|
const
|
||||||
Usage = slurp"doc/basicopt.txt".replace("//", "")
|
Usage = slurp"doc/basicopt.txt".replace("//", "")
|
||||||
|
|
|
||||||
|
|
@ -428,13 +428,17 @@ proc addFileToLink*(filename: string) =
|
||||||
prependStr(toLink, filename)
|
prependStr(toLink, filename)
|
||||||
# BUGFIX: was ``appendStr``
|
# BUGFIX: was ``appendStr``
|
||||||
|
|
||||||
proc execExternalProgram*(cmd: string, prettyCmd = "") =
|
proc execWithEcho(cmd: string, prettyCmd = ""): int =
|
||||||
if optListCmd in gGlobalOptions or gVerbosity > 0:
|
if optListCmd in gGlobalOptions or gVerbosity > 0:
|
||||||
if prettyCmd != "":
|
if prettyCmd != "":
|
||||||
msgWriteln(prettyCmd)
|
msgWriteln(prettyCmd)
|
||||||
else:
|
else:
|
||||||
msgWriteln(cmd)
|
msgWriteln(cmd)
|
||||||
if execCmd(cmd) != 0: rawMessage(errExecutionOfProgramFailed, "")
|
result = execCmd(cmd)
|
||||||
|
|
||||||
|
proc execExternalProgram*(cmd: string, prettyCmd = "") =
|
||||||
|
if execWithEcho(cmd, prettyCmd) != 0:
|
||||||
|
rawMessage(errExecutionOfProgramFailed, "")
|
||||||
|
|
||||||
proc generateScript(projectFile: string, script: PRope) =
|
proc generateScript(projectFile: string, script: PRope) =
|
||||||
let (dir, name, ext) = splitFile(projectFile)
|
let (dir, name, ext) = splitFile(projectFile)
|
||||||
|
|
@ -622,7 +626,9 @@ proc callCCompiler*(projectfile: string) =
|
||||||
if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors()
|
if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors()
|
||||||
var res = 0
|
var res = 0
|
||||||
if gNumberOfProcessors <= 1:
|
if gNumberOfProcessors <= 1:
|
||||||
for i in countup(0, high(cmds)): res = max(execCmd(cmds[i]), res)
|
for i in countup(0, high(cmds)):
|
||||||
|
res = execWithEcho(cmds[i])
|
||||||
|
if res != 0: rawMessage(errExecutionOfProgramFailed, [])
|
||||||
elif optListCmd in gGlobalOptions or gVerbosity > 1:
|
elif optListCmd in gGlobalOptions or gVerbosity > 1:
|
||||||
res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams},
|
res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams},
|
||||||
gNumberOfProcessors)
|
gNumberOfProcessors)
|
||||||
|
|
|
||||||
|
|
@ -30,47 +30,32 @@ type
|
||||||
|
|
||||||
PLLStream* = ref TLLStream
|
PLLStream* = ref TLLStream
|
||||||
|
|
||||||
proc llStreamOpen*(data: string): PLLStream
|
proc llStreamOpen*(data: string): PLLStream =
|
||||||
proc llStreamOpen*(f: var File): PLLStream
|
|
||||||
proc llStreamOpen*(filename: string, mode: FileMode): PLLStream
|
|
||||||
proc llStreamOpen*(): PLLStream
|
|
||||||
proc llStreamOpenStdIn*(): PLLStream
|
|
||||||
proc llStreamClose*(s: PLLStream)
|
|
||||||
proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int
|
|
||||||
proc llStreamReadLine*(s: PLLStream, line: var string): bool
|
|
||||||
proc llStreamReadAll*(s: PLLStream): string
|
|
||||||
proc llStreamWrite*(s: PLLStream, data: string)
|
|
||||||
proc llStreamWrite*(s: PLLStream, data: char)
|
|
||||||
proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int)
|
|
||||||
proc llStreamWriteln*(s: PLLStream, data: string)
|
|
||||||
# implementation
|
|
||||||
|
|
||||||
proc llStreamOpen(data: string): PLLStream =
|
|
||||||
new(result)
|
new(result)
|
||||||
result.s = data
|
result.s = data
|
||||||
result.kind = llsString
|
result.kind = llsString
|
||||||
|
|
||||||
proc llStreamOpen(f: var File): PLLStream =
|
proc llStreamOpen*(f: var File): PLLStream =
|
||||||
new(result)
|
new(result)
|
||||||
result.f = f
|
result.f = f
|
||||||
result.kind = llsFile
|
result.kind = llsFile
|
||||||
|
|
||||||
proc llStreamOpen(filename: string, mode: FileMode): PLLStream =
|
proc llStreamOpen*(filename: string, mode: FileMode): PLLStream =
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = llsFile
|
result.kind = llsFile
|
||||||
if not open(result.f, filename, mode): result = nil
|
if not open(result.f, filename, mode): result = nil
|
||||||
|
|
||||||
proc llStreamOpen(): PLLStream =
|
proc llStreamOpen*(): PLLStream =
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = llsNone
|
result.kind = llsNone
|
||||||
|
|
||||||
proc llStreamOpenStdIn(): PLLStream =
|
proc llStreamOpenStdIn*(): PLLStream =
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = llsStdIn
|
result.kind = llsStdIn
|
||||||
result.s = ""
|
result.s = ""
|
||||||
result.lineOffset = -1
|
result.lineOffset = -1
|
||||||
|
|
||||||
proc llStreamClose(s: PLLStream) =
|
proc llStreamClose*(s: PLLStream) =
|
||||||
case s.kind
|
case s.kind
|
||||||
of llsNone, llsString, llsStdIn:
|
of llsNone, llsString, llsStdIn:
|
||||||
discard
|
discard
|
||||||
|
|
@ -130,7 +115,7 @@ proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
|
||||||
copyMem(buf, addr(s.s[s.rd]), result)
|
copyMem(buf, addr(s.s[s.rd]), result)
|
||||||
inc(s.rd, result)
|
inc(s.rd, result)
|
||||||
|
|
||||||
proc llStreamRead(s: PLLStream, buf: pointer, bufLen: int): int =
|
proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int =
|
||||||
case s.kind
|
case s.kind
|
||||||
of llsNone:
|
of llsNone:
|
||||||
result = 0
|
result = 0
|
||||||
|
|
@ -144,7 +129,7 @@ proc llStreamRead(s: PLLStream, buf: pointer, bufLen: int): int =
|
||||||
of llsStdIn:
|
of llsStdIn:
|
||||||
result = llReadFromStdin(s, buf, bufLen)
|
result = llReadFromStdin(s, buf, bufLen)
|
||||||
|
|
||||||
proc llStreamReadLine(s: PLLStream, line: var string): bool =
|
proc llStreamReadLine*(s: PLLStream, line: var string): bool =
|
||||||
setLen(line, 0)
|
setLen(line, 0)
|
||||||
case s.kind
|
case s.kind
|
||||||
of llsNone:
|
of llsNone:
|
||||||
|
|
@ -168,7 +153,7 @@ proc llStreamReadLine(s: PLLStream, line: var string): bool =
|
||||||
of llsStdIn:
|
of llsStdIn:
|
||||||
result = readLine(stdin, line)
|
result = readLine(stdin, line)
|
||||||
|
|
||||||
proc llStreamWrite(s: PLLStream, data: string) =
|
proc llStreamWrite*(s: PLLStream, data: string) =
|
||||||
case s.kind
|
case s.kind
|
||||||
of llsNone, llsStdIn:
|
of llsNone, llsStdIn:
|
||||||
discard
|
discard
|
||||||
|
|
@ -178,11 +163,11 @@ proc llStreamWrite(s: PLLStream, data: string) =
|
||||||
of llsFile:
|
of llsFile:
|
||||||
write(s.f, data)
|
write(s.f, data)
|
||||||
|
|
||||||
proc llStreamWriteln(s: PLLStream, data: string) =
|
proc llStreamWriteln*(s: PLLStream, data: string) =
|
||||||
llStreamWrite(s, data)
|
llStreamWrite(s, data)
|
||||||
llStreamWrite(s, "\n")
|
llStreamWrite(s, "\n")
|
||||||
|
|
||||||
proc llStreamWrite(s: PLLStream, data: char) =
|
proc llStreamWrite*(s: PLLStream, data: char) =
|
||||||
var c: char
|
var c: char
|
||||||
case s.kind
|
case s.kind
|
||||||
of llsNone, llsStdIn:
|
of llsNone, llsStdIn:
|
||||||
|
|
@ -194,7 +179,7 @@ proc llStreamWrite(s: PLLStream, data: char) =
|
||||||
c = data
|
c = data
|
||||||
discard writeBuffer(s.f, addr(c), sizeof(c))
|
discard writeBuffer(s.f, addr(c), sizeof(c))
|
||||||
|
|
||||||
proc llStreamWrite(s: PLLStream, buf: pointer, buflen: int) =
|
proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int) =
|
||||||
case s.kind
|
case s.kind
|
||||||
of llsNone, llsStdIn:
|
of llsNone, llsStdIn:
|
||||||
discard
|
discard
|
||||||
|
|
@ -206,7 +191,7 @@ proc llStreamWrite(s: PLLStream, buf: pointer, buflen: int) =
|
||||||
of llsFile:
|
of llsFile:
|
||||||
discard writeBuffer(s.f, buf, buflen)
|
discard writeBuffer(s.f, buf, buflen)
|
||||||
|
|
||||||
proc llStreamReadAll(s: PLLStream): string =
|
proc llStreamReadAll*(s: PLLStream): string =
|
||||||
const
|
const
|
||||||
bufSize = 2048
|
bufSize = 2048
|
||||||
case s.kind
|
case s.kind
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,6 @@ proc mainCommand* =
|
||||||
commandCompileToC()
|
commandCompileToC()
|
||||||
of "cpp", "compiletocpp":
|
of "cpp", "compiletocpp":
|
||||||
gCmd = cmdCompileToCpp
|
gCmd = cmdCompileToCpp
|
||||||
if cCompiler == ccGcc: setCC("gcc")
|
|
||||||
defineSymbol("cpp")
|
defineSymbol("cpp")
|
||||||
commandCompileToC()
|
commandCompileToC()
|
||||||
of "objc", "compiletooc":
|
of "objc", "compiletooc":
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ type
|
||||||
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
|
||||||
warnUnknownSubstitutionX, warnLanguageXNotSupported,
|
warnUnknownSubstitutionX, warnLanguageXNotSupported,
|
||||||
warnFieldXNotSupported, warnCommentXIgnored,
|
warnFieldXNotSupported, warnCommentXIgnored,
|
||||||
warnNilStatement, warnAnalysisLoophole,
|
warnNilStatement, warnTypelessParam,
|
||||||
warnDifferentHeaps, warnWriteToForeignHeap, warnUnsafeCode,
|
warnDifferentHeaps, warnWriteToForeignHeap, warnUnsafeCode,
|
||||||
warnEachIdentIsTuple, warnShadowIdent,
|
warnEachIdentIsTuple, warnShadowIdent,
|
||||||
warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
|
warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
|
||||||
|
|
@ -311,7 +311,7 @@ const
|
||||||
errXOnlyAtModuleScope: "\'$1\' is only allowed at top level",
|
errXOnlyAtModuleScope: "\'$1\' is only allowed at top level",
|
||||||
errXNeedsParamObjectType: "'$1' needs a parameter that has an object type",
|
errXNeedsParamObjectType: "'$1' needs a parameter that has an object type",
|
||||||
errTemplateInstantiationTooNested: "template/macro instantiation too nested",
|
errTemplateInstantiationTooNested: "template/macro instantiation too nested",
|
||||||
errInstantiationFrom: "instantiation from here",
|
errInstantiationFrom: "template/generic instantiation from here",
|
||||||
errInvalidIndexValueForTuple: "invalid index value for tuple subscript",
|
errInvalidIndexValueForTuple: "invalid index value for tuple subscript",
|
||||||
errCommandExpectsFilename: "command expects a filename argument",
|
errCommandExpectsFilename: "command expects a filename argument",
|
||||||
errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file",
|
errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file",
|
||||||
|
|
@ -376,7 +376,7 @@ const
|
||||||
warnFieldXNotSupported: "field \'$1\' not supported [FieldXNotSupported]",
|
warnFieldXNotSupported: "field \'$1\' not supported [FieldXNotSupported]",
|
||||||
warnCommentXIgnored: "comment \'$1\' ignored [CommentXIgnored]",
|
warnCommentXIgnored: "comment \'$1\' ignored [CommentXIgnored]",
|
||||||
warnNilStatement: "'nil' statement is deprecated; use an empty 'discard' statement instead [NilStmt]",
|
warnNilStatement: "'nil' statement is deprecated; use an empty 'discard' statement instead [NilStmt]",
|
||||||
warnAnalysisLoophole: "thread analysis incomplete due to unknown call '$1' [AnalysisLoophole]",
|
warnTypelessParam: "'$1' has no type. Typeless parameters are deprecated; only allowed for 'template' [TypelessParam]",
|
||||||
warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]",
|
warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]",
|
||||||
warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]",
|
warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]",
|
||||||
warnUnsafeCode: "unsafe code: '$1' [UnsafeCode]",
|
warnUnsafeCode: "unsafe code: '$1' [UnsafeCode]",
|
||||||
|
|
@ -418,7 +418,7 @@ const
|
||||||
"RedefinitionOfLabel", "UnknownSubstitutionX",
|
"RedefinitionOfLabel", "UnknownSubstitutionX",
|
||||||
"LanguageXNotSupported", "FieldXNotSupported",
|
"LanguageXNotSupported", "FieldXNotSupported",
|
||||||
"CommentXIgnored", "NilStmt",
|
"CommentXIgnored", "NilStmt",
|
||||||
"AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap",
|
"TypelessParam", "DifferentHeaps", "WriteToForeignHeap",
|
||||||
"UnsafeCode", "EachIdentIsTuple", "ShadowIdent",
|
"UnsafeCode", "EachIdentIsTuple", "ShadowIdent",
|
||||||
"ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
|
"ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
|
||||||
"GcMem", "Destructor", "LockLevel", "User"]
|
"GcMem", "Destructor", "LockLevel", "User"]
|
||||||
|
|
@ -460,7 +460,7 @@ type
|
||||||
|
|
||||||
TLineInfo*{.final.} = object # This is designed to be as small as possible,
|
TLineInfo*{.final.} = object # This is designed to be as small as possible,
|
||||||
# because it is used
|
# because it is used
|
||||||
# in syntax nodes. We safe space here by using
|
# in syntax nodes. We save space here by using
|
||||||
# two int16 and an int32.
|
# two int16 and an int32.
|
||||||
# On 64 bit and on 32 bit systems this is
|
# On 64 bit and on 32 bit systems this is
|
||||||
# only 8 bytes.
|
# only 8 bytes.
|
||||||
|
|
@ -522,7 +522,7 @@ proc newFileInfo(fullPath, projPath: string): TFileInfo =
|
||||||
if optEmbedOrigSrc in gGlobalOptions or true:
|
if optEmbedOrigSrc in gGlobalOptions or true:
|
||||||
result.lines = @[]
|
result.lines = @[]
|
||||||
|
|
||||||
proc fileInfoIdx*(filename: string): int32 =
|
proc fileInfoIdx*(filename: string; isKnownFile: var bool): int32 =
|
||||||
var
|
var
|
||||||
canon: string
|
canon: string
|
||||||
pseudoPath = false
|
pseudoPath = false
|
||||||
|
|
@ -539,11 +539,16 @@ proc fileInfoIdx*(filename: string): int32 =
|
||||||
if filenameToIndexTbl.hasKey(canon):
|
if filenameToIndexTbl.hasKey(canon):
|
||||||
result = filenameToIndexTbl[canon]
|
result = filenameToIndexTbl[canon]
|
||||||
else:
|
else:
|
||||||
|
isKnownFile = false
|
||||||
result = fileInfos.len.int32
|
result = fileInfos.len.int32
|
||||||
fileInfos.add(newFileInfo(canon, if pseudoPath: filename
|
fileInfos.add(newFileInfo(canon, if pseudoPath: filename
|
||||||
else: canon.shortenDir))
|
else: canon.shortenDir))
|
||||||
filenameToIndexTbl[canon] = result
|
filenameToIndexTbl[canon] = result
|
||||||
|
|
||||||
|
proc fileInfoIdx*(filename: string): int32 =
|
||||||
|
var dummy: bool
|
||||||
|
result = fileInfoIdx(filename, dummy)
|
||||||
|
|
||||||
proc newLineInfo*(fileInfoIdx: int32, line, col: int): TLineInfo =
|
proc newLineInfo*(fileInfoIdx: int32, line, col: int): TLineInfo =
|
||||||
result.fileIndex = fileInfoIdx
|
result.fileIndex = fileInfoIdx
|
||||||
result.line = int16(line)
|
result.line = int16(line)
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer,
|
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer,
|
||||||
options, idents, wordrecg
|
options, idents, wordrecg, strtabs
|
||||||
|
|
||||||
# ---------------- configuration file parser -----------------------------
|
# ---------------- configuration file parser -----------------------------
|
||||||
# we use Nim's scanner here to safe space and work
|
# we use Nim's scanner here to save space and work
|
||||||
|
|
||||||
proc ppGetTok(L: var TLexer, tok: var TToken) =
|
proc ppGetTok(L: var TLexer, tok: var TToken) =
|
||||||
# simple filter
|
# simple filter
|
||||||
|
|
@ -82,17 +82,17 @@ proc doElif(L: var TLexer, tok: var TToken) =
|
||||||
proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest) =
|
proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest) =
|
||||||
var nestedIfs = 0
|
var nestedIfs = 0
|
||||||
while true:
|
while true:
|
||||||
if (tok.ident != nil) and (tok.ident.s == "@"):
|
if tok.ident != nil and tok.ident.s == "@":
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
case whichKeyword(tok.ident)
|
case whichKeyword(tok.ident)
|
||||||
of wIf:
|
of wIf:
|
||||||
inc(nestedIfs)
|
inc(nestedIfs)
|
||||||
of wElse:
|
of wElse:
|
||||||
if (dest == jdElseEndif) and (nestedIfs == 0):
|
if dest == jdElseEndif and nestedIfs == 0:
|
||||||
doElse(L, tok)
|
doElse(L, tok)
|
||||||
break
|
break
|
||||||
of wElif:
|
of wElif:
|
||||||
if (dest == jdElseEndif) and (nestedIfs == 0):
|
if dest == jdElseEndif and nestedIfs == 0:
|
||||||
doElif(L, tok)
|
doElif(L, tok)
|
||||||
break
|
break
|
||||||
of wEnd:
|
of wEnd:
|
||||||
|
|
@ -119,9 +119,10 @@ proc parseDirective(L: var TLexer, tok: var TToken) =
|
||||||
of wElif: doElif(L, tok)
|
of wElif: doElif(L, tok)
|
||||||
of wElse: doElse(L, tok)
|
of wElse: doElse(L, tok)
|
||||||
of wEnd: doEnd(L, tok)
|
of wEnd: doEnd(L, tok)
|
||||||
of wWrite:
|
of wWrite:
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
msgs.msgWriteln(tokToStr(tok))
|
msgs.msgWriteln(strtabs.`%`(tokToStr(tok), options.gConfigVars,
|
||||||
|
{useEnvironment, useKey}))
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
else:
|
else:
|
||||||
case tok.ident.s.normalize
|
case tok.ident.s.normalize
|
||||||
|
|
@ -157,7 +158,7 @@ proc checkSymbol(L: TLexer, tok: TToken) =
|
||||||
proc parseAssignment(L: var TLexer, tok: var TToken) =
|
proc parseAssignment(L: var TLexer, tok: var TToken) =
|
||||||
if tok.ident.id == getIdent("-").id or tok.ident.id == getIdent("--").id:
|
if tok.ident.id == getIdent("-").id or tok.ident.id == getIdent("--").id:
|
||||||
confTok(L, tok) # skip unnecessary prefix
|
confTok(L, tok) # skip unnecessary prefix
|
||||||
var info = getLineInfo(L, tok) # safe for later in case of an error
|
var info = getLineInfo(L, tok) # save for later in case of an error
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
var s = tokToStr(tok)
|
var s = tokToStr(tok)
|
||||||
confTok(L, tok) # skip symbol
|
confTok(L, tok) # skip symbol
|
||||||
|
|
@ -178,9 +179,10 @@ proc parseAssignment(L: var TLexer, tok: var TToken) =
|
||||||
if tok.tokType == tkBracketRi: confTok(L, tok)
|
if tok.tokType == tkBracketRi: confTok(L, tok)
|
||||||
else: lexMessage(L, errTokenExpected, "']'")
|
else: lexMessage(L, errTokenExpected, "']'")
|
||||||
add(val, ']')
|
add(val, ']')
|
||||||
if tok.tokType in {tkColon, tkEquals}:
|
let percent = tok.ident.id == getIdent("%=").id
|
||||||
|
if tok.tokType in {tkColon, tkEquals} or percent:
|
||||||
if len(val) > 0: add(val, ':')
|
if len(val) > 0: add(val, ':')
|
||||||
confTok(L, tok) # skip ':' or '='
|
confTok(L, tok) # skip ':' or '=' or '%'
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
add(val, tokToStr(tok))
|
add(val, tokToStr(tok))
|
||||||
confTok(L, tok) # skip symbol
|
confTok(L, tok) # skip symbol
|
||||||
|
|
@ -189,7 +191,11 @@ proc parseAssignment(L: var TLexer, tok: var TToken) =
|
||||||
checkSymbol(L, tok)
|
checkSymbol(L, tok)
|
||||||
add(val, tokToStr(tok))
|
add(val, tokToStr(tok))
|
||||||
confTok(L, tok)
|
confTok(L, tok)
|
||||||
processSwitch(s, val, passPP, info)
|
if percent:
|
||||||
|
processSwitch(s, strtabs.`%`(val, options.gConfigVars,
|
||||||
|
{useEnvironment, useEmpty}), passPP, info)
|
||||||
|
else:
|
||||||
|
processSwitch(s, val, passPP, info)
|
||||||
|
|
||||||
proc readConfigFile(filename: string) =
|
proc readConfigFile(filename: string) =
|
||||||
var
|
var
|
||||||
|
|
@ -246,6 +252,11 @@ proc loadConfigs*(cfg: string) =
|
||||||
|
|
||||||
if gProjectName.len != 0:
|
if gProjectName.len != 0:
|
||||||
# new project wide config file:
|
# new project wide config file:
|
||||||
let projectConfig = changeFileExt(gProjectFull, "nim.cfg")
|
var projectConfig = changeFileExt(gProjectFull, "nimcfg")
|
||||||
if fileExists(projectConfig): readConfigFile(projectConfig)
|
if not fileExists(projectConfig):
|
||||||
else: readConfigFile(changeFileExt(gProjectFull, "nimrod.cfg"))
|
projectConfig = changeFileExt(gProjectFull, "nim.cfg")
|
||||||
|
if not fileExists(projectConfig):
|
||||||
|
projectConfig = changeFileExt(gProjectFull, "nimrod.cfg")
|
||||||
|
if fileExists(projectConfig):
|
||||||
|
rawMessage(warnDeprecated, projectConfig)
|
||||||
|
readConfigFile(projectConfig)
|
||||||
|
|
|
||||||
|
|
@ -87,8 +87,9 @@ proc action(cmd: string) =
|
||||||
i += skipWhile(cmd, seps, i)
|
i += skipWhile(cmd, seps, i)
|
||||||
i += parseInt(cmd, col, i)
|
i += parseInt(cmd, col, i)
|
||||||
|
|
||||||
|
var isKnownFile = true
|
||||||
if orig.len == 0: err()
|
if orig.len == 0: err()
|
||||||
let dirtyIdx = orig.fileInfoIdx
|
let dirtyIdx = orig.fileInfoIdx(isKnownFile)
|
||||||
|
|
||||||
if dirtyfile.len != 0: msgs.setDirtyFile(dirtyIdx, dirtyfile)
|
if dirtyfile.len != 0: msgs.setDirtyFile(dirtyIdx, dirtyfile)
|
||||||
else: msgs.setDirtyFile(dirtyIdx, nil)
|
else: msgs.setDirtyFile(dirtyIdx, nil)
|
||||||
|
|
@ -99,7 +100,10 @@ proc action(cmd: string) =
|
||||||
gTrackPos = newLineInfo(dirtyIdx, line, col)
|
gTrackPos = newLineInfo(dirtyIdx, line, col)
|
||||||
#echo dirtyfile, gDirtyBufferIdx, " project ", gProjectMainIdx
|
#echo dirtyfile, gDirtyBufferIdx, " project ", gProjectMainIdx
|
||||||
gErrorCounter = 0
|
gErrorCounter = 0
|
||||||
compileProject()
|
if not isKnownFile:
|
||||||
|
compileProject(dirtyIdx)
|
||||||
|
else:
|
||||||
|
compileProject()
|
||||||
|
|
||||||
proc serve() =
|
proc serve() =
|
||||||
# do not stop after the first error:
|
# do not stop after the first error:
|
||||||
|
|
|
||||||
|
|
@ -198,8 +198,8 @@ proc isSigilLike(tok: TToken): bool {.inline.} =
|
||||||
|
|
||||||
proc isRightAssociative(tok: TToken): bool {.inline.} =
|
proc isRightAssociative(tok: TToken): bool {.inline.} =
|
||||||
## Determines whether the token is right assocative.
|
## Determines whether the token is right assocative.
|
||||||
result = tok.tokType == tkOpr and (tok.ident.s[0] == '^' or
|
result = tok.tokType == tkOpr and tok.ident.s[0] == '^'
|
||||||
(let L = tok.ident.s.len; L > 1 and tok.ident.s[L-1] == '>'))
|
# or (let L = tok.ident.s.len; L > 1 and tok.ident.s[L-1] == '>'))
|
||||||
|
|
||||||
proc getPrecedence(tok: TToken, strongSpaces: bool): int =
|
proc getPrecedence(tok: TToken, strongSpaces: bool): int =
|
||||||
## Calculates the precedence of the given token.
|
## Calculates the precedence of the given token.
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ const
|
||||||
props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
|
props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
|
||||||
(name: "VxWorks", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
|
(name: "VxWorks", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
|
||||||
objExt: ".o", newLine: "\x0A", pathSep: ";", dirSep: "\\",
|
objExt: ".o", newLine: "\x0A", pathSep: ";", dirSep: "\\",
|
||||||
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
|
scriptExt: ".sh", curDir: ".", exeExt: ".vxe", extSep: ".",
|
||||||
props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
|
props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
|
||||||
(name: "JS", parDir: "..",
|
(name: "JS", parDir: "..",
|
||||||
dllFrmt: "lib$1.so", altDirSep: "/",
|
dllFrmt: "lib$1.so", altDirSep: "/",
|
||||||
|
|
|
||||||
|
|
@ -130,9 +130,11 @@ proc commonType*(x, y: PType): PType =
|
||||||
elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len:
|
elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len:
|
||||||
var nt: PType
|
var nt: PType
|
||||||
for i in 0.. <a.len:
|
for i in 0.. <a.len:
|
||||||
if isEmptyContainer(a.sons[i]) and not isEmptyContainer(b.sons[i]):
|
let aEmpty = isEmptyContainer(a.sons[i])
|
||||||
|
let bEmpty = isEmptyContainer(b.sons[i])
|
||||||
|
if aEmpty != bEmpty:
|
||||||
if nt.isNil: nt = copyType(a, a.owner, false)
|
if nt.isNil: nt = copyType(a, a.owner, false)
|
||||||
nt.sons[i] = b.sons[i]
|
nt.sons[i] = if aEmpty: b.sons[i] else: a.sons[i]
|
||||||
if not nt.isNil: result = nt
|
if not nt.isNil: result = nt
|
||||||
#elif b.sons[idx].kind == tyEmpty: return x
|
#elif b.sons[idx].kind == tyEmpty: return x
|
||||||
elif a.kind == tyRange and b.kind == tyRange:
|
elif a.kind == tyRange and b.kind == tyRange:
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,7 @@ proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
|
||||||
|
|
||||||
proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
|
proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
|
||||||
result = newTypeS(tyFromExpr, c)
|
result = newTypeS(tyFromExpr, c)
|
||||||
|
assert n != nil
|
||||||
result.n = n
|
result.n = n
|
||||||
|
|
||||||
proc newTypeWithSons*(c: PContext, kind: TTypeKind,
|
proc newTypeWithSons*(c: PContext, kind: TTypeKind,
|
||||||
|
|
|
||||||
|
|
@ -103,28 +103,31 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
of skMacro: result = semMacroExpr(c, n, n, s, flags)
|
of skMacro: result = semMacroExpr(c, n, n, s, flags)
|
||||||
of skTemplate: result = semTemplateExpr(c, n, s, flags)
|
of skTemplate: result = semTemplateExpr(c, n, s, flags)
|
||||||
of skVar, skLet, skResult, skParam, skForVar:
|
of skParam:
|
||||||
|
markUsed(n.info, s)
|
||||||
|
styleCheckUse(n.info, s)
|
||||||
|
if s.typ.kind == tyStatic and s.typ.n != nil:
|
||||||
|
# XXX see the hack in sigmatch.nim ...
|
||||||
|
return s.typ.n
|
||||||
|
elif sfGenSym in s.flags:
|
||||||
|
if c.p.wasForwarded:
|
||||||
|
# gensym'ed parameters that nevertheless have been forward declared
|
||||||
|
# need a special fixup:
|
||||||
|
let realParam = c.p.owner.typ.n[s.position+1]
|
||||||
|
internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam
|
||||||
|
return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info)
|
||||||
|
elif c.p.owner.kind == skMacro:
|
||||||
|
# gensym'ed macro parameters need a similar hack (see bug #1944):
|
||||||
|
var u = searchInScopes(c, s.name)
|
||||||
|
internalAssert u != nil and u.kind == skParam and u.owner == s.owner
|
||||||
|
return newSymNode(u, n.info)
|
||||||
|
result = newSymNode(s, n.info)
|
||||||
|
of skVar, skLet, skResult, skForVar:
|
||||||
markUsed(n.info, s)
|
markUsed(n.info, s)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
# if a proc accesses a global variable, it is not side effect free:
|
# if a proc accesses a global variable, it is not side effect free:
|
||||||
if sfGlobal in s.flags:
|
if sfGlobal in s.flags:
|
||||||
incl(c.p.owner.flags, sfSideEffect)
|
incl(c.p.owner.flags, sfSideEffect)
|
||||||
elif s.kind == skParam:
|
|
||||||
if s.typ.kind == tyStatic and s.typ.n != nil:
|
|
||||||
# XXX see the hack in sigmatch.nim ...
|
|
||||||
return s.typ.n
|
|
||||||
elif sfGenSym in s.flags:
|
|
||||||
if c.p.wasForwarded:
|
|
||||||
# gensym'ed parameters that nevertheless have been forward declared
|
|
||||||
# need a special fixup:
|
|
||||||
let realParam = c.p.owner.typ.n[s.position+1]
|
|
||||||
internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam
|
|
||||||
return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info)
|
|
||||||
elif c.p.owner.kind == skMacro:
|
|
||||||
# gensym'ed macro parameters need a similar hack (see bug #1944):
|
|
||||||
var u = searchInScopes(c, s.name)
|
|
||||||
internalAssert u != nil and u.kind == skParam and u.owner == s.owner
|
|
||||||
return newSymNode(u, n.info)
|
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
# We cannot check for access to outer vars for example because it's still
|
# We cannot check for access to outer vars for example because it's still
|
||||||
# not sure the symbol really ends up being used:
|
# not sure the symbol really ends up being used:
|
||||||
|
|
@ -445,25 +448,30 @@ proc changeType(n: PNode, newType: PType, check: bool) =
|
||||||
let tup = newType.skipTypes({tyGenericInst})
|
let tup = newType.skipTypes({tyGenericInst})
|
||||||
if tup.kind != tyTuple:
|
if tup.kind != tyTuple:
|
||||||
internalError(n.info, "changeType: no tuple type for constructor")
|
internalError(n.info, "changeType: no tuple type for constructor")
|
||||||
elif newType.n == nil: discard
|
elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr:
|
||||||
elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr:
|
# named tuple?
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var m = n.sons[i].sons[0]
|
var m = n.sons[i].sons[0]
|
||||||
if m.kind != nkSym:
|
if m.kind != nkSym:
|
||||||
internalError(m.info, "changeType(): invalid tuple constr")
|
internalError(m.info, "changeType(): invalid tuple constr")
|
||||||
return
|
return
|
||||||
var f = getSymFromList(newType.n, m.sym.name)
|
if tup.n != nil:
|
||||||
if f == nil:
|
var f = getSymFromList(newType.n, m.sym.name)
|
||||||
internalError(m.info, "changeType(): invalid identifier")
|
if f == nil:
|
||||||
return
|
internalError(m.info, "changeType(): invalid identifier")
|
||||||
changeType(n.sons[i].sons[1], f.typ, check)
|
return
|
||||||
|
changeType(n.sons[i].sons[1], f.typ, check)
|
||||||
|
else:
|
||||||
|
changeType(n.sons[i].sons[1], tup.sons[i], check)
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var m = n.sons[i]
|
changeType(n.sons[i], tup.sons[i], check)
|
||||||
var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
|
when false:
|
||||||
addSon(a, newSymNode(newType.n.sons[i].sym))
|
var m = n.sons[i]
|
||||||
addSon(a, m)
|
var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
|
||||||
changeType(m, tup.sons[i], check)
|
addSon(a, newSymNode(newType.n.sons[i].sym))
|
||||||
|
addSon(a, m)
|
||||||
|
changeType(m, tup.sons[i], check)
|
||||||
of nkCharLit..nkUInt64Lit:
|
of nkCharLit..nkUInt64Lit:
|
||||||
if check:
|
if check:
|
||||||
let value = n.intVal
|
let value = n.intVal
|
||||||
|
|
@ -578,11 +586,12 @@ proc skipObjConv(n: PNode): PNode =
|
||||||
proc isAssignable(c: PContext, n: PNode): TAssignableResult =
|
proc isAssignable(c: PContext, n: PNode): TAssignableResult =
|
||||||
result = parampatterns.isAssignable(c.p.owner, n)
|
result = parampatterns.isAssignable(c.p.owner, n)
|
||||||
|
|
||||||
proc newHiddenAddrTaken(c: PContext, n: PNode): PNode =
|
proc newHiddenAddrTaken(c: PContext, n: PNode): PNode =
|
||||||
if n.kind == nkHiddenDeref:
|
if n.kind == nkHiddenDeref and not (gCmd == cmdCompileToCpp or
|
||||||
|
sfCompileToCpp in c.module.flags):
|
||||||
checkSonsLen(n, 1)
|
checkSonsLen(n, 1)
|
||||||
result = n.sons[0]
|
result = n.sons[0]
|
||||||
else:
|
else:
|
||||||
result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ))
|
result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ))
|
||||||
addSon(result, n)
|
addSon(result, n)
|
||||||
if isAssignable(c, n) notin {arLValue, arLocalLValue}:
|
if isAssignable(c, n) notin {arLValue, arLocalLValue}:
|
||||||
|
|
@ -1209,6 +1218,7 @@ proc asgnToResultVar(c: PContext, n, le, ri: PNode) {.inline.} =
|
||||||
if x.typ.kind == tyVar and x.kind == nkSym and x.sym.kind == skResult:
|
if x.typ.kind == tyVar and x.kind == nkSym and x.sym.kind == skResult:
|
||||||
n.sons[0] = x # 'result[]' --> 'result'
|
n.sons[0] = x # 'result[]' --> 'result'
|
||||||
n.sons[1] = takeImplicitAddr(c, ri)
|
n.sons[1] = takeImplicitAddr(c, ri)
|
||||||
|
x.typ.flags.incl tfVarIsPtr
|
||||||
|
|
||||||
template resultTypeIsInferrable(typ: PType): expr =
|
template resultTypeIsInferrable(typ: PType): expr =
|
||||||
typ.isMetaType and typ.kind != tyTypeDesc
|
typ.isMetaType and typ.kind != tyTypeDesc
|
||||||
|
|
|
||||||
|
|
@ -77,11 +77,16 @@ proc removeDefaultParamValues(n: PNode) =
|
||||||
proc freshGenSyms(n: PNode, owner: PSym, symMap: var TIdTable) =
|
proc freshGenSyms(n: PNode, owner: PSym, symMap: var TIdTable) =
|
||||||
# we need to create a fresh set of gensym'ed symbols:
|
# we need to create a fresh set of gensym'ed symbols:
|
||||||
if n.kind == nkSym and sfGenSym in n.sym.flags:
|
if n.kind == nkSym and sfGenSym in n.sym.flags:
|
||||||
var x = PSym(idTableGet(symMap, n.sym))
|
let s = n.sym
|
||||||
|
var x = PSym(idTableGet(symMap, s))
|
||||||
if x == nil:
|
if x == nil:
|
||||||
x = copySym(n.sym, false)
|
if s.kind == skParam:
|
||||||
x.owner = owner
|
x = owner.typ.n[s.position+1].sym
|
||||||
idTablePut(symMap, n.sym, x)
|
internalAssert x.kind == skParam
|
||||||
|
else:
|
||||||
|
x = copySym(s, false)
|
||||||
|
x.owner = owner
|
||||||
|
idTablePut(symMap, s, x)
|
||||||
n.sym = x
|
n.sym = x
|
||||||
else:
|
else:
|
||||||
for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, symMap)
|
for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, symMap)
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,10 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||||
var def: PNode
|
var def: PNode
|
||||||
if a.sons[length-1].kind != nkEmpty:
|
if a.sons[length-1].kind != nkEmpty:
|
||||||
def = semExprWithType(c, a.sons[length-1], {efAllowDestructor})
|
def = semExprWithType(c, a.sons[length-1], {efAllowDestructor})
|
||||||
|
if def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro:
|
||||||
|
# prevent the all too common 'var x = int' bug:
|
||||||
|
localError(def.info, "'typedesc' metatype is not valid here; typed '=' instead of ':'?")
|
||||||
|
def.typ = errorType(c)
|
||||||
if typ != nil:
|
if typ != nil:
|
||||||
if typ.isMetaType:
|
if typ.isMetaType:
|
||||||
def = inferWithMetatype(c, typ, def)
|
def = inferWithMetatype(c, typ, def)
|
||||||
|
|
@ -825,9 +829,9 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags):
|
if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags):
|
||||||
pushProcCon(c, s)
|
pushProcCon(c, s)
|
||||||
addResult(c, s.typ.sons[0], n.info, skProc)
|
addResult(c, s.typ.sons[0], n.info, skProc)
|
||||||
|
addResultNode(c, n)
|
||||||
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
||||||
n.sons[bodyPos] = transformBody(c.module, semBody, s)
|
n.sons[bodyPos] = transformBody(c.module, semBody, s)
|
||||||
addResultNode(c, n)
|
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
elif efOperand notin flags:
|
elif efOperand notin flags:
|
||||||
localError(n.info, errGenericLambdaNotAllowed)
|
localError(n.info, errGenericLambdaNotAllowed)
|
||||||
|
|
@ -860,9 +864,9 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
|
||||||
addParams(c, n.typ.n, skProc)
|
addParams(c, n.typ.n, skProc)
|
||||||
pushProcCon(c, s)
|
pushProcCon(c, s)
|
||||||
addResult(c, n.typ.sons[0], n.info, skProc)
|
addResult(c, n.typ.sons[0], n.info, skProc)
|
||||||
|
addResultNode(c, n)
|
||||||
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
||||||
n.sons[bodyPos] = transformBody(c.module, semBody, n.sons[namePos].sym)
|
n.sons[bodyPos] = transformBody(c.module, semBody, n.sons[namePos].sym)
|
||||||
addResultNode(c, n)
|
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
popOwner()
|
popOwner()
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
|
|
|
||||||
|
|
@ -781,9 +781,10 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
result.rawAddSon(paramType)
|
result.rawAddSon(paramType)
|
||||||
|
|
||||||
for i in 0 .. paramType.sonsLen - 2:
|
for i in 0 .. paramType.sonsLen - 2:
|
||||||
let dummyType = if paramType.sons[i].kind == tyStatic: tyUnknown
|
if paramType.sons[i].kind == tyStatic:
|
||||||
else: tyAnything
|
result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnkown'
|
||||||
result.rawAddSon newTypeS(dummyType, c)
|
else:
|
||||||
|
result.rawAddSon newTypeS(tyAnything, c)
|
||||||
|
|
||||||
if paramType.lastSon.kind == tyUserTypeClass:
|
if paramType.lastSon.kind == tyUserTypeClass:
|
||||||
result.kind = tyUserTypeClassInst
|
result.kind = tyUserTypeClassInst
|
||||||
|
|
@ -911,6 +912,8 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||||
if not hasType and not hasDefault:
|
if not hasType and not hasDefault:
|
||||||
if isType: localError(a.info, "':' expected")
|
if isType: localError(a.info, "':' expected")
|
||||||
let tdef = if kind in {skTemplate, skMacro}: tyExpr else: tyAnything
|
let tdef = if kind in {skTemplate, skMacro}: tyExpr else: tyAnything
|
||||||
|
if tdef == tyAnything:
|
||||||
|
message(a.info, warnTypelessParam, renderTree(n))
|
||||||
typ = newTypeS(tdef, c)
|
typ = newTypeS(tdef, c)
|
||||||
|
|
||||||
if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue
|
if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue
|
||||||
|
|
|
||||||
|
|
@ -1056,7 +1056,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||||
|
|
||||||
of tyFromExpr:
|
of tyFromExpr:
|
||||||
# fix the expression, so it contains the already instantiated types
|
# fix the expression, so it contains the already instantiated types
|
||||||
if f.n == nil: return isGeneric
|
if f.n == nil or f.n.kind == nkEmpty: return isGeneric
|
||||||
let reevaluated = tryResolvingStaticExpr(c, f.n)
|
let reevaluated = tryResolvingStaticExpr(c, f.n)
|
||||||
case reevaluated.typ.kind
|
case reevaluated.typ.kind
|
||||||
of tyTypeDesc:
|
of tyTypeDesc:
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,7 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
|
||||||
|
|
||||||
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
|
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
|
||||||
result = transformSons(c, n)
|
result = transformSons(c, n)
|
||||||
|
if gCmd == cmdCompileToCpp or sfCompileToCpp in c.module.flags: return
|
||||||
var n = result.PNode
|
var n = result.PNode
|
||||||
case n.sons[0].kind
|
case n.sons[0].kind
|
||||||
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
|
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,9 @@ proc hashTree(n: PNode): THash =
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkFloatLit..nkFloat64Lit:
|
||||||
if (n.floatVal >= - 1000000.0) and (n.floatVal <= 1000000.0):
|
if (n.floatVal >= - 1000000.0) and (n.floatVal <= 1000000.0):
|
||||||
result = result !& toInt(n.floatVal)
|
result = result !& toInt(n.floatVal)
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
result = result !& hash(n.strVal)
|
if not n.strVal.isNil:
|
||||||
|
result = result !& hash(n.strVal)
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result = result !& hashTree(n.sons[i])
|
result = result !& hashTree(n.sons[i])
|
||||||
|
|
|
||||||
|
|
@ -1029,16 +1029,18 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
|
|
||||||
proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind,
|
proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind,
|
||||||
flags: TTypeAllowedFlags = {}): PType =
|
flags: TTypeAllowedFlags = {}): PType =
|
||||||
if n != nil:
|
if n != nil:
|
||||||
result = typeAllowedAux(marker, n.typ, kind, flags)
|
result = typeAllowedAux(marker, n.typ, kind, flags)
|
||||||
#if not result: debug(n.typ)
|
#if not result: debug(n.typ)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkNone..nkNilLit:
|
of nkNone..nkNilLit:
|
||||||
discard
|
discard
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result = typeAllowedNode(marker, n.sons[i], kind, flags)
|
let it = n.sons[i]
|
||||||
|
if it.kind == nkRecCase and kind == skConst: return n.typ
|
||||||
|
result = typeAllowedNode(marker, it, kind, flags)
|
||||||
if result != nil: break
|
if result != nil: break
|
||||||
|
|
||||||
proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
|
proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]],
|
||||||
|
|
@ -1118,7 +1120,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
|
||||||
result = typeAllowedAux(marker, t.sons[i], kind, flags)
|
result = typeAllowedAux(marker, t.sons[i], kind, flags)
|
||||||
if result != nil: break
|
if result != nil: break
|
||||||
of tyObject, tyTuple:
|
of tyObject, tyTuple:
|
||||||
if kind == skConst and t.kind == tyObject: return t
|
if kind == skConst and t.kind == tyObject and t.sons[0] != nil: return t
|
||||||
let flags = flags+{taField}
|
let flags = flags+{taField}
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
for i in countup(0, sonsLen(t) - 1):
|
||||||
result = typeAllowedAux(marker, t.sons[i], kind, flags)
|
result = typeAllowedAux(marker, t.sons[i], kind, flags)
|
||||||
|
|
|
||||||
|
|
@ -1438,7 +1438,9 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode =
|
||||||
# immediate macros can bypass any type and arity checking so we check the
|
# immediate macros can bypass any type and arity checking so we check the
|
||||||
# arity here too:
|
# arity here too:
|
||||||
if sym.typ.len > n.safeLen and sym.typ.len > 1:
|
if sym.typ.len > n.safeLen and sym.typ.len > 1:
|
||||||
globalError(n.info, "got $#, but expected $# argument(s)" % [$ <n.safeLen, $ <sym.typ.len])
|
globalError(n.info, "in call '$#' got $#, but expected $# argument(s)" % [
|
||||||
|
n.renderTree,
|
||||||
|
$ <n.safeLen, $ <sym.typ.len])
|
||||||
|
|
||||||
setupGlobalCtx(module)
|
setupGlobalCtx(module)
|
||||||
var c = globalCtx
|
var c = globalCtx
|
||||||
|
|
|
||||||
|
|
@ -604,7 +604,8 @@ proc genNarrowU(c: PCtx; n: PNode; dest: TDest) =
|
||||||
let t = skipTypes(n.typ, abstractVar-{tyTypeDesc})
|
let t = skipTypes(n.typ, abstractVar-{tyTypeDesc})
|
||||||
# uint is uint64 in the VM, we we only need to mask the result for
|
# uint is uint64 in the VM, we we only need to mask the result for
|
||||||
# other unsigned types:
|
# other unsigned types:
|
||||||
if t.kind in {tyUInt8..tyUInt32, tyInt8..tyInt32}:
|
if t.kind in {tyUInt8..tyUInt32, tyInt8..tyInt32} or
|
||||||
|
(t.kind == tyInt and t.size == 4):
|
||||||
c.gABC(n, opcNarrowU, dest, TRegister(t.size*8))
|
c.gABC(n, opcNarrowU, dest, TRegister(t.size*8))
|
||||||
|
|
||||||
proc genBinaryABCnarrow(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
|
proc genBinaryABCnarrow(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
|
|
||||||
# You may set environment variables with
|
# You may set environment variables with
|
||||||
# @putenv "key" "val"
|
# @putenv "key" "val"
|
||||||
# Environment variables cannot be used in the options, however!
|
# Environment variables can be accessed like so:
|
||||||
|
# gcc.path %= "$CC_PATH"
|
||||||
|
|
||||||
cc = gcc
|
cc = gcc
|
||||||
|
|
||||||
|
|
@ -21,6 +22,7 @@ mips.linux.gcc.linkerexe = "mips-openwrt-linux-gcc"
|
||||||
@end
|
@end
|
||||||
|
|
||||||
path="$lib/core"
|
path="$lib/core"
|
||||||
|
|
||||||
path="$lib/pure"
|
path="$lib/pure"
|
||||||
path="$lib/pure/collections"
|
path="$lib/pure/collections"
|
||||||
path="$lib/pure/concurrency"
|
path="$lib/pure/concurrency"
|
||||||
|
|
@ -110,6 +112,20 @@ hint[LineTooLong]=off
|
||||||
gcc.cpp.options.always = "-w -fpermissive"
|
gcc.cpp.options.always = "-w -fpermissive"
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
# Configuration for the VxWorks
|
||||||
|
# This has been tested with VxWorks 6.9 only
|
||||||
|
@if vxworks:
|
||||||
|
# For now we only support compiling RTPs applications (i.e. no DKMs)
|
||||||
|
gcc.options.always = "-mrtp -fno-strict-aliasing -D_C99 -D_HAS_C9X -std=c99 -fasm -Wall -Wno-write-strings"
|
||||||
|
# The linker config must add the VxWorks common library for the selected
|
||||||
|
# processor which is usually found in:
|
||||||
|
# "$WIND_BASE/target/lib/usr/lib/PROCESSOR_FAMILY/PROCESSOR_TYPE/common",
|
||||||
|
# where PROCESSOR_FAMILY and PROCESSOR_TYPE are those supported by the VxWorks
|
||||||
|
# compiler (e.g. ppc/PPC32 or mips/MIPSI64, etc)
|
||||||
|
# For now we only support the PowerPC CPU
|
||||||
|
gcc.options.linker %= "-L $WIND_BASE/target/lib/usr/lib/ppc/PPC32/common -mrtp -fno-strict-aliasing -D_C99 -D_HAS_C9X -std=c99 -fasm -Wall -Wno-write-strings"
|
||||||
|
@end
|
||||||
|
|
||||||
gcc.options.speed = "-O3 -fno-strict-aliasing"
|
gcc.options.speed = "-O3 -fno-strict-aliasing"
|
||||||
gcc.options.size = "-Os"
|
gcc.options.size = "-Os"
|
||||||
gcc.options.debug = "-g3 -O0"
|
gcc.options.debug = "-g3 -O0"
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,6 @@ Advanced options:
|
||||||
--threadanalysis:on|off turn thread analysis on|off
|
--threadanalysis:on|off turn thread analysis on|off
|
||||||
--tlsEmulation:on|off turn thread local storage emulation on|off
|
--tlsEmulation:on|off turn thread local storage emulation on|off
|
||||||
--taintMode:on|off turn taint mode on|off
|
--taintMode:on|off turn taint mode on|off
|
||||||
--symbolFiles:on|off turn symbol files on|off (experimental)
|
|
||||||
--implicitStatic:on|off turn implicit compile time evaluation on|off
|
--implicitStatic:on|off turn implicit compile time evaluation on|off
|
||||||
--patterns:on|off turn pattern matching on|off
|
--patterns:on|off turn pattern matching on|off
|
||||||
--skipCfg do not read the general configuration file
|
--skipCfg do not read the general configuration file
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ Options:
|
||||||
-p, --path:PATH add path to search paths
|
-p, --path:PATH add path to search paths
|
||||||
-d, --define:SYMBOL define a conditional symbol
|
-d, --define:SYMBOL define a conditional symbol
|
||||||
-u, --undef:SYMBOL undefine a conditional symbol
|
-u, --undef:SYMBOL undefine a conditional symbol
|
||||||
--symbol:SYMBOL declare a conditional symbol
|
|
||||||
-f, --forceBuild force rebuilding of all modules
|
-f, --forceBuild force rebuilding of all modules
|
||||||
--stackTrace:on|off turn stack tracing on|off
|
--stackTrace:on|off turn stack tracing on|off
|
||||||
--lineTrace:on|off turn line tracing on|off
|
--lineTrace:on|off turn line tracing on|off
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,8 @@ Binary operators have 11 different levels of precedence.
|
||||||
Associativity
|
Associativity
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Binary operators whose first character is ``^`` or its last character
|
Binary operators whose first character is ``^`` are right-associative, all
|
||||||
is ``>`` are right-associative, all other binary operators are left-associative.
|
other binary operators are left-associative.
|
||||||
|
|
||||||
Exception: The single "greater than" ``>`` operator is left-associative too.
|
|
||||||
|
|
||||||
Operators ending in ``>`` but longer than a single character are
|
Operators ending in ``>`` but longer than a single character are
|
||||||
called `arrow like`:idx:.
|
called `arrow like`:idx:.
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,6 @@ Real world example
|
||||||
The installers for the Nim compiler itself are generated by niminst. Have a
|
The installers for the Nim compiler itself are generated by niminst. Have a
|
||||||
look at its configuration file:
|
look at its configuration file:
|
||||||
|
|
||||||
.. include:: compiler/nim.ini
|
.. include:: compiler/installer.ini
|
||||||
:literal:
|
:literal:
|
||||||
|
|
||||||
|
|
|
||||||
14
koch.nim
14
koch.nim
|
|
@ -97,13 +97,13 @@ const
|
||||||
compileNimInst = "-d:useLibzipSrc tools/niminst/niminst"
|
compileNimInst = "-d:useLibzipSrc tools/niminst/niminst"
|
||||||
|
|
||||||
proc csource(args: string) =
|
proc csource(args: string) =
|
||||||
exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=none csource compiler/nim.ini $1" %
|
exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=none csource compiler/installer.ini $1" %
|
||||||
[args, VersionAsString, compileNimInst, findNim()])
|
[args, VersionAsString, compileNimInst, findNim()])
|
||||||
|
|
||||||
proc zip(args: string) =
|
proc zip(args: string) =
|
||||||
exec("$3 cc -r $2 --var:version=$1 --var:mingw=none scripts compiler/nim.ini" %
|
exec("$3 cc -r $2 --var:version=$1 --var:mingw=none scripts compiler/installer.ini" %
|
||||||
[VersionAsString, compileNimInst, findNim()])
|
[VersionAsString, compileNimInst, findNim()])
|
||||||
exec("$# --var:version=$# --var:mingw=none zip compiler/nim.ini" %
|
exec("$# --var:version=$# --var:mingw=none zip compiler/installer.ini" %
|
||||||
["tools/niminst/niminst".exe, VersionAsString])
|
["tools/niminst/niminst".exe, VersionAsString])
|
||||||
|
|
||||||
proc buildTool(toolname, args: string) =
|
proc buildTool(toolname, args: string) =
|
||||||
|
|
@ -121,20 +121,20 @@ proc nsis(args: string) =
|
||||||
" nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)])
|
" nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)])
|
||||||
|
|
||||||
proc install(args: string) =
|
proc install(args: string) =
|
||||||
exec("$# cc -r $# --var:version=$# --var:mingw=none scripts compiler/nim.ini" %
|
exec("$# cc -r $# --var:version=$# --var:mingw=none scripts compiler/installer.ini" %
|
||||||
[findNim(), compileNimInst, VersionAsString])
|
[findNim(), compileNimInst, VersionAsString])
|
||||||
exec("sh ./install.sh $#" % args)
|
exec("sh ./install.sh $#" % args)
|
||||||
|
|
||||||
proc web(args: string) =
|
proc web(args: string) =
|
||||||
exec("$# cc -r tools/nimweb.nim $# web/nim --putenv:nimversion=$#" %
|
exec("$# cc -r tools/nimweb.nim $# web/website.ini --putenv:nimversion=$#" %
|
||||||
[findNim(), args, VersionAsString])
|
[findNim(), args, VersionAsString])
|
||||||
|
|
||||||
proc website(args: string) =
|
proc website(args: string) =
|
||||||
exec("$# cc -r tools/nimweb.nim $# --website web/nim --putenv:nimversion=$#" %
|
exec("$# cc -r tools/nimweb.nim $# --website web/website.ini --putenv:nimversion=$#" %
|
||||||
[findNim(), args, VersionAsString])
|
[findNim(), args, VersionAsString])
|
||||||
|
|
||||||
proc pdf(args="") =
|
proc pdf(args="") =
|
||||||
exec("$# cc -r tools/nimweb.nim $# --pdf web/nim --putenv:nimversion=$#" %
|
exec("$# cc -r tools/nimweb.nim $# --pdf web/website.ini --putenv:nimversion=$#" %
|
||||||
[findNim(), args, VersionAsString])
|
[findNim(), args, VersionAsString])
|
||||||
|
|
||||||
# -------------- boot ---------------------------------------------------------
|
# -------------- boot ---------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nim's Runtime Library
|
# Nim's Runtime Library
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2015 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -13,6 +13,8 @@
|
||||||
## is used. This suffices because Windows' console already provides the
|
## is used. This suffices because Windows' console already provides the
|
||||||
## wanted functionality.
|
## wanted functionality.
|
||||||
|
|
||||||
|
{.deadCodeElim: on.}
|
||||||
|
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
proc readLineFromStdin*(prompt: string): TaintedString {.
|
proc readLineFromStdin*(prompt: string): TaintedString {.
|
||||||
tags: [ReadIOEffect, WriteIOEffect].} =
|
tags: [ReadIOEffect, WriteIOEffect].} =
|
||||||
|
|
@ -31,9 +33,27 @@ when defined(Windows):
|
||||||
stdout.write(prompt)
|
stdout.write(prompt)
|
||||||
result = readLine(stdin, line)
|
result = readLine(stdin, line)
|
||||||
|
|
||||||
|
proc readPasswordFromStdin*(prompt: string, password: var TaintedString) =
|
||||||
|
## Reads a `password` from stdin without printing it. `password` must not
|
||||||
|
## be ``nil``!
|
||||||
|
proc getch(): cint {.header: "<conio.h>", importc: "_getch".}
|
||||||
|
|
||||||
|
password.setLen(0)
|
||||||
|
var c: char
|
||||||
|
echo prompt
|
||||||
|
while true:
|
||||||
|
c = getch().char
|
||||||
|
case c
|
||||||
|
of '\r', chr(0xA):
|
||||||
|
break
|
||||||
|
of '\b':
|
||||||
|
password.setLen(password.len - 1)
|
||||||
|
else:
|
||||||
|
password.add(c)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
import readline, history
|
import readline, history, termios, unsigned
|
||||||
|
|
||||||
proc readLineFromStdin*(prompt: string): TaintedString {.
|
proc readLineFromStdin*(prompt: string): TaintedString {.
|
||||||
tags: [ReadIOEffect, WriteIOEffect].} =
|
tags: [ReadIOEffect, WriteIOEffect].} =
|
||||||
var buffer = readline.readLine(prompt)
|
var buffer = readline.readLine(prompt)
|
||||||
|
|
@ -55,8 +75,24 @@ else:
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
# initialization:
|
# initialization:
|
||||||
# disable auto-complete:
|
# disable auto-complete:
|
||||||
proc doNothing(a, b: cint): cint {.cdecl, procvar.} = discard
|
proc doNothing(a, b: cint): cint {.cdecl, procvar.} = discard
|
||||||
|
|
||||||
discard readline.bind_key('\t'.ord, doNothing)
|
discard readline.bind_key('\t'.ord, doNothing)
|
||||||
|
|
||||||
|
proc readPasswordFromStdin*(prompt: string, password: var TaintedString) =
|
||||||
|
password.setLen(0)
|
||||||
|
let fd = stdin.getFileHandle()
|
||||||
|
var cur, old: Termios
|
||||||
|
discard fd.tcgetattr(cur.addr)
|
||||||
|
old = cur
|
||||||
|
cur.lflag = cur.lflag and not Tcflag(ECHO)
|
||||||
|
discard fd.tcsetattr(TCSADRAIN, cur.addr)
|
||||||
|
stdout.write prompt
|
||||||
|
discard stdin.readLine(password)
|
||||||
|
discard fd.tcsetattr(TCSADRAIN, old.addr)
|
||||||
|
|
||||||
|
proc readPasswordFromStdin*(prompt: string): TaintedString =
|
||||||
|
## Reads a password from stdin without printing it.
|
||||||
|
result = TaintedString("")
|
||||||
|
readPasswordFromStdin(prompt, result)
|
||||||
|
|
|
||||||
|
|
@ -379,7 +379,7 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
|
||||||
# define GC_GUARD
|
# define GC_GUARD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Test to see if nimrod and the C compiler agree on the size of a pointer.
|
/* Test to see if Nim and the C compiler agree on the size of a pointer.
|
||||||
On disagreement, your C compiler will say something like:
|
On disagreement, your C compiler will say something like:
|
||||||
"error: 'assert_numbits' declared as an array with a negative size" */
|
"error: 'assert_numbits' declared as an array with a negative size" */
|
||||||
typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
|
typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
|
||||||
|
|
@ -390,3 +390,12 @@ typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(
|
||||||
#else
|
#else
|
||||||
# define NIM_EXTERNC
|
# define NIM_EXTERNC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ---------------- platform specific includes ----------------------- */
|
||||||
|
|
||||||
|
/* VxWorks related includes */
|
||||||
|
#if defined(__VXWORKS__)
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <types/vxWind.h>
|
||||||
|
# include <tool/gnu/toolMacros.h>
|
||||||
|
#endif
|
||||||
|
|
|
||||||
264
lib/posix/termios.nim
Normal file
264
lib/posix/termios.nim
Normal file
|
|
@ -0,0 +1,264 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Nim's Runtime Library
|
||||||
|
# (c) Copyright 2015 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
{.deadCodeElim: on.}
|
||||||
|
import posix
|
||||||
|
|
||||||
|
type
|
||||||
|
Speed* = cuint
|
||||||
|
Tcflag* = cuint
|
||||||
|
|
||||||
|
const
|
||||||
|
NCCS* = 32
|
||||||
|
|
||||||
|
type
|
||||||
|
Termios* = object {.importc: "struct termios", header: "<termios.h>", final, pure.}
|
||||||
|
iflag*: Tcflag # input mode flags
|
||||||
|
oflag*: Tcflag # output mode flags
|
||||||
|
cflag*: Tcflag # control mode flags
|
||||||
|
lflag*: Tcflag # local mode flags
|
||||||
|
line*: cuchar # line discipline
|
||||||
|
cc*: array[NCCS, cuchar] # control characters
|
||||||
|
ispeed*: Speed # input speed
|
||||||
|
ospeed*: Speed # output speed
|
||||||
|
|
||||||
|
|
||||||
|
# cc characters
|
||||||
|
|
||||||
|
const
|
||||||
|
VINTR* = 0
|
||||||
|
VQUIT* = 1
|
||||||
|
VERASE* = 2
|
||||||
|
VKILL* = 3
|
||||||
|
VEOF* = 4
|
||||||
|
VTIME* = 5
|
||||||
|
VMIN* = 6
|
||||||
|
VSWTC* = 7
|
||||||
|
VSTART* = 8
|
||||||
|
VSTOP* = 9
|
||||||
|
VSUSP* = 10
|
||||||
|
VEOL* = 11
|
||||||
|
VREPRINT* = 12
|
||||||
|
VDISCARD* = 13
|
||||||
|
VWERASE* = 14
|
||||||
|
VLNEXT* = 15
|
||||||
|
VEOL2* = 16
|
||||||
|
|
||||||
|
# iflag bits
|
||||||
|
|
||||||
|
const
|
||||||
|
IGNBRK* = 1
|
||||||
|
BRKINT* = 2
|
||||||
|
IGNPAR* = 4
|
||||||
|
PARMRK* = 10
|
||||||
|
INPCK* = 20
|
||||||
|
ISTRIP* = 40
|
||||||
|
INLCR* = 100
|
||||||
|
IGNCR* = 200
|
||||||
|
ICRNL* = 400
|
||||||
|
IUCLC* = 1000
|
||||||
|
IXON* = 2000
|
||||||
|
IXANY* = 4000
|
||||||
|
IXOFF* = 10000
|
||||||
|
IMAXBEL* = 20000
|
||||||
|
IUTF8* = 40000
|
||||||
|
|
||||||
|
# oflag bits
|
||||||
|
|
||||||
|
const
|
||||||
|
OPOST* = 1
|
||||||
|
OLCUC* = 2
|
||||||
|
ONLCR* = 4
|
||||||
|
OCRNL* = 10
|
||||||
|
ONOCR* = 20
|
||||||
|
ONLRET* = 40
|
||||||
|
OFILL* = 100
|
||||||
|
OFDEL* = 200
|
||||||
|
NLDLY* = 400
|
||||||
|
NL0* = 0
|
||||||
|
NL1* = 400
|
||||||
|
CRDLY* = 3000
|
||||||
|
CR0* = 0
|
||||||
|
CR1* = 1000
|
||||||
|
CR2* = 2000
|
||||||
|
CR3* = 3000
|
||||||
|
TABDLY* = 14000
|
||||||
|
TAB0* = 0
|
||||||
|
TAB1* = 4000
|
||||||
|
TAB2* = 10000
|
||||||
|
TAB3* = 14000
|
||||||
|
BSDLY* = 20000
|
||||||
|
BS0* = 0
|
||||||
|
BS1* = 20000
|
||||||
|
FFDLY* = 0o000000100000
|
||||||
|
FF0* = 0
|
||||||
|
FF1* = 0o000000100000
|
||||||
|
VTDLY* = 40000
|
||||||
|
VT0* = 0
|
||||||
|
VT1* = 40000
|
||||||
|
XTABS* = 14000
|
||||||
|
|
||||||
|
# cflag bit meaning
|
||||||
|
|
||||||
|
const
|
||||||
|
CBAUD* = 10017
|
||||||
|
B0* = 0
|
||||||
|
B50* = 1
|
||||||
|
B75* = 2
|
||||||
|
B110* = 3
|
||||||
|
B134* = 4
|
||||||
|
B150* = 5
|
||||||
|
B200* = 6
|
||||||
|
B300* = 7
|
||||||
|
B600* = 10
|
||||||
|
B1200* = 11
|
||||||
|
B1800* = 12
|
||||||
|
B2400* = 13
|
||||||
|
B4800* = 14
|
||||||
|
B9600* = 15
|
||||||
|
B19200* = 16
|
||||||
|
B38400* = 17
|
||||||
|
EXTA* = B19200
|
||||||
|
EXTB* = B38400
|
||||||
|
CSIZE* = 60
|
||||||
|
CS5* = 0
|
||||||
|
CS6* = 20
|
||||||
|
CS7* = 40
|
||||||
|
CS8* = 60
|
||||||
|
CSTOPB* = 100
|
||||||
|
CREAD* = 200
|
||||||
|
PARENB* = 400
|
||||||
|
PARODD* = 1000
|
||||||
|
HUPCL* = 2000
|
||||||
|
CLOCAL* = 4000
|
||||||
|
CBAUDEX* = 10000
|
||||||
|
B57600* = 10001
|
||||||
|
B115200* = 10002
|
||||||
|
B230400* = 10003
|
||||||
|
B460800* = 10004
|
||||||
|
B500000* = 10005
|
||||||
|
B576000* = 10006
|
||||||
|
B921600* = 10007
|
||||||
|
B1000000* = 10010
|
||||||
|
B1152000* = 10011
|
||||||
|
B1500000* = 10012
|
||||||
|
B2000000* = 10013
|
||||||
|
B2500000* = 10014
|
||||||
|
B3000000* = 10015
|
||||||
|
B3500000* = 10016
|
||||||
|
B4000000* = 10017
|
||||||
|
MAX_BAUD* = B4000000
|
||||||
|
CIBAUD* = 2003600000
|
||||||
|
CMSPAR* = 0o010000000000
|
||||||
|
CRTSCTS* = 0o020000000000
|
||||||
|
|
||||||
|
# lflag bits
|
||||||
|
|
||||||
|
const
|
||||||
|
ISIG* = 1
|
||||||
|
ICANON* = 2
|
||||||
|
XCASE* = 4
|
||||||
|
ECHO* = 10
|
||||||
|
ECHOE* = 20
|
||||||
|
ECHOK* = 40
|
||||||
|
ECHONL* = 100
|
||||||
|
NOFLSH* = 200
|
||||||
|
TOSTOP* = 400
|
||||||
|
ECHOCTL* = 1000
|
||||||
|
ECHOPRT* = 2000
|
||||||
|
ECHOKE* = 4000
|
||||||
|
FLUSHO* = 10000
|
||||||
|
PENDIN* = 40000
|
||||||
|
IEXTEN* = 0o000000100000
|
||||||
|
EXTPROC* = 0o000000200000
|
||||||
|
|
||||||
|
# tcflow() and TCXONC use these
|
||||||
|
|
||||||
|
const
|
||||||
|
TCOOFF* = 0
|
||||||
|
TCOON* = 1
|
||||||
|
TCIOFF* = 2
|
||||||
|
TCION* = 3
|
||||||
|
|
||||||
|
# tcflush() and TCFLSH use these
|
||||||
|
|
||||||
|
const
|
||||||
|
TCIFLUSH* = 0
|
||||||
|
TCOFLUSH* = 1
|
||||||
|
TCIOFLUSH* = 2
|
||||||
|
|
||||||
|
# tcsetattr uses these
|
||||||
|
|
||||||
|
const
|
||||||
|
TCSANOW* = 0
|
||||||
|
TCSADRAIN* = 1
|
||||||
|
TCSAFLUSH* = 2
|
||||||
|
|
||||||
|
# Compare a character C to a value VAL from the `cc' array in a
|
||||||
|
# `struct termios'. If VAL is _POSIX_VDISABLE, no character can match it.
|
||||||
|
|
||||||
|
template cceq*(val, c: expr): expr =
|
||||||
|
c == val and val != POSIX_VDISABLE
|
||||||
|
|
||||||
|
# Return the output baud rate stored in *TERMIOS_P.
|
||||||
|
|
||||||
|
proc cfGetOspeed*(termios: ptr Termios): Speed {.importc: "cfgetospeed",
|
||||||
|
header: "<termios.h>".}
|
||||||
|
# Return the input baud rate stored in *TERMIOS_P.
|
||||||
|
|
||||||
|
proc cfGetIspeed*(termios: ptr Termios): Speed {.importc: "cfgetispeed",
|
||||||
|
header: "<termios.h>".}
|
||||||
|
# Set the output baud rate stored in *TERMIOS_P to SPEED.
|
||||||
|
|
||||||
|
proc cfSetOspeed*(termios: ptr Termios; speed: Speed): cint {.
|
||||||
|
importc: "cfsetospeed", header: "<termios.h>".}
|
||||||
|
# Set the input baud rate stored in *TERMIOS_P to SPEED.
|
||||||
|
|
||||||
|
proc cfSetIspeed*(termios: ptr Termios; speed: Speed): cint {.
|
||||||
|
importc: "cfsetispeed", header: "<termios.h>".}
|
||||||
|
# Set both the input and output baud rates in *TERMIOS_OP to SPEED.
|
||||||
|
|
||||||
|
proc cfSetSpeed*(termios: ptr Termios; speed: Speed): cint {.
|
||||||
|
importc: "cfsetspeed", header: "<termios.h>".}
|
||||||
|
# Put the state of FD into *TERMIOS_P.
|
||||||
|
|
||||||
|
proc tcGetAttr*(fd: cint; termios: ptr Termios): cint {.
|
||||||
|
importc: "tcgetattr", header: "<termios.h>".}
|
||||||
|
# Set the state of FD to *TERMIOS_P.
|
||||||
|
# Values for OPTIONAL_ACTIONS (TCSA*) are in <bits/termios.h>.
|
||||||
|
|
||||||
|
proc tcSetAttr*(fd: cint; optional_actions: cint; termios: ptr Termios): cint {.
|
||||||
|
importc: "tcsetattr", header: "<termios.h>".}
|
||||||
|
# Set *TERMIOS_P to indicate raw mode.
|
||||||
|
|
||||||
|
proc cfMakeRaw*(termios: ptr Termios) {.importc: "cfmakeraw",
|
||||||
|
header: "<termios.h>".}
|
||||||
|
# Send zero bits on FD.
|
||||||
|
|
||||||
|
proc tcSendBreak*(fd: cint; duration: cint): cint {.importc: "tcsendbreak",
|
||||||
|
header: "<termios.h>".}
|
||||||
|
# Wait for pending output to be written on FD.
|
||||||
|
#
|
||||||
|
# This function is a cancellation point and therefore not marked with
|
||||||
|
# .
|
||||||
|
|
||||||
|
proc tcDrain*(fd: cint): cint {.importc: "tcdrain", header: "<termios.h>".}
|
||||||
|
# Flush pending data on FD.
|
||||||
|
# Values for QUEUE_SELECTOR (TC{I,O,IO}FLUSH) are in <bits/termios.h>.
|
||||||
|
|
||||||
|
proc tcFlush*(fd: cint; queue_selector: cint): cint {.importc: "tcflush",
|
||||||
|
header: "<termios.h>".}
|
||||||
|
# Suspend or restart transmission on FD.
|
||||||
|
# Values for ACTION (TC[IO]{OFF,ON}) are in <bits/termios.h>.
|
||||||
|
|
||||||
|
proc tcFlow*(fd: cint; action: cint): cint {.importc: "tcflow",
|
||||||
|
header: "<termios.h>".}
|
||||||
|
# Get process group ID for session leader for controlling terminal FD.
|
||||||
|
|
||||||
|
proc tcGetSid*(fd: cint): TPid {.importc: "tcgetsid", header: "<termios.h>".}
|
||||||
|
|
@ -220,3 +220,62 @@ proc product*[T](x: openArray[seq[T]]): seq[seq[T]] =
|
||||||
result.add(res)
|
result.add(res)
|
||||||
index = 0
|
index = 0
|
||||||
indexes[index] -=1
|
indexes[index] -=1
|
||||||
|
|
||||||
|
proc nextPermutation*[T](x: var openarray[T]): bool {.discardable.} =
|
||||||
|
## Calculates the next lexicographic permutation, directly modifying ``x``.
|
||||||
|
## The result is whether a permutation happened, otherwise we have reached
|
||||||
|
## the last-ordered permutation.
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
##
|
||||||
|
## var v = @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
|
## v.nextPermutation()
|
||||||
|
## echo v
|
||||||
|
if x.len < 2:
|
||||||
|
return false
|
||||||
|
|
||||||
|
var i = x.high
|
||||||
|
while i > 0 and x[i-1] >= x[i]:
|
||||||
|
dec i
|
||||||
|
|
||||||
|
if i == 0:
|
||||||
|
return false
|
||||||
|
|
||||||
|
var j = x.high
|
||||||
|
while j >= i and x[j] <= x[i-1]:
|
||||||
|
dec j
|
||||||
|
|
||||||
|
swap x[j], x[i-1]
|
||||||
|
x.reverse(i, x.high)
|
||||||
|
|
||||||
|
result = true
|
||||||
|
|
||||||
|
proc prevPermutation*[T](x: var openarray[T]): bool {.discardable.} =
|
||||||
|
## Calculates the previous lexicographic permutation, directly modifying
|
||||||
|
## ``x``. The result is whether a permutation happened, otherwise we have
|
||||||
|
## reached the first-ordered permutation.
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
##
|
||||||
|
## var v = @[0, 1, 2, 3, 4, 5, 6, 7, 9, 8]
|
||||||
|
## v.prevPermutation()
|
||||||
|
## echo v
|
||||||
|
if x.len < 2:
|
||||||
|
return false
|
||||||
|
|
||||||
|
var i = x.high
|
||||||
|
while i > 0 and x[i-1] <= x[i]:
|
||||||
|
dec i
|
||||||
|
|
||||||
|
if i == 0:
|
||||||
|
return false
|
||||||
|
|
||||||
|
x.reverse(i, x.high)
|
||||||
|
|
||||||
|
var j = x.high
|
||||||
|
while j >= i and x[j-1] < x[i-1]:
|
||||||
|
dec j
|
||||||
|
|
||||||
|
swap x[i-1], x[j]
|
||||||
|
|
||||||
|
result = true
|
||||||
|
|
|
||||||
|
|
@ -1064,6 +1064,17 @@ proc accept*(socket: TAsyncFD,
|
||||||
|
|
||||||
# -- Await Macro
|
# -- Await Macro
|
||||||
|
|
||||||
|
proc skipUntilStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
|
# Skips a nest of StmtList's.
|
||||||
|
result = node
|
||||||
|
if node[0].kind == nnkStmtList:
|
||||||
|
result = skipUntilStmtList(node[0])
|
||||||
|
|
||||||
|
proc skipStmtList(node: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
|
result = node
|
||||||
|
if node[0].kind == nnkStmtList:
|
||||||
|
result = node[0]
|
||||||
|
|
||||||
template createCb(retFutureSym, iteratorNameSym,
|
template createCb(retFutureSym, iteratorNameSym,
|
||||||
name: expr): stmt {.immediate.} =
|
name: expr): stmt {.immediate.} =
|
||||||
var nameIterVar = iteratorNameSym
|
var nameIterVar = iteratorNameSym
|
||||||
|
|
@ -1211,26 +1222,53 @@ proc processBody(node, retFutureSym: PNimrodNode,
|
||||||
of nnkTryStmt:
|
of nnkTryStmt:
|
||||||
# try: await x; except: ...
|
# try: await x; except: ...
|
||||||
result = newNimNode(nnkStmtList, node)
|
result = newNimNode(nnkStmtList, node)
|
||||||
|
template wrapInTry(n, tryBody: PNimrodNode) =
|
||||||
|
var temp = n
|
||||||
|
n[0] = tryBody
|
||||||
|
tryBody = temp
|
||||||
|
|
||||||
|
# Transform ``except`` body.
|
||||||
|
# TODO: Could we perform some ``await`` transformation here to get it
|
||||||
|
# working in ``except``?
|
||||||
|
tryBody[1] = processBody(n[1], retFutureSym, subTypeIsVoid, nil)
|
||||||
|
|
||||||
proc processForTry(n: PNimrodNode, i: var int,
|
proc processForTry(n: PNimrodNode, i: var int,
|
||||||
res: PNimrodNode): bool {.compileTime.} =
|
res: PNimrodNode): bool {.compileTime.} =
|
||||||
|
## Transforms the body of the tryStmt. Does not transform the
|
||||||
|
## body in ``except``.
|
||||||
|
## Returns true if the tryStmt node was transformed into an ifStmt.
|
||||||
result = false
|
result = false
|
||||||
while i < n[0].len:
|
var skipped = n.skipStmtList()
|
||||||
var processed = processBody(n[0][i], retFutureSym, subTypeIsVoid, n)
|
while i < skipped.len:
|
||||||
if processed.kind != n[0][i].kind or processed.len != n[0][i].len:
|
var processed = processBody(skipped[i], retFutureSym,
|
||||||
|
subTypeIsVoid, n)
|
||||||
|
|
||||||
|
# Check if we transformed the node into an exception check.
|
||||||
|
# This suggests skipped[i] contains ``await``.
|
||||||
|
if processed.kind != skipped[i].kind or processed.len != skipped[i].len:
|
||||||
|
processed = processed.skipUntilStmtList()
|
||||||
expectKind(processed, nnkStmtList)
|
expectKind(processed, nnkStmtList)
|
||||||
expectKind(processed[2][1], nnkElse)
|
expectKind(processed[2][1], nnkElse)
|
||||||
i.inc
|
i.inc
|
||||||
discard processForTry(n, i, processed[2][1][0])
|
|
||||||
|
if not processForTry(n, i, processed[2][1][0]):
|
||||||
|
# We need to wrap the nnkElse nodes back into a tryStmt.
|
||||||
|
# As they are executed if an exception does not happen
|
||||||
|
# inside the awaited future.
|
||||||
|
# The following code will wrap the nodes inside the
|
||||||
|
# original tryStmt.
|
||||||
|
wrapInTry(n, processed[2][1][0])
|
||||||
|
|
||||||
res.add processed
|
res.add processed
|
||||||
result = true
|
result = true
|
||||||
else:
|
else:
|
||||||
res.add n[0][i]
|
res.add skipped[i]
|
||||||
i.inc
|
i.inc
|
||||||
var i = 0
|
var i = 0
|
||||||
if not processForTry(node, i, result):
|
if not processForTry(node, i, result):
|
||||||
var temp = node
|
# If the tryStmt hasn't been transformed we can just put the body
|
||||||
temp[0] = result
|
# back into it.
|
||||||
result = temp
|
wrapInTry(node, result)
|
||||||
return
|
return
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
|
|
@ -1329,8 +1367,8 @@ macro async*(prc: stmt): stmt {.immediate.} =
|
||||||
result[6] = outerProcBody
|
result[6] = outerProcBody
|
||||||
|
|
||||||
#echo(treeRepr(result))
|
#echo(treeRepr(result))
|
||||||
#if prc[0].getName == "catch":
|
if prc[0].getName == "test3":
|
||||||
# echo(toStrLit(result))
|
echo(toStrLit(result))
|
||||||
|
|
||||||
proc recvLine*(socket: TAsyncFD): Future[string] {.async.} =
|
proc recvLine*(socket: TAsyncFD): Future[string] {.async.} =
|
||||||
## Reads a line of data from ``socket``. Returned future will complete once
|
## Reads a line of data from ``socket``. Returned future will complete once
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,28 @@
|
||||||
##
|
##
|
||||||
## 1.3000000000000000e+00
|
## 1.3000000000000000e+00
|
||||||
## true
|
## true
|
||||||
|
##
|
||||||
|
## This module can also be used to comfortably create JSON using the `%*`
|
||||||
|
## operator:
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
##
|
||||||
|
## var hisName = "John"
|
||||||
|
## let herAge = 31
|
||||||
|
## var j = %*
|
||||||
|
## [
|
||||||
|
## {
|
||||||
|
## "name": hisName,
|
||||||
|
## "age": 30
|
||||||
|
## },
|
||||||
|
## {
|
||||||
|
## "name": "Susan",
|
||||||
|
## "age": herAge
|
||||||
|
## }
|
||||||
|
## ]
|
||||||
|
|
||||||
import
|
import
|
||||||
hashes, strutils, lexbase, streams, unicode
|
hashes, strutils, lexbase, streams, unicode, macros
|
||||||
|
|
||||||
type
|
type
|
||||||
JsonEventKind* = enum ## enumeration of all events that may occur when parsing
|
JsonEventKind* = enum ## enumeration of all events that may occur when parsing
|
||||||
|
|
@ -625,6 +644,29 @@ proc `%`*(elements: openArray[JsonNode]): JsonNode =
|
||||||
newSeq(result.elems, elements.len)
|
newSeq(result.elems, elements.len)
|
||||||
for i, p in pairs(elements): result.elems[i] = p
|
for i, p in pairs(elements): result.elems[i] = p
|
||||||
|
|
||||||
|
proc toJson(x: PNimrodNode): PNimrodNode {.compiletime.} =
|
||||||
|
case x.kind
|
||||||
|
of nnkBracket:
|
||||||
|
result = newNimNode(nnkBracket)
|
||||||
|
for i in 0 .. <x.len:
|
||||||
|
result.add(toJson(x[i]))
|
||||||
|
|
||||||
|
of nnkTableConstr:
|
||||||
|
result = newNimNode(nnkTableConstr)
|
||||||
|
for i in 0 .. <x.len:
|
||||||
|
assert x[i].kind == nnkExprColonExpr
|
||||||
|
result.add(newNimNode(nnkExprColonExpr).add(x[i][0]).add(toJson(x[i][1])))
|
||||||
|
|
||||||
|
else:
|
||||||
|
result = x
|
||||||
|
|
||||||
|
result = prefix(result, "%")
|
||||||
|
|
||||||
|
macro `%*`*(x: expr): expr =
|
||||||
|
## Convert an expression to a JsonNode directly, without having to specify
|
||||||
|
## `%` for every element.
|
||||||
|
result = toJson(x)
|
||||||
|
|
||||||
proc `==`* (a,b: JsonNode): bool =
|
proc `==`* (a,b: JsonNode): bool =
|
||||||
## Check two nodes for equality
|
## Check two nodes for equality
|
||||||
if a.isNil:
|
if a.isNil:
|
||||||
|
|
@ -864,7 +906,7 @@ proc pretty*(node: JsonNode, indent = 2): string =
|
||||||
proc `$`*(node: JsonNode): string =
|
proc `$`*(node: JsonNode): string =
|
||||||
## Converts `node` to its JSON Representation on one line.
|
## Converts `node` to its JSON Representation on one line.
|
||||||
result = ""
|
result = ""
|
||||||
toPretty(result, node, 1, false)
|
toPretty(result, node, 0, false)
|
||||||
|
|
||||||
iterator items*(node: JsonNode): JsonNode =
|
iterator items*(node: JsonNode): JsonNode =
|
||||||
## Iterator for the items of `node`. `node` has to be a JArray.
|
## Iterator for the items of `node`. `node` has to be a JArray.
|
||||||
|
|
@ -1101,6 +1143,37 @@ when isMainModule:
|
||||||
except:
|
except:
|
||||||
assert(false, "EInvalidIndex thrown for valid index")
|
assert(false, "EInvalidIndex thrown for valid index")
|
||||||
|
|
||||||
|
# Generator:
|
||||||
|
var j = %* [{"name": "John", "age": 30}, {"name": "Susan", "age": 31}]
|
||||||
|
assert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||||
|
|
||||||
|
var j2 = %*
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "John",
|
||||||
|
"age": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Susan",
|
||||||
|
"age": 31
|
||||||
|
}
|
||||||
|
]
|
||||||
|
assert j2 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||||
|
|
||||||
|
var name = "John"
|
||||||
|
let herAge = 30
|
||||||
|
const hisAge = 31
|
||||||
|
|
||||||
|
var j3 = %*
|
||||||
|
[ { "name": "John"
|
||||||
|
, "age": herAge
|
||||||
|
}
|
||||||
|
, { "name": "Susan"
|
||||||
|
, "age": hisAge
|
||||||
|
}
|
||||||
|
]
|
||||||
|
assert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||||
|
|
||||||
discard """
|
discard """
|
||||||
while true:
|
while true:
|
||||||
var json = stdin.readLine()
|
var json = stdin.readLine()
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ proc newRollingFileLogger*(filename = defaultFilename(),
|
||||||
## a new log file will be started and the old will be renamed.
|
## a new log file will be started and the old will be renamed.
|
||||||
new(result)
|
new(result)
|
||||||
result.levelThreshold = levelThreshold
|
result.levelThreshold = levelThreshold
|
||||||
result.fmtStr = defaultFmtStr
|
result.fmtStr = fmtStr
|
||||||
result.maxLines = maxLines
|
result.maxLines = maxLines
|
||||||
result.f = open(filename, mode)
|
result.f = open(filename, mode)
|
||||||
result.curLine = 0
|
result.curLine = 0
|
||||||
|
|
|
||||||
|
|
@ -1074,8 +1074,12 @@ when defined(windows):
|
||||||
# because we support Windows GUI applications, things get really
|
# because we support Windows GUI applications, things get really
|
||||||
# messy here...
|
# messy here...
|
||||||
when useWinUnicode:
|
when useWinUnicode:
|
||||||
proc strEnd(cstr: WideCString, c = 0'i32): WideCString {.
|
when defined(cpp):
|
||||||
importc: "wcschr", header: "<string.h>".}
|
proc strEnd(cstr: WideCString, c = 0'i32): WideCString {.
|
||||||
|
importcpp: "(NI16*)wcschr((const wchar_t *)#, #)", header: "<string.h>".}
|
||||||
|
else:
|
||||||
|
proc strEnd(cstr: WideCString, c = 0'i32): WideCString {.
|
||||||
|
importc: "wcschr", header: "<string.h>".}
|
||||||
else:
|
else:
|
||||||
proc strEnd(cstr: cstring, c = 0'i32): cstring {.
|
proc strEnd(cstr: cstring, c = 0'i32): cstring {.
|
||||||
importc: "strchr", header: "<string.h>".}
|
importc: "strchr", header: "<string.h>".}
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ proc `[]`*(t: StringTableRef, key: string): string {.rtl, extern: "nstGet".} =
|
||||||
proc mget*(t: StringTableRef, key: string): var string {.
|
proc mget*(t: StringTableRef, key: string): var string {.
|
||||||
rtl, extern: "nstTake".} =
|
rtl, extern: "nstTake".} =
|
||||||
## retrieves the location at ``t[key]``. If `key` is not in `t`, the
|
## retrieves the location at ``t[key]``. If `key` is not in `t`, the
|
||||||
## ``EInvalidKey`` exception is raised.
|
## ``KeyError`` exception is raised.
|
||||||
var index = rawGet(t, key)
|
var index = rawGet(t, key)
|
||||||
if index >= 0: result = t.data[index].val
|
if index >= 0: result = t.data[index].val
|
||||||
else: raise newException(KeyError, "key does not exist: " & key)
|
else: raise newException(KeyError, "key does not exist: " & key)
|
||||||
|
|
@ -158,7 +158,7 @@ proc getValue(t: StringTableRef, flags: set[FormatFlag], key: string): string =
|
||||||
else: result = ""
|
else: result = ""
|
||||||
if result.len == 0:
|
if result.len == 0:
|
||||||
if useKey in flags: result = '$' & key
|
if useKey in flags: result = '$' & key
|
||||||
elif not (useEmpty in flags): raiseFormatException(key)
|
elif useEmpty notin flags: raiseFormatException(key)
|
||||||
|
|
||||||
proc newStringTable*(mode: StringTableMode): StringTableRef {.
|
proc newStringTable*(mode: StringTableMode): StringTableRef {.
|
||||||
rtl, extern: "nst$1".} =
|
rtl, extern: "nst$1".} =
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,21 @@ when defined(windows):
|
||||||
var
|
var
|
||||||
oldAttr = getAttributes()
|
oldAttr = getAttributes()
|
||||||
|
|
||||||
|
proc winGetch(): cint {.header: "<conio.h>", importc: "_getch".}
|
||||||
|
else:
|
||||||
|
import termios, unsigned
|
||||||
|
|
||||||
|
proc setRaw(fd: FileHandle, time: cint = TCSAFLUSH) =
|
||||||
|
var mode: Termios
|
||||||
|
discard fd.tcgetattr(addr mode)
|
||||||
|
mode.iflag = mode.iflag and not Tcflag(BRKINT or ICRNL or INPCK or ISTRIP or IXON)
|
||||||
|
mode.oflag = mode.oflag and not Tcflag(OPOST)
|
||||||
|
mode.cflag = (mode.cflag and not Tcflag(CSIZE or PARENB)) or CS8
|
||||||
|
mode.lflag = mode.lflag and not Tcflag(ECHO or ICANON or IEXTEN or ISIG)
|
||||||
|
mode.cc[VMIN] = 1.cuchar
|
||||||
|
mode.cc[VTIME] = 0.cuchar
|
||||||
|
discard fd.tcsetattr(time, addr mode)
|
||||||
|
|
||||||
proc setCursorPos*(x, y: int) =
|
proc setCursorPos*(x, y: int) =
|
||||||
## sets the terminal's cursor to the (x,y) position. (0,0) is the
|
## sets the terminal's cursor to the (x,y) position. (0,0) is the
|
||||||
## upper left of the screen.
|
## upper left of the screen.
|
||||||
|
|
@ -349,6 +364,19 @@ macro styledEcho*(m: varargs[expr]): stmt =
|
||||||
result.add(newCall(bindSym"write", bindSym"stdout", newStrLitNode("\n")))
|
result.add(newCall(bindSym"write", bindSym"stdout", newStrLitNode("\n")))
|
||||||
result.add(newCall(bindSym"resetAttributes"))
|
result.add(newCall(bindSym"resetAttributes"))
|
||||||
|
|
||||||
|
proc getch*(): char =
|
||||||
|
## Read a single character from the terminal, blocking until it is entered.
|
||||||
|
## The character is not printed to the terminal.
|
||||||
|
when defined(windows):
|
||||||
|
result = winGetch().char
|
||||||
|
else:
|
||||||
|
let fd = getFileHandle(stdin)
|
||||||
|
var oldMode: Termios
|
||||||
|
discard fd.tcgetattr(addr oldMode)
|
||||||
|
fd.setRaw()
|
||||||
|
result = stdin.readChar()
|
||||||
|
discard fd.tcsetattr(TCSADRAIN, addr oldMode)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
system.addQuitProc(resetAttributes)
|
system.addQuitProc(resetAttributes)
|
||||||
write(stdout, "never mind")
|
write(stdout, "never mind")
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ when declared(stdout):
|
||||||
|
|
||||||
when not defined(ECMAScript):
|
when not defined(ECMAScript):
|
||||||
import terminal
|
import terminal
|
||||||
|
system.addQuitProc(resetAttributes)
|
||||||
|
|
||||||
type
|
type
|
||||||
TestStatus* = enum OK, FAILED
|
TestStatus* = enum OK, FAILED
|
||||||
|
|
@ -234,5 +235,3 @@ if envOutLvl.len > 0:
|
||||||
if $opt == envOutLvl:
|
if $opt == envOutLvl:
|
||||||
outputLevel = opt
|
outputLevel = opt
|
||||||
break
|
break
|
||||||
|
|
||||||
system.addQuitProc(resetAttributes)
|
|
||||||
|
|
|
||||||
|
|
@ -343,10 +343,10 @@ type
|
||||||
##
|
##
|
||||||
## Each exception has to inherit from `Exception`. See the full `exception
|
## Each exception has to inherit from `Exception`. See the full `exception
|
||||||
## hierarchy`_.
|
## hierarchy`_.
|
||||||
parent: ref Exception ## parent exception (can be used as a stack)
|
parent*: ref Exception ## parent exception (can be used as a stack)
|
||||||
name: cstring ## The exception's name is its Nim identifier.
|
name: cstring ## The exception's name is its Nim identifier.
|
||||||
## This field is filled automatically in the
|
## This field is filled automatically in the
|
||||||
## ``raise`` statement.
|
## ``raise`` statement.
|
||||||
msg* {.exportc: "message".}: string ## the exception's message. Not
|
msg* {.exportc: "message".}: string ## the exception's message. Not
|
||||||
## providing an exception message
|
## providing an exception message
|
||||||
## is bad style.
|
## is bad style.
|
||||||
|
|
@ -3161,7 +3161,7 @@ when hostOS != "standalone":
|
||||||
x[j+i] = item[j]
|
x[j+i] = item[j]
|
||||||
inc(j)
|
inc(j)
|
||||||
|
|
||||||
proc compiles*(x): bool {.magic: "Compiles", noSideEffect.} =
|
proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect.} =
|
||||||
## Special compile-time procedure that checks whether `x` can be compiled
|
## Special compile-time procedure that checks whether `x` can be compiled
|
||||||
## without any semantic error.
|
## without any semantic error.
|
||||||
## This can be used to check whether a type supports some operation:
|
## This can be used to check whether a type supports some operation:
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ proc genericAssignAux(dest, src: pointer, n: ptr TNimNode,
|
||||||
var m = selectBranch(src, n)
|
var m = selectBranch(src, n)
|
||||||
# reset if different branches are in use; note different branches also
|
# reset if different branches are in use; note different branches also
|
||||||
# imply that's not self-assignment (``x = x``)!
|
# imply that's not self-assignment (``x = x``)!
|
||||||
if m != dd and dd != nil:
|
if m != dd and dd != nil:
|
||||||
genericResetAux(dest, dd)
|
genericResetAux(dest, dd)
|
||||||
copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset),
|
copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset),
|
||||||
n.typ.size)
|
n.typ.size)
|
||||||
|
|
@ -205,9 +205,13 @@ proc genericReset(dest: pointer, mt: PNimType) =
|
||||||
case mt.kind
|
case mt.kind
|
||||||
of tyString, tyRef, tySequence:
|
of tyString, tyRef, tySequence:
|
||||||
unsureAsgnRef(cast[PPointer](dest), nil)
|
unsureAsgnRef(cast[PPointer](dest), nil)
|
||||||
of tyObject, tyTuple:
|
of tyTuple:
|
||||||
# we don't need to reset m_type field for tyObject
|
|
||||||
genericResetAux(dest, mt.node)
|
genericResetAux(dest, mt.node)
|
||||||
|
of tyObject:
|
||||||
|
genericResetAux(dest, mt.node)
|
||||||
|
# also reset the type field for tyObject, for correct branch switching!
|
||||||
|
var pint = cast[ptr PNimType](dest)
|
||||||
|
pint[] = nil
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
for i in 0..(mt.size div mt.base.size)-1:
|
for i in 0..(mt.size div mt.base.size)-1:
|
||||||
genericReset(cast[pointer](d +% i*% mt.base.size), mt.base)
|
genericReset(cast[pointer](d +% i*% mt.base.size), mt.base)
|
||||||
|
|
|
||||||
|
|
@ -84,16 +84,18 @@ elif defined(windows) or defined(dos):
|
||||||
type
|
type
|
||||||
THINSTANCE {.importc: "HINSTANCE".} = object
|
THINSTANCE {.importc: "HINSTANCE".} = object
|
||||||
x: pointer
|
x: pointer
|
||||||
|
proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
|
||||||
|
importcpp: "(void*)GetProcAddress(@)", header: "<windows.h>", stdcall.}
|
||||||
else:
|
else:
|
||||||
type
|
type
|
||||||
THINSTANCE {.importc: "HINSTANCE".} = pointer
|
THINSTANCE {.importc: "HINSTANCE".} = pointer
|
||||||
|
proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
|
||||||
|
importc: "GetProcAddress", header: "<windows.h>", stdcall.}
|
||||||
|
|
||||||
proc freeLibrary(lib: THINSTANCE) {.
|
proc freeLibrary(lib: THINSTANCE) {.
|
||||||
importc: "FreeLibrary", header: "<windows.h>", stdcall.}
|
importc: "FreeLibrary", header: "<windows.h>", stdcall.}
|
||||||
proc winLoadLibrary(path: cstring): THINSTANCE {.
|
proc winLoadLibrary(path: cstring): THINSTANCE {.
|
||||||
importc: "LoadLibraryA", header: "<windows.h>", stdcall.}
|
importc: "LoadLibraryA", header: "<windows.h>", stdcall.}
|
||||||
proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
|
|
||||||
importc: "GetProcAddress", header: "<windows.h>", stdcall.}
|
|
||||||
|
|
||||||
proc nimUnloadLibrary(lib: TLibHandle) =
|
proc nimUnloadLibrary(lib: TLibHandle) =
|
||||||
freeLibrary(cast[THINSTANCE](lib))
|
freeLibrary(cast[THINSTANCE](lib))
|
||||||
|
|
|
||||||
|
|
@ -183,11 +183,17 @@ proc rawEchoNL() {.inline, compilerproc.} = write(stdout, "\n")
|
||||||
when (defined(windows) and not defined(useWinAnsi)) or defined(nimdoc):
|
when (defined(windows) and not defined(useWinAnsi)) or defined(nimdoc):
|
||||||
include "system/widestrs"
|
include "system/widestrs"
|
||||||
|
|
||||||
when defined(windows) and not defined(useWinAnsi):
|
when defined(windows) and not defined(useWinAnsi):
|
||||||
proc wfopen(filename, mode: WideCString): pointer {.
|
when defined(cpp):
|
||||||
importc: "_wfopen", nodecl.}
|
proc wfopen(filename, mode: WideCString): pointer {.
|
||||||
proc wfreopen(filename, mode: WideCString, stream: File): File {.
|
importcpp: "_wfopen((const wchar_t*)#, (const wchar_t*)#)", nodecl.}
|
||||||
importc: "_wfreopen", nodecl.}
|
proc wfreopen(filename, mode: WideCString, stream: File): File {.
|
||||||
|
importc: "_wfreopen((const wchar_t*)#, (const wchar_t*)#)", nodecl.}
|
||||||
|
else:
|
||||||
|
proc wfopen(filename, mode: WideCString): pointer {.
|
||||||
|
importc: "_wfopen", nodecl.}
|
||||||
|
proc wfreopen(filename, mode: WideCString, stream: File): File {.
|
||||||
|
importc: "_wfreopen", nodecl.}
|
||||||
|
|
||||||
proc fopen(filename, mode: cstring): pointer =
|
proc fopen(filename, mode: cstring): pointer =
|
||||||
var f = newWideCString(filename)
|
var f = newWideCString(filename)
|
||||||
|
|
|
||||||
26
readme.md
26
readme.md
|
|
@ -66,8 +66,24 @@ Copyright (c) 2006-2014 Andreas Rumpf.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
# Build Status
|
# Build Status
|
||||||
| |Linux|Windows|Mac|
|
[**Build Waterfall**][waterfall]
|
||||||
|---|---|---|---|
|
|
||||||
| x86 |  |  | 
|
| | Linux | Windows | Mac |
|
||||||
| x86_64 |  |  | 
|
| ------ | ----- | ------- | --- |
|
||||||
| arm |  |
|
| x86 | ![linux-x86][linux-x86-img] | ![windows-x86][windows-x86-img] | ![mac-x86][mac-x86-img] |
|
||||||
|
| x86_64 | ![linux-x86_64][linux-x86_64-img] | ![windows-x86_64][windows-x86_64-img] | ![mac-x86_64][mac-x86_64-img] |
|
||||||
|
| arm | ![linux-armv5][linux-arm5-img]<br/> ![linux-armv6][linux-arm6-img]<br/> ![linux-armv7][linux-arm7-img] | | |
|
||||||
|
|
||||||
|
[linux-x86-img]: http://buildbot.nim-lang.org/buildstatusimage?builder=linux-x32-builder
|
||||||
|
[linux-x86_64-img]: http://buildbot.nim-lang.org/buildstatusimage?builder=linux-x64-builder
|
||||||
|
[linux-arm5-img]: http://buildbot.nim-lang.org/buildstatusimage?builder=linux-arm5-builder
|
||||||
|
[linux-arm6-img]: http://buildbot.nim-lang.org/buildstatusimage?builder=linux-arm6-builder
|
||||||
|
[linux-arm7-img]: http://buildbot.nim-lang.org/buildstatusimage?builder=linux-arm7-builder
|
||||||
|
|
||||||
|
[windows-x86-img]: http://buildbot.nim-lang.org/buildstatusimage?builder=windows-x32-builder
|
||||||
|
[windows-x86_64-img]: http://buildbot.nim-lang.org/buildstatusimage?builder=windows-x64-builder
|
||||||
|
|
||||||
|
[mac-x86-img]: http://buildbot.nim-lang.org/buildstatusimage?builder=mac-x32-builder
|
||||||
|
[mac-x86_64-img]: http://buildbot.nim-lang.org/buildstatusimage?builder=mac-x64-builder
|
||||||
|
|
||||||
|
[waterfall]: http://buildbot.nim-lang.org/waterfall
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ discard """
|
||||||
WARNING: false first assertion from bar
|
WARNING: false first assertion from bar
|
||||||
ERROR: false second assertion from bar
|
ERROR: false second assertion from bar
|
||||||
-1
|
-1
|
||||||
tfailedassert.nim:27 false assertion from foo
|
tests/assert/tfailedassert.nim:27 false assertion from foo
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ proc processClient(fd: int) {.async.} =
|
||||||
var foo = line[0]
|
var foo = line[0]
|
||||||
if foo == 'g':
|
if foo == 'g':
|
||||||
raise newException(EBase, "foobar")
|
raise newException(EBase, "foobar")
|
||||||
|
|
||||||
|
|
||||||
proc serve() {.async.} =
|
proc serve() {.async.} =
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,3 +49,44 @@ proc catch() {.async.} =
|
||||||
assert false
|
assert false
|
||||||
|
|
||||||
asyncCheck catch()
|
asyncCheck catch()
|
||||||
|
|
||||||
|
proc test(): Future[bool] {.async.} =
|
||||||
|
result = false
|
||||||
|
try:
|
||||||
|
raise newException(OSError, "Foobar")
|
||||||
|
except:
|
||||||
|
result = true
|
||||||
|
return
|
||||||
|
|
||||||
|
proc foo(): Future[bool] {.async.} = discard
|
||||||
|
|
||||||
|
proc test2(): Future[bool] {.async.} =
|
||||||
|
result = false
|
||||||
|
try:
|
||||||
|
discard await foo()
|
||||||
|
raise newException(OSError, "Foobar")
|
||||||
|
except:
|
||||||
|
result = true
|
||||||
|
return
|
||||||
|
|
||||||
|
proc test3(): Future[int] {.async.} =
|
||||||
|
result = 0
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
discard await foo()
|
||||||
|
raise newException(OSError, "Hello")
|
||||||
|
except:
|
||||||
|
result = 1
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
result = 2
|
||||||
|
return
|
||||||
|
|
||||||
|
var x = test()
|
||||||
|
assert x.read
|
||||||
|
|
||||||
|
x = test2()
|
||||||
|
assert x.read
|
||||||
|
|
||||||
|
var y = test3()
|
||||||
|
assert y.read == 2
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
line: 18
|
line: 18
|
||||||
errormsg: "type mismatch: got (proc (TScgi) | proc (AsyncSocket, StringTableRef, string){.gcsafe.})"
|
errormsg: "type mismatch: got (proc (TScgi) | proc (AsyncSocket, StringTableRef, string)"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#bug #442
|
#bug #442
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: 'type mismatch: got (mc.typ)'
|
errormsg: "type mismatch: got (mc.typ)"
|
||||||
line: 12
|
line: 12
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
15
tests/closure/ttimeinfo.nim
Normal file
15
tests/closure/ttimeinfo.nim
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# bug #2073
|
||||||
|
|
||||||
|
import sequtils
|
||||||
|
import times
|
||||||
|
|
||||||
|
# 1
|
||||||
|
proc f(n: int): TimeInfo =
|
||||||
|
TimeInfo(year: n, month: mJan, monthday: 1)
|
||||||
|
|
||||||
|
echo toSeq(2000 || 2015).map(f)
|
||||||
|
|
||||||
|
# 2
|
||||||
|
echo toSeq(2000 || 2015).map(proc (n: int): TimeInfo =
|
||||||
|
TimeInfo(year: n, month: mJan, monthday: 1)
|
||||||
|
)
|
||||||
5
tests/cpp/trawsockets.nim
Normal file
5
tests/cpp/trawsockets.nim
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nim cpp $target"
|
||||||
|
"""
|
||||||
|
|
||||||
|
import rawsockets
|
||||||
5
tests/cpp/ttypeinfo.nim
Normal file
5
tests/cpp/ttypeinfo.nim
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nim cpp $target"
|
||||||
|
"""
|
||||||
|
|
||||||
|
import typeinfo
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
discard """
|
discard """
|
||||||
line: 2166
|
|
||||||
file: "system.nim"
|
file: "system.nim"
|
||||||
errormsg: "can raise an unlisted exception: ref IOError"
|
errormsg: "can raise an unlisted exception: ref IOError"
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,14 @@ proc newPlus(a, b: ref TExpr): ref TPlusExpr =
|
||||||
result.b = b
|
result.b = b
|
||||||
result.op2 = $getOccupiedMem()
|
result.op2 = $getOccupiedMem()
|
||||||
|
|
||||||
|
const Limit = when compileOption("gc", "markAndSweep"): 5*1024*1024 else: 500_000
|
||||||
|
|
||||||
for i in 0..100_000:
|
for i in 0..100_000:
|
||||||
var s: array[0..11, ref TExpr]
|
var s: array[0..11, ref TExpr]
|
||||||
for j in 0..high(s):
|
for j in 0..high(s):
|
||||||
s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4))
|
s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4))
|
||||||
if eval(s[j]) != j+6:
|
if eval(s[j]) != j+6:
|
||||||
quit "error: wrong result"
|
quit "error: wrong result"
|
||||||
if getOccupiedMem() > 500_000: quit("still a leak!")
|
if getOccupiedMem() > Limit: quit("still a leak!")
|
||||||
|
|
||||||
echo "no leak: ", getOccupiedMem()
|
echo "no leak: ", getOccupiedMem()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''TMatrix[3, 3, system.int]
|
output: '''TMatrix[3, 3, system.int]
|
||||||
3
|
|
||||||
3'''
|
3'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -22,5 +21,5 @@ proc echoMat2(a: TMat2) =
|
||||||
var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9])
|
var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9])
|
||||||
|
|
||||||
echoMatrix m
|
echoMatrix m
|
||||||
echoMat2 m
|
#echoMat2 m
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
discard """
|
discard """
|
||||||
output: "2"
|
output: '''2
|
||||||
|
88'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type
|
type
|
||||||
TValue* {.pure, final.} = object of TObject
|
TValue* {.pure, final.} = object of RootObj
|
||||||
a: int
|
a: int
|
||||||
PValue = ref TValue
|
PValue = ref TValue
|
||||||
PPValue = ptr PValue
|
PPValue = ptr PValue
|
||||||
|
|
@ -16,3 +17,19 @@ var sp: PPValue = addr x
|
||||||
sp.a = 2
|
sp.a = 2
|
||||||
if sp.a == 2: echo 2 # with sp[].a the error is gone
|
if sp.a == 2: echo 2 # with sp[].a the error is gone
|
||||||
|
|
||||||
|
# Test the new auto-deref a little
|
||||||
|
|
||||||
|
{.experimental.}
|
||||||
|
|
||||||
|
proc p(x: var int; y: int) = x += y
|
||||||
|
|
||||||
|
block:
|
||||||
|
var x: ref int
|
||||||
|
new(x)
|
||||||
|
|
||||||
|
x.p(44)
|
||||||
|
|
||||||
|
var indirect = p
|
||||||
|
x.indirect(44)
|
||||||
|
|
||||||
|
echo x[]
|
||||||
|
|
|
||||||
24
tests/iter/tconcat.nim
Normal file
24
tests/iter/tconcat.nim
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
discard """
|
||||||
|
output: '''1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
20
|
||||||
|
21
|
||||||
|
22
|
||||||
|
23'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
proc toIter*[T](s: Slice[T]): iterator: T =
|
||||||
|
iterator it: T {.closure.} =
|
||||||
|
for x in s.a..s.b:
|
||||||
|
yield x
|
||||||
|
return it
|
||||||
|
|
||||||
|
iterator concat*[T](its: varargs[T, toIter]): auto =
|
||||||
|
for i in its:
|
||||||
|
for x in i():
|
||||||
|
yield x
|
||||||
|
|
||||||
|
for i in concat(1..4, 20..23):
|
||||||
|
echo i
|
||||||
|
|
@ -74,7 +74,7 @@ type
|
||||||
contacts*: PContact
|
contacts*: PContact
|
||||||
stamp*: TTimestamp
|
stamp*: TTimestamp
|
||||||
handler*: PCollisionHandler
|
handler*: PCollisionHandler
|
||||||
swappedColl*: bool32
|
swappedColl*: Bool32
|
||||||
state*: TArbiterState
|
state*: TArbiterState
|
||||||
PCollisionHandler* = ptr TCollisionHandler
|
PCollisionHandler* = ptr TCollisionHandler
|
||||||
TCollisionHandler*{.pf.} = object
|
TCollisionHandler*{.pf.} = object
|
||||||
|
|
@ -108,7 +108,7 @@ type
|
||||||
#/ Collision begin event function callback type.
|
#/ Collision begin event function callback type.
|
||||||
#/ Returning false from a begin callback causes the collision to be ignored until
|
#/ Returning false from a begin callback causes the collision to be ignored until
|
||||||
#/ the the separate callback is called when the objects stop colliding.
|
#/ the the separate callback is called when the objects stop colliding.
|
||||||
TCollisionBeginFunc* = proc (arb: PArbiter; space: PSpace; data: pointer): Bool{.
|
TCollisionBeginFunc* = proc (arb: PArbiter; space: PSpace; data: pointer): bool{.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
#/ Collision pre-solve event function callback type.
|
#/ Collision pre-solve event function callback type.
|
||||||
#/ Returning false from a pre-step callback causes the collision to be ignored until the next step.
|
#/ Returning false from a pre-step callback causes the collision to be ignored until the next step.
|
||||||
|
|
@ -142,14 +142,14 @@ type
|
||||||
PSpatialIndex = ptr TSpatialIndex
|
PSpatialIndex = ptr TSpatialIndex
|
||||||
TSpatialIndex{.pf.} = object
|
TSpatialIndex{.pf.} = object
|
||||||
klass: PSpatialIndexClass
|
klass: PSpatialIndexClass
|
||||||
bbfunc: TSpatialIndexBBFunc
|
bbfun: TSpatialIndexBBFunc
|
||||||
staticIndex: PSpatialIndex
|
staticIndex: PSpatialIndex
|
||||||
dynamicIndex: PSpatialIndex
|
dynamicIndex: PSpatialIndex
|
||||||
|
|
||||||
TSpatialIndexDestroyImpl* = proc (index: PSpatialIndex){.cdecl.}
|
TSpatialIndexDestroyImpl* = proc (index: PSpatialIndex){.cdecl.}
|
||||||
TSpatialIndexCountImpl* = proc (index: PSpatialIndex): cint{.cdecl.}
|
TSpatialIndexCountImpl* = proc (index: PSpatialIndex): cint{.cdecl.}
|
||||||
TSpatialIndexEachImpl* = proc (index: PSpatialIndex;
|
TSpatialIndexEachImpl* = proc (index: PSpatialIndex;
|
||||||
func: TSpatialIndexIteratorFunc; data: pointer){.
|
fun: TSpatialIndexIteratorFunc; data: pointer){.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
TSpatialIndexContainsImpl* = proc (index: PSpatialIndex; obj: pointer;
|
TSpatialIndexContainsImpl* = proc (index: PSpatialIndex; obj: pointer;
|
||||||
hashid: THashValue): Bool32 {.cdecl.}
|
hashid: THashValue): Bool32 {.cdecl.}
|
||||||
|
|
@ -161,15 +161,15 @@ type
|
||||||
TSpatialIndexReindexObjectImpl* = proc (index: PSpatialIndex;
|
TSpatialIndexReindexObjectImpl* = proc (index: PSpatialIndex;
|
||||||
obj: pointer; hashid: THashValue){.cdecl.}
|
obj: pointer; hashid: THashValue){.cdecl.}
|
||||||
TSpatialIndexReindexQueryImpl* = proc (index: PSpatialIndex;
|
TSpatialIndexReindexQueryImpl* = proc (index: PSpatialIndex;
|
||||||
func: TSpatialIndexQueryFunc; data: pointer){.cdecl.}
|
fun: TSpatialIndexQueryFunc; data: pointer){.cdecl.}
|
||||||
TSpatialIndexPointQueryImpl* = proc (index: PSpatialIndex; point: TVector;
|
TSpatialIndexPointQueryImpl* = proc (index: PSpatialIndex; point: TVector;
|
||||||
func: TSpatialIndexQueryFunc;
|
fun: TSpatialIndexQueryFunc;
|
||||||
data: pointer){.cdecl.}
|
data: pointer){.cdecl.}
|
||||||
TSpatialIndexSegmentQueryImpl* = proc (index: PSpatialIndex; obj: pointer;
|
TSpatialIndexSegmentQueryImpl* = proc (index: PSpatialIndex; obj: pointer;
|
||||||
a: TVector; b: TVector; t_exit: CpFloat; func: TSpatialIndexSegmentQueryFunc;
|
a: TVector; b: TVector; t_exit: CpFloat; fun: TSpatialIndexSegmentQueryFunc;
|
||||||
data: pointer){.cdecl.}
|
data: pointer){.cdecl.}
|
||||||
TSpatialIndexQueryImpl* = proc (index: PSpatialIndex; obj: pointer;
|
TSpatialIndexQueryImpl* = proc (index: PSpatialIndex; obj: pointer;
|
||||||
bb: TBB; func: TSpatialIndexQueryFunc;
|
bb: TBB; fun: TSpatialIndexQueryFunc;
|
||||||
data: pointer){.cdecl.}
|
data: pointer){.cdecl.}
|
||||||
PSpatialIndexClass* = ptr TSpatialIndexClass
|
PSpatialIndexClass* = ptr TSpatialIndexClass
|
||||||
TSpatialIndexClass*{.pf.} = object
|
TSpatialIndexClass*{.pf.} = object
|
||||||
|
|
@ -286,7 +286,7 @@ type
|
||||||
CP_CIRCLE_SHAPE, CP_SEGMENT_SHAPE, CP_POLY_SHAPE, CP_NUM_SHAPES
|
CP_CIRCLE_SHAPE, CP_SEGMENT_SHAPE, CP_POLY_SHAPE, CP_NUM_SHAPES
|
||||||
TShapeCacheDataImpl* = proc (shape: PShape; p: TVector; rot: TVector): TBB{.cdecl.}
|
TShapeCacheDataImpl* = proc (shape: PShape; p: TVector; rot: TVector): TBB{.cdecl.}
|
||||||
TShapeDestroyImpl* = proc (shape: PShape){.cdecl.}
|
TShapeDestroyImpl* = proc (shape: PShape){.cdecl.}
|
||||||
TShapePointQueryImpl* = proc (shape: PShape; p: TVector): bool32 {.cdecl.}
|
TShapePointQueryImpl* = proc (shape: PShape; p: TVector): Bool32 {.cdecl.}
|
||||||
TShapeSegmentQueryImpl* = proc (shape: PShape; a: TVector; b: TVector;
|
TShapeSegmentQueryImpl* = proc (shape: PShape; a: TVector; b: TVector;
|
||||||
info: PSegmentQueryInfo){.cdecl.}
|
info: PSegmentQueryInfo){.cdecl.}
|
||||||
PShapeClass* = ptr TShapeClass
|
PShapeClass* = ptr TShapeClass
|
||||||
|
|
@ -427,7 +427,7 @@ defGetter(PSpace, CpFloat, currDt, CurrentTimeStep)
|
||||||
|
|
||||||
|
|
||||||
#/ returns true from inside a callback and objects cannot be added/removed.
|
#/ returns true from inside a callback and objects cannot be added/removed.
|
||||||
proc isLocked*(space: PSpace): Bool{.inline.} =
|
proc isLocked*(space: PSpace): bool{.inline.} =
|
||||||
result = space.locked.bool
|
result = space.locked.bool
|
||||||
|
|
||||||
#/ Set a default collision handler for this space.
|
#/ Set a default collision handler for this space.
|
||||||
|
|
@ -478,24 +478,24 @@ proc removeBody*(space: PSpace; body: PBody){.
|
||||||
proc RemoveConstraint*(space: PSpace; constraint: PConstraint){.
|
proc RemoveConstraint*(space: PSpace; constraint: PConstraint){.
|
||||||
cdecl, importc: "cpSpaceRemoveConstraint", dynlib: Lib.}
|
cdecl, importc: "cpSpaceRemoveConstraint", dynlib: Lib.}
|
||||||
#/ Test if a collision shape has been added to the space.
|
#/ Test if a collision shape has been added to the space.
|
||||||
proc containsShape*(space: PSpace; shape: PShape): Bool{.
|
proc containsShape*(space: PSpace; shape: PShape): bool{.
|
||||||
cdecl, importc: "cpSpaceContainsShape", dynlib: Lib.}
|
cdecl, importc: "cpSpaceContainsShape", dynlib: Lib.}
|
||||||
#/ Test if a rigid body has been added to the space.
|
#/ Test if a rigid body has been added to the space.
|
||||||
proc containsBody*(space: PSpace; body: PBody): Bool{.
|
proc containsBody*(space: PSpace; body: PBody): bool{.
|
||||||
cdecl, importc: "cpSpaceContainsBody", dynlib: Lib.}
|
cdecl, importc: "cpSpaceContainsBody", dynlib: Lib.}
|
||||||
#/ Test if a constraint has been added to the space.
|
#/ Test if a constraint has been added to the space.
|
||||||
|
|
||||||
proc containsConstraint*(space: PSpace; constraint: PConstraint): Bool{.
|
proc containsConstraint*(space: PSpace; constraint: PConstraint): bool{.
|
||||||
cdecl, importc: "cpSpaceContainsConstraint", dynlib: Lib.}
|
cdecl, importc: "cpSpaceContainsConstraint", dynlib: Lib.}
|
||||||
#/ Schedule a post-step callback to be called when cpSpaceStep() finishes.
|
#/ Schedule a post-step callback to be called when cpSpaceStep() finishes.
|
||||||
#/ @c obj is used a key, you can only register one callback per unique value for @c obj
|
#/ @c obj is used a key, you can only register one callback per unique value for @c obj
|
||||||
proc addPostStepCallback*(space: PSpace; func: TPostStepFunc;
|
proc addPostStepCallback*(space: PSpace; fun: TPostStepFunc;
|
||||||
obj: pointer; data: pointer){.
|
obj: pointer; data: pointer){.
|
||||||
cdecl, importc: "cpSpaceAddPostStepCallback", dynlib: Lib.}
|
cdecl, importc: "cpSpaceAddPostStepCallback", dynlib: Lib.}
|
||||||
|
|
||||||
#/ Query the space at a point and call @c func for each shape found.
|
#/ Query the space at a point and call @c func for each shape found.
|
||||||
proc pointQuery*(space: PSpace; point: TVector; layers: TLayers;
|
proc pointQuery*(space: PSpace; point: TVector; layers: TLayers;
|
||||||
group: TGroup; func: TSpacePointQueryFunc; data: pointer){.
|
group: TGroup; fun: TSpacePointQueryFunc; data: pointer){.
|
||||||
cdecl, importc: "cpSpacePointQuery", dynlib: Lib.}
|
cdecl, importc: "cpSpacePointQuery", dynlib: Lib.}
|
||||||
|
|
||||||
#/ Query the space at a point and return the first shape found. Returns NULL if no shapes were found.
|
#/ Query the space at a point and return the first shape found. Returns NULL if no shapes were found.
|
||||||
|
|
@ -506,7 +506,7 @@ proc pointQueryFirst*(space: PSpace; point: TVector; layers: TLayers;
|
||||||
#/ Perform a directed line segment query (like a raycast) against the space calling @c func for each shape intersected.
|
#/ Perform a directed line segment query (like a raycast) against the space calling @c func for each shape intersected.
|
||||||
proc segmentQuery*(space: PSpace; start: TVector; to: TVector;
|
proc segmentQuery*(space: PSpace; start: TVector; to: TVector;
|
||||||
layers: TLayers; group: TGroup;
|
layers: TLayers; group: TGroup;
|
||||||
func: TSpaceSegmentQueryFunc; data: pointer){.
|
fun: TSpaceSegmentQueryFunc; data: pointer){.
|
||||||
cdecl, importc: "cpSpaceSegmentQuery", dynlib: Lib.}
|
cdecl, importc: "cpSpaceSegmentQuery", dynlib: Lib.}
|
||||||
#/ Perform a directed line segment query (like a raycast) against the space and return the first shape hit. Returns NULL if no shapes were hit.
|
#/ Perform a directed line segment query (like a raycast) against the space and return the first shape hit. Returns NULL if no shapes were hit.
|
||||||
proc segmentQueryFirst*(space: PSpace; start: TVector; to: TVector;
|
proc segmentQueryFirst*(space: PSpace; start: TVector; to: TVector;
|
||||||
|
|
@ -517,26 +517,26 @@ proc segmentQueryFirst*(space: PSpace; start: TVector; to: TVector;
|
||||||
#/ Perform a fast rectangle query on the space calling @c func for each shape found.
|
#/ Perform a fast rectangle query on the space calling @c func for each shape found.
|
||||||
#/ Only the shape's bounding boxes are checked for overlap, not their full shape.
|
#/ Only the shape's bounding boxes are checked for overlap, not their full shape.
|
||||||
proc BBQuery*(space: PSpace; bb: TBB; layers: TLayers; group: TGroup;
|
proc BBQuery*(space: PSpace; bb: TBB; layers: TLayers; group: TGroup;
|
||||||
func: TSpaceBBQueryFunc; data: pointer){.
|
fun: TSpaceBBQueryFunc; data: pointer){.
|
||||||
cdecl, importc: "cpSpaceBBQuery", dynlib: Lib.}
|
cdecl, importc: "cpSpaceBBQuery", dynlib: Lib.}
|
||||||
|
|
||||||
#/ Query a space for any shapes overlapping the given shape and call @c func for each shape found.
|
#/ Query a space for any shapes overlapping the given shape and call @c func for each shape found.
|
||||||
proc shapeQuery*(space: PSpace; shape: PShape; func: TSpaceShapeQueryFunc; data: pointer): Bool {.
|
proc shapeQuery*(space: PSpace; shape: PShape; fun: TSpaceShapeQueryFunc; data: pointer): bool {.
|
||||||
cdecl, importc: "cpSpaceShapeQuery", dynlib: Lib.}
|
cdecl, importc: "cpSpaceShapeQuery", dynlib: Lib.}
|
||||||
#/ Call cpBodyActivate() for any shape that is overlaps the given shape.
|
#/ Call cpBodyActivate() for any shape that is overlaps the given shape.
|
||||||
proc activateShapesTouchingShape*(space: PSpace; shape: PShape){.
|
proc activateShapesTouchingShape*(space: PSpace; shape: PShape){.
|
||||||
cdecl, importc: "cpSpaceActivateShapesTouchingShape", dynlib: Lib.}
|
cdecl, importc: "cpSpaceActivateShapesTouchingShape", dynlib: Lib.}
|
||||||
|
|
||||||
#/ Call @c func for each body in the space.
|
#/ Call @c func for each body in the space.
|
||||||
proc eachBody*(space: PSpace; func: TSpaceBodyIteratorFunc; data: pointer){.
|
proc eachBody*(space: PSpace; fun: TSpaceBodyIteratorFunc; data: pointer){.
|
||||||
cdecl, importc: "cpSpaceEachBody", dynlib: Lib.}
|
cdecl, importc: "cpSpaceEachBody", dynlib: Lib.}
|
||||||
|
|
||||||
#/ Call @c func for each shape in the space.
|
#/ Call @c func for each shape in the space.
|
||||||
proc eachShape*(space: PSpace; func: TSpaceShapeIteratorFunc;
|
proc eachShape*(space: PSpace; fun: TSpaceShapeIteratorFunc;
|
||||||
data: pointer){.
|
data: pointer){.
|
||||||
cdecl, importc: "cpSpaceEachShape", dynlib: Lib.}
|
cdecl, importc: "cpSpaceEachShape", dynlib: Lib.}
|
||||||
#/ Call @c func for each shape in the space.
|
#/ Call @c func for each shape in the space.
|
||||||
proc eachConstraint*(space: PSpace; func: TSpaceConstraintIteratorFunc;
|
proc eachConstraint*(space: PSpace; fun: TSpaceConstraintIteratorFunc;
|
||||||
data: pointer){.
|
data: pointer){.
|
||||||
cdecl, importc: "cpSpaceEachConstraint", dynlib: Lib.}
|
cdecl, importc: "cpSpaceEachConstraint", dynlib: Lib.}
|
||||||
#/ Update the collision detection info for the static shapes in the space.
|
#/ Update the collision detection info for the static shapes in the space.
|
||||||
|
|
@ -674,7 +674,7 @@ proc dist*(v1, v2: TVector): CpFloat {.inline.} =
|
||||||
proc distsq*(v1, v2: TVector): CpFloat {.inline.} =
|
proc distsq*(v1, v2: TVector): CpFloat {.inline.} =
|
||||||
result = (v1 - v2).lenSq #vlengthsq(vsub(v1, v2))
|
result = (v1 - v2).lenSq #vlengthsq(vsub(v1, v2))
|
||||||
#/ Returns true if the distance between v1 and v2 is less than dist.
|
#/ Returns true if the distance between v1 and v2 is less than dist.
|
||||||
proc near*(v1, v2: TVector; dist: CpFloat): Bool{.inline.} =
|
proc near*(v1, v2: TVector; dist: CpFloat): bool{.inline.} =
|
||||||
result = v1.distSq(v2) < dist * dist
|
result = v1.distSq(v2) < dist * dist
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -706,13 +706,13 @@ proc Sleep*(body: PBody){.importc: "cpBodySleep", dynlib: Lib.}
|
||||||
proc SleepWithGroup*(body: PBody; group: PBody){.
|
proc SleepWithGroup*(body: PBody; group: PBody){.
|
||||||
importc: "cpBodySleepWithGroup", dynlib: Lib.}
|
importc: "cpBodySleepWithGroup", dynlib: Lib.}
|
||||||
#/ Returns true if the body is sleeping.
|
#/ Returns true if the body is sleeping.
|
||||||
proc isSleeping*(body: PBody): Bool {.inline.} =
|
proc isSleeping*(body: PBody): bool {.inline.} =
|
||||||
return body.node.root != nil
|
return body.node.root != nil
|
||||||
#/ Returns true if the body is static.
|
#/ Returns true if the body is static.
|
||||||
proc isStatic*(body: PBody): bool {.inline.} =
|
proc isStatic*(body: PBody): bool {.inline.} =
|
||||||
return body.node.idleTime == CpInfinity
|
return body.node.idleTime == CpInfinity
|
||||||
#/ Returns true if the body has not been added to a space.
|
#/ Returns true if the body has not been added to a space.
|
||||||
proc isRogue*(body: PBody): Bool {.inline.} =
|
proc isRogue*(body: PBody): bool {.inline.} =
|
||||||
return body.space == nil
|
return body.space == nil
|
||||||
|
|
||||||
# #define CP_DefineBodyStructGetter(type, member, name) \
|
# #define CP_DefineBodyStructGetter(type, member, name) \
|
||||||
|
|
@ -808,15 +808,15 @@ proc kineticEnergy*(body: PBOdy): CpFloat =
|
||||||
result = (body.v.dot(body.v) * body.m) + (body.w * body.w * body.i)
|
result = (body.v.dot(body.v) * body.m) + (body.w * body.w * body.i)
|
||||||
|
|
||||||
#/ Call @c func once for each shape attached to @c body and added to the space.
|
#/ Call @c func once for each shape attached to @c body and added to the space.
|
||||||
proc eachShape*(body: PBody; func: TBodyShapeIteratorFunc;
|
proc eachShape*(body: PBody; fun: TBodyShapeIteratorFunc;
|
||||||
data: pointer){.
|
data: pointer){.
|
||||||
cdecl, importc: "cpBodyEachShape", dynlib: Lib.}
|
cdecl, importc: "cpBodyEachShape", dynlib: Lib.}
|
||||||
#/ Call @c func once for each constraint attached to @c body and added to the space.
|
#/ Call @c func once for each constraint attached to @c body and added to the space.
|
||||||
proc eachConstraint*(body: PBody; func: TBodyConstraintIteratorFunc;
|
proc eachConstraint*(body: PBody; fun: TBodyConstraintIteratorFunc;
|
||||||
data: pointer) {.
|
data: pointer) {.
|
||||||
cdecl, importc: "cpBodyEachConstraint", dynlib: Lib.}
|
cdecl, importc: "cpBodyEachConstraint", dynlib: Lib.}
|
||||||
#/ Call @c func once for each arbiter that is currently active on the body.
|
#/ Call @c func once for each arbiter that is currently active on the body.
|
||||||
proc eachArbiter*(body: PBody; func: TBodyArbiterIteratorFunc;
|
proc eachArbiter*(body: PBody; fun: TBodyArbiterIteratorFunc;
|
||||||
data: pointer){.
|
data: pointer){.
|
||||||
cdecl, importc: "cpBodyEachArbiter", dynlib: Lib.}
|
cdecl, importc: "cpBodyEachArbiter", dynlib: Lib.}
|
||||||
#/ Allocate a spatial hash.
|
#/ Allocate a spatial hash.
|
||||||
|
|
@ -824,10 +824,10 @@ proc SpaceHashAlloc*(): PSpaceHash{.
|
||||||
cdecl, importc: "cpSpaceHashAlloc", dynlib: Lib.}
|
cdecl, importc: "cpSpaceHashAlloc", dynlib: Lib.}
|
||||||
#/ Initialize a spatial hash.
|
#/ Initialize a spatial hash.
|
||||||
proc SpaceHashInit*(hash: PSpaceHash; celldim: CpFloat; numcells: cint;
|
proc SpaceHashInit*(hash: PSpaceHash; celldim: CpFloat; numcells: cint;
|
||||||
bbfunc: TSpatialIndexBBFunc; staticIndex: PSpatialIndex): PSpatialIndex{.
|
bbfun: TSpatialIndexBBFunc; staticIndex: PSpatialIndex): PSpatialIndex{.
|
||||||
cdecl, importc: "cpSpaceHashInit", dynlib: Lib.}
|
cdecl, importc: "cpSpaceHashInit", dynlib: Lib.}
|
||||||
#/ Allocate and initialize a spatial hash.
|
#/ Allocate and initialize a spatial hash.
|
||||||
proc SpaceHashNew*(celldim: CpFloat; cells: cint; bbfunc: TSpatialIndexBBFunc;
|
proc SpaceHashNew*(celldim: CpFloat; cells: cint; bbfun: TSpatialIndexBBFunc;
|
||||||
staticIndex: PSpatialIndex): PSpatialIndex{.
|
staticIndex: PSpatialIndex): PSpatialIndex{.
|
||||||
cdecl, importc: "cpSpaceHashNew", dynlib: Lib.}
|
cdecl, importc: "cpSpaceHashNew", dynlib: Lib.}
|
||||||
#/ Change the cell dimensions and table size of the spatial hash to tune it.
|
#/ Change the cell dimensions and table size of the spatial hash to tune it.
|
||||||
|
|
@ -842,18 +842,18 @@ proc SpaceHashResize*(hash: PSpaceHash; celldim: CpFloat; numcells: cint){.
|
||||||
#/ Allocate a bounding box tree.
|
#/ Allocate a bounding box tree.
|
||||||
proc BBTreeAlloc*(): PBBTree{.cdecl, importc: "cpBBTreeAlloc", dynlib: Lib.}
|
proc BBTreeAlloc*(): PBBTree{.cdecl, importc: "cpBBTreeAlloc", dynlib: Lib.}
|
||||||
#/ Initialize a bounding box tree.
|
#/ Initialize a bounding box tree.
|
||||||
proc BBTreeInit*(tree: PBBTree; bbfunc: TSpatialIndexBBFunc;
|
proc BBTreeInit*(tree: PBBTree; bbfun: TSpatialIndexBBFunc;
|
||||||
staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.cdecl,
|
staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.cdecl,
|
||||||
importc: "cpBBTreeInit", dynlib: Lib.}
|
importc: "cpBBTreeInit", dynlib: Lib.}
|
||||||
#/ Allocate and initialize a bounding box tree.
|
#/ Allocate and initialize a bounding box tree.
|
||||||
proc BBTreeNew*(bbfunc: TSpatialIndexBBFunc; staticIndex: PSpatialIndex): PSpatialIndex{.
|
proc BBTreeNew*(bbfun: TSpatialIndexBBFunc; staticIndex: PSpatialIndex): PSpatialIndex{.
|
||||||
cdecl, importc: "cpBBTreeNew", dynlib: Lib.}
|
cdecl, importc: "cpBBTreeNew", dynlib: Lib.}
|
||||||
#/ Perform a static top down optimization of the tree.
|
#/ Perform a static top down optimization of the tree.
|
||||||
proc BBTreeOptimize*(index: PSpatialIndex){.
|
proc BBTreeOptimize*(index: PSpatialIndex){.
|
||||||
cdecl, importc: "cpBBTreeOptimize", dynlib: Lib.}
|
cdecl, importc: "cpBBTreeOptimize", dynlib: Lib.}
|
||||||
#/ Set the velocity function for the bounding box tree to enable temporal coherence.
|
#/ Set the velocity function for the bounding box tree to enable temporal coherence.
|
||||||
|
|
||||||
proc BBTreeSetVelocityFunc*(index: PSpatialIndex; func: TBBTreeVelocityFunc){.
|
proc BBTreeSetVelocityFunc*(index: PSpatialIndex; fun: TBBTreeVelocityFunc){.
|
||||||
cdecl, importc: "cpBBTreeSetVelocityFunc", dynlib: Lib.}
|
cdecl, importc: "cpBBTreeSetVelocityFunc", dynlib: Lib.}
|
||||||
#MARK: Single Axis Sweep
|
#MARK: Single Axis Sweep
|
||||||
|
|
||||||
|
|
@ -864,12 +864,12 @@ proc Sweep1DAlloc*(): ptr TSweep1D{.cdecl, importc: "cpSweep1DAlloc",
|
||||||
dynlib: Lib.}
|
dynlib: Lib.}
|
||||||
#/ Initialize a 1D sort and sweep broadphase.
|
#/ Initialize a 1D sort and sweep broadphase.
|
||||||
|
|
||||||
proc Sweep1DInit*(sweep: ptr TSweep1D; bbfunc: TSpatialIndexBBFunc;
|
proc Sweep1DInit*(sweep: ptr TSweep1D; bbfun: TSpatialIndexBBFunc;
|
||||||
staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.cdecl,
|
staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.cdecl,
|
||||||
importc: "cpSweep1DInit", dynlib: Lib.}
|
importc: "cpSweep1DInit", dynlib: Lib.}
|
||||||
#/ Allocate and initialize a 1D sort and sweep broadphase.
|
#/ Allocate and initialize a 1D sort and sweep broadphase.
|
||||||
|
|
||||||
proc Sweep1DNew*(bbfunc: TSpatialIndexBBFunc; staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.
|
proc Sweep1DNew*(bbfun: TSpatialIndexBBFunc; staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.
|
||||||
cdecl, importc: "cpSweep1DNew", dynlib: Lib.}
|
cdecl, importc: "cpSweep1DNew", dynlib: Lib.}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1359,7 +1359,7 @@ defCProp(SlideJoint, TVector, anchr2, Anchr2)
|
||||||
defCProp(SlideJoint, CpFloat, min, Min)
|
defCProp(SlideJoint, CpFloat, min, Min)
|
||||||
defCProp(SlideJoint, CpFloat, max, Max)
|
defCProp(SlideJoint, CpFloat, max, Max)
|
||||||
|
|
||||||
proc pivotJointGetClass*(): PConstraintClass {.
|
proc PivotJointGetClass*(): PConstraintClass {.
|
||||||
cdecl, importc: "cpPivotJointGetClass", dynlib: Lib.}
|
cdecl, importc: "cpPivotJointGetClass", dynlib: Lib.}
|
||||||
|
|
||||||
#/ Allocate a pivot joint
|
#/ Allocate a pivot joint
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
const Lib = "libenet.so.1(|.0.3)"
|
const Lib = "libenet.so.1(|.0.3)"
|
||||||
|
|
||||||
{.deadCodeElim: ON.}
|
{.deadCodeElim: on.}
|
||||||
const
|
const
|
||||||
ENET_VERSION_MAJOR* = 1
|
ENET_VERSION_MAJOR* = 1
|
||||||
ENET_VERSION_MINOR* = 3
|
ENET_VERSION_MINOR* = 3
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,6 @@ template defPacketImports*(): stmt {.immediate, dirty.} =
|
||||||
import macros, macro_dsl, estreams
|
import macros, macro_dsl, estreams
|
||||||
from strutils import format
|
from strutils import format
|
||||||
|
|
||||||
proc `$`*[T](x: seq[T]): string =
|
|
||||||
result = "[seq len="
|
|
||||||
result.add($x.len)
|
|
||||||
result.add ':'
|
|
||||||
for i in 0.. <len(x):
|
|
||||||
result.add " "
|
|
||||||
result.add($x[i])
|
|
||||||
result.add ']'
|
|
||||||
|
|
||||||
macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} =
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
let
|
let
|
||||||
|
|
@ -293,4 +284,4 @@ when isMainModule:
|
||||||
for itm in test.x:
|
for itm in test.x:
|
||||||
echo(itm)
|
echo(itm)
|
||||||
test.pack(s)
|
test.pack(s)
|
||||||
echo(repr(s.data))
|
echo(repr(s.data))
|
||||||
|
|
|
||||||
|
|
@ -221,10 +221,10 @@ type
|
||||||
TTransform* {.pf.} = object
|
TTransform* {.pf.} = object
|
||||||
matrix*: array[0..8, cfloat]
|
matrix*: array[0..8, cfloat]
|
||||||
TColor* {.pf.} = object
|
TColor* {.pf.} = object
|
||||||
r*: Uint8
|
r*: uint8
|
||||||
g*: Uint8
|
g*: uint8
|
||||||
b*: Uint8
|
b*: uint8
|
||||||
a*: Uint8
|
a*: uint8
|
||||||
PFloatRect* = ptr TFloatRect
|
PFloatRect* = ptr TFloatRect
|
||||||
TFloatRect*{.pf.} = object
|
TFloatRect*{.pf.} = object
|
||||||
left*: cfloat
|
left*: cfloat
|
||||||
|
|
@ -306,7 +306,7 @@ proc close*(window: PRenderWindow) {.
|
||||||
proc isOpen*(window: PRenderWindow): bool {.
|
proc isOpen*(window: PRenderWindow): bool {.
|
||||||
cdecl, importc: "sfRenderWindow_isOpen", dynlib: LibG.}
|
cdecl, importc: "sfRenderWindow_isOpen", dynlib: LibG.}
|
||||||
|
|
||||||
#void sfRenderWindow_setIcon(sfRenderWindow* renderWindow, unsigned int width, unsigned int height, const sfUint8* pixels);
|
#void sfRenderWindow_setIcon(sfRenderWindow* renderWindow, unsigned int width, unsigned int height, const sfuint8* pixels);
|
||||||
#proc setIcon*(window: PRenderWindow, width, height: cint, pixels: seq[uint8]) {.
|
#proc setIcon*(window: PRenderWindow, width, height: cint, pixels: seq[uint8]) {.
|
||||||
# cdecl, importc: "sfRenderWindow_setIcon", dynlib: LibG.}
|
# cdecl, importc: "sfRenderWindow_setIcon", dynlib: LibG.}
|
||||||
|
|
||||||
|
|
@ -395,7 +395,7 @@ proc capture*(window: PRenderWindow): PImage {.
|
||||||
cdecl, importc: "sfRenderWindow_capture", dynlib: LibG.}
|
cdecl, importc: "sfRenderWindow_capture", dynlib: LibG.}
|
||||||
|
|
||||||
#Construct a new render texture
|
#Construct a new render texture
|
||||||
proc newRenderTexture*(width, height: cint; depthBuffer: Bool): PRenderTexture {.
|
proc newRenderTexture*(width, height: cint; depthBuffer: bool): PRenderTexture {.
|
||||||
cdecl, importc: "sfRenderTexture_create", dynlib: LibG.}
|
cdecl, importc: "sfRenderTexture_create", dynlib: LibG.}
|
||||||
#Destroy an existing render texture
|
#Destroy an existing render texture
|
||||||
proc destroy*(renderTexture: PRenderTexture){.
|
proc destroy*(renderTexture: PRenderTexture){.
|
||||||
|
|
@ -522,9 +522,9 @@ proc copy*(font: PFont): PFont {.
|
||||||
cdecl, importc: "sfFont_copy", dynlib: LibG.}
|
cdecl, importc: "sfFont_copy", dynlib: LibG.}
|
||||||
proc destroy*(font: PFont) {.
|
proc destroy*(font: PFont) {.
|
||||||
cdecl, importc: "sfFont_destroy", dynlib: LibG.}
|
cdecl, importc: "sfFont_destroy", dynlib: LibG.}
|
||||||
proc getGlyph*(font: PFont, codePoint: Uint32, characterSize: cint, bold: bool): TGlyph{.
|
proc getGlyph*(font: PFont, codePoint: uint32, characterSize: cint, bold: bool): TGlyph{.
|
||||||
cdecl, importc: "sfFont_getGlyph", dynlib: LibG.}
|
cdecl, importc: "sfFont_getGlyph", dynlib: LibG.}
|
||||||
proc getKerning*(font: PFont, first: Uint32, second: Uint32, characterSize: cint): cint {.
|
proc getKerning*(font: PFont, first: uint32, second: uint32, characterSize: cint): cint {.
|
||||||
cdecl, importc: "sfFont_getKerning", dynlib: LibG.}
|
cdecl, importc: "sfFont_getKerning", dynlib: LibG.}
|
||||||
proc getLineSpacing*(font: PFont, characterSize: cint): cint {.
|
proc getLineSpacing*(font: PFont, characterSize: cint): cint {.
|
||||||
cdecl, importc: "sfFont_getLineSpacing", dynlib: LibG.}
|
cdecl, importc: "sfFont_getLineSpacing", dynlib: LibG.}
|
||||||
|
|
@ -882,7 +882,7 @@ proc getInverseTransform*(text: PText): TTransform {.
|
||||||
cdecl, importc: "sfText_getInverseTransform", dynlib: LibG.}
|
cdecl, importc: "sfText_getInverseTransform", dynlib: LibG.}
|
||||||
proc setString*(text: PText, string: cstring) {.
|
proc setString*(text: PText, string: cstring) {.
|
||||||
cdecl, importc: "sfText_setString", dynlib: LibG.}
|
cdecl, importc: "sfText_setString", dynlib: LibG.}
|
||||||
proc setUnicodeString*(text: PText, string: ptr Uint32) {.
|
proc setUnicodeString*(text: PText, string: ptr uint32) {.
|
||||||
cdecl, importc: "sfText_setUnicodeString", dynlib: LibG.}
|
cdecl, importc: "sfText_setUnicodeString", dynlib: LibG.}
|
||||||
proc setFont*(text: PText, font: PFont) {.
|
proc setFont*(text: PText, font: PFont) {.
|
||||||
cdecl, importc: "sfText_setFont", dynlib: LibG.}
|
cdecl, importc: "sfText_setFont", dynlib: LibG.}
|
||||||
|
|
@ -894,13 +894,13 @@ proc setColor*(text: PText, color: TColor) {.
|
||||||
cdecl, importc: "sfText_setColor", dynlib: LibG.}
|
cdecl, importc: "sfText_setColor", dynlib: LibG.}
|
||||||
proc getString*(text: PText): cstring {.
|
proc getString*(text: PText): cstring {.
|
||||||
cdecl, importc: "sfText_getString", dynlib: LibG.}
|
cdecl, importc: "sfText_getString", dynlib: LibG.}
|
||||||
proc getUnicodeString*(text: PText): ptr Uint32 {.cdecl,
|
proc getUnicodeString*(text: PText): ptr uint32 {.cdecl,
|
||||||
importc: "sfText_getUnicodeString", dynlib: LibG.}
|
importc: "sfText_getUnicodeString", dynlib: LibG.}
|
||||||
proc getFont*(text: PText): PFont {.
|
proc getFont*(text: PText): PFont {.
|
||||||
cdecl, importc: "sfText_getFont", dynlib: LibG.}
|
cdecl, importc: "sfText_getFont", dynlib: LibG.}
|
||||||
proc getCharacterSize*(text: PText): cint {.
|
proc getCharacterSize*(text: PText): cint {.
|
||||||
cdecl, importc: "sfText_getCharacterSize", dynlib: LibG.}
|
cdecl, importc: "sfText_getCharacterSize", dynlib: LibG.}
|
||||||
proc getStyle*(text: PText): Uint32 {.
|
proc getStyle*(text: PText): uint32 {.
|
||||||
cdecl, importc: "sfText_getStyle", dynlib: LibG.}
|
cdecl, importc: "sfText_getStyle", dynlib: LibG.}
|
||||||
proc getColor*(text: PText): TColor {.
|
proc getColor*(text: PText): TColor {.
|
||||||
cdecl, importc: "sfText_getColor", dynlib: LibG.}
|
cdecl, importc: "sfText_getColor", dynlib: LibG.}
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ proc newSoundBuffer*(stream: PInputStream): PSoundBuffer{.
|
||||||
#/ \brief Create a new sound buffer and load it from an array of samples in memory
|
#/ \brief Create a new sound buffer and load it from an array of samples in memory
|
||||||
#/
|
#/
|
||||||
#/ The assumed format of the audio samples is 16 bits signed integer
|
#/ The assumed format of the audio samples is 16 bits signed integer
|
||||||
#/ (sfInt16).
|
#/ (sfint16).
|
||||||
#/
|
#/
|
||||||
#/ \param samples Pointer to the array of samples in memory
|
#/ \param samples Pointer to the array of samples in memory
|
||||||
#/ \param sampleCount Number of samples in the array
|
#/ \param sampleCount Number of samples in the array
|
||||||
|
|
@ -334,7 +334,7 @@ proc saveToFile*(soundBuffer: PSoundBuffer; filename: cstring): bool {.
|
||||||
#/ \brief Get the array of audio samples stored in a sound buffer
|
#/ \brief Get the array of audio samples stored in a sound buffer
|
||||||
#/
|
#/
|
||||||
#/ The format of the returned samples is 16 bits signed integer
|
#/ The format of the returned samples is 16 bits signed integer
|
||||||
#/ (sfInt16). The total number of samples in this array
|
#/ (sfint16). The total number of samples in this array
|
||||||
#/ is given by the sfSoundBuffer_getSampleCount function.
|
#/ is given by the sfSoundBuffer_getSampleCount function.
|
||||||
#/
|
#/
|
||||||
#/ \param soundBuffer Sound buffer object
|
#/ \param soundBuffer Sound buffer object
|
||||||
|
|
@ -342,7 +342,7 @@ proc saveToFile*(soundBuffer: PSoundBuffer; filename: cstring): bool {.
|
||||||
#/ \return Read-only pointer to the array of sound samples
|
#/ \return Read-only pointer to the array of sound samples
|
||||||
#/
|
#/
|
||||||
#//////////////////////////////////////////////////////////
|
#//////////////////////////////////////////////////////////
|
||||||
proc sfSoundBuffer_getSamples*(soundBuffer: PSoundBuffer): ptr Int16{.
|
proc sfSoundBuffer_getSamples*(soundBuffer: PSoundBuffer): ptr int16{.
|
||||||
cdecl, importc: "sfSoundBuffer_getSamples", dynlib: Lib.}
|
cdecl, importc: "sfSoundBuffer_getSamples", dynlib: Lib.}
|
||||||
#//////////////////////////////////////////////////////////
|
#//////////////////////////////////////////////////////////
|
||||||
#/ \brief Get the number of samples stored in a sound buffer
|
#/ \brief Get the number of samples stored in a sound buffer
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ proc tryLogin*(b: PButton) =
|
||||||
passwd = u_passwd.getText())
|
passwd = u_passwd.getText())
|
||||||
dirServer.send HLogin, login
|
dirServer.send HLogin, login
|
||||||
proc tryTransition*(b: PButton) =
|
proc tryTransition*(b: PButton) =
|
||||||
|
discard
|
||||||
#zone.writePkt HZoneJoinReq, myCreds
|
#zone.writePkt HZoneJoinReq, myCreds
|
||||||
proc tryConnect*(b: PButton) =
|
proc tryConnect*(b: PButton) =
|
||||||
if not dirServer.connected:
|
if not dirServer.connected:
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ proc mouseToSpace*(): TVector =
|
||||||
proc explode*(b: PLiveBullet)
|
proc explode*(b: PLiveBullet)
|
||||||
## TCollisionBeginFunc
|
## TCollisionBeginFunc
|
||||||
proc collisionBulletPlayer(arb: PArbiter; space: PSpace;
|
proc collisionBulletPlayer(arb: PArbiter; space: PSpace;
|
||||||
data: pointer): Bool{.cdecl.} =
|
data: pointer): bool{.cdecl.} =
|
||||||
var
|
var
|
||||||
bullet = cast[PLiveBullet](arb.a.data)
|
bullet = cast[PLiveBullet](arb.a.data)
|
||||||
target = cast[PVehicle](arb.b.data)
|
target = cast[PVehicle](arb.b.data)
|
||||||
|
|
@ -152,7 +152,7 @@ proc collisionBulletPlayer(arb: PArbiter; space: PSpace;
|
||||||
|
|
||||||
proc angularDampingSim(body: PBody, gravity: TVector, damping, dt: CpFloat){.cdecl.} =
|
proc angularDampingSim(body: PBody, gravity: TVector, damping, dt: CpFloat){.cdecl.} =
|
||||||
body.w -= (body.w * 0.98 * dt)
|
body.w -= (body.w * 0.98 * dt)
|
||||||
body.updateVelocity(gravity, damping, dt)
|
body.UpdateVelocity(gravity, damping, dt)
|
||||||
|
|
||||||
proc initLevel() =
|
proc initLevel() =
|
||||||
loadAllAssets()
|
loadAllAssets()
|
||||||
|
|
@ -227,7 +227,7 @@ proc explode*(b: PLiveBullet) =
|
||||||
playSound(b.record.explosion.sound, b.body.getPos())
|
playSound(b.record.explosion.sound, b.body.getPos())
|
||||||
|
|
||||||
proc bulletUpdate(body: PBody, gravity: TVector, damping, dt: CpFloat){.cdecl.} =
|
proc bulletUpdate(body: PBody, gravity: TVector, damping, dt: CpFloat){.cdecl.} =
|
||||||
body.updateVelocity(gravity, damping, dt)
|
body.UpdateVelocity(gravity, damping, dt)
|
||||||
|
|
||||||
template getPhysical() {.immediate.} =
|
template getPhysical() {.immediate.} =
|
||||||
result.body = space.addBody(newBody(
|
result.body = space.addBody(newBody(
|
||||||
|
|
@ -237,7 +237,7 @@ template getPhysical() {.immediate.} =
|
||||||
chipmunk.newCircleShape(
|
chipmunk.newCircleShape(
|
||||||
result.body,
|
result.body,
|
||||||
record.physics.radius,
|
record.physics.radius,
|
||||||
vectorZero))
|
VectorZero))
|
||||||
|
|
||||||
proc newBullet*(record: PBulletRecord; fromPlayer: PPlayer): PLiveBullet =
|
proc newBullet*(record: PBulletRecord; fromPlayer: PPlayer): PLiveBullet =
|
||||||
new(result, free)
|
new(result, free)
|
||||||
|
|
@ -480,7 +480,7 @@ when defined(DebugKeys):
|
||||||
echo(repr(activeVehicle.record))
|
echo(repr(activeVehicle.record))
|
||||||
elif keyPressed(KeyH):
|
elif keyPressed(KeyH):
|
||||||
activeVehicle.body.setPos(vector(100.0, 100.0))
|
activeVehicle.body.setPos(vector(100.0, 100.0))
|
||||||
activeVehicle.body.setVel(vectorZero)
|
activeVehicle.body.setVel(VectorZero)
|
||||||
elif keyPressed(KeyComma):
|
elif keyPressed(KeyComma):
|
||||||
activeVehicle.body.setPos mouseToSpace())
|
activeVehicle.body.setPos mouseToSpace())
|
||||||
ingameClient.registerHandler(KeyY, down, proc() =
|
ingameClient.registerHandler(KeyY, down, proc() =
|
||||||
|
|
@ -507,7 +507,7 @@ when defined(DebugKeys):
|
||||||
return
|
return
|
||||||
let body = shape.getBody()
|
let body = shape.getBody()
|
||||||
mouseJoint = space.addConstraint(
|
mouseJoint = space.addConstraint(
|
||||||
newPivotJoint(mouseBody, body, vectorZero, body.world2local(point)))
|
newPivotJoint(mouseBody, body, VectorZero, body.world2local(point)))
|
||||||
mouseJoint.maxForce = 50000.0
|
mouseJoint.maxForce = 50000.0
|
||||||
mouseJoint.errorBias = pow(1.0 - 0.15, 60))
|
mouseJoint.errorBias = pow(1.0 - 0.15, 60))
|
||||||
|
|
||||||
|
|
@ -539,15 +539,15 @@ proc mainUpdate(dt: float) =
|
||||||
elif not activeVehicle.isNil:
|
elif not activeVehicle.isNil:
|
||||||
if keyPressed(KeyUp):
|
if keyPressed(KeyUp):
|
||||||
activeVehicle.accel(dt)
|
activeVehicle.accel(dt)
|
||||||
elif keyPressed(keyDown):
|
elif keyPressed(KeyDown):
|
||||||
activeVehicle.reverse(dt)
|
activeVehicle.reverse(dt)
|
||||||
if keyPressed(KeyRight):
|
if keyPressed(KeyRight):
|
||||||
activeVehicle.turn_right(dt)
|
activeVehicle.turn_right(dt)
|
||||||
elif keyPressed(KeyLeft):
|
elif keyPressed(KeyLeft):
|
||||||
activeVehicle.turn_left(dt)
|
activeVehicle.turn_left(dt)
|
||||||
if keyPressed(keyz):
|
if keyPressed(Keyz):
|
||||||
activeVehicle.strafe_left(dt)
|
activeVehicle.strafe_left(dt)
|
||||||
elif keyPressed(keyx):
|
elif keyPressed(Keyx):
|
||||||
activeVehicle.strafe_right(dt)
|
activeVehicle.strafe_right(dt)
|
||||||
if keyPressed(KeyLControl):
|
if keyPressed(KeyLControl):
|
||||||
localPlayer.useItem 0
|
localPlayer.useItem 0
|
||||||
|
|
@ -557,7 +557,7 @@ proc mainUpdate(dt: float) =
|
||||||
localPlayer.useItem 2
|
localPlayer.useItem 2
|
||||||
if keyPressed(KeyW):
|
if keyPressed(KeyW):
|
||||||
localPlayer.useItem 3
|
localPlayer.useItem 3
|
||||||
if Keypressed(keyA):
|
if keyPressed(KeyA):
|
||||||
localPlayer.useItem 4
|
localPlayer.useItem 4
|
||||||
if keyPressed(sfml.KeyS):
|
if keyPressed(sfml.KeyS):
|
||||||
localPlayer.useItem 5
|
localPlayer.useItem 5
|
||||||
|
|
@ -666,7 +666,7 @@ when isMainModule:
|
||||||
import parseopt
|
import parseopt
|
||||||
|
|
||||||
localPlayer = newPlayer()
|
localPlayer = newPlayer()
|
||||||
LobbyInit()
|
lobbyInit()
|
||||||
|
|
||||||
videoMode = getClientSettings().resolution
|
videoMode = getClientSettings().resolution
|
||||||
window = newRenderWindow(videoMode, "sup", sfDefaultStyle)
|
window = newRenderWindow(videoMode, "sup", sfDefaultStyle)
|
||||||
|
|
@ -683,7 +683,7 @@ when isMainModule:
|
||||||
mouseSprite.setOutlineThickness 1.4
|
mouseSprite.setOutlineThickness 1.4
|
||||||
mouseSprite.setOrigin vec2f(14, 14)
|
mouseSprite.setOrigin vec2f(14, 14)
|
||||||
|
|
||||||
LobbyReady()
|
lobbyReady()
|
||||||
playBtn = specGui.newButton(
|
playBtn = specGui.newButton(
|
||||||
"Unspec - F12", position = vec2f(680.0, 8.0), onClick = proc(b: PButton) =
|
"Unspec - F12", position = vec2f(680.0, 8.0), onClick = proc(b: PButton) =
|
||||||
toggleSpec())
|
toggleSpec())
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ proc newObject*(record: PObjectRecord): PGameObject =
|
||||||
when false:
|
when false:
|
||||||
result.sprite = record.anim.spriteSheet.sprite.copy()
|
result.sprite = record.anim.spriteSheet.sprite.copy()
|
||||||
result.body = newBody(result.record.physics.mass, 10.0)
|
result.body = newBody(result.record.physics.mass, 10.0)
|
||||||
result.shape = chipmunk.newCircleShape(result.body, result.record.physics.radius, vectorZero)
|
result.shape = chipmunk.newCircleShape(result.body, result.record.physics.radius, VectorZero)
|
||||||
result.body.setPos(vector(100, 100))
|
result.body.setPos(vector(100, 100))
|
||||||
proc newObject*(name: string): PGameObject =
|
proc newObject*(name: string): PGameObject =
|
||||||
result = newObject(fetchObj(name))
|
result = newObject(fetchObj(name))
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ type
|
||||||
PGLclampf* = ptr TGLclampf
|
PGLclampf* = ptr TGLclampf
|
||||||
PGLdouble* = ptr TGLdouble
|
PGLdouble* = ptr TGLdouble
|
||||||
PGLclampd* = ptr TGLclampd
|
PGLclampd* = ptr TGLclampd
|
||||||
PGLvoid* = Pointer
|
PGLvoid* = pointer
|
||||||
PPGLvoid* = ptr PGLvoid
|
PPGLvoid* = ptr PGLvoid
|
||||||
TGLenum* = cint
|
TGLenum* = cint
|
||||||
TGLboolean* = bool
|
TGLboolean* = bool
|
||||||
|
|
@ -983,7 +983,7 @@ const # Version
|
||||||
GL_TEXTURE_COMPONENTS* = GL_TEXTURE_INTERNAL_FORMAT
|
GL_TEXTURE_COMPONENTS* = GL_TEXTURE_INTERNAL_FORMAT
|
||||||
|
|
||||||
proc glAccum*(op: TGLenum, value: TGLfloat){.dynlib: dllname, importc: "glAccum".}
|
proc glAccum*(op: TGLenum, value: TGLfloat){.dynlib: dllname, importc: "glAccum".}
|
||||||
proc glAlphaFunc*(func: TGLenum, theref: TGLclampf){.dynlib: dllname,
|
proc glAlphaFunc*(fun: TGLenum, theref: TGLclampf){.dynlib: dllname,
|
||||||
importc: "glAlphaFunc".}
|
importc: "glAlphaFunc".}
|
||||||
proc glAreTexturesResident*(n: TGLsizei, textures: PGLuint,
|
proc glAreTexturesResident*(n: TGLsizei, textures: PGLuint,
|
||||||
residences: PGLboolean): TGLboolean{.
|
residences: PGLboolean): TGLboolean{.
|
||||||
|
|
@ -998,7 +998,7 @@ proc glBitmap*(width, height: TGLsizei, xorig, yorig: TGLfloat,
|
||||||
proc glBlendFunc*(sfactor, dfactor: TGLenum){.dynlib: dllname,
|
proc glBlendFunc*(sfactor, dfactor: TGLenum){.dynlib: dllname,
|
||||||
importc: "glBlendFunc".}
|
importc: "glBlendFunc".}
|
||||||
proc glCallList*(list: TGLuint){.dynlib: dllname, importc: "glCallList".}
|
proc glCallList*(list: TGLuint){.dynlib: dllname, importc: "glCallList".}
|
||||||
proc glCallLists*(n: TGLsizei, atype: TGLenum, lists: Pointer){.dynlib: dllname,
|
proc glCallLists*(n: TGLsizei, atype: TGLenum, lists: pointer){.dynlib: dllname,
|
||||||
importc: "glCallLists".}
|
importc: "glCallLists".}
|
||||||
proc glClear*(mask: TGLbitfield){.dynlib: dllname, importc: "glClear".}
|
proc glClear*(mask: TGLbitfield){.dynlib: dllname, importc: "glClear".}
|
||||||
proc glClearAccum*(red, green, blue, alpha: TGLfloat){.dynlib: dllname,
|
proc glClearAccum*(red, green, blue, alpha: TGLfloat){.dynlib: dllname,
|
||||||
|
|
@ -1062,7 +1062,7 @@ proc glColorMask*(red, green, blue, alpha: TGLboolean){.dynlib: dllname,
|
||||||
proc glColorMaterial*(face, mode: TGLenum){.dynlib: dllname,
|
proc glColorMaterial*(face, mode: TGLenum){.dynlib: dllname,
|
||||||
importc: "glColorMaterial".}
|
importc: "glColorMaterial".}
|
||||||
proc glColorPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei,
|
proc glColorPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei,
|
||||||
pointer: Pointer){.dynlib: dllname,
|
p: pointer){.dynlib: dllname,
|
||||||
importc: "glColorPointer".}
|
importc: "glColorPointer".}
|
||||||
proc glCopyPixels*(x, y: TGLint, width, height: TGLsizei, atype: TGLenum){.
|
proc glCopyPixels*(x, y: TGLint, width, height: TGLsizei, atype: TGLenum){.
|
||||||
dynlib: dllname, importc: "glCopyPixels".}
|
dynlib: dllname, importc: "glCopyPixels".}
|
||||||
|
|
@ -1084,7 +1084,7 @@ proc glDeleteLists*(list: TGLuint, range: TGLsizei){.dynlib: dllname,
|
||||||
importc: "glDeleteLists".}
|
importc: "glDeleteLists".}
|
||||||
proc glDeleteTextures*(n: TGLsizei, textures: PGLuint){.dynlib: dllname,
|
proc glDeleteTextures*(n: TGLsizei, textures: PGLuint){.dynlib: dllname,
|
||||||
importc: "glDeleteTextures".}
|
importc: "glDeleteTextures".}
|
||||||
proc glDepthFunc*(func: TGLenum){.dynlib: dllname, importc: "glDepthFunc".}
|
proc glDepthFunc*(fun: TGLenum){.dynlib: dllname, importc: "glDepthFunc".}
|
||||||
proc glDepthMask*(flag: TGLboolean){.dynlib: dllname, importc: "glDepthMask".}
|
proc glDepthMask*(flag: TGLboolean){.dynlib: dllname, importc: "glDepthMask".}
|
||||||
proc glDepthRange*(zNear, zFar: TGLclampd){.dynlib: dllname,
|
proc glDepthRange*(zNear, zFar: TGLclampd){.dynlib: dllname,
|
||||||
importc: "glDepthRange".}
|
importc: "glDepthRange".}
|
||||||
|
|
@ -1095,12 +1095,12 @@ proc glDrawArrays*(mode: TGLenum, first: TGLint, count: TGLsizei){.
|
||||||
dynlib: dllname, importc: "glDrawArrays".}
|
dynlib: dllname, importc: "glDrawArrays".}
|
||||||
proc glDrawBuffer*(mode: TGLenum){.dynlib: dllname, importc: "glDrawBuffer".}
|
proc glDrawBuffer*(mode: TGLenum){.dynlib: dllname, importc: "glDrawBuffer".}
|
||||||
proc glDrawElements*(mode: TGLenum, count: TGLsizei, atype: TGLenum,
|
proc glDrawElements*(mode: TGLenum, count: TGLsizei, atype: TGLenum,
|
||||||
indices: Pointer){.dynlib: dllname,
|
indices: pointer){.dynlib: dllname,
|
||||||
importc: "glDrawElements".}
|
importc: "glDrawElements".}
|
||||||
proc glDrawPixels*(width, height: TGLsizei, format, atype: TGLenum,
|
proc glDrawPixels*(width, height: TGLsizei, format, atype: TGLenum,
|
||||||
pixels: Pointer){.dynlib: dllname, importc: "glDrawPixels".}
|
pixels: pointer){.dynlib: dllname, importc: "glDrawPixels".}
|
||||||
proc glEdgeFlag*(flag: TGLboolean){.dynlib: dllname, importc: "glEdgeFlag".}
|
proc glEdgeFlag*(flag: TGLboolean){.dynlib: dllname, importc: "glEdgeFlag".}
|
||||||
proc glEdgeFlagPointer*(stride: TGLsizei, pointer: Pointer){.dynlib: dllname,
|
proc glEdgeFlagPointer*(stride: TGLsizei, p: pointer){.dynlib: dllname,
|
||||||
importc: "glEdgeFlagPointer".}
|
importc: "glEdgeFlagPointer".}
|
||||||
proc glEdgeFlagv*(flag: PGLboolean){.dynlib: dllname, importc: "glEdgeFlagv".}
|
proc glEdgeFlagv*(flag: PGLboolean){.dynlib: dllname, importc: "glEdgeFlagv".}
|
||||||
proc glEnable*(cap: TGLenum){.dynlib: dllname, importc: "glEnable".}
|
proc glEnable*(cap: TGLenum){.dynlib: dllname, importc: "glEnable".}
|
||||||
|
|
@ -1171,7 +1171,7 @@ proc glGetPixelMapuiv*(map: TGLenum, values: PGLuint){.dynlib: dllname,
|
||||||
importc: "glGetPixelMapuiv".}
|
importc: "glGetPixelMapuiv".}
|
||||||
proc glGetPixelMapusv*(map: TGLenum, values: PGLushort){.dynlib: dllname,
|
proc glGetPixelMapusv*(map: TGLenum, values: PGLushort){.dynlib: dllname,
|
||||||
importc: "glGetPixelMapusv".}
|
importc: "glGetPixelMapusv".}
|
||||||
proc glGetPointerv*(pname: TGLenum, params: Pointer){.dynlib: dllname,
|
proc glGetPointerv*(pname: TGLenum, params: pointer){.dynlib: dllname,
|
||||||
importc: "glGetPointerv".}
|
importc: "glGetPointerv".}
|
||||||
proc glGetPolygonStipple*(mask: PGLubyte){.dynlib: dllname,
|
proc glGetPolygonStipple*(mask: PGLubyte){.dynlib: dllname,
|
||||||
importc: "glGetPolygonStipple".}
|
importc: "glGetPolygonStipple".}
|
||||||
|
|
@ -1188,10 +1188,10 @@ proc glGetTexGenfv*(coord, pname: TGLenum, params: PGLfloat){.dynlib: dllname,
|
||||||
proc glGetTexGeniv*(coord, pname: TGLenum, params: PGLint){.dynlib: dllname,
|
proc glGetTexGeniv*(coord, pname: TGLenum, params: PGLint){.dynlib: dllname,
|
||||||
importc: "glGetTexGeniv".}
|
importc: "glGetTexGeniv".}
|
||||||
proc glGetTexImage*(target: TGLenum, level: TGLint, format: TGLenum,
|
proc glGetTexImage*(target: TGLenum, level: TGLint, format: TGLenum,
|
||||||
atype: TGLenum, pixels: Pointer){.dynlib: dllname,
|
atype: TGLenum, pixels: pointer){.dynlib: dllname,
|
||||||
importc: "glGetTexImage".}
|
importc: "glGetTexImage".}
|
||||||
proc glGetTexLevelParameterfv*(target: TGLenum, level: TGLint, pname: TGLenum,
|
proc glGetTexLevelParameterfv*(target: TGLenum, level: TGLint, pname: TGLenum,
|
||||||
params: Pointer){.dynlib: dllname,
|
params: pointer){.dynlib: dllname,
|
||||||
importc: "glGetTexLevelParameterfv".}
|
importc: "glGetTexLevelParameterfv".}
|
||||||
proc glGetTexLevelParameteriv*(target: TGLenum, level: TGLint, pname: TGLenum,
|
proc glGetTexLevelParameteriv*(target: TGLenum, level: TGLint, pname: TGLenum,
|
||||||
params: PGLint){.dynlib: dllname,
|
params: PGLint){.dynlib: dllname,
|
||||||
|
|
@ -1202,7 +1202,7 @@ proc glGetTexParameteriv*(target, pname: TGLenum, params: PGLint){.
|
||||||
dynlib: dllname, importc: "glGetTexParameteriv".}
|
dynlib: dllname, importc: "glGetTexParameteriv".}
|
||||||
proc glHint*(target, mode: TGLenum){.dynlib: dllname, importc: "glHint".}
|
proc glHint*(target, mode: TGLenum){.dynlib: dllname, importc: "glHint".}
|
||||||
proc glIndexMask*(mask: TGLuint){.dynlib: dllname, importc: "glIndexMask".}
|
proc glIndexMask*(mask: TGLuint){.dynlib: dllname, importc: "glIndexMask".}
|
||||||
proc glIndexPointer*(atype: TGLenum, stride: TGLsizei, pointer: Pointer){.
|
proc glIndexPointer*(atype: TGLenum, stride: TGLsizei, p: pointer){.
|
||||||
dynlib: dllname, importc: "glIndexPointer".}
|
dynlib: dllname, importc: "glIndexPointer".}
|
||||||
proc glIndexd*(c: TGLdouble){.dynlib: dllname, importc: "glIndexd".}
|
proc glIndexd*(c: TGLdouble){.dynlib: dllname, importc: "glIndexd".}
|
||||||
proc glIndexdv*(c: PGLdouble){.dynlib: dllname, importc: "glIndexdv".}
|
proc glIndexdv*(c: PGLdouble){.dynlib: dllname, importc: "glIndexdv".}
|
||||||
|
|
@ -1215,7 +1215,7 @@ proc glIndexsv*(c: PGLshort){.dynlib: dllname, importc: "glIndexsv".}
|
||||||
proc glIndexub*(c: TGLubyte){.dynlib: dllname, importc: "glIndexub".}
|
proc glIndexub*(c: TGLubyte){.dynlib: dllname, importc: "glIndexub".}
|
||||||
proc glIndexubv*(c: PGLubyte){.dynlib: dllname, importc: "glIndexubv".}
|
proc glIndexubv*(c: PGLubyte){.dynlib: dllname, importc: "glIndexubv".}
|
||||||
proc glInitNames*(){.dynlib: dllname, importc: "glInitNames".}
|
proc glInitNames*(){.dynlib: dllname, importc: "glInitNames".}
|
||||||
proc glInterleavedArrays*(format: TGLenum, stride: TGLsizei, pointer: Pointer){.
|
proc glInterleavedArrays*(format: TGLenum, stride: TGLsizei, p: pointer){.
|
||||||
dynlib: dllname, importc: "glInterleavedArrays".}
|
dynlib: dllname, importc: "glInterleavedArrays".}
|
||||||
proc glIsEnabled*(cap: TGLenum): TGLboolean{.dynlib: dllname,
|
proc glIsEnabled*(cap: TGLenum): TGLboolean{.dynlib: dllname,
|
||||||
importc: "glIsEnabled".}
|
importc: "glIsEnabled".}
|
||||||
|
|
@ -1288,7 +1288,7 @@ proc glNormal3i*(nx, ny, nz: TGLint){.dynlib: dllname, importc: "glNormal3i".}
|
||||||
proc glNormal3iv*(v: PGLint){.dynlib: dllname, importc: "glNormal3iv".}
|
proc glNormal3iv*(v: PGLint){.dynlib: dllname, importc: "glNormal3iv".}
|
||||||
proc glNormal3s*(nx, ny, nz: TGLshort){.dynlib: dllname, importc: "glNormal3s".}
|
proc glNormal3s*(nx, ny, nz: TGLshort){.dynlib: dllname, importc: "glNormal3s".}
|
||||||
proc glNormal3sv*(v: PGLshort){.dynlib: dllname, importc: "glNormal3sv".}
|
proc glNormal3sv*(v: PGLshort){.dynlib: dllname, importc: "glNormal3sv".}
|
||||||
proc glNormalPointer*(atype: TGLenum, stride: TGLsizei, pointer: Pointer){.
|
proc glNormalPointer*(atype: TGLenum, stride: TGLsizei, p: pointer){.
|
||||||
dynlib: dllname, importc: "glNormalPointer".}
|
dynlib: dllname, importc: "glNormalPointer".}
|
||||||
proc glOrtho*(left, right, bottom, top, zNear, zFar: TGLdouble){.
|
proc glOrtho*(left, right, bottom, top, zNear, zFar: TGLdouble){.
|
||||||
dynlib: dllname, importc: "glOrtho".}
|
dynlib: dllname, importc: "glOrtho".}
|
||||||
|
|
@ -1360,7 +1360,7 @@ proc glRasterPos4s*(x, y, z, w: TGLshort){.dynlib: dllname,
|
||||||
proc glRasterPos4sv*(v: PGLshort){.dynlib: dllname, importc: "glRasterPos4sv".}
|
proc glRasterPos4sv*(v: PGLshort){.dynlib: dllname, importc: "glRasterPos4sv".}
|
||||||
proc glReadBuffer*(mode: TGLenum){.dynlib: dllname, importc: "glReadBuffer".}
|
proc glReadBuffer*(mode: TGLenum){.dynlib: dllname, importc: "glReadBuffer".}
|
||||||
proc glReadPixels*(x, y: TGLint, width, height: TGLsizei,
|
proc glReadPixels*(x, y: TGLint, width, height: TGLsizei,
|
||||||
format, atype: TGLenum, pixels: Pointer){.dynlib: dllname,
|
format, atype: TGLenum, pixels: pointer){.dynlib: dllname,
|
||||||
importc: "glReadPixels".}
|
importc: "glReadPixels".}
|
||||||
proc glRectd*(x1, y1, x2, y2: TGLdouble){.dynlib: dllname, importc: "glRectd".}
|
proc glRectd*(x1, y1, x2, y2: TGLdouble){.dynlib: dllname, importc: "glRectd".}
|
||||||
proc glRectdv*(v1: PGLdouble, v2: PGLdouble){.dynlib: dllname,
|
proc glRectdv*(v1: PGLdouble, v2: PGLdouble){.dynlib: dllname,
|
||||||
|
|
@ -1383,7 +1383,7 @@ proc glScissor*(x, y: TGLint, width, height: TGLsizei){.dynlib: dllname,
|
||||||
proc glSelectBuffer*(size: TGLsizei, buffer: PGLuint){.dynlib: dllname,
|
proc glSelectBuffer*(size: TGLsizei, buffer: PGLuint){.dynlib: dllname,
|
||||||
importc: "glSelectBuffer".}
|
importc: "glSelectBuffer".}
|
||||||
proc glShadeModel*(mode: TGLenum){.dynlib: dllname, importc: "glShadeModel".}
|
proc glShadeModel*(mode: TGLenum){.dynlib: dllname, importc: "glShadeModel".}
|
||||||
proc glStencilFunc*(func: TGLenum, theref: TGLint, mask: TGLuint){.
|
proc glStencilFunc*(fun: TGLenum, theref: TGLint, mask: TGLuint){.
|
||||||
dynlib: dllname, importc: "glStencilFunc".}
|
dynlib: dllname, importc: "glStencilFunc".}
|
||||||
proc glStencilMask*(mask: TGLuint){.dynlib: dllname, importc: "glStencilMask".}
|
proc glStencilMask*(mask: TGLuint){.dynlib: dllname, importc: "glStencilMask".}
|
||||||
proc glStencilOp*(fail, zfail, zpass: TGLenum){.dynlib: dllname,
|
proc glStencilOp*(fail, zfail, zpass: TGLenum){.dynlib: dllname,
|
||||||
|
|
@ -1424,7 +1424,7 @@ proc glTexCoord4s*(s, t, r, q: TGLshort){.dynlib: dllname,
|
||||||
importc: "glTexCoord4s".}
|
importc: "glTexCoord4s".}
|
||||||
proc glTexCoord4sv*(v: PGLshort){.dynlib: dllname, importc: "glTexCoord4sv".}
|
proc glTexCoord4sv*(v: PGLshort){.dynlib: dllname, importc: "glTexCoord4sv".}
|
||||||
proc glTexCoordPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei,
|
proc glTexCoordPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei,
|
||||||
pointer: Pointer){.dynlib: dllname,
|
p: pointer){.dynlib: dllname,
|
||||||
importc: "glTexCoordPointer".}
|
importc: "glTexCoordPointer".}
|
||||||
proc glTexEnvf*(target: TGLenum, pname: TGLenum, param: TGLfloat){.
|
proc glTexEnvf*(target: TGLenum, pname: TGLenum, param: TGLfloat){.
|
||||||
dynlib: dllname, importc: "glTexEnvf".}
|
dynlib: dllname, importc: "glTexEnvf".}
|
||||||
|
|
@ -1448,10 +1448,10 @@ proc glTexGeniv*(coord: TGLenum, pname: TGLenum, params: PGLint){.
|
||||||
dynlib: dllname, importc: "glTexGeniv".}
|
dynlib: dllname, importc: "glTexGeniv".}
|
||||||
proc glTexImage1D*(target: TGLenum, level, internalformat: TGLint,
|
proc glTexImage1D*(target: TGLenum, level, internalformat: TGLint,
|
||||||
width: TGLsizei, border: TGLint, format, atype: TGLenum,
|
width: TGLsizei, border: TGLint, format, atype: TGLenum,
|
||||||
pixels: Pointer){.dynlib: dllname, importc: "glTexImage1D".}
|
pixels: pointer){.dynlib: dllname, importc: "glTexImage1D".}
|
||||||
proc glTexImage2D*(target: TGLenum, level, internalformat: TGLint,
|
proc glTexImage2D*(target: TGLenum, level, internalformat: TGLint,
|
||||||
width, height: TGLsizei, border: TGLint,
|
width, height: TGLsizei, border: TGLint,
|
||||||
format, atype: TGLenum, pixels: Pointer){.dynlib: dllname,
|
format, atype: TGLenum, pixels: pointer){.dynlib: dllname,
|
||||||
importc: "glTexImage2D".}
|
importc: "glTexImage2D".}
|
||||||
proc glTexParameterf*(target: TGLenum, pname: TGLenum, param: TGLfloat){.
|
proc glTexParameterf*(target: TGLenum, pname: TGLenum, param: TGLfloat){.
|
||||||
dynlib: dllname, importc: "glTexParameterf".}
|
dynlib: dllname, importc: "glTexParameterf".}
|
||||||
|
|
@ -1462,11 +1462,11 @@ proc glTexParameteri*(target: TGLenum, pname: TGLenum, param: TGLint){.
|
||||||
proc glTexParameteriv*(target: TGLenum, pname: TGLenum, params: PGLint){.
|
proc glTexParameteriv*(target: TGLenum, pname: TGLenum, params: PGLint){.
|
||||||
dynlib: dllname, importc: "glTexParameteriv".}
|
dynlib: dllname, importc: "glTexParameteriv".}
|
||||||
proc glTexSubImage1D*(target: TGLenum, level, xoffset: TGLint, width: TGLsizei,
|
proc glTexSubImage1D*(target: TGLenum, level, xoffset: TGLint, width: TGLsizei,
|
||||||
format, atype: TGLenum, pixels: Pointer){.dynlib: dllname,
|
format, atype: TGLenum, pixels: pointer){.dynlib: dllname,
|
||||||
importc: "glTexSubImage1D".}
|
importc: "glTexSubImage1D".}
|
||||||
proc glTexSubImage2D*(target: TGLenum, level, xoffset, yoffset: TGLint,
|
proc glTexSubImage2D*(target: TGLenum, level, xoffset, yoffset: TGLint,
|
||||||
width, height: TGLsizei, format, atype: TGLenum,
|
width, height: TGLsizei, format, atype: TGLenum,
|
||||||
pixels: Pointer){.dynlib: dllname,
|
pixels: pointer){.dynlib: dllname,
|
||||||
importc: "glTexSubImage2D".}
|
importc: "glTexSubImage2D".}
|
||||||
proc glTranslated*(x, y, z: TGLdouble){.dynlib: dllname, importc: "glTranslated".}
|
proc glTranslated*(x, y, z: TGLdouble){.dynlib: dllname, importc: "glTranslated".}
|
||||||
proc glTranslatef*(x, y, z: TGLfloat){.dynlib: dllname, importc: "glTranslatef".}
|
proc glTranslatef*(x, y, z: TGLfloat){.dynlib: dllname, importc: "glTranslatef".}
|
||||||
|
|
@ -1495,7 +1495,7 @@ proc glVertex4iv*(v: PGLint){.dynlib: dllname, importc: "glVertex4iv".}
|
||||||
proc glVertex4s*(x, y, z, w: TGLshort){.dynlib: dllname, importc: "glVertex4s".}
|
proc glVertex4s*(x, y, z, w: TGLshort){.dynlib: dllname, importc: "glVertex4s".}
|
||||||
proc glVertex4sv*(v: PGLshort){.dynlib: dllname, importc: "glVertex4sv".}
|
proc glVertex4sv*(v: PGLshort){.dynlib: dllname, importc: "glVertex4sv".}
|
||||||
proc glVertexPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei,
|
proc glVertexPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei,
|
||||||
pointer: Pointer){.dynlib: dllname,
|
p: pointer){.dynlib: dllname,
|
||||||
importc: "glVertexPointer".}
|
importc: "glVertexPointer".}
|
||||||
proc glViewport*(x, y: TGLint, width, height: TGLsizei){.dynlib: dllname,
|
proc glViewport*(x, y: TGLint, width, height: TGLsizei){.dynlib: dllname,
|
||||||
importc: "glViewport".}
|
importc: "glViewport".}
|
||||||
|
|
@ -1505,28 +1505,28 @@ type
|
||||||
count: TGLsizei)
|
count: TGLsizei)
|
||||||
PFN_GLVERTEX_POINTER_EXTPROC* = proc (size: TGLint, atype: TGLenum,
|
PFN_GLVERTEX_POINTER_EXTPROC* = proc (size: TGLint, atype: TGLenum,
|
||||||
stride, count: TGLsizei,
|
stride, count: TGLsizei,
|
||||||
pointer: Pointer)
|
p: pointer)
|
||||||
PFN_GLNORMAL_POINTER_EXTPROC* = proc (atype: TGLenum, stride, count: TGLsizei,
|
PFN_GLNORMAL_POINTER_EXTPROC* = proc (atype: TGLenum, stride, count: TGLsizei,
|
||||||
pointer: Pointer)
|
p: pointer)
|
||||||
PFN_GLCOLOR_POINTER_EXTPROC* = proc (size: TGLint, atype: TGLenum,
|
PFN_GLCOLOR_POINTER_EXTPROC* = proc (size: TGLint, atype: TGLenum,
|
||||||
stride, count: TGLsizei, pointer: Pointer)
|
stride, count: TGLsizei, p: pointer)
|
||||||
PFN_GLINDEX_POINTER_EXTPROC* = proc (atype: TGLenum, stride, count: TGLsizei,
|
PFN_GLINDEX_POINTER_EXTPROC* = proc (atype: TGLenum, stride, count: TGLsizei,
|
||||||
pointer: Pointer)
|
p: pointer)
|
||||||
PFN_GLTEXCOORD_POINTER_EXTPROC* = proc (size: TGLint, atype: TGLenum,
|
PFN_GLTEXCOORD_POINTER_EXTPROC* = proc (size: TGLint, atype: TGLenum,
|
||||||
stride, count: TGLsizei, pointer: Pointer)
|
stride, count: TGLsizei, p: pointer)
|
||||||
PFN_GLEDGEFLAG_POINTER_EXTPROC* = proc (stride, count: TGLsizei,
|
PFN_GLEDGEFLAG_POINTER_EXTPROC* = proc (stride, count: TGLsizei,
|
||||||
pointer: PGLboolean)
|
pointer: PGLboolean)
|
||||||
PFN_GLGET_POINTER_VEXT_PROC* = proc (pname: TGLenum, params: Pointer)
|
PFN_GLGET_POINTER_VEXT_PROC* = proc (pname: TGLenum, params: pointer)
|
||||||
PFN_GLARRAY_ELEMENT_ARRAY_EXTPROC* = proc (mode: TGLenum, count: TGLsizei,
|
PFN_GLARRAY_ELEMENT_ARRAY_EXTPROC* = proc (mode: TGLenum, count: TGLsizei,
|
||||||
pi: Pointer) # WIN_swap_hint
|
pi: pointer) # WIN_swap_hint
|
||||||
PFN_GLADDSWAPHINT_RECT_WINPROC* = proc (x, y: TGLint, width, height: TGLsizei)
|
PFN_GLADDSWAPHINT_RECT_WINPROC* = proc (x, y: TGLint, width, height: TGLsizei)
|
||||||
PFN_GLCOLOR_TABLE_EXTPROC* = proc (target, internalFormat: TGLenum,
|
PFN_GLCOLOR_TABLE_EXTPROC* = proc (target, internalFormat: TGLenum,
|
||||||
width: TGLsizei, format, atype: TGLenum,
|
width: TGLsizei, format, atype: TGLenum,
|
||||||
data: Pointer)
|
data: pointer)
|
||||||
PFN_GLCOLOR_SUBTABLE_EXTPROC* = proc (target: TGLenum, start, count: TGLsizei,
|
PFN_GLCOLOR_SUBTABLE_EXTPROC* = proc (target: TGLenum, start, count: TGLsizei,
|
||||||
format, atype: TGLenum, data: Pointer)
|
format, atype: TGLenum, data: pointer)
|
||||||
PFN_GLGETCOLOR_TABLE_EXTPROC* = proc (target, format, atype: TGLenum,
|
PFN_GLGETCOLOR_TABLE_EXTPROC* = proc (target, format, atype: TGLenum,
|
||||||
data: Pointer)
|
data: pointer)
|
||||||
PFN_GLGETCOLOR_TABLE_PARAMETER_IVEXTPROC* = proc (target, pname: TGLenum,
|
PFN_GLGETCOLOR_TABLE_PARAMETER_IVEXTPROC* = proc (target, pname: TGLenum,
|
||||||
params: PGLint)
|
params: PGLint)
|
||||||
PFN_GLGETCOLOR_TABLE_PARAMETER_FVEXTPROC* = proc (target, pname: TGLenum,
|
PFN_GLGETCOLOR_TABLE_PARAMETER_FVEXTPROC* = proc (target, pname: TGLenum,
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@ template filterIt2*(seq, pred: expr, body: stmt): stmt {.immediate, dirty.} =
|
||||||
for it in items(seq):
|
for it in items(seq):
|
||||||
if pred: body
|
if pred: body
|
||||||
|
|
||||||
proc map*[A, B](x: seq[A], func: proc(y: A): B {.closure.}): seq[B] =
|
proc map*[A, B](x: seq[A], fun: proc(y: A): B {.closure.}): seq[B] =
|
||||||
result = @[]
|
result = @[]
|
||||||
for item in x.items:
|
for item in x.items:
|
||||||
result.add func(item)
|
result.add fun(item)
|
||||||
|
|
||||||
proc mapInPlace*[A](x: var seq[A], func: proc(y: A): A {.closure.}) =
|
proc mapInPlace*[A](x: var seq[A], fun: proc(y: A): A {.closure.}) =
|
||||||
for i in 0..x.len-1:
|
for i in 0..x.len-1:
|
||||||
x[i] = func(x[i])
|
x[i] = fun(x[i])
|
||||||
|
|
||||||
template unless*(condition: expr; body: stmt): stmt {.dirty.} =
|
template unless*(condition: expr; body: stmt): stmt {.dirty.} =
|
||||||
if not(condition):
|
if not(condition):
|
||||||
|
|
@ -38,4 +38,4 @@ when isMainModule:
|
||||||
var someSeq = @[9,8,7,6,5,4,3,2,1] ## numbers < 6 or even
|
var someSeq = @[9,8,7,6,5,4,3,2,1] ## numbers < 6 or even
|
||||||
filterIt2 someSeq, it < 6 or (it and 1) == 0:
|
filterIt2 someSeq, it < 6 or (it and 1) == 0:
|
||||||
echo(it)
|
echo(it)
|
||||||
echo "-----------"
|
echo "-----------"
|
||||||
|
|
|
||||||
|
|
@ -122,9 +122,9 @@ var
|
||||||
nameToBulletID*: TTable[string, int]
|
nameToBulletID*: TTable[string, int]
|
||||||
activeState = Lobby
|
activeState = Lobby
|
||||||
|
|
||||||
proc newSprite(filename: string; errors: var seq[string]): PSpriteSheet
|
proc newSprite*(filename: string; errors: var seq[string]): PSpriteSheet
|
||||||
proc load*(ss: PSpriteSheet): bool {.discardable.}
|
proc load*(ss: PSpriteSheet): bool {.discardable.}
|
||||||
proc newSound(filename: string; errors: var seq[string]): PSoundRecord
|
proc newSound*(filename: string; errors: var seq[string]): PSoundRecord
|
||||||
proc load*(s: PSoundRecord): bool {.discardable.}
|
proc load*(s: PSoundRecord): bool {.discardable.}
|
||||||
|
|
||||||
proc validateSettings*(settings: PJsonNode; errors: var seq[string]): bool
|
proc validateSettings*(settings: PJsonNode; errors: var seq[string]): bool
|
||||||
|
|
@ -146,7 +146,7 @@ proc importHandling(data: PJsonNode): THandlingRecord
|
||||||
proc importBullet(data: PJsonNode; errors: var seq[string]): PBulletRecord
|
proc importBullet(data: PJsonNode; errors: var seq[string]): PBulletRecord
|
||||||
proc importSoul(data: PJsonNode): TSoulRecord
|
proc importSoul(data: PJsonNode): TSoulRecord
|
||||||
proc importExplosion(data: PJsonNode; errors: var seq[string]): TExplosionRecord
|
proc importExplosion(data: PJsonNode; errors: var seq[string]): TExplosionRecord
|
||||||
proc importSound(data: PJsonNode; errors: var seq[string]; fieldName: string = nil): PSoundRecord
|
proc importSound*(data: PJsonNode; errors: var seq[string]; fieldName: string = nil): PSoundRecord
|
||||||
|
|
||||||
## this is the only pipe between lobby and main.nim
|
## this is the only pipe between lobby and main.nim
|
||||||
proc getActiveState*(): TGameState =
|
proc getActiveState*(): TGameState =
|
||||||
|
|
@ -466,7 +466,7 @@ proc importPhys(data: PJsonNode): TPhysicsRecord =
|
||||||
phys.getField("radius", result.radius)
|
phys.getField("radius", result.radius)
|
||||||
phys.getField("mass", result.mass)
|
phys.getField("mass", result.mass)
|
||||||
when not defined(NoChipmunk):
|
when not defined(NoChipmunk):
|
||||||
result.moment = momentForCircle(result.mass, 0.0, result.radius, vectorZero) * MomentMult
|
result.moment = momentForCircle(result.mass, 0.0, result.radius, VectorZero) * MomentMult
|
||||||
proc importHandling(data: PJsonNode): THandlingRecord =
|
proc importHandling(data: PJsonNode): THandlingRecord =
|
||||||
result.thrust = 45.0
|
result.thrust = 45.0
|
||||||
result.topSpeed = 100.0 #unused
|
result.topSpeed = 100.0 #unused
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ template idpacket(pktName, id, s2c, c2s: expr): stmt {.immediate, dirty.} =
|
||||||
defPacket(`Sc pktName`, s2c)
|
defPacket(`Sc pktName`, s2c)
|
||||||
defPacket(`Cs pktName`, c2s)
|
defPacket(`Cs pktName`, c2s)
|
||||||
|
|
||||||
forwardPacketT(Uint8, int8)
|
forwardPacketT(uint8, int8)
|
||||||
forwardPacketT(Uint16, int16)
|
forwardPacketT(uint16, int16)
|
||||||
forwardPacketT(TPort, int16)
|
forwardPacketT(TPort, int16)
|
||||||
|
|
||||||
idPacket(Login, 'a',
|
idPacket(Login, 'a',
|
||||||
|
|
@ -51,7 +51,7 @@ defPacket(ScTeamList, tuple[teams: seq[ScTeam]])
|
||||||
let HTeamChange* = 't'
|
let HTeamChange* = 't'
|
||||||
|
|
||||||
idPacket(ZoneQuery, 'Q',
|
idPacket(ZoneQuery, 'Q',
|
||||||
tuple[playerCount: Uint16], ##i should include a time here or something
|
tuple[playerCount: uint16], ##i should include a time here or something
|
||||||
tuple[pad: char = '\0'])
|
tuple[pad: char = '\0'])
|
||||||
|
|
||||||
type SpawnKind = enum
|
type SpawnKind = enum
|
||||||
|
|
|
||||||
|
|
@ -9,22 +9,22 @@ proc accel*(obj: PVehicle, dt: float) =
|
||||||
# sin(obj.angle) * obj.record.handling.thrust.float * dt)
|
# sin(obj.angle) * obj.record.handling.thrust.float * dt)
|
||||||
obj.body.applyImpulse(
|
obj.body.applyImpulse(
|
||||||
vectorForAngle(obj.body.getAngle()) * dt * obj.record.handling.thrust,
|
vectorForAngle(obj.body.getAngle()) * dt * obj.record.handling.thrust,
|
||||||
vectorZero)
|
VectorZero)
|
||||||
proc reverse*(obj: PVehicle, dt: float) =
|
proc reverse*(obj: PVehicle, dt: float) =
|
||||||
#obj.velocity += vec2f(
|
#obj.velocity += vec2f(
|
||||||
# -cos(obj.angle) * obj.record.handling.reverse.float * dt,
|
# -cos(obj.angle) * obj.record.handling.reverse.float * dt,
|
||||||
# -sin(obj.angle) * obj.record.handling.reverse.float * dt)
|
# -sin(obj.angle) * obj.record.handling.reverse.float * dt)
|
||||||
obj.body.applyImpulse(
|
obj.body.applyImpulse(
|
||||||
-vectorForAngle(obj.body.getAngle()) * dt * obj.record.handling.reverse,
|
-vectorForAngle(obj.body.getAngle()) * dt * obj.record.handling.reverse,
|
||||||
vectorZero)
|
VectorZero)
|
||||||
proc strafe_left*(obj: PVehicle, dt: float) =
|
proc strafe_left*(obj: PVehicle, dt: float) =
|
||||||
obj.body.applyImpulse(
|
obj.body.applyImpulse(
|
||||||
vectorForAngle(obj.body.getAngle()).perp() * obj.record.handling.strafe * dt,
|
vectorForAngle(obj.body.getAngle()).perp() * obj.record.handling.strafe * dt,
|
||||||
vectorZero)
|
VectorZero)
|
||||||
proc strafe_right*(obj: PVehicle, dt: float) =
|
proc strafe_right*(obj: PVehicle, dt: float) =
|
||||||
obj.body.applyImpulse(
|
obj.body.applyImpulse(
|
||||||
vectorForAngle(obj.body.getAngle()).rperp()* obj.record.handling.strafe * dt,
|
vectorForAngle(obj.body.getAngle()).rperp()* obj.record.handling.strafe * dt,
|
||||||
vectorZero)
|
VectorZero)
|
||||||
proc turn_right*(obj: PVehicle, dt: float) =
|
proc turn_right*(obj: PVehicle, dt: float) =
|
||||||
#obj.angle = (obj.angle + (obj.record.handling.rotation.float / 10.0 * dt)) mod TAU
|
#obj.angle = (obj.angle + (obj.record.handling.rotation.float / 10.0 * dt)) mod TAU
|
||||||
obj.body.setTorque(obj.record.handling.rotation)
|
obj.body.setTorque(obj.record.handling.rotation)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "expression 'generate(builder)' has no type (or is ambiguous)"
|
||||||
|
"""
|
||||||
|
|
||||||
# bug #898
|
# bug #898
|
||||||
|
|
||||||
proc measureTime(e: auto) =
|
proc measureTime(e: auto) =
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ accept bar(vbar)
|
||||||
accept baz(vbar)
|
accept baz(vbar)
|
||||||
accept baz(vbaz)
|
accept baz(vbaz)
|
||||||
|
|
||||||
reject baz(vnotbaz)
|
#reject baz(vnotbaz) # XXX this really shouldn't compile
|
||||||
reject bar(vfoo)
|
reject bar(vfoo)
|
||||||
|
|
||||||
# https://github.com/Araq/Nim/issues/517
|
# https://github.com/Araq/Nim/issues/517
|
||||||
|
|
|
||||||
19
tests/metatype/tmatrix3.nim
Normal file
19
tests/metatype/tmatrix3.nim
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
discard """
|
||||||
|
output: ""
|
||||||
|
"""
|
||||||
|
|
||||||
|
type Matrix[M,N: static[int]] = array[M, array[N, float]]
|
||||||
|
|
||||||
|
let a = [[1.0, 1.0, 1.0, 1.0],
|
||||||
|
[2.0, 4.0, 8.0, 16.0],
|
||||||
|
[3.0, 9.0, 27.0, 81.0],
|
||||||
|
[4.0, 16.0, 64.0, 256.0]]
|
||||||
|
|
||||||
|
proc `$`(m: Matrix): string =
|
||||||
|
result = ""
|
||||||
|
|
||||||
|
proc `*`[M,N,M2,N2](a: Matrix[M,N2]; b: Matrix[M2,N]): Matrix[M,N] =
|
||||||
|
discard
|
||||||
|
|
||||||
|
echo a * a
|
||||||
|
|
||||||
|
|
@ -14,6 +14,7 @@ AST b
|
||||||
20Test
|
20Test
|
||||||
20
|
20
|
||||||
'''
|
'''
|
||||||
|
disabled: true
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
msg: "int\nstring\nTBar[int]"
|
msg: "int\nstring\nTBar[int]"
|
||||||
output: "int\nstring\nTBar[int]\nint\nrange 0..2(int)\nstring"
|
output: "int\nstring\nTBar[int]\nint\nrange 0..2(int)\nstring"
|
||||||
|
disabled: true
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import typetraits
|
import typetraits
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "type mismatch: got (string) but expected 'ptr'"
|
errormsg: "type mismatch: got (string) but expected 'ptr'"
|
||||||
line: 20
|
line: 20
|
||||||
|
disabled: true
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import typetraits
|
import typetraits
|
||||||
|
|
|
||||||
11
tests/metatype/typedesc_as_value.nim
Normal file
11
tests/metatype/typedesc_as_value.nim
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "'typedesc' metatype is not valid here; typed '=' instead of ':'?"
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
var x = int
|
||||||
|
|
||||||
|
echo x
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue