Merge branch 'devel' into gcbugfix

This commit is contained in:
Araq 2015-02-10 16:58:50 +01:00
commit 373a79b28a
127 changed files with 1341 additions and 612 deletions

View file

@ -459,7 +459,7 @@ type
tfNeedsInit, # type constains a "not nil" constraint somewhere or some
# 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
# or other type classes
tfHasGCedMem, # type contains GC'ed memory
@ -522,7 +522,7 @@ const
skError* = skUnknown
# type flags that are essential for type equality:
eqTypeFlags* = {tfIterator, tfShared, tfNotNil}
eqTypeFlags* = {tfIterator, tfShared, tfNotNil, tfVarIsPtr}
type
TMagic* = enum # symbols that require compiler magic:
@ -1348,7 +1348,7 @@ proc isGCedMem*(t: PType): bool {.inline.} =
proc propagateToOwner*(owner, elem: PType) =
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 owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvokation}:
owner.flags.incl tfNotNil
@ -1359,9 +1359,6 @@ proc propagateToOwner*(owner, elem: PType) =
if owner.kind in HaveTheirOwnEmpty: discard
else: owner.flags.incl tfNeedsInit
if tfShared in elem.flags:
owner.flags.incl tfHasShared
if elem.isMetaType:
owner.flags.incl tfHasMeta

View file

@ -130,8 +130,8 @@ proc skipConvAndClosure*(n: PNode): PNode =
proc sameValue*(a, b: PNode): bool =
result = false
case a.kind
of nkCharLit..nkInt64Lit:
if b.kind in {nkCharLit..nkInt64Lit}: result = a.intVal == b.intVal
of nkCharLit..nkUInt64Lit:
if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal
of nkFloatLit..nkFloat64Lit:
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
of nkStrLit..nkTripleStrLit:
@ -145,13 +145,13 @@ proc leValue*(a, b: PNode): bool =
# a <= b?
result = false
case a.kind
of nkCharLit..nkInt64Lit:
if b.kind in {nkCharLit..nkInt64Lit}: result = a.intVal <= b.intVal
of nkFloatLit..nkFloat64Lit:
of nkCharLit..nkUInt32Lit:
if b.kind in {nkCharLit..nkUInt32Lit}: result = a.intVal <= b.intVal
of nkFloatLit..nkFloat64Lit:
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
else:
else:
# don't raise an internal error for 'nimrod check':
#InternalError(a.info, "leValue")
discard

View file

@ -124,8 +124,8 @@ proc genArgStringToCString(p: BProc, n: PNode): PRope {.inline.} =
var a: TLoc
initLocExpr(p, n.sons[0], a)
result = ropef("$1->data", [a.rdLoc])
proc genArg(p: BProc, n: PNode, param: PSym): PRope =
proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): PRope =
var a: TLoc
if n.kind == nkStringToCString:
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
n.kind == nkHiddenAddr:
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:
initLocExprSingleUse(p, n, a)
result = rdLoc(a)
@ -166,7 +174,7 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
if params != nil: app(params, ~", ")
if i < sonsLen(typ):
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:
app(params, genArgNoParam(p, ri.sons[i]))
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))
if i < sonsLen(typ):
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:
app(pl, genArgNoParam(p, ri.sons[i]))
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:
result = genArgNoParam(p, x)
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.app("->")
else:
@ -424,12 +432,12 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
assert(sonsLen(typ) == sonsLen(typ.n))
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, op.r)
if length > 2:
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):
assert(sonsLen(typ) == sonsLen(typ.n))
if i >= sonsLen(typ):
@ -439,7 +447,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
app(pl, ~" ")
app(pl, param.name.s)
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 isInvalidReturnType(typ.sons[0]):
if sonsLen(ri) > 1: app(pl, ~" ")

View file

@ -83,7 +83,9 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope =
else:
result = toRope("NIM_NIL")
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)
if id == gBackendId:
# 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.} =
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) =
let mt = mapType(e.sons[0].typ)
@ -677,12 +680,14 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
else:
var a: TLoc
initLocExprSingleUse(p, e.sons[0], a)
case skipTypes(a.t, abstractInst).kind
let typ = skipTypes(a.t, abstractInst)
case typ.kind
of tyRef:
d.s = OnHeap
of tyVar:
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))
return
of tyPtr:
@ -923,6 +928,7 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
L: TLabel
tmp: TLoc
getTemp(p, e.typ, tmp) # force it into a temp!
inc p.splitDecls
expr(p, e.sons[1], tmp)
L = getLabel(p)
if m == mOr:
@ -935,6 +941,7 @@ proc genAndOr(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
d = tmp
else:
genAssignment(p, d, tmp, {}) # no need for deep copying
dec p.splitDecls
proc genEcho(p: BProc, n: PNode) =
# 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
for i in countup(0, n.len-1):
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",
makeCString(repeatStr(n.len, "%s") & tnl), args)
@ -2168,7 +2175,7 @@ proc genConstExpr(p: BProc, n: PNode): PRope =
var cs: TBitSet
toBitSet(n, cs)
result = genRawSetData(cs, int(getSize(n.typ)))
of nkBracket, nkPar, nkClosure:
of nkBracket, nkPar, nkClosure, nkObjConstr:
var t = skipTypes(n.typ, abstractInst)
if t.kind == tySequence:
result = genConstSeq(p, n, t)

View file

@ -203,7 +203,7 @@ proc genSingleVar(p: BProc, a: PNode) =
registerGcRoot(p, v)
else:
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
# parameterless constructor followed by an assignment operator. So we
# 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
c.ast.len != 0:
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) =
#
# { if (!expr1) goto L1;
@ -286,17 +277,22 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
let it = n.sons[i]
if it.len == 2:
when newScopeForIf: startBlock(p)
initLocExpr(p, it.sons[0], a)
initLocExprSingleUse(p, it.sons[0], a)
lelse = getLabel(p)
inc(p.labels)
lineFF(p, cpsStmts, "if (!$1) goto $2;$n",
"br i1 $1, label %LOC$3, label %$2$nLOC$3: $n",
[rdLoc(a), lelse, toRope(p.labels)])
lineF(p, cpsStmts, "if (!$1) goto $2;$n",
[rdLoc(a), lelse])
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)
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)
elif it.len == 1:
startBlock(p)
@ -355,7 +351,7 @@ proc genReturnStmt(p: BProc, t: PNode) =
# consume it before we return.
var safePoint = p.finallySafePoints[p.finallySafePoints.len-1]
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) =
# first pass: Generate array of computed labels:

View file

