Merge branch 'devel' into gcbugfix
This commit is contained in:
commit
373a79b28a
127 changed files with 1341 additions and 612 deletions
|
|
@ -459,7 +459,7 @@ type
|
|||
|
||||
tfNeedsInit, # type constains a "not nil" constraint somewhere or some
|
||||
# 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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, ~" ")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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("//", "")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -251,7 +251,6 @@ proc mainCommand* =
|
|||
commandCompileToC()
|
||||
of "cpp", "compiletocpp":
|
||||
gCmd = cmdCompileToCpp
|
||||
if cCompiler == ccGcc: setCC("gcc")
|
||||
defineSymbol("cpp")
|
||||
commandCompileToC()
|
||||
of "objc", "compiletooc":
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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: "/",
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) =
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
14
koch.nim
14
koch.nim
|
|
@ -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 ---------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
264
lib/posix/termios.nim
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
#
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2015 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
import posix
|
||||
|
||||
type
|
||||
Speed* = cuint
|
||||
Tcflag* = cuint
|
||||
|
||||
const
|
||||
NCCS* = 32
|
||||
|
||||
type
|
||||
Termios* = object {.importc: "struct termios", header: "<termios.h>", final, pure.}
|
||||
iflag*: Tcflag # input mode flags
|
||||
oflag*: Tcflag # output mode flags
|
||||
cflag*: Tcflag # control mode flags
|
||||
lflag*: Tcflag # local mode flags
|
||||
line*: cuchar # line discipline
|
||||
cc*: array[NCCS, cuchar] # control characters
|
||||
ispeed*: Speed # input speed
|
||||
ospeed*: Speed # output speed
|
||||
|
||||
|
||||
# cc characters
|
||||
|
||||
const
|
||||
VINTR* = 0
|
||||
VQUIT* = 1
|
||||
VERASE* = 2
|
||||
VKILL* = 3
|
||||
VEOF* = 4
|
||||
VTIME* = 5
|
||||
VMIN* = 6
|
||||
VSWTC* = 7
|
||||
VSTART* = 8
|
||||
VSTOP* = 9
|
||||
VSUSP* = 10
|
||||
VEOL* = 11
|
||||
VREPRINT* = 12
|
||||
VDISCARD* = 13
|
||||
VWERASE* = 14
|
||||
VLNEXT* = 15
|
||||
VEOL2* = 16
|
||||
|
||||
# iflag bits
|
||||
|
||||
const
|
||||
IGNBRK* = 1
|
||||
BRKINT* = 2
|
||||
IGNPAR* = 4
|
||||
PARMRK* = 10
|
||||
INPCK* = 20
|
||||
ISTRIP* = 40
|
||||
INLCR* = 100
|
||||
IGNCR* = 200
|
||||
ICRNL* = 400
|
||||
IUCLC* = 1000
|
||||
IXON* = 2000
|
||||
IXANY* = 4000
|
||||
IXOFF* = 10000
|
||||
IMAXBEL* = 20000
|
||||
IUTF8* = 40000
|
||||
|
||||
# oflag bits
|
||||
|
||||
const
|
||||
OPOST* = 1
|
||||
OLCUC* = 2
|
||||
ONLCR* = 4
|
||||
OCRNL* = 10
|
||||
ONOCR* = 20
|
||||
ONLRET* = 40
|
||||
OFILL* = 100
|
||||
OFDEL* = 200
|
||||
NLDLY* = 400
|
||||
NL0* = 0
|
||||
NL1* = 400
|
||||
CRDLY* = 3000
|
||||
CR0* = 0
|
||||
CR1* = 1000
|
||||
CR2* = 2000
|
||||
CR3* = 3000
|
||||
TABDLY* = 14000
|
||||
TAB0* = 0
|
||||
TAB1* = 4000
|
||||
TAB2* = 10000
|
||||
TAB3* = 14000
|
||||
BSDLY* = 20000
|
||||
BS0* = 0
|
||||
BS1* = 20000
|
||||
FFDLY* = 0o000000100000
|
||||
FF0* = 0
|
||||
FF1* = 0o000000100000
|
||||
VTDLY* = 40000
|
||||
VT0* = 0
|
||||
VT1* = 40000
|
||||
XTABS* = 14000
|
||||
|
||||
# cflag bit meaning
|
||||
|
||||
const
|
||||
CBAUD* = 10017
|
||||
B0* = 0
|
||||
B50* = 1
|
||||
B75* = 2
|
||||
B110* = 3
|
||||
B134* = 4
|
||||
B150* = 5
|
||||
B200* = 6
|
||||
B300* = 7
|
||||
B600* = 10
|
||||
B1200* = 11
|
||||
B1800* = 12
|
||||
B2400* = 13
|
||||
B4800* = 14
|
||||
B9600* = 15
|
||||
B19200* = 16
|
||||
B38400* = 17
|
||||
EXTA* = B19200
|
||||
EXTB* = B38400
|
||||
CSIZE* = 60
|
||||
CS5* = 0
|
||||
CS6* = 20
|
||||
CS7* = 40
|
||||
CS8* = 60
|
||||
CSTOPB* = 100
|
||||
CREAD* = 200
|
||||
PARENB* = 400
|
||||
PARODD* = 1000
|
||||
HUPCL* = 2000
|
||||
CLOCAL* = 4000
|
||||
CBAUDEX* = 10000
|
||||
B57600* = 10001
|
||||
B115200* = 10002
|
||||
B230400* = 10003
|
||||
B460800* = 10004
|
||||
B500000* = 10005
|
||||
B576000* = 10006
|
||||
B921600* = 10007
|
||||
B1000000* = 10010
|
||||
B1152000* = 10011
|
||||
B1500000* = 10012
|
||||
B2000000* = 10013
|
||||
B2500000* = 10014
|
||||
B3000000* = 10015
|
||||
B3500000* = 10016
|
||||
B4000000* = 10017
|
||||
MAX_BAUD* = B4000000
|
||||
CIBAUD* = 2003600000
|
||||
CMSPAR* = 0o010000000000
|
||||
CRTSCTS* = 0o020000000000
|
||||
|
||||
# lflag bits
|
||||
|
||||
const
|
||||
ISIG* = 1
|
||||
ICANON* = 2
|
||||
XCASE* = 4
|
||||
ECHO* = 10
|
||||
ECHOE* = 20
|
||||
ECHOK* = 40
|
||||
ECHONL* = 100
|
||||
NOFLSH* = 200
|
||||
TOSTOP* = 400
|
||||
ECHOCTL* = 1000
|
||||
ECHOPRT* = 2000
|
||||
ECHOKE* = 4000
|
||||
FLUSHO* = 10000
|
||||
PENDIN* = 40000
|
||||
IEXTEN* = 0o000000100000
|
||||
EXTPROC* = 0o000000200000
|
||||
|
||||
# tcflow() and TCXONC use these
|
||||
|
||||
const
|
||||
TCOOFF* = 0
|
||||
TCOON* = 1
|
||||
TCIOFF* = 2
|
||||
TCION* = 3
|
||||
|
||||
# tcflush() and TCFLSH use these
|
||||
|
||||
const
|
||||
TCIFLUSH* = 0
|
||||
TCOFLUSH* = 1
|
||||
TCIOFLUSH* = 2
|
||||
|
||||
# tcsetattr uses these
|
||||
|
||||
const
|
||||
TCSANOW* = 0
|
||||
TCSADRAIN* = 1
|
||||
TCSAFLUSH* = 2
|
||||
|
||||
# Compare a character C to a value VAL from the `cc' array in a
|
||||
# `struct termios'. If VAL is _POSIX_VDISABLE, no character can match it.
|
||||
|
||||
template cceq*(val, c: expr): expr =
|
||||
c == val and val != POSIX_VDISABLE
|
||||
|
||||
# Return the output baud rate stored in *TERMIOS_P.
|
||||
|
||||
proc cfGetOspeed*(termios: ptr Termios): Speed {.importc: "cfgetospeed",
|
||||
header: "<termios.h>".}
|
||||
# Return the input baud rate stored in *TERMIOS_P.
|
||||
|
||||
proc cfGetIspeed*(termios: ptr Termios): Speed {.importc: "cfgetispeed",
|
||||
header: "<termios.h>".}
|
||||
# Set the output baud rate stored in *TERMIOS_P to SPEED.
|
||||
|
||||
proc cfSetOspeed*(termios: ptr Termios; speed: Speed): cint {.
|
||||
importc: "cfsetospeed", header: "<termios.h>".}
|
||||
# Set the input baud rate stored in *TERMIOS_P to SPEED.
|
||||
|
||||
proc cfSetIspeed*(termios: ptr Termios; speed: Speed): cint {.
|
||||
importc: "cfsetispeed", header: "<termios.h>".}
|
||||
# Set both the input and output baud rates in *TERMIOS_OP to SPEED.
|
||||
|
||||
proc cfSetSpeed*(termios: ptr Termios; speed: Speed): cint {.
|
||||
importc: "cfsetspeed", header: "<termios.h>".}
|
||||
# Put the state of FD into *TERMIOS_P.
|
||||
|
||||
proc tcGetAttr*(fd: cint; termios: ptr Termios): cint {.
|
||||
importc: "tcgetattr", header: "<termios.h>".}
|
||||
# Set the state of FD to *TERMIOS_P.
|
||||
# Values for OPTIONAL_ACTIONS (TCSA*) are in <bits/termios.h>.
|
||||
|
||||
proc tcSetAttr*(fd: cint; optional_actions: cint; termios: ptr Termios): cint {.
|
||||
importc: "tcsetattr", header: "<termios.h>".}
|
||||
# Set *TERMIOS_P to indicate raw mode.
|
||||
|
||||
proc cfMakeRaw*(termios: ptr Termios) {.importc: "cfmakeraw",
|
||||
header: "<termios.h>".}
|
||||
# Send zero bits on FD.
|
||||
|
||||
proc tcSendBreak*(fd: cint; duration: cint): cint {.importc: "tcsendbreak",
|
||||
header: "<termios.h>".}
|
||||
# Wait for pending output to be written on FD.
|
||||
#
|
||||
# This function is a cancellation point and therefore not marked with
|
||||
# .
|
||||
|
||||
proc tcDrain*(fd: cint): cint {.importc: "tcdrain", header: "<termios.h>".}
|
||||
# Flush pending data on FD.
|
||||
# Values for QUEUE_SELECTOR (TC{I,O,IO}FLUSH) are in <bits/termios.h>.
|
||||
|
||||
proc tcFlush*(fd: cint; queue_selector: cint): cint {.importc: "tcflush",
|
||||
header: "<termios.h>".}
|
||||
# Suspend or restart transmission on FD.
|
||||
# Values for ACTION (TC[IO]{OFF,ON}) are in <bits/termios.h>.
|
||||
|
||||
proc tcFlow*(fd: cint; action: cint): cint {.importc: "tcflow",
|
||||
header: "<termios.h>".}
|
||||
# Get process group ID for session leader for controlling terminal FD.
|
||||
|
||||
proc tcGetSid*(fd: cint): TPid {.importc: "tcgetsid", header: "<termios.h>".}
|
||||
|
|
@ -220,3 +220,62 @@ proc product*[T](x: openArray[seq[T]]): seq[seq[T]] =
|
|||
result.add(res)
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>".}
|
||||
|
|
|
|||
|
|
@ -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".} =
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
26
readme.md
26
readme.md
|
|
@ -66,8 +66,24 @@ Copyright (c) 2006-2014 Andreas Rumpf.
|
|||
All rights reserved.
|
||||
|
||||
# Build Status
|
||||
| |Linux|Windows|Mac|
|
||||
|---|---|---|---|
|
||||
| x86 |  |  | 
|
||||
| x86_64 |  |  | 
|
||||
| arm |  |
|
||||
[**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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
'''
|
||||
"""
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ proc processClient(fd: int) {.async.} =
|
|||
var foo = line[0]
|
||||
if foo == 'g':
|
||||
raise newException(EBase, "foobar")
|
||||
|
||||
|
||||
proc serve() {.async.} =
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
discard """
|
||||
errormsg: 'type mismatch: got (mc.typ)'
|
||||
errormsg: "type mismatch: got (mc.typ)"
|
||||
line: 12
|
||||
"""
|
||||
|
||||
|
|
|
|||
15
tests/closure/ttimeinfo.nim
Normal file
15
tests/closure/ttimeinfo.nim
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# bug #2073
|
||||
|
||||
import sequtils
|
||||
import times
|
||||
|
||||
# 1
|
||||
proc f(n: int): TimeInfo =
|
||||
TimeInfo(year: n, month: mJan, monthday: 1)
|
||||
|
||||
echo toSeq(2000 || 2015).map(f)
|
||||
|
||||
# 2
|
||||
echo toSeq(2000 || 2015).map(proc (n: int): TimeInfo =
|
||||
TimeInfo(year: n, month: mJan, monthday: 1)
|
||||
)
|
||||
5
tests/cpp/trawsockets.nim
Normal file
5
tests/cpp/trawsockets.nim
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
discard """
|
||||
cmd: "nim cpp $target"
|
||||
"""
|
||||
|
||||
import rawsockets
|
||||
5
tests/cpp/ttypeinfo.nim
Normal file
5
tests/cpp/ttypeinfo.nim
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
discard """
|
||||
cmd: "nim cpp $target"
|
||||
"""
|
||||
|
||||
import typeinfo
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
discard """
|
||||
line: 2166
|
||||
file: "system.nim"
|
||||
errormsg: "can raise an unlisted exception: ref IOError"
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
24
tests/iter/tconcat.nim
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
discard """
|
||||
output: '''1
|
||||
2
|
||||
3
|
||||
4
|
||||
20
|
||||
21
|
||||
22
|
||||
23'''
|
||||
"""
|
||||
|
||||
proc toIter*[T](s: Slice[T]): iterator: T =
|
||||
iterator it: T {.closure.} =
|
||||
for x in s.a..s.b:
|
||||
yield x
|
||||
return it
|
||||
|
||||
iterator concat*[T](its: varargs[T, toIter]): auto =
|
||||
for i in its:
|
||||
for x in i():
|
||||
yield x
|
||||
|
||||
for i in concat(1..4, 20..23):
|
||||
echo i
|
||||
|
|
@ -74,7 +74,7 @@ type
|
|||
contacts*: PContact
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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.}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 "-----------"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
discard """
|
||||
errormsg: "expression 'generate(builder)' has no type (or is ambiguous)"
|
||||
"""
|
||||
|
||||
# bug #898
|
||||
|
||||
proc measureTime(e: auto) =
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
19
tests/metatype/tmatrix3.nim
Normal file
19
tests/metatype/tmatrix3.nim
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
discard """
|
||||
output: ""
|
||||
"""
|
||||
|
||||
type Matrix[M,N: static[int]] = array[M, array[N, float]]
|
||||
|
||||
let a = [[1.0, 1.0, 1.0, 1.0],
|
||||
[2.0, 4.0, 8.0, 16.0],
|
||||
[3.0, 9.0, 27.0, 81.0],
|
||||
[4.0, 16.0, 64.0, 256.0]]
|
||||
|
||||
proc `$`(m: Matrix): string =
|
||||
result = ""
|
||||
|
||||
proc `*`[M,N,M2,N2](a: Matrix[M,N2]; b: Matrix[M2,N]): Matrix[M,N] =
|
||||
discard
|
||||
|
||||
echo a * a
|
||||
|
||||
|
|
@ -14,6 +14,7 @@ AST b
|
|||
20Test
|
||||
20
|
||||
'''
|
||||
disabled: true
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
discard """
|
||||
errormsg: "type mismatch: got (string) but expected 'ptr'"
|
||||
line: 20
|
||||
disabled: true
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
|
|
|||
11
tests/metatype/typedesc_as_value.nim
Normal file
11
tests/metatype/typedesc_as_value.nim
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
discard """
|
||||
errormsg: "'typedesc' metatype is not valid here; typed '=' instead of ':'?"
|
||||
"""
|
||||
|
||||
|
||||
var x = int
|
||||
|
||||
echo x
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue