Merge branch 'devel' into araq

This commit is contained in:
Andreas Rumpf 2017-05-04 16:02:50 +02:00
commit 764cc02177
42 changed files with 960 additions and 453 deletions

View file

@ -1324,8 +1324,11 @@ proc shouldRecompile(code: Rope, cfile: Cfile): bool =
if optForceFullMake notin gGlobalOptions:
if not equalsFile(code, cfile.cname):
if isDefined("nimdiff"):
copyFile(cfile.cname, cfile.cname & ".backup")
echo "diff ", cfile.cname, ".backup ", cfile.cname
if fileExists(cfile.cname):
copyFile(cfile.cname, cfile.cname & ".backup")
echo "diff ", cfile.cname, ".backup ", cfile.cname
else:
echo "new file ", cfile.cname
writeRope(code, cfile.cname)
return
if existsFile(cfile.obj) and os.fileNewer(cfile.obj, cfile.cname):

View file

@ -434,22 +434,23 @@ proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
proc unsignedTrimmerJS(size: BiggestInt): Rope =
case size
of 1: rope"& 0xff"
of 2: rope"& 0xffff"
of 4: rope">>> 0"
else: rope""
of 1: rope"& 0xff"
of 2: rope"& 0xffff"
of 4: rope">>> 0"
else: rope""
proc unsignedTrimmerPHP(size: BiggestInt): Rope =
case size
of 1: rope"& 0xff"
of 2: rope"& 0xffff"
of 4: rope"& 0xffffffff"
else: rope""
of 1: rope"& 0xff"
of 2: rope"& 0xffff"
of 4: rope"& 0xffffffff"
else: rope""
template unsignedTrimmer(size: BiggestInt): Rope =
size.unsignedTrimmerJS | size.unsignedTrimmerPHP
proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string, reassign: bool = false) =
proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string,
reassign = false) =
var x, y: TCompRes
gen(p, n.sons[1], x)
gen(p, n.sons[2], y)
@ -1633,11 +1634,11 @@ proc genReprAux(p: PProc, n: PNode, r: var TCompRes, magic: string, typ: Rope =
gen(p, n.sons[1], a)
if magic == "reprAny":
# the pointer argument in reprAny is expandend to
# the pointer argument in reprAny is expandend to
# (pointedto, pointer), so we need to fill it
if a.address.isNil:
add(r.res, a.res)
add(r.res, ", null")
add(r.res, ", null")
else:
add(r.res, "$1, $2" % [a.address, a.res])
else:
@ -1670,7 +1671,7 @@ proc genRepr(p: PProc, n: PNode, r: var TCompRes) =
genReprAux(p, n, r, "reprSet", genTypeInfo(p, t))
of tyEmpty, tyVoid:
localError(n.info, "'repr' doesn't support 'void' type")
of tyPointer:
of tyPointer:
genReprAux(p, n, r, "reprPointer")
of tyOpenArray, tyVarargs:
genReprAux(p, n, r, "reprJSONStringify")
@ -1863,8 +1864,8 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
proc genSetConstr(p: PProc, n: PNode, r: var TCompRes) =
var
a, b: TCompRes
useMagic(p, "SetConstr")
r.res = rope("SetConstr(")
useMagic(p, "setConstr")
r.res = rope("setConstr(")
r.kind = resExpr
for i in countup(0, sonsLen(n) - 1):
if i > 0: add(r.res, ", ")
@ -1877,6 +1878,12 @@ proc genSetConstr(p: PProc, n: PNode, r: var TCompRes) =
gen(p, it, a)
add(r.res, a.res)
add(r.res, ")")
# emit better code for constant sets:
if p.target == targetJS and isDeepConstExpr(n):
inc(p.g.unique)
let tmp = rope("ConstSet") & rope(p.g.unique)
addf(p.g.constants, "var $1 = $2;$n", [tmp, r.res])
r.res = tmp
proc genArrayConstr(p: PProc, n: PNode, r: var TCompRes) =
var a: TCompRes
@ -2128,6 +2135,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) =
else: r.res = rope(f.toStrMaxPrecision)
r.kind = resExpr
of nkCallKinds:
if isEmptyType(n.typ): genLineDir(p, n)
if (n.sons[0].kind == nkSym) and (n.sons[0].sym.magic != mNone):
genMagic(p, n, r)
elif n.sons[0].kind == nkSym and sfInfixCall in n.sons[0].sym.flags and

View file