@ -27,17 +27,7 @@ proc isKeyword(w: PIdent): bool =
proc mangleName(s: PSym): PRope =
result = s.loc.r
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")
if result == nil:
when oKeepVariableNames:
let keepOrigName = s.kind in skLocalVars - {skForVar} and
{sfFromGeneric, sfGlobal, sfShadowed, sfGenSym} * s.flags == {} and
@ -103,13 +93,11 @@ proc typeName(typ: PType): PRope =
else: ~"TY"
proc getTypeName(typ: PType): PRope =
if (typ.sym != nil) and ({sfImportc, sfExportc} * typ.sym.flags != {}) and
(gCmd != cmdCompileToLLVM):
if typ.sym != nil and {sfImportc, sfExportc} * typ.sym.flags != {}:
result = typ.sym.loc.r
else:
if typ.loc.r == nil:
typ.loc.r = if gCmd != cmdCompileToLLVM: con(typ.typeName, typ.id.toRope)
else: con([~"%", typ.typeName, typ.id.toRope])
typ.loc.r = con(typ.typeName, typ.id.toRope)
result = typ.loc.r
if result == nil: internalError("getTypeName: " & $typ.kind)
@ -200,9 +188,6 @@ const
"N_SYSCALL", # this is probably not correct for all platforms,
# but one can #define it to what one wants
"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 =
# 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:
if param.typ.kind == tyVar: param.loc.s = OnUnknown
# 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)
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]
if params != nil: app(params, ", ")
app(params, getTypeDescAux(m, arr, check))
if (mapReturnType(t.sons[0]) != ctArray) or (gCmd == cmdCompileToLLVM):
if (mapReturnType(t.sons[0]) != ctArray):
app(params, "*")
appff(params, " Result", " @Result", [])
appf(params, " Result", [])
if t.callConv == ccClosure and declareEnvironment:
if params != nil: app(params, ", ")
app(params, "void* ClEnv")
if tfVarargs in t.flags:
if params != nil: app(params, ", ")
app(params, "...")
if params == nil and gCmd != cmdCompileToLLVM: app(params, "void)")
if params == nil: app(params, "void)")
else: app(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
# C type generation into an analysis and a code generation phase somehow.
case t.kind
of tyRef, tyPtr, tyVar:
let star = if t.kind == tyVar and compileToCpp(m): "&" else: "*"
of tyRef, tyPtr, tyVar:
var star = if t.kind == tyVar and tfVarIsPtr notin typ.flags and
compileToCpp(m): "&" else: "*"
var et = t.lastSon
var etB = et.skipTypes(abstractInst)
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`
et = elemType(etB)
etB = et.skipTypes(abstractInst)
star[0] = '*'
case etB.kind
of tyObject, tyTuple:
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
let x = getUniqueType(etB)
let name = getTypeForward(m, x)
result = con(name, "**")
result = con(name, "*" & star)
idTablePut(m.typeCache, t, result)
pushType(m, x)
else:
@ -677,7 +664,7 @@ proc genProcHeader(m: BModule, prc: PSym): PRope =
rettype, params: PRope
genCLineDir(result, prc.info)
# 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:
result.app "N_LIB_IMPORT "
else:

View file

@ -25,15 +25,6 @@ when options.hasTinyCBackend:
var
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) =
m.forwardedProcs.add(prc)
inc(gForwardedProcsCounter)
@ -137,79 +128,8 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
if i - 1 >= start:
app(result, substr(frmt, start, i - 1))
const compileTimeRopeFmt = false
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)
template rfmt(m: BModule, fmt: string, args: varargs[PRope]): expr =
ropecg(m, fmt, args)
proc appcg(m: BModule, c: var PRope, frmt: TFormatStr,
args: varargs[PRope]) =
@ -242,24 +162,14 @@ proc lineCg(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: varargs[PRope]) =
app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
when compileTimeRopeFmt:
template linefmt(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: varargs[PRope]) =
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 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,
args: varargs[PRope]) =
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 =
result = toLinenumber(info)
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) =
assert line >= 0
if optLineDir in gOptions:
appff(r, "$N#line $2 $1$N", "; line $2 \"$1\"$n",
[toRope(makeSingleLineCString(filename)), toRope(line)])
appf(r, "$N#line $2 $1$N",
[toRope(makeSingleLineCString(filename)), toRope(line)])
proc genCLineDir(r: var PRope, info: TLineInfo) =
genCLineDir(r, info.toFullPath, info.safeLineNm)
@ -443,29 +353,6 @@ proc deinitGCFrame(p: BProc): PRope =
if p.gcFrameId > 0:
result = ropecg(p.module,
"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) =
assert(s.kind == skParam)
@ -507,7 +394,7 @@ proc localVarDecl(p: BProc; s: PSym): PRope =
result = ropef(s.cgDeclFrmt, result, s.loc.r)
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
# for each module that uses them!
let decl = localVarDecl(p, s).con(";" & tnl)
@ -553,13 +440,11 @@ proc assignGlobalVar(p: BProc, s: PSym) =
{optStackTrace, optEndb}:
appcg(p.module, p.module.s[cfsDebugInit],
"#dbgRegisterGlobal($1, &$2, $3);$n",
[cstringLit(p, p.module.s[cfsDebugInit],
normalize(s.owner.name.s & '.' & s.name.s)),
[makeCString(normalize(s.owner.name.s & '.' & s.name.s)),
s.loc.r, genTypeInfo(p.module, s.typ)])
proc assignParam(p: BProc, s: PSym) =
assert(s.loc.r != nil)
if sfAddrTaken in s.flags and gCmd == cmdCompileToLLVM: allocParam(p, s)
localDebugInfo(p, s)
proc fillProcLoc(sym: PSym) =
@ -653,7 +538,6 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
let isCall = isGetProcAddr(lib)
var extname = sym.loc.r
if not isCall: loadDynamicLib(m, lib)
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
var tmp = mangleDynLibProc(sym)
sym.loc.r = tmp # from now on we only need the internal name
sym.typ.sym = nil # generate a new name
@ -669,7 +553,7 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
params.app(", ")
let load = ropef("\t$1 = ($2) ($3$4));$n",
[tmp, getTypeDesc(m, sym.typ),
params, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))])
params, makeCString(ropeToStr(extname))])
var last = lastSon(n)
if last.kind == nkHiddenStdConv: last = last.sons[1]
internalAssert(last.kind == nkStrLit)
@ -684,10 +568,8 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
appcg(m, m.s[cfsDynLibInit],
"\t$1 = ($2) #nimGetProcAddr($3, $4);$n",
[tmp, getTypeDesc(m, sym.typ),
lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))])
appff(m.s[cfsVars], "$2 $1;$n",
"$1 = linkonce global $2 zeroinitializer$n",
[sym.loc.r, getTypeDesc(m, sym.loc.t)])
lib.name, makeCString(ropeToStr(extname))])
appf(m.s[cfsVars], "$2 $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)])
proc varInDynamicLib(m: BModule, sym: PSym) =
var lib = sym.annex
@ -700,7 +582,7 @@ proc varInDynamicLib(m: BModule, sym: PSym) =
appcg(m, m.s[cfsDynLibInit],
"$1 = ($2*) #nimGetProcAddr($3, $4);$n",
[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",
[sym.loc.r, getTypeDesc(m, sym.loc.t)])
@ -723,13 +605,13 @@ proc cgsym(m: BModule, name: string): PRope =
rawMessage(errSystemNeeds, name)
result = sym.loc.r
proc generateHeaders(m: BModule) =
proc generateHeaders(m: BModule) =
app(m.s[cfsHeaders], tnl & "#include \"nimbase.h\"" & tnl)
var it = PStrEntry(m.headerFiles.head)
while it != nil:
while it != nil:
if it.data[0] notin {'\"', '<'}:
appf(m.s[cfsHeaders], "$N#include \"$1\"$N", [toRope(it.data)])
else:
else:
appf(m.s[cfsHeaders], "$N#include $1$N", [toRope(it.data)])
it = PStrEntry(it.next)
@ -802,16 +684,17 @@ proc genProcAux(m: BModule, prc: PSym) =
app(generatedProc, initGCFrame(p))
if optStackTrace in prc.options:
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))
else:
app(generatedProc, p.s(cpsLocals))
if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM):
if optProfiler in prc.options:
# invoke at proc entry for recursion:
appcg(p, cpsInit, "\t#nimProfile();$n", [])
if p.beforeRetNeeded: app(generatedProc, "{")
app(generatedProc, p.s(cpsInit))
app(generatedProc, p.s(cpsStmts))
if p.beforeRetNeeded: app(generatedProc, ~"\tBeforeRet: ;$n")
if p.beforeRetNeeded: app(generatedProc, ~"\t}BeforeRet: ;$n")
app(generatedProc, deinitGCFrame(p))
if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
app(generatedProc, returnStmt)
@ -831,7 +714,6 @@ proc genProcPrototype(m: BModule, sym: PSym) =
not containsOrIncl(m.declaredThings, sym.id):
app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
elif not containsOrIncl(m.declaredProtos, sym.id):
var header = genProcHeader(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 =
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" &
"/* The generated code is subject to the original license. */$N",
"; Generated by Nim Compiler v$1$N" &
"; (c) 2012 Andreas Rumpf$N", [toRope(VersionAsString)])
[toRope(VersionAsString)])
else:
result = ropeff("/* Generated by Nim Compiler v$1 */$N" &
result = ropef("/* Generated by Nim Compiler v$1 */$N" &
"/* (c) 2015 Andreas Rumpf */$N" &
"/* The generated code is subject to the original license. */$N" &
"/* Compiled for: $2, $3, $4 */$N" &
"/* Command for C compiler:$n $5 */$N",
"; Generated by Nim Compiler v$1$N" &
"; (c) 2015 Andreas Rumpf$N" &
"; Compiled for: $2, $3, $4$N" &
"; Command for LLVM compiler:$N $5$N", [toRope(VersionAsString),
[toRope(VersionAsString),
toRope(platform.OS[targetOS].name),
toRope(platform.CPU[targetCPU].name),
toRope(extccomp.CC[extccomp.cCompiler].name),
@ -1094,13 +972,11 @@ proc registerModuleToMain(m: PSym) =
var
init = m.getInitName
datInit = m.getDatInitName
appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
"declare void $1() noinline$N", [init])
appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
"declare void $1() noinline$N", [datInit])
appf(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N", [init])
appf(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N", [datInit])
if sfSystemModule notin m.flags:
appff(mainDatInit, "\t$1();$N", "call void ()* $1$n", [datInit])
let initCall = ropeff("\t$1();$N", "call void ()* $1$n", [init])
appf(mainDatInit, "\t$1();$N", [datInit])
let initCall = ropef("\t$1();$N", [init])
if sfMainModule in m.flags:
app(mainModInit, initCall)
else:
@ -1108,8 +984,7 @@ proc registerModuleToMain(m: PSym) =
proc genInitCode(m: BModule) =
var initname = getInitName(m.module)
var prc = ropeff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
"define void $1() noinline {$n", [initname])
var prc = ropef("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N", [initname])
if m.typeNodes > 0:
appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
[m.typeNodesName, toRope(m.typeNodes)])
@ -1130,7 +1005,7 @@ proc genInitCode(m: BModule) =
# declare it nevertheless:
m.frameDeclared = true
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))
else:
app(prc, ~"\tTFrame F; F.len = 0;$N")
@ -1151,8 +1026,8 @@ proc genInitCode(m: BModule) =
app(prc, deinitGCFrame(m.initProc))
appf(prc, "}$N$N")
prc.appff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
"define void $1() noinline {$n", [getDatInitName(m.module)])
prc.appf("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
[getDatInitName(m.module)])
for i in cfsTypeInit1..cfsDynLibInit:
app(prc, genSectionStart(i))

View file

@ -82,6 +82,9 @@ type
maxFrameLen*: int # max length of frame descriptor
module*: BModule # used to prevent excessive parameter passing
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
gcFrameType*: PRope # the struct {} we put the GC markers into

View file

@ -52,7 +52,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo)
const
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
Usage = slurp"doc/basicopt.txt".replace("//", "")

View file

@ -428,13 +428,17 @@ proc addFileToLink*(filename: string) =
prependStr(toLink, filename)
# BUGFIX: was ``appendStr``
proc execExternalProgram*(cmd: string, prettyCmd = "") =
proc execWithEcho(cmd: string, prettyCmd = ""): int =
if optListCmd in gGlobalOptions or gVerbosity > 0:
if prettyCmd != "":
msgWriteln(prettyCmd)
else:
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) =
let (dir, name, ext) = splitFile(projectFile)
@ -622,7 +626,9 @@ proc callCCompiler*(projectfile: string) =
if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors()
var res = 0
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:
res = execProcesses(cmds, {poEchoCmd, poUseShell, poParentStreams},
gNumberOfProcessors)

View file

@ -30,47 +30,32 @@ type
PLLStream* = ref TLLStream
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 =
proc llStreamOpen*(data: string): PLLStream =
new(result)
result.s = data
result.kind = llsString
proc llStreamOpen(f: var File): PLLStream =
proc llStreamOpen*(f: var File): PLLStream =
new(result)
result.f = f
result.kind = llsFile
proc llStreamOpen(filename: string, mode: FileMode): PLLStream =
proc llStreamOpen*(filename: string, mode: FileMode): PLLStream =
new(result)
result.kind = llsFile
if not open(result.f, filename, mode): result = nil
proc llStreamOpen(): PLLStream =
proc llStreamOpen*(): PLLStream =
new(result)
result.kind = llsNone
proc llStreamOpenStdIn(): PLLStream =
proc llStreamOpenStdIn*(): PLLStream =
new(result)
result.kind = llsStdIn
result.s = ""
result.lineOffset = -1
proc llStreamClose(s: PLLStream) =
proc llStreamClose*(s: PLLStream) =
case s.kind
of llsNone, llsString, llsStdIn:
discard
@ -130,7 +115,7 @@ proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
copyMem(buf, addr(s.s[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
of llsNone:
result = 0
@ -144,7 +129,7 @@ proc llStreamRead(s: PLLStream, buf: pointer, bufLen: int): int =
of llsStdIn:
result = llReadFromStdin(s, buf, bufLen)
proc llStreamReadLine(s: PLLStream, line: var string): bool =
proc llStreamReadLine*(s: PLLStream, line: var string): bool =
setLen(line, 0)
case s.kind
of llsNone:
@ -168,7 +153,7 @@ proc llStreamReadLine(s: PLLStream, line: var string): bool =
of llsStdIn:
result = readLine(stdin, line)
proc llStreamWrite(s: PLLStream, data: string) =
proc llStreamWrite*(s: PLLStream, data: string) =
case s.kind
of llsNone, llsStdIn:
discard
@ -178,11 +163,11 @@ proc llStreamWrite(s: PLLStream, data: string) =
of llsFile:
write(s.f, data)
proc llStreamWriteln(s: PLLStream, data: string) =
proc llStreamWriteln*(s: PLLStream, data: string) =
llStreamWrite(s, data)
llStreamWrite(s, "\n")
proc llStreamWrite(s: PLLStream, data: char) =
proc llStreamWrite*(s: PLLStream, data: char) =
var c: char
case s.kind
of llsNone, llsStdIn:
@ -194,7 +179,7 @@ proc llStreamWrite(s: PLLStream, data: char) =
c = data
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
of llsNone, llsStdIn:
discard
@ -206,7 +191,7 @@ proc llStreamWrite(s: PLLStream, buf: pointer, buflen: int) =
of llsFile:
discard writeBuffer(s.f, buf, buflen)
proc llStreamReadAll(s: PLLStream): string =
proc llStreamReadAll*(s: PLLStream): string =
const
bufSize = 2048
case s.kind

View file

@ -251,7 +251,6 @@ proc mainCommand* =
commandCompileToC()
of "cpp", "compiletocpp":
gCmd = cmdCompileToCpp
if cCompiler == ccGcc: setCC("gcc")
defineSymbol("cpp")
commandCompileToC()
of "objc", "compiletooc":

View file

@ -113,7 +113,7 @@ type
warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
warnUnknownSubstitutionX, warnLanguageXNotSupported,
warnFieldXNotSupported, warnCommentXIgnored,
warnNilStatement, warnAnalysisLoophole,
warnNilStatement, warnTypelessParam,
warnDifferentHeaps, warnWriteToForeignHeap, warnUnsafeCode,
warnEachIdentIsTuple, warnShadowIdent,
warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
@ -311,7 +311,7 @@ const
errXOnlyAtModuleScope: "\'$1\' is only allowed at top level",
errXNeedsParamObjectType: "'$1' needs a parameter that has an object type",
errTemplateInstantiationTooNested: "template/macro instantiation too nested",
errInstantiationFrom: "instantiation from here",
errInstantiationFrom: "template/generic instantiation from here",
errInvalidIndexValueForTuple: "invalid index value for tuple subscript",
errCommandExpectsFilename: "command expects a filename argument",
errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file",
@ -376,7 +376,7 @@ const
warnFieldXNotSupported: "field \'$1\' not supported [FieldXNotSupported]",
warnCommentXIgnored: "comment \'$1\' ignored [CommentXIgnored]",
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]",
warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]",
warnUnsafeCode: "unsafe code: '$1' [UnsafeCode]",
@ -418,7 +418,7 @@ const
"RedefinitionOfLabel", "UnknownSubstitutionX",
"LanguageXNotSupported", "FieldXNotSupported",
"CommentXIgnored", "NilStmt",
"AnalysisLoophole", "DifferentHeaps", "WriteToForeignHeap",
"TypelessParam", "DifferentHeaps", "WriteToForeignHeap",
"UnsafeCode", "EachIdentIsTuple", "ShadowIdent",
"ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
"GcMem", "Destructor", "LockLevel", "User"]
@ -460,7 +460,7 @@ type
TLineInfo*{.final.} = object # This is designed to be as small as possible,
# 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.
# On 64 bit and on 32 bit systems this is
# only 8 bytes.
@ -522,7 +522,7 @@ proc newFileInfo(fullPath, projPath: string): TFileInfo =
if optEmbedOrigSrc in gGlobalOptions or true:
result.lines = @[]
proc fileInfoIdx*(filename: string): int32 =
proc fileInfoIdx*(filename: string; isKnownFile: var bool): int32 =
var
canon: string
pseudoPath = false
@ -539,11 +539,16 @@ proc fileInfoIdx*(filename: string): int32 =
if filenameToIndexTbl.hasKey(canon):
result = filenameToIndexTbl[canon]
else:
isKnownFile = false
result = fileInfos.len.int32
fileInfos.add(newFileInfo(canon, if pseudoPath: filename
else: canon.shortenDir))
filenameToIndexTbl[canon] = result
proc fileInfoIdx*(filename: string): int32 =
var dummy: bool
result = fileInfoIdx(filename, dummy)
proc newLineInfo*(fileInfoIdx: int32, line, col: int): TLineInfo =
result.fileIndex = fileInfoIdx
result.line = int16(line)

View file

@ -11,10 +11,10 @@
import
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer,
options, idents, wordrecg
options, idents, wordrecg, strtabs
# ---------------- 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) =
# simple filter
@ -82,17 +82,17 @@ proc doElif(L: var TLexer, tok: var TToken) =
proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest) =
var nestedIfs = 0
while true:
if (tok.ident != nil) and (tok.ident.s == "@"):
if tok.ident != nil and tok.ident.s == "@":
ppGetTok(L, tok)
case whichKeyword(tok.ident)
of wIf:
inc(nestedIfs)
of wElse:
if (dest == jdElseEndif) and (nestedIfs == 0):
if dest == jdElseEndif and nestedIfs == 0:
doElse(L, tok)
break
of wElif:
if (dest == jdElseEndif) and (nestedIfs == 0):
if dest == jdElseEndif and nestedIfs == 0:
doElif(L, tok)
break
of wEnd:
@ -119,9 +119,10 @@ proc parseDirective(L: var TLexer, tok: var TToken) =
of wElif: doElif(L, tok)
of wElse: doElse(L, tok)
of wEnd: doEnd(L, tok)
of wWrite:
of wWrite:
ppGetTok(L, tok)
msgs.msgWriteln(tokToStr(tok))
msgs.msgWriteln(strtabs.`%`(tokToStr(tok), options.gConfigVars,
{useEnvironment, useKey}))
ppGetTok(L, tok)
else:
case tok.ident.s.normalize
@ -157,7 +158,7 @@ proc checkSymbol(L: TLexer, tok: TToken) =
proc parseAssignment(L: var TLexer, tok: var TToken) =
if tok.ident.id == getIdent("-").id or tok.ident.id == getIdent("--").id:
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)
var s = tokToStr(tok)
confTok(L, tok) # skip symbol
@ -178,9 +179,10 @@ proc parseAssignment(L: var TLexer, tok: var TToken) =
if tok.tokType == tkBracketRi: confTok(L, tok)
else: lexMessage(L, errTokenExpected, "']'")
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, ':')
confTok(L, tok) # skip ':' or '='
confTok(L, tok) # skip ':' or '=' or '%'
checkSymbol(L, tok)
add(val, tokToStr(tok))
confTok(L, tok) # skip symbol
@ -189,7 +191,11 @@ proc parseAssignment(L: var TLexer, tok: var TToken) =
checkSymbol(L, tok)
add(val, tokToStr(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) =
var
@ -246,6 +252,11 @@ proc loadConfigs*(cfg: string) =
if gProjectName.len != 0:
# new project wide config file:
let projectConfig = changeFileExt(gProjectFull, "nim.cfg")
if fileExists(projectConfig): readConfigFile(projectConfig)
else: readConfigFile(changeFileExt(gProjectFull, "nimrod.cfg"))
var projectConfig = changeFileExt(gProjectFull, "nimcfg")
if not fileExists(projectConfig):
projectConfig = changeFileExt(gProjectFull, "nim.cfg")
if not fileExists(projectConfig):
projectConfig = changeFileExt(gProjectFull, "nimrod.cfg")
if fileExists(projectConfig):
rawMessage(warnDeprecated, projectConfig)
readConfigFile(projectConfig)

View file

@ -87,8 +87,9 @@ proc action(cmd: string) =
i += skipWhile(cmd, seps, i)
i += parseInt(cmd, col, i)
var isKnownFile = true
if orig.len == 0: err()
let dirtyIdx = orig.fileInfoIdx
let dirtyIdx = orig.fileInfoIdx(isKnownFile)
if dirtyfile.len != 0: msgs.setDirtyFile(dirtyIdx, dirtyfile)
else: msgs.setDirtyFile(dirtyIdx, nil)
@ -99,7 +100,10 @@ proc action(cmd: string) =
gTrackPos = newLineInfo(dirtyIdx, line, col)
#echo dirtyfile, gDirtyBufferIdx, " project ", gProjectMainIdx
gErrorCounter = 0
compileProject()
if not isKnownFile:
compileProject(dirtyIdx)
else:
compileProject()
proc serve() =
# do not stop after the first error:

View file

@ -198,8 +198,8 @@ proc isSigilLike(tok: TToken): bool {.inline.} =
proc isRightAssociative(tok: TToken): bool {.inline.} =
## Determines whether the token is right assocative.
result = tok.tokType == tkOpr and (tok.ident.s[0] == '^' or
(let L = tok.ident.s.len; L > 1 and tok.ident.s[L-1] == '>'))
result = tok.tokType == tkOpr and tok.ident.s[0] == '^'
# or (let L = tok.ident.s.len; L > 1 and tok.ident.s[L-1] == '>'))
proc getPrecedence(tok: TToken, strongSpaces: bool): int =
## Calculates the precedence of the given token.

View file

@ -138,7 +138,7 @@ const
props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
(name: "VxWorks", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
objExt: ".o", newLine: "\x0A", pathSep: ";", dirSep: "\\",
scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
scriptExt: ".sh", curDir: ".", exeExt: ".vxe", extSep: ".",
props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
(name: "JS", parDir: "..",
dllFrmt: "lib$1.so", altDirSep: "/",

View file

@ -130,9 +130,11 @@ proc commonType*(x, y: PType): PType =
elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len:
var nt: PType
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)
nt.sons[i] = b.sons[i]
nt.sons[i] = if aEmpty: b.sons[i] else: a.sons[i]
if not nt.isNil: result = nt
#elif b.sons[idx].kind == tyEmpty: return x
elif a.kind == tyRange and b.kind == tyRange:

View file

@ -221,6 +221,7 @@ proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
result = newTypeS(tyFromExpr, c)
assert n != nil
result.n = n
proc newTypeWithSons*(c: PContext, kind: TTypeKind,

View file

@ -103,28 +103,31 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
result = newSymNode(s, n.info)
of skMacro: result = semMacroExpr(c, n, 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)
styleCheckUse(n.info, s)
# if a proc accesses a global variable, it is not side effect free:
if sfGlobal in s.flags:
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)
# We cannot check for access to outer vars for example because it's still
# 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})
if tup.kind != tyTuple:
internalError(n.info, "changeType: no tuple type for constructor")
elif newType.n == nil: discard
elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr:
for i in countup(0, sonsLen(n) - 1):
elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr:
# named tuple?
for i in countup(0, sonsLen(n) - 1):
var m = n.sons[i].sons[0]
if m.kind != nkSym:
if m.kind != nkSym:
internalError(m.info, "changeType(): invalid tuple constr")
return
var f = getSymFromList(newType.n, m.sym.name)
if f == nil:
internalError(m.info, "changeType(): invalid identifier")
return
changeType(n.sons[i].sons[1], f.typ, check)
if tup.n != nil:
var f = getSymFromList(newType.n, m.sym.name)
if f == nil:
internalError(m.info, "changeType(): invalid identifier")
return
changeType(n.sons[i].sons[1], f.typ, check)
else:
changeType(n.sons[i].sons[1], tup.sons[i], check)
else:
for i in countup(0, sonsLen(n) - 1):
var m = n.sons[i]
var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
addSon(a, newSymNode(newType.n.sons[i].sym))
addSon(a, m)
changeType(m, tup.sons[i], check)
changeType(n.sons[i], tup.sons[i], check)
when false:
var m = n.sons[i]
var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
addSon(a, newSymNode(newType.n.sons[i].sym))
addSon(a, m)
changeType(m, tup.sons[i], check)
of nkCharLit..nkUInt64Lit:
if check:
let value = n.intVal
@ -578,11 +586,12 @@ proc skipObjConv(n: PNode): PNode =
proc isAssignable(c: PContext, n: PNode): TAssignableResult =
result = parampatterns.isAssignable(c.p.owner, n)
proc newHiddenAddrTaken(c: PContext, n: PNode): PNode =
if n.kind == nkHiddenDeref:
proc newHiddenAddrTaken(c: PContext, n: PNode): PNode =
if n.kind == nkHiddenDeref and not (gCmd == cmdCompileToCpp or
sfCompileToCpp in c.module.flags):
checkSonsLen(n, 1)
result = n.sons[0]
else:
else:
result = newNodeIT(nkHiddenAddr, n.info, makeVarType(c, n.typ))
addSon(result, n)
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:
n.sons[0] = x # 'result[]' --> 'result'
n.sons[1] = takeImplicitAddr(c, ri)
x.typ.flags.incl tfVarIsPtr
template resultTypeIsInferrable(typ: PType): expr =
typ.isMetaType and typ.kind != tyTypeDesc

View file

@ -77,11 +77,16 @@ proc removeDefaultParamValues(n: PNode) =
proc freshGenSyms(n: PNode, owner: PSym, symMap: var TIdTable) =
# we need to create a fresh set of gensym'ed symbols:
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:
x = copySym(n.sym, false)
x.owner = owner
idTablePut(symMap, n.sym, x)
if s.kind == skParam:
x = owner.typ.n[s.position+1].sym
internalAssert x.kind == skParam
else:
x = copySym(s, false)
x.owner = owner
idTablePut(symMap, s, x)
n.sym = x
else:
for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, symMap)

View file

@ -359,6 +359,10 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
var def: PNode
if a.sons[length-1].kind != nkEmpty:
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.isMetaType:
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):
pushProcCon(c, s)
addResult(c, s.typ.sons[0], n.info, skProc)
addResultNode(c, n)
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
n.sons[bodyPos] = transformBody(c.module, semBody, s)
addResultNode(c, n)
popProcCon(c)
elif efOperand notin flags:
localError(n.info, errGenericLambdaNotAllowed)
@ -860,9 +864,9 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode =
addParams(c, n.typ.n, skProc)
pushProcCon(c, s)
addResult(c, n.typ.sons[0], n.info, skProc)
addResultNode(c, n)
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
n.sons[bodyPos] = transformBody(c.module, semBody, n.sons[namePos].sym)
addResultNode(c, n)
popProcCon(c)
popOwner()
closeScope(c)

View file

@ -781,9 +781,10 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
result.rawAddSon(paramType)
for i in 0 .. paramType.sonsLen - 2:
let dummyType = if paramType.sons[i].kind == tyStatic: tyUnknown
else: tyAnything
result.rawAddSon newTypeS(dummyType, c)
if paramType.sons[i].kind == tyStatic:
result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnkown'
else:
result.rawAddSon newTypeS(tyAnything, c)
if paramType.lastSon.kind == tyUserTypeClass:
result.kind = tyUserTypeClassInst
@ -911,6 +912,8 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
if not hasType and not hasDefault:
if isType: localError(a.info, "':' expected")
let tdef = if kind in {skTemplate, skMacro}: tyExpr else: tyAnything
if tdef == tyAnything:
message(a.info, warnTypelessParam, renderTree(n))
typ = newTypeS(tdef, c)
if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue

View file

@ -1056,7 +1056,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
of tyFromExpr:
# 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)
case reevaluated.typ.kind
of tyTypeDesc:

View file

@ -321,6 +321,7 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
result = transformSons(c, n)
if gCmd == cmdCompileToCpp or sfCompileToCpp in c.module.flags: return
var n = result.PNode
case n.sons[0].kind
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:

View file

@ -28,8 +28,9 @@ proc hashTree(n: PNode): THash =
of nkFloatLit..nkFloat64Lit:
if (n.floatVal >= - 1000000.0) and (n.floatVal <= 1000000.0):
result = result !& toInt(n.floatVal)
of nkStrLit..nkTripleStrLit:
result = result !& hash(n.strVal)
of nkStrLit..nkTripleStrLit:
if not n.strVal.isNil:
result = result !& hash(n.strVal)
else:
for i in countup(0, sonsLen(n) - 1):
result = result !& hashTree(n.sons[i])

View file

@ -1029,16 +1029,18 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind,
flags: TTypeAllowedFlags = {}): PType =
if n != nil:
if n != nil:
result = typeAllowedAux(marker, n.typ, kind, flags)
#if not result: debug(n.typ)
if result == nil:
case n.kind
of nkNone..nkNilLit:
of nkNone..nkNilLit:
discard
else:
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
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)
if result != nil: break
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}
for i in countup(0, sonsLen(t) - 1):
result = typeAllowedAux(marker, t.sons[i], kind, flags)

View file

@ -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
# arity here too:
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)
var c = globalCtx

View file

@ -604,7 +604,8 @@ proc genNarrowU(c: PCtx; n: PNode; dest: TDest) =
let t = skipTypes(n.typ, abstractVar-{tyTypeDesc})
# uint is uint64 in the VM, we we only need to mask the result for
# 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))
proc genBinaryABCnarrow(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =

View file

@ -5,7 +5,8 @@
# You may set environment variables with
# @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
@ -21,6 +22,7 @@ mips.linux.gcc.linkerexe = "mips-openwrt-linux-gcc"
@end
path="$lib/core"
path="$lib/pure"
path="$lib/pure/collections"
path="$lib/pure/concurrency"
@ -110,6 +112,20 @@ hint[LineTooLong]=off
gcc.cpp.options.always = "-w -fpermissive"
@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.size = "-Os"
gcc.options.debug = "-g3 -O0"

View file

@ -66,7 +66,6 @@ Advanced options:
--threadanalysis:on|off turn thread analysis on|off
--tlsEmulation:on|off turn thread local storage emulation 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
--patterns:on|off turn pattern matching on|off
--skipCfg do not read the general configuration file

View file

@ -14,7 +14,6 @@ Options:
-p, --path:PATH add path to search paths
-d, --define:SYMBOL define a conditional symbol
-u, --undef:SYMBOL undefine a conditional symbol
--symbol:SYMBOL declare a conditional symbol
-f, --forceBuild force rebuilding of all modules
--stackTrace:on|off turn stack tracing on|off
--lineTrace:on|off turn line tracing on|off

View file

@ -12,10 +12,8 @@ Binary operators have 11 different levels of precedence.
Associativity
-------------
Binary operators whose first character is ``^`` or its last character
is ``>`` are right-associative, all other binary operators are left-associative.
Exception: The single "greater than" ``>`` operator is left-associative too.
Binary operators whose first character is ``^`` are right-associative, all
other binary operators are left-associative.
Operators ending in ``>`` but longer than a single character are
called `arrow like`:idx:.

View file

@ -190,6 +190,6 @@ Real world example
The installers for the Nim compiler itself are generated by niminst. Have a
look at its configuration file:
.. include:: compiler/nim.ini
.. include:: compiler/installer.ini
:literal:

View file

@ -97,13 +97,13 @@ const
compileNimInst = "-d:useLibzipSrc tools/niminst/niminst"
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()])
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()])
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])
proc buildTool(toolname, args: string) =
@ -121,20 +121,20 @@ proc nsis(args: string) =
" nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)])
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])
exec("sh ./install.sh $#" % args)
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])
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])
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])
# -------------- boot ---------------------------------------------------------

View file

@ -1,7 +1,7 @@
#
#
# Nim's Runtime Library
# (c) Copyright 2012 Andreas Rumpf
# (c) Copyright 2015 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@ -13,6 +13,8 @@
## is used. This suffices because Windows' console already provides the
## wanted functionality.
{.deadCodeElim: on.}
when defined(Windows):
proc readLineFromStdin*(prompt: string): TaintedString {.
tags: [ReadIOEffect, WriteIOEffect].} =
@ -31,9 +33,27 @@ when defined(Windows):
stdout.write(prompt)
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:
import readline, history
import readline, history, termios, unsigned
proc readLineFromStdin*(prompt: string): TaintedString {.
tags: [ReadIOEffect, WriteIOEffect].} =
var buffer = readline.readLine(prompt)
@ -55,8 +75,24 @@ else:
result = true
# initialization:
# disable auto-complete:
# disable auto-complete:
proc doNothing(a, b: cint): cint {.cdecl, procvar.} = discard
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)

View file

@ -379,7 +379,7 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
# define GC_GUARD
#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:
"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];
@ -390,3 +390,12 @@ typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(
#else
# define NIM_EXTERNC
#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
View 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>".}

View file

@ -220,3 +220,62 @@ proc product*[T](x: openArray[seq[T]]): seq[seq[T]] =
result.add(res)
index = 0
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

View file

@ -1064,6 +1064,17 @@ proc accept*(socket: TAsyncFD,
# -- 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,
name: expr): stmt {.immediate.} =
var nameIterVar = iteratorNameSym
@ -1211,26 +1222,53 @@ proc processBody(node, retFutureSym: PNimrodNode,
of nnkTryStmt:
# try: await x; except: ...
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,
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
while i < n[0].len:
var processed = processBody(n[0][i], retFutureSym, subTypeIsVoid, n)
if processed.kind != n[0][i].kind or processed.len != n[0][i].len:
var skipped = n.skipStmtList()
while i < skipped.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[2][1], nnkElse)
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
result = true
else:
res.add n[0][i]
res.add skipped[i]
i.inc
var i = 0
if not processForTry(node, i, result):
var temp = node
temp[0] = result
result = temp
# If the tryStmt hasn't been transformed we can just put the body
# back into it.
wrapInTry(node, result)
return
else: discard
@ -1329,8 +1367,8 @@ macro async*(prc: stmt): stmt {.immediate.} =
result[6] = outerProcBody
#echo(treeRepr(result))
#if prc[0].getName == "catch":
# echo(toStrLit(result))
if prc[0].getName == "test3":
echo(toStrLit(result))
proc recvLine*(socket: TAsyncFD): Future[string] {.async.} =
## Reads a line of data from ``socket``. Returned future will complete once

View file

@ -30,9 +30,28 @@
##
## 1.3000000000000000e+00
## 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
hashes, strutils, lexbase, streams, unicode
hashes, strutils, lexbase, streams, unicode, macros
type
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)
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 =
## Check two nodes for equality
if a.isNil:
@ -864,7 +906,7 @@ proc pretty*(node: JsonNode, indent = 2): string =
proc `$`*(node: JsonNode): string =
## Converts `node` to its JSON Representation on one line.
result = ""
toPretty(result, node, 1, false)
toPretty(result, node, 0, false)
iterator items*(node: JsonNode): JsonNode =
## Iterator for the items of `node`. `node` has to be a JArray.
@ -1101,6 +1143,37 @@ when isMainModule:
except:
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 """
while true:
var json = stdin.readLine()

View file

@ -186,7 +186,7 @@ proc newRollingFileLogger*(filename = defaultFilename(),
## a new log file will be started and the old will be renamed.
new(result)
result.levelThreshold = levelThreshold
result.fmtStr = defaultFmtStr
result.fmtStr = fmtStr
result.maxLines = maxLines
result.f = open(filename, mode)
result.curLine = 0

View file

@ -1074,8 +1074,12 @@ when defined(windows):
# because we support Windows GUI applications, things get really
# messy here...
when useWinUnicode:
proc strEnd(cstr: WideCString, c = 0'i32): WideCString {.
importc: "wcschr", header: "<string.h>".}
when defined(cpp):
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:
proc strEnd(cstr: cstring, c = 0'i32): cstring {.
importc: "strchr", header: "<string.h>".}

View file

@ -112,7 +112,7 @@ proc `[]`*(t: StringTableRef, key: string): string {.rtl, extern: "nstGet".} =
proc mget*(t: StringTableRef, key: string): var string {.
rtl, extern: "nstTake".} =
## 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)
if index >= 0: result = t.data[index].val
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 = ""
if result.len == 0:
if useKey in flags: result = '$' & key
elif not (useEmpty in flags): raiseFormatException(key)
elif useEmpty notin flags: raiseFormatException(key)
proc newStringTable*(mode: StringTableMode): StringTableRef {.
rtl, extern: "nst$1".} =

View file

@ -45,6 +45,21 @@ when defined(windows):
var
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) =
## sets the terminal's cursor to the (x,y) position. (0,0) is the
## 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"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:
system.addQuitProc(resetAttributes)
write(stdout, "never mind")

View file

@ -39,6 +39,7 @@ when declared(stdout):
when not defined(ECMAScript):
import terminal
system.addQuitProc(resetAttributes)
type
TestStatus* = enum OK, FAILED
@ -234,5 +235,3 @@ if envOutLvl.len > 0:
if $opt == envOutLvl:
outputLevel = opt
break
system.addQuitProc(resetAttributes)

View file

@ -343,10 +343,10 @@ type
##
## Each exception has to inherit from `Exception`. See the full `exception
## hierarchy`_.
parent: ref Exception ## parent exception (can be used as a stack)
name: cstring ## The exception's name is its Nim identifier.
## This field is filled automatically in the
## ``raise`` statement.
parent*: ref Exception ## parent exception (can be used as a stack)
name: cstring ## The exception's name is its Nim identifier.
## This field is filled automatically in the
## ``raise`` statement.
msg* {.exportc: "message".}: string ## the exception's message. Not
## providing an exception message
## is bad style.
@ -3161,7 +3161,7 @@ when hostOS != "standalone":
x[j+i] = item[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
## without any semantic error.
## This can be used to check whether a type supports some operation:

View file

@ -27,7 +27,7 @@ proc genericAssignAux(dest, src: pointer, n: ptr TNimNode,
var m = selectBranch(src, n)
# reset if different branches are in use; note different branches also
# imply that's not self-assignment (``x = x``)!
if m != dd and dd != nil:
if m != dd and dd != nil:
genericResetAux(dest, dd)
copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset),
n.typ.size)
@ -205,9 +205,13 @@ proc genericReset(dest: pointer, mt: PNimType) =
case mt.kind
of tyString, tyRef, tySequence:
unsureAsgnRef(cast[PPointer](dest), nil)
of tyObject, tyTuple:
# we don't need to reset m_type field for tyObject
of tyTuple:
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:
for i in 0..(mt.size div mt.base.size)-1:
genericReset(cast[pointer](d +% i*% mt.base.size), mt.base)

View file

@ -84,16 +84,18 @@ elif defined(windows) or defined(dos):
type
THINSTANCE {.importc: "HINSTANCE".} = object
x: pointer
proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
importcpp: "(void*)GetProcAddress(@)", header: "<windows.h>", stdcall.}
else:
type
THINSTANCE {.importc: "HINSTANCE".} = pointer
proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
importc: "GetProcAddress", header: "<windows.h>", stdcall.}
proc freeLibrary(lib: THINSTANCE) {.
importc: "FreeLibrary", header: "<windows.h>", stdcall.}
proc winLoadLibrary(path: cstring): THINSTANCE {.
importc: "LoadLibraryA", header: "<windows.h>", stdcall.}
proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
importc: "GetProcAddress", header: "<windows.h>", stdcall.}
proc nimUnloadLibrary(lib: TLibHandle) =
freeLibrary(cast[THINSTANCE](lib))