@ -74,9 +74,9 @@ proc lowerTupleUnpackingForAsgn*(n: PNode; owner: PSym): PNode =
let value = n.lastSon
result = newNodeI(nkStmtList, n.info)
var temp = newSym(skTemp, getIdent(genPrefix), owner, value.info)
var temp = newSym(skLet, getIdent("_"), owner, value.info)
var v = newNodeI(nkLetSection, value.info)
let tempAsNode = newIdentNode(getIdent(genPrefix & $temp.id), value.info)
let tempAsNode = newSymNode(temp) #newIdentNode(getIdent(genPrefix & $temp.id), value.info)
var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3)
vpart.sons[0] = tempAsNode
@ -115,7 +115,7 @@ proc createObj*(owner: PSym, info: TLineInfo): PType =
incl result.flags, tfFinal
result.n = newNodeI(nkRecList, info)
when true:
let s = newSym(skType, getIdent("Env_" & info.toFilename & "_" & $info.line),
let s = newSym(skType, getIdent("Env_" & info.toFilename),
owner, info)
incl s.flags, sfAnon
s.typ = result
@ -137,10 +137,32 @@ proc rawIndirectAccess*(a: PNode; field: PSym; info: TLineInfo): PNode =
addSon(result, newSymNode(field))
result.typ = field.typ
proc lookupInRecord(n: PNode, id: int): PSym =
result = nil
case n.kind
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
result = lookupInRecord(n.sons[i], id)
if result != nil: return
of nkRecCase:
if n.sons[0].kind != nkSym: return
result = lookupInRecord(n.sons[0], id)
if result != nil: return
for i in countup(1, sonsLen(n) - 1):
case n.sons[i].kind
of nkOfBranch, nkElse:
result = lookupInRecord(lastSon(n.sons[i]), id)
if result != nil: return
else: discard
of nkSym:
if n.sym.id == -abs(id): result = n.sym
else: discard
proc addField*(obj: PType; s: PSym) =
# because of 'gensym' support, we have to mangle the name with its ID.
# This is hacky but the clean solution is much more complex than it looks.
var field = newSym(skField, getIdent(s.name.s & $s.id), s.owner, s.info)
var field = newSym(skField, getIdent(s.name.s & $obj.n.len), s.owner, s.info)
field.id = -s.id
let t = skipIntLit(s.typ)
field.typ = t
assert t.kind != tyStmt
@ -148,9 +170,9 @@ proc addField*(obj: PType; s: PSym) =
addSon(obj.n, newSymNode(field))
proc addUniqueField*(obj: PType; s: PSym) =
let fieldName = getIdent(s.name.s & $s.id)
if lookupInRecord(obj.n, fieldName) == nil:
var field = newSym(skField, fieldName, s.owner, s.info)
if lookupInRecord(obj.n, s.id) == nil:
var field = newSym(skField, getIdent(s.name.s & $obj.n.len), s.owner, s.info)
field.id = -s.id
let t = skipIntLit(s.typ)
field.typ = t
assert t.kind != tyStmt
@ -159,13 +181,36 @@ proc addUniqueField*(obj: PType; s: PSym) =
proc newDotExpr(obj, b: PSym): PNode =
result = newNodeI(nkDotExpr, obj.info)
let field = getSymFromList(obj.typ.n, getIdent(b.name.s & $b.id))
let field = lookupInRecord(obj.typ.n, b.id)
assert field != nil, b.name.s
addSon(result, newSymNode(obj))
addSon(result, newSymNode(field))
result.typ = field.typ
proc indirectAccess*(a: PNode, b: string, info: TLineInfo): PNode =
proc indirectAccess*(a: PNode, b: int, info: TLineInfo): PNode =
# returns a[].b as a node
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = a.typ.skipTypes(abstractInst).sons[0]
var t = deref.typ.skipTypes(abstractInst)
var field: PSym
while true:
assert t.kind == tyObject
field = lookupInRecord(t.n, b)
if field != nil: break
t = t.sons[0]
if t == nil: break
t = t.skipTypes(skipPtrs)
#if field == nil:
# echo "FIELD ", b
# debug deref.typ
internalAssert field != nil
addSon(deref, a)
result = newNodeI(nkDotExpr, info)
addSon(result, deref)
addSon(result, newSymNode(field))
result.typ = field.typ
proc indirectAccess(a: PNode, b: string, info: TLineInfo): PNode =
# returns a[].b as a node
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = a.typ.skipTypes(abstractInst).sons[0]
@ -191,11 +236,10 @@ proc indirectAccess*(a: PNode, b: string, info: TLineInfo): PNode =
proc getFieldFromObj*(t: PType; v: PSym): PSym =
assert v.kind != skField
let fieldName = getIdent(v.name.s & $v.id)
var t = t
while true:
assert t.kind == tyObject
result = getSymFromList(t.n, fieldName)
result = lookupInRecord(t.n, v.id)
if result != nil: break
t = t.sons[0]
if t == nil: break
@ -203,7 +247,7 @@ proc getFieldFromObj*(t: PType; v: PSym): PSym =
proc indirectAccess*(a: PNode, b: PSym, info: TLineInfo): PNode =
# returns a[].b as a node
result = indirectAccess(a, b.name.s & $b.id, info)
result = indirectAccess(a, b.id, info)
proc indirectAccess*(a, b: PSym, info: TLineInfo): PNode =
result = indirectAccess(newSymNode(a), b, info)

View file

@ -17,15 +17,17 @@ proc addPath*(path: string, info: TLineInfo) =
proc versionSplitPos(s: string): int =
result = s.len-2
while result > 1 and s[result] in {'0'..'9', '.'}: dec result
#while result > 1 and s[result] in {'0'..'9', '.'}: dec result
while result > 1 and s[result] != '-': dec result
if s[result] != '-': result = s.len
const
latest = "head"
latest = ""
proc `<.`(a, b: string): bool =
# wether a has a smaller version than b:
if a == latest: return false
if a == latest: return true
elif b == latest: return false
var i = 0
var j = 0
var verA = 0
@ -33,8 +35,13 @@ proc `<.`(a, b: string): bool =
while true:
let ii = parseInt(a, verA, i)
let jj = parseInt(b, verB, j)
# if A has no number left, but B has, B is preferred: 0.8 vs 0.8.3
if ii <= 0 or jj <= 0: return jj > 0
if ii <= 0 or jj <= 0:
# if A has no number and B has but A has no number whatsoever ("#head"),
# A is preferred:
if ii > 0 and jj <= 0 and j == 0: return true
if ii <= 0 and jj > 0 and i == 0: return false
# if A has no number left, but B has, B is preferred: 0.8 vs 0.8.3
return jj > 0
if verA < verB: return true
elif verA > verB: return false
# else: same version number; continue:
@ -46,12 +53,9 @@ proc `<.`(a, b: string): bool =
proc addPackage(packages: StringTableRef, p: string) =
let x = versionSplitPos(p)
let name = p.substr(0, x-1)
if x < p.len:
let version = p.substr(x+1)
if packages.getOrDefault(name) <. version:
packages[name] = version
else:
packages[name] = latest
let version = if x < p.len: p.substr(x+1) else: ""
if packages.getOrDefault(name) <. version:
packages[name] = version
iterator chosen(packages: StringTableRef): string =
for key, val in pairs(packages):
@ -76,3 +80,18 @@ proc addPathRec(dir: string, info: TLineInfo) =
proc nimblePath*(path: string, info: TLineInfo) =
addPathRec(path, info)
addNimblePath(path, info)
when isMainModule:
var rr = newStringTable()
addPackage rr, "irc-#head"
addPackage rr, "irc-0.1.0"
addPackage rr, "irc"
addPackage rr, "another"
addPackage rr, "another-0.1"
addPackage rr, "ab-0.1.3"
addPackage rr, "ab-0.1"
addPackage rr, "justone"
for p in rr.chosen:
echo p

View file

@ -1238,10 +1238,7 @@ proc parseExprStmt(p: var TParser): PNode =
addSon(result, e)
if p.tok.tokType != tkComma: break
elif p.tok.indent < 0 and isExprStart(p):
if a.kind == nkCommand:
result = a
else:
result = newNode(nkCommand, a.info, @[a])
result = newNode(nkCommand, a.info, @[a])
while true:
var e = parseExpr(p)
addSon(result, e)

View file

@ -1266,7 +1266,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
result.typ = makeTypeDesc(c, semTypeNode(c, n, nil))
#result = symNodeFromType(c, semTypeNode(c, n, nil), n.info)
of tyTuple:
checkSonsLen(n, 2)
if n.len != 2: return nil
n.sons[0] = makeDeref(n.sons[0])
c.p.bracketExpr = n.sons[0]
# [] operator for tuples requires constant expression:
@ -1276,9 +1276,9 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
var idx = getOrdValue(n.sons[1])
if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)]
else: localError(n.info, errInvalidIndexValueForTuple)
result = n
else:
localError(n.info, errIndexTypesDoNotMatch)
result = n
result = nil
else:
let s = if n.sons[0].kind == nkSym: n.sons[0].sym
elif n[0].kind in nkSymChoices: n.sons[0][0].sym

View file

@ -517,7 +517,7 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
proc procVarcheck(n: PNode) =
if n.kind in nkSymChoices:
for x in n: procVarCheck(x)
elif n.kind == nkSym and n.sym.magic != mNone:
elif n.kind == nkSym and n.sym.magic != mNone and n.sym.kind in routineKinds:
localError(n.info, errXCannotBePassedToProcVar, n.sym.name.s)
proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) =

View file

@ -96,7 +96,7 @@ proc isDeepConstExpr*(n: PNode): bool =
result = true
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv:
result = isDeepConstExpr(n.sons[1])
of nkCurly, nkBracket, nkPar, nkObjConstr, nkClosure:
of nkCurly, nkBracket, nkPar, nkObjConstr, nkClosure, nkRange:
for i in ord(n.kind == nkObjConstr) .. <n.len:
if not isDeepConstExpr(n.sons[i]): return false
if n.typ.isNil: result = true