View file

@ -183,11 +183,17 @@ proc rawEchoNL() {.inline, compilerproc.} = write(stdout, "\n")
when (defined(windows) and not defined(useWinAnsi)) or defined(nimdoc):
include "system/widestrs"
when defined(windows) and not defined(useWinAnsi):
proc wfopen(filename, mode: WideCString): pointer {.
importc: "_wfopen", nodecl.}
proc wfreopen(filename, mode: WideCString, stream: File): File {.
importc: "_wfreopen", nodecl.}
when defined(windows) and not defined(useWinAnsi):
when defined(cpp):
proc wfopen(filename, mode: WideCString): pointer {.
importcpp: "_wfopen((const wchar_t*)#, (const wchar_t*)#)", 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 =
var f = newWideCString(filename)

View file

@ -66,8 +66,24 @@ Copyright (c) 2006-2014 Andreas Rumpf.
All rights reserved.
# Build Status
| |Linux|Windows|Mac|
|---|---|---|---|
| x86 | ![](http://178.62.143.63:8010/buildstatusimage?builder=linux-x32-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=windows-x32-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=mac-x32-builder)
| x86_64 | ![](http://178.62.143.63:8010/buildstatusimage?builder=linux-x64-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=windows-x64-builder) | ![](http://178.62.143.63:8010/buildstatusimage?builder=mac-x64-builder)
| arm | ![](http://178.62.143.63:8010/buildstatusimage?builder=linux-arm5-builder) |
[**Build Waterfall**][waterfall]
| | Linux | Windows | Mac |
| ------ | ----- | ------- | --- |
| 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

View file

@ -3,7 +3,7 @@ discard """
WARNING: false first assertion from bar
ERROR: false second assertion from bar
-1
tfailedassert.nim:27 false assertion from foo
tests/assert/tfailedassert.nim:27 false assertion from foo
'''
"""

View file

@ -19,7 +19,6 @@ proc processClient(fd: int) {.async.} =
var foo = line[0]
if foo == 'g':
raise newException(EBase, "foobar")
proc serve() {.async.} =

View file

@ -49,3 +49,44 @@ proc catch() {.async.} =
assert false
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

View file

@ -1,6 +1,6 @@
discard """
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

View file

@ -1,5 +1,5 @@
discard """
errormsg: 'type mismatch: got (mc.typ)'
errormsg: "type mismatch: got (mc.typ)"
line: 12
"""

View 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)
)

View file

@ -0,0 +1,5 @@
discard """
cmd: "nim cpp $target"
"""
import rawsockets

5
tests/cpp/ttypeinfo.nim Normal file
View file

@ -0,0 +1,5 @@
discard """
cmd: "nim cpp $target"
"""
import typeinfo

View file

@ -1,5 +1,4 @@
discard """
line: 2166
file: "system.nim"
errormsg: "can raise an unlisted exception: ref IOError"
"""

View file

@ -38,12 +38,14 @@ proc newPlus(a, b: ref TExpr): ref TPlusExpr =
result.b = b
result.op2 = $getOccupiedMem()
const Limit = when compileOption("gc", "markAndSweep"): 5*1024*1024 else: 500_000
for i in 0..100_000:
var s: array[0..11, ref TExpr]
for j in 0..high(s):
s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4))
if eval(s[j]) != j+6:
quit "error: wrong result"
if getOccupiedMem() > 500_000: quit("still a leak!")
if getOccupiedMem() > Limit: quit("still a leak!")
echo "no leak: ", getOccupiedMem()

View file

@ -1,6 +1,5 @@
discard """
output: '''TMatrix[3, 3, system.int]
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])
echoMatrix m
echoMat2 m
#echoMat2 m

View file

@ -1,9 +1,10 @@
discard """
output: "2"
output: '''2
88'''
"""
type
TValue* {.pure, final.} = object of TObject
TValue* {.pure, final.} = object of RootObj
a: int
PValue = ref TValue
PPValue = ptr PValue
@ -16,3 +17,19 @@ var sp: PPValue = addr x
sp.a = 2
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
View 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

View file

@ -74,7 +74,7 @@ type
contacts*: PContact
stamp*: TTimestamp
handler*: PCollisionHandler
swappedColl*: bool32
swappedColl*: Bool32
state*: TArbiterState
PCollisionHandler* = ptr TCollisionHandler
TCollisionHandler*{.pf.} = object
@ -108,7 +108,7 @@ type
#/ Collision begin event function callback type.
#/ Returning false from a begin callback causes the collision to be ignored until
#/ 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.}
#/ Collision pre-solve event function callback type.
#/ 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
TSpatialIndex{.pf.} = object
klass: PSpatialIndexClass
bbfunc: TSpatialIndexBBFunc
bbfun: TSpatialIndexBBFunc
staticIndex: PSpatialIndex
dynamicIndex: PSpatialIndex
TSpatialIndexDestroyImpl* = proc (index: PSpatialIndex){.cdecl.}
TSpatialIndexCountImpl* = proc (index: PSpatialIndex): cint{.cdecl.}
TSpatialIndexEachImpl* = proc (index: PSpatialIndex;
func: TSpatialIndexIteratorFunc; data: pointer){.
fun: TSpatialIndexIteratorFunc; data: pointer){.
cdecl.}
TSpatialIndexContainsImpl* = proc (index: PSpatialIndex; obj: pointer;
hashid: THashValue): Bool32 {.cdecl.}
@ -161,15 +161,15 @@ type
TSpatialIndexReindexObjectImpl* = proc (index: PSpatialIndex;
obj: pointer; hashid: THashValue){.cdecl.}
TSpatialIndexReindexQueryImpl* = proc (index: PSpatialIndex;
func: TSpatialIndexQueryFunc; data: pointer){.cdecl.}
fun: TSpatialIndexQueryFunc; data: pointer){.cdecl.}
TSpatialIndexPointQueryImpl* = proc (index: PSpatialIndex; point: TVector;
func: TSpatialIndexQueryFunc;
fun: TSpatialIndexQueryFunc;
data: pointer){.cdecl.}
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.}
TSpatialIndexQueryImpl* = proc (index: PSpatialIndex; obj: pointer;
bb: TBB; func: TSpatialIndexQueryFunc;
bb: TBB; fun: TSpatialIndexQueryFunc;
data: pointer){.cdecl.}
PSpatialIndexClass* = ptr TSpatialIndexClass
TSpatialIndexClass*{.pf.} = object
@ -286,7 +286,7 @@ type
CP_CIRCLE_SHAPE, CP_SEGMENT_SHAPE, CP_POLY_SHAPE, CP_NUM_SHAPES
TShapeCacheDataImpl* = proc (shape: PShape; p: TVector; rot: TVector): TBB{.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;
info: PSegmentQueryInfo){.cdecl.}
PShapeClass* = ptr TShapeClass
@ -427,7 +427,7 @@ defGetter(PSpace, CpFloat, currDt, CurrentTimeStep)
#/ 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
#/ Set a default collision handler for this space.
@ -478,24 +478,24 @@ proc removeBody*(space: PSpace; body: PBody){.
proc RemoveConstraint*(space: PSpace; constraint: PConstraint){.
cdecl, importc: "cpSpaceRemoveConstraint", dynlib: Lib.}
#/ 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.}
#/ 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.}
#/ 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.}
#/ 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
proc addPostStepCallback*(space: PSpace; func: TPostStepFunc;
proc addPostStepCallback*(space: PSpace; fun: TPostStepFunc;
obj: pointer; data: pointer){.
cdecl, importc: "cpSpaceAddPostStepCallback", dynlib: Lib.}
#/ Query the space at a point and call @c func for each shape found.
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.}
#/ 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.
proc segmentQuery*(space: PSpace; start: TVector; to: TVector;
layers: TLayers; group: TGroup;
func: TSpaceSegmentQueryFunc; data: pointer){.
fun: TSpaceSegmentQueryFunc; data: pointer){.
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.
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.
#/ Only the shape's bounding boxes are checked for overlap, not their full shape.
proc BBQuery*(space: PSpace; bb: TBB; layers: TLayers; group: TGroup;
func: TSpaceBBQueryFunc; data: pointer){.
fun: TSpaceBBQueryFunc; data: pointer){.
cdecl, importc: "cpSpaceBBQuery", dynlib: Lib.}
#/ 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.}
#/ Call cpBodyActivate() for any shape that is overlaps the given shape.
proc activateShapesTouchingShape*(space: PSpace; shape: PShape){.
cdecl, importc: "cpSpaceActivateShapesTouchingShape", dynlib: Lib.}
#/ 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.}
#/ Call @c func for each shape in the space.
proc eachShape*(space: PSpace; func: TSpaceShapeIteratorFunc;
proc eachShape*(space: PSpace; fun: TSpaceShapeIteratorFunc;
data: pointer){.
cdecl, importc: "cpSpaceEachShape", dynlib: Lib.}
#/ Call @c func for each shape in the space.
proc eachConstraint*(space: PSpace; func: TSpaceConstraintIteratorFunc;
proc eachConstraint*(space: PSpace; fun: TSpaceConstraintIteratorFunc;
data: pointer){.
cdecl, importc: "cpSpaceEachConstraint", dynlib: Lib.}
#/ 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.} =
result = (v1 - v2).lenSq #vlengthsq(vsub(v1, v2))
#/ 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
@ -706,13 +706,13 @@ proc Sleep*(body: PBody){.importc: "cpBodySleep", dynlib: Lib.}
proc SleepWithGroup*(body: PBody; group: PBody){.
importc: "cpBodySleepWithGroup", dynlib: Lib.}
#/ Returns true if the body is sleeping.
proc isSleeping*(body: PBody): Bool {.inline.} =
proc isSleeping*(body: PBody): bool {.inline.} =
return body.node.root != nil
#/ Returns true if the body is static.
proc isStatic*(body: PBody): bool {.inline.} =
return body.node.idleTime == CpInfinity
#/ 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
# #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)
#/ 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){.
cdecl, importc: "cpBodyEachShape", dynlib: Lib.}
#/ 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) {.
cdecl, importc: "cpBodyEachConstraint", dynlib: Lib.}
#/ 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){.
cdecl, importc: "cpBodyEachArbiter", dynlib: Lib.}
#/ Allocate a spatial hash.
@ -824,10 +824,10 @@ proc SpaceHashAlloc*(): PSpaceHash{.
cdecl, importc: "cpSpaceHashAlloc", dynlib: Lib.}
#/ Initialize a spatial hash.
proc SpaceHashInit*(hash: PSpaceHash; celldim: CpFloat; numcells: cint;
bbfunc: TSpatialIndexBBFunc; staticIndex: PSpatialIndex): PSpatialIndex{.
bbfun: TSpatialIndexBBFunc; staticIndex: PSpatialIndex): PSpatialIndex{.
cdecl, importc: "cpSpaceHashInit", dynlib: Lib.}
#/ 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{.
cdecl, importc: "cpSpaceHashNew", dynlib: Lib.}
#/ 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.
proc BBTreeAlloc*(): PBBTree{.cdecl, importc: "cpBBTreeAlloc", dynlib: Lib.}
#/ Initialize a bounding box tree.
proc BBTreeInit*(tree: PBBTree; bbfunc: TSpatialIndexBBFunc;
proc BBTreeInit*(tree: PBBTree; bbfun: TSpatialIndexBBFunc;
staticIndex: ptr TSpatialIndex): ptr TSpatialIndex{.cdecl,
importc: "cpBBTreeInit", dynlib: Lib.}
#/ 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.}
#/ Perform a static top down optimization of the tree.
proc BBTreeOptimize*(index: PSpatialIndex){.
cdecl, importc: "cpBBTreeOptimize", dynlib: Lib.}
#/ 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.}
#MARK: Single Axis Sweep
@ -864,12 +864,12 @@ proc Sweep1DAlloc*(): ptr TSweep1D{.cdecl, importc: "cpSweep1DAlloc",
dynlib: Lib.}
#/ 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,
importc: "cpSweep1DInit", dynlib: Lib.}
#/ 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.}
@ -1359,7 +1359,7 @@ defCProp(SlideJoint, TVector, anchr2, Anchr2)
defCProp(SlideJoint, CpFloat, min, Min)
defCProp(SlideJoint, CpFloat, max, Max)
proc pivotJointGetClass*(): PConstraintClass {.
proc PivotJointGetClass*(): PConstraintClass {.
cdecl, importc: "cpPivotJointGetClass", dynlib: Lib.}
#/ Allocate a pivot joint

View file

@ -20,7 +20,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
const Lib = "libenet.so.1(|.0.3)"
{.deadCodeElim: ON.}
{.deadCodeElim: on.}
const
ENET_VERSION_MAJOR* = 1
ENET_VERSION_MINOR* = 3

View file

@ -9,15 +9,6 @@ template defPacketImports*(): stmt {.immediate, dirty.} =
import macros, macro_dsl, estreams
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.} =
result = newNimNode(nnkStmtList)
let
@ -293,4 +284,4 @@ when isMainModule:
for itm in test.x:
echo(itm)
test.pack(s)
echo(repr(s.data))
echo(repr(s.data))

View file

@ -221,10 +221,10 @@ type
TTransform* {.pf.} = object
matrix*: array[0..8, cfloat]
TColor* {.pf.} = object
r*: Uint8
g*: Uint8
b*: Uint8
a*: Uint8
r*: uint8
g*: uint8
b*: uint8
a*: uint8
PFloatRect* = ptr TFloatRect
TFloatRect*{.pf.} = object
left*: cfloat
@ -306,7 +306,7 @@ proc close*(window: PRenderWindow) {.
proc isOpen*(window: PRenderWindow): bool {.
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]) {.
# cdecl, importc: "sfRenderWindow_setIcon", dynlib: LibG.}
@ -395,7 +395,7 @@ proc capture*(window: PRenderWindow): PImage {.
cdecl, importc: "sfRenderWindow_capture", dynlib: LibG.}
#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.}
#Destroy an existing render texture
proc destroy*(renderTexture: PRenderTexture){.
@ -522,9 +522,9 @@ proc copy*(font: PFont): PFont {.
cdecl, importc: "sfFont_copy", dynlib: LibG.}
proc destroy*(font: PFont) {.
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.}
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.}
proc getLineSpacing*(font: PFont, characterSize: cint): cint {.
cdecl, importc: "sfFont_getLineSpacing", dynlib: LibG.}
@ -882,7 +882,7 @@ proc getInverseTransform*(text: PText): TTransform {.
cdecl, importc: "sfText_getInverseTransform", dynlib: LibG.}
proc setString*(text: PText, string: cstring) {.
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.}
proc setFont*(text: PText, font: PFont) {.
cdecl, importc: "sfText_setFont", dynlib: LibG.}
@ -894,13 +894,13 @@ proc setColor*(text: PText, color: TColor) {.
cdecl, importc: "sfText_setColor", dynlib: LibG.}
proc getString*(text: PText): cstring {.
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.}
proc getFont*(text: PText): PFont {.
cdecl, importc: "sfText_getFont", dynlib: LibG.}
proc getCharacterSize*(text: PText): cint {.
cdecl, importc: "sfText_getCharacterSize", dynlib: LibG.}
proc getStyle*(text: PText): Uint32 {.
proc getStyle*(text: PText): uint32 {.
cdecl, importc: "sfText_getStyle", dynlib: LibG.}
proc getColor*(text: PText): TColor {.
cdecl, importc: "sfText_getColor", dynlib: LibG.}

View file

@ -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
#/
#/ 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 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
#/
#/ 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.
#/
#/ \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
#/
#//////////////////////////////////////////////////////////
proc sfSoundBuffer_getSamples*(soundBuffer: PSoundBuffer): ptr Int16{.
proc sfSoundBuffer_getSamples*(soundBuffer: PSoundBuffer): ptr int16{.
cdecl, importc: "sfSoundBuffer_getSamples", dynlib: Lib.}
#//////////////////////////////////////////////////////////
#/ \brief Get the number of samples stored in a sound buffer

View file

@ -105,6 +105,7 @@ proc tryLogin*(b: PButton) =
passwd = u_passwd.getText())
dirServer.send HLogin, login
proc tryTransition*(b: PButton) =
discard
#zone.writePkt HZoneJoinReq, myCreds
proc tryConnect*(b: PButton) =
if not dirServer.connected:

View file

@ -143,7 +143,7 @@ proc mouseToSpace*(): TVector =
proc explode*(b: PLiveBullet)
## TCollisionBeginFunc
proc collisionBulletPlayer(arb: PArbiter; space: PSpace;
data: pointer): Bool{.cdecl.} =
data: pointer): bool{.cdecl.} =
var
bullet = cast[PLiveBullet](arb.a.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.} =
body.w -= (body.w * 0.98 * dt)
body.updateVelocity(gravity, damping, dt)
body.UpdateVelocity(gravity, damping, dt)
proc initLevel() =
loadAllAssets()
@ -227,7 +227,7 @@ proc explode*(b: PLiveBullet) =
playSound(b.record.explosion.sound, b.body.getPos())
proc bulletUpdate(body: PBody, gravity: TVector, damping, dt: CpFloat){.cdecl.} =
body.updateVelocity(gravity, damping, dt)
body.UpdateVelocity(gravity, damping, dt)
template getPhysical() {.immediate.} =
result.body = space.addBody(newBody(
@ -237,7 +237,7 @@ template getPhysical() {.immediate.} =
chipmunk.newCircleShape(
result.body,
record.physics.radius,
vectorZero))
VectorZero))
proc newBullet*(record: PBulletRecord; fromPlayer: PPlayer): PLiveBullet =
new(result, free)
@ -480,7 +480,7 @@ when defined(DebugKeys):
echo(repr(activeVehicle.record))
elif keyPressed(KeyH):
activeVehicle.body.setPos(vector(100.0, 100.0))
activeVehicle.body.setVel(vectorZero)
activeVehicle.body.setVel(VectorZero)
elif keyPressed(KeyComma):
activeVehicle.body.setPos mouseToSpace())
ingameClient.registerHandler(KeyY, down, proc() =
@ -507,7 +507,7 @@ when defined(DebugKeys):
return
let body = shape.getBody()
mouseJoint = space.addConstraint(
newPivotJoint(mouseBody, body, vectorZero, body.world2local(point)))
newPivotJoint(mouseBody, body, VectorZero, body.world2local(point)))
mouseJoint.maxForce = 50000.0
mouseJoint.errorBias = pow(1.0 - 0.15, 60))
@ -539,15 +539,15 @@ proc mainUpdate(dt: float) =
elif not activeVehicle.isNil:
if keyPressed(KeyUp):
activeVehicle.accel(dt)
elif keyPressed(keyDown):
elif keyPressed(KeyDown):
activeVehicle.reverse(dt)
if keyPressed(KeyRight):
activeVehicle.turn_right(dt)
elif keyPressed(KeyLeft):
activeVehicle.turn_left(dt)
if keyPressed(keyz):
if keyPressed(Keyz):
activeVehicle.strafe_left(dt)
elif keyPressed(keyx):
elif keyPressed(Keyx):
activeVehicle.strafe_right(dt)
if keyPressed(KeyLControl):
localPlayer.useItem 0
@ -557,7 +557,7 @@ proc mainUpdate(dt: float) =
localPlayer.useItem 2
if keyPressed(KeyW):
localPlayer.useItem 3
if Keypressed(keyA):
if keyPressed(KeyA):
localPlayer.useItem 4
if keyPressed(sfml.KeyS):
localPlayer.useItem 5
@ -666,7 +666,7 @@ when isMainModule:
import parseopt
localPlayer = newPlayer()
LobbyInit()
lobbyInit()
videoMode = getClientSettings().resolution
window = newRenderWindow(videoMode, "sup", sfDefaultStyle)
@ -683,7 +683,7 @@ when isMainModule:
mouseSprite.setOutlineThickness 1.4
mouseSprite.setOrigin vec2f(14, 14)
LobbyReady()
lobbyReady()
playBtn = specGui.newButton(
"Unspec - F12", position = vec2f(680.0, 8.0), onClick = proc(b: PButton) =
toggleSpec())

View file

@ -26,7 +26,7 @@ proc newObject*(record: PObjectRecord): PGameObject =
when false:
result.sprite = record.anim.spriteSheet.sprite.copy()
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))
proc newObject*(name: string): PGameObject =
result = newObject(fetchObj(name))

View file

@ -38,7 +38,7 @@ type
PGLclampf* = ptr TGLclampf
PGLdouble* = ptr TGLdouble
PGLclampd* = ptr TGLclampd
PGLvoid* = Pointer
PGLvoid* = pointer
PPGLvoid* = ptr PGLvoid
TGLenum* = cint
TGLboolean* = bool
@ -983,7 +983,7 @@ const # Version
GL_TEXTURE_COMPONENTS* = GL_TEXTURE_INTERNAL_FORMAT
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".}
proc glAreTexturesResident*(n: TGLsizei, textures: PGLuint,
residences: PGLboolean): TGLboolean{.
@ -998,7 +998,7 @@ proc glBitmap*(width, height: TGLsizei, xorig, yorig: TGLfloat,
proc glBlendFunc*(sfactor, dfactor: TGLenum){.dynlib: dllname,
importc: "glBlendFunc".}
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".}
proc glClear*(mask: TGLbitfield){.dynlib: dllname, importc: "glClear".}
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,
importc: "glColorMaterial".}
proc glColorPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei,
pointer: Pointer){.dynlib: dllname,
p: pointer){.dynlib: dllname,
importc: "glColorPointer".}
proc glCopyPixels*(x, y: TGLint, width, height: TGLsizei, atype: TGLenum){.
dynlib: dllname, importc: "glCopyPixels".}
@ -1084,7 +1084,7 @@ proc glDeleteLists*(list: TGLuint, range: TGLsizei){.dynlib: dllname,
importc: "glDeleteLists".}
proc glDeleteTextures*(n: TGLsizei, textures: PGLuint){.dynlib: dllname,
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 glDepthRange*(zNear, zFar: TGLclampd){.dynlib: dllname,
importc: "glDepthRange".}
@ -1095,12 +1095,12 @@ proc glDrawArrays*(mode: TGLenum, first: TGLint, count: TGLsizei){.
dynlib: dllname, importc: "glDrawArrays".}
proc glDrawBuffer*(mode: TGLenum){.dynlib: dllname, importc: "glDrawBuffer".}
proc glDrawElements*(mode: TGLenum, count: TGLsizei, atype: TGLenum,
indices: Pointer){.dynlib: dllname,
indices: pointer){.dynlib: dllname,
importc: "glDrawElements".}
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 glEdgeFlagPointer*(stride: TGLsizei, pointer: Pointer){.dynlib: dllname,
proc glEdgeFlagPointer*(stride: TGLsizei, p: pointer){.dynlib: dllname,
importc: "glEdgeFlagPointer".}
proc glEdgeFlagv*(flag: PGLboolean){.dynlib: dllname, importc: "glEdgeFlagv".}
proc glEnable*(cap: TGLenum){.dynlib: dllname, importc: "glEnable".}
@ -1171,7 +1171,7 @@ proc glGetPixelMapuiv*(map: TGLenum, values: PGLuint){.dynlib: dllname,
importc: "glGetPixelMapuiv".}
proc glGetPixelMapusv*(map: TGLenum, values: PGLushort){.dynlib: dllname,
importc: "glGetPixelMapusv".}
proc glGetPointerv*(pname: TGLenum, params: Pointer){.dynlib: dllname,
proc glGetPointerv*(pname: TGLenum, params: pointer){.dynlib: dllname,
importc: "glGetPointerv".}
proc glGetPolygonStipple*(mask: PGLubyte){.dynlib: dllname,
importc: "glGetPolygonStipple".}
@ -1188,10 +1188,10 @@ proc glGetTexGenfv*(coord, pname: TGLenum, params: PGLfloat){.dynlib: dllname,
proc glGetTexGeniv*(coord, pname: TGLenum, params: PGLint){.dynlib: dllname,
importc: "glGetTexGeniv".}
proc glGetTexImage*(target: TGLenum, level: TGLint, format: TGLenum,
atype: TGLenum, pixels: Pointer){.dynlib: dllname,
atype: TGLenum, pixels: pointer){.dynlib: dllname,
importc: "glGetTexImage".}
proc glGetTexLevelParameterfv*(target: TGLenum, level: TGLint, pname: TGLenum,
params: Pointer){.dynlib: dllname,
params: pointer){.dynlib: dllname,
importc: "glGetTexLevelParameterfv".}
proc glGetTexLevelParameteriv*(target: TGLenum, level: TGLint, pname: TGLenum,
params: PGLint){.dynlib: dllname,
@ -1202,7 +1202,7 @@ proc glGetTexParameteriv*(target, pname: TGLenum, params: PGLint){.
dynlib: dllname, importc: "glGetTexParameteriv".}
proc glHint*(target, mode: TGLenum){.dynlib: dllname, importc: "glHint".}
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".}
proc glIndexd*(c: TGLdouble){.dynlib: dllname, importc: "glIndexd".}
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 glIndexubv*(c: PGLubyte){.dynlib: dllname, importc: "glIndexubv".}
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".}
proc glIsEnabled*(cap: TGLenum): TGLboolean{.dynlib: dllname,
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 glNormal3s*(nx, ny, nz: TGLshort){.dynlib: dllname, importc: "glNormal3s".}
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".}
proc glOrtho*(left, right, bottom, top, zNear, zFar: TGLdouble){.
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 glReadBuffer*(mode: TGLenum){.dynlib: dllname, importc: "glReadBuffer".}
proc glReadPixels*(x, y: TGLint, width, height: TGLsizei,
format, atype: TGLenum, pixels: Pointer){.dynlib: dllname,
format, atype: TGLenum, pixels: pointer){.dynlib: dllname,
importc: "glReadPixels".}
proc glRectd*(x1, y1, x2, y2: TGLdouble){.dynlib: dllname, importc: "glRectd".}
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,
importc: "glSelectBuffer".}
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".}
proc glStencilMask*(mask: TGLuint){.dynlib: dllname, importc: "glStencilMask".}
proc glStencilOp*(fail, zfail, zpass: TGLenum){.dynlib: dllname,
@ -1424,7 +1424,7 @@ proc glTexCoord4s*(s, t, r, q: TGLshort){.dynlib: dllname,
importc: "glTexCoord4s".}
proc glTexCoord4sv*(v: PGLshort){.dynlib: dllname, importc: "glTexCoord4sv".}
proc glTexCoordPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei,
pointer: Pointer){.dynlib: dllname,
p: pointer){.dynlib: dllname,
importc: "glTexCoordPointer".}
proc glTexEnvf*(target: TGLenum, pname: TGLenum, param: TGLfloat){.
dynlib: dllname, importc: "glTexEnvf".}
@ -1448,10 +1448,10 @@ proc glTexGeniv*(coord: TGLenum, pname: TGLenum, params: PGLint){.
dynlib: dllname, importc: "glTexGeniv".}
proc glTexImage1D*(target: TGLenum, level, internalformat: TGLint,
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,
width, height: TGLsizei, border: TGLint,
format, atype: TGLenum, pixels: Pointer){.dynlib: dllname,
format, atype: TGLenum, pixels: pointer){.dynlib: dllname,
importc: "glTexImage2D".}
proc glTexParameterf*(target: TGLenum, pname: TGLenum, param: TGLfloat){.
dynlib: dllname, importc: "glTexParameterf".}
@ -1462,11 +1462,11 @@ proc glTexParameteri*(target: TGLenum, pname: TGLenum, param: TGLint){.
proc glTexParameteriv*(target: TGLenum, pname: TGLenum, params: PGLint){.
dynlib: dllname, importc: "glTexParameteriv".}
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".}
proc glTexSubImage2D*(target: TGLenum, level, xoffset, yoffset: TGLint,
width, height: TGLsizei, format, atype: TGLenum,
pixels: Pointer){.dynlib: dllname,
pixels: pointer){.dynlib: dllname,
importc: "glTexSubImage2D".}
proc glTranslated*(x, y, z: TGLdouble){.dynlib: dllname, importc: "glTranslated".}
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 glVertex4sv*(v: PGLshort){.dynlib: dllname, importc: "glVertex4sv".}
proc glVertexPointer*(size: TGLint, atype: TGLenum, stride: TGLsizei,
pointer: Pointer){.dynlib: dllname,
p: pointer){.dynlib: dllname,
importc: "glVertexPointer".}
proc glViewport*(x, y: TGLint, width, height: TGLsizei){.dynlib: dllname,
importc: "glViewport".}
@ -1505,28 +1505,28 @@ type
count: TGLsizei)
PFN_GLVERTEX_POINTER_EXTPROC* = proc (size: TGLint, atype: TGLenum,
stride, count: TGLsizei,
pointer: Pointer)
p: pointer)
PFN_GLNORMAL_POINTER_EXTPROC* = proc (atype: TGLenum, stride, count: TGLsizei,
pointer: Pointer)
p: pointer)
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,
pointer: Pointer)
p: pointer)
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,
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,
pi: Pointer) # WIN_swap_hint
pi: pointer) # WIN_swap_hint
PFN_GLADDSWAPHINT_RECT_WINPROC* = proc (x, y: TGLint, width, height: TGLsizei)
PFN_GLCOLOR_TABLE_EXTPROC* = proc (target, internalFormat: TGLenum,
width: TGLsizei, format, atype: TGLenum,
data: Pointer)
data: pointer)
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,
data: Pointer)
data: pointer)
PFN_GLGETCOLOR_TABLE_PARAMETER_IVEXTPROC* = proc (target, pname: TGLenum,
params: PGLint)
PFN_GLGETCOLOR_TABLE_PARAMETER_FVEXTPROC* = proc (target, pname: TGLenum,

View file

@ -4,14 +4,14 @@ template filterIt2*(seq, pred: expr, body: stmt): stmt {.immediate, dirty.} =
for it in items(seq):
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 = @[]
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:
x[i] = func(x[i])
x[i] = fun(x[i])
template unless*(condition: expr; body: stmt): stmt {.dirty.} =
if not(condition):
@ -38,4 +38,4 @@ when isMainModule:
var someSeq = @[9,8,7,6,5,4,3,2,1] ## numbers < 6 or even
filterIt2 someSeq, it < 6 or (it and 1) == 0:
echo(it)
echo "-----------"
echo "-----------"

View file

@ -122,9 +122,9 @@ var
nameToBulletID*: TTable[string, int]
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 newSound(filename: string; errors: var seq[string]): PSoundRecord
proc newSound*(filename: string; errors: var seq[string]): PSoundRecord
proc load*(s: PSoundRecord): bool {.discardable.}
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 importSoul(data: PJsonNode): TSoulRecord
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
proc getActiveState*(): TGameState =
@ -466,7 +466,7 @@ proc importPhys(data: PJsonNode): TPhysicsRecord =
phys.getField("radius", result.radius)
phys.getField("mass", result.mass)
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 =
result.thrust = 45.0
result.topSpeed = 100.0 #unused

View file

@ -9,8 +9,8 @@ template idpacket(pktName, id, s2c, c2s: expr): stmt {.immediate, dirty.} =
defPacket(`Sc pktName`, s2c)
defPacket(`Cs pktName`, c2s)
forwardPacketT(Uint8, int8)
forwardPacketT(Uint16, int16)
forwardPacketT(uint8, int8)
forwardPacketT(uint16, int16)
forwardPacketT(TPort, int16)
idPacket(Login, 'a',
@ -51,7 +51,7 @@ defPacket(ScTeamList, tuple[teams: seq[ScTeam]])
let HTeamChange* = 't'
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'])
type SpawnKind = enum

View file

@ -9,22 +9,22 @@ proc accel*(obj: PVehicle, dt: float) =
# sin(obj.angle) * obj.record.handling.thrust.float * dt)
obj.body.applyImpulse(
vectorForAngle(obj.body.getAngle()) * dt * obj.record.handling.thrust,
vectorZero)
VectorZero)
proc reverse*(obj: PVehicle, dt: float) =
#obj.velocity += vec2f(
# -cos(obj.angle) * obj.record.handling.reverse.float * dt,
# -sin(obj.angle) * obj.record.handling.reverse.float * dt)
obj.body.applyImpulse(
-vectorForAngle(obj.body.getAngle()) * dt * obj.record.handling.reverse,
vectorZero)
VectorZero)
proc strafe_left*(obj: PVehicle, dt: float) =
obj.body.applyImpulse(
vectorForAngle(obj.body.getAngle()).perp() * obj.record.handling.strafe * dt,
vectorZero)
VectorZero)
proc strafe_right*(obj: PVehicle, dt: float) =
obj.body.applyImpulse(
vectorForAngle(obj.body.getAngle()).rperp()* obj.record.handling.strafe * dt,
vectorZero)
VectorZero)
proc turn_right*(obj: PVehicle, dt: float) =
#obj.angle = (obj.angle + (obj.record.handling.rotation.float / 10.0 * dt)) mod TAU
obj.body.setTorque(obj.record.handling.rotation)

View file

@ -1,3 +1,7 @@
discard """
errormsg: "expression 'generate(builder)' has no type (or is ambiguous)"
"""
# bug #898
proc measureTime(e: auto) =

View file

@ -30,7 +30,7 @@ accept bar(vbar)
accept baz(vbar)
accept baz(vbaz)
reject baz(vnotbaz)
#reject baz(vnotbaz) # XXX this really shouldn't compile
reject bar(vfoo)
# https://github.com/Araq/Nim/issues/517

View 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

View file

@ -14,6 +14,7 @@ AST b
20Test
20
'''
disabled: true
"""
import macros

View file

@ -1,6 +1,7 @@
discard """
msg: "int\nstring\nTBar[int]"
output: "int\nstring\nTBar[int]\nint\nrange 0..2(int)\nstring"
disabled: true
"""
import typetraits

View file

@ -1,6 +1,7 @@
discard """
errormsg: "type mismatch: got (string) but expected 'ptr'"
line: 20
disabled: true
"""
import typetraits

View 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