From d93ae34d2a03c87ea536b78a45048d2f2c0ebb1c Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sun, 20 Sep 2015 18:16:51 -0700 Subject: [PATCH 1/6] s/advanted/advanced/g --- doc/lib.txt | 2 +- doc/subexes.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/lib.txt b/doc/lib.txt index 6a8f32e071..868adde89b 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -122,7 +122,7 @@ String handling This module contains various string matchers for email addresses, etc. * `subexes `_ - This module implements advanted string substitution operations. + This module implements advanced string substitution operations. Generic Operating System Services diff --git a/doc/subexes.txt b/doc/subexes.txt index f43983e090..54304f0333 100644 --- a/doc/subexes.txt +++ b/doc/subexes.txt @@ -1,7 +1,7 @@ Substitution Expressions (subex) ================================ -A *subex* (*Substitution Expression*) represents an advanted string +A *subex* (*Substitution Expression*) represents an advanced string substitution. In contrast to a `regex`:idx: which deals with string analysis, a *subex* deals with string synthesis. From 50b44066949e912855855ba4b34ff2eb6fd7c410 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sun, 20 Sep 2015 18:24:38 -0700 Subject: [PATCH 2/6] s/acces/access/g --- lib/pure/basic2d.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pure/basic2d.nim b/lib/pure/basic2d.nim index ad8f8653dc..cee3bada44 100644 --- a/lib/pure/basic2d.nim +++ b/lib/pure/basic2d.nim @@ -93,11 +93,11 @@ let IDMATRIX*:Matrix2d=matrix2d(1.0,0.0,0.0,1.0,0.0,0.0) ## Quick access to an identity matrix ORIGO*:Point2d=point2d(0.0,0.0) - ## Quick acces to point (0,0) + ## Quick access to point (0,0) XAXIS*:Vector2d=vector2d(1.0,0.0) - ## Quick acces to an 2d x-axis unit vector + ## Quick access to an 2d x-axis unit vector YAXIS*:Vector2d=vector2d(0.0,1.0) - ## Quick acces to an 2d y-axis unit vector + ## Quick access to an 2d y-axis unit vector # *************************************** From cd40137d1e5124e6cbac0922b93c076b3a714e23 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sun, 20 Sep 2015 18:24:49 -0700 Subject: [PATCH 3/6] mark code-blocks in 2d/3d docs --- lib/pure/basic2d.nim | 2 ++ lib/pure/basic3d.nim | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/pure/basic2d.nim b/lib/pure/basic2d.nim index cee3bada44..7d74424fae 100644 --- a/lib/pure/basic2d.nim +++ b/lib/pure/basic2d.nim @@ -18,6 +18,8 @@ import strutils ## ## Quick start example: ## +## .. code-block:: nim +## ## # Create a matrix which first rotates, then scales and at last translates ## ## var m:Matrix2d=rotate(DEG90) & scale(2.0) & move(100.0,200.0) diff --git a/lib/pure/basic3d.nim b/lib/pure/basic3d.nim index 7fea54d580..424c191f8b 100644 --- a/lib/pure/basic3d.nim +++ b/lib/pure/basic3d.nim @@ -23,6 +23,8 @@ import times ## ## Quick start example: ## +## .. code-block:: nim +## ## # Create a matrix which first rotates, then scales and at last translates ## ## var m:Matrix3d=rotate(PI,vector3d(1,1,2.5)) & scale(2.0) & move(100.0,200.0,300.0) From 73279aba39bfdb6ae7e8ff06e9e0a9c2ba9e8da6 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 21 Sep 2015 15:14:04 +0200 Subject: [PATCH 4/6] added unicode.lastRun, unicode.graphemeLen --- lib/pure/unicode.nim | 41 +++++++++++++++++++++++++++++++++++------ web/news.txt | 1 + 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/lib/pure/unicode.nim b/lib/pure/unicode.nim index 396957f6ce..d3dc77909b 100644 --- a/lib/pure/unicode.nim +++ b/lib/pure/unicode.nim @@ -1319,15 +1319,44 @@ proc reversed*(s: string): string = reverseUntil(len(s)) +proc graphemeLen*(s: string; i: Natural): Natural = + ## The number of bytes belonging to 's[i]' including following combining + ## characters. + var j = i.int + var r, r2: Rune + if j < s.len: + fastRuneAt(s, j, r, true) + result = j-i + while j < s.len: + fastRuneAt(s, j, r2, true) + if not isCombining(r2): break + result = j-i + +proc lastRune*(s: string; last: int): (Rune, int) = + ## length of the last rune in 's[0..last]'. Returns the rune and its length + ## in bytes. + if s[last] <= chr(127): + result = (Rune(s[last]), 1) + else: + var L = 0 + while last-L >= 0 and ord(s[last-L]) shr 6 == 0b10: inc(L) + inc(L) + var r: Rune + fastRuneAt(s, last-L, r, false) + result = (r, L) + when isMainModule: let someString = "öÑ" someRunes = @[runeAt(someString, 0), runeAt(someString, 2)] compared = (someString == $someRunes) - assert compared == true + doAssert compared == true - assert reversed("Reverse this!") == "!siht esreveR" - assert reversed("先秦兩漢") == "漢兩秦先" - assert reversed("as⃝df̅") == "f̅ds⃝a" - assert reversed("a⃞b⃞c⃞") == "c⃞b⃞a⃞" - assert len(toRunes("as⃝df̅")) == runeLen("as⃝df̅") + doAssert reversed("Reverse this!") == "!siht esreveR" + doAssert reversed("先秦兩漢") == "漢兩秦先" + doAssert reversed("as⃝df̅") == "f̅ds⃝a" + doAssert reversed("a⃞b⃞c⃞") == "c⃞b⃞a⃞" + doAssert len(toRunes("as⃝df̅")) == runeLen("as⃝df̅") + const test = "as⃝" + doAssert lastRune(test, test.len-1)[1] == 3 + doAssert graphemeLen("è", 0) == 2 diff --git a/web/news.txt b/web/news.txt index c70824b87e..af8168f365 100644 --- a/web/news.txt +++ b/web/news.txt @@ -97,6 +97,7 @@ News to benchmark it. - ``strutils.formatFloat`` and ``formatBiggestFloat`` do not depend on the C locale anymore and now take an optional ``decimalSep = '.'`` parameter. + - Added ``unicode.lastRune``, ``unicode.graphemeLen``. Compiler Additions From c04e17aea36ddf03955abd8d07ea09ac43f8051e Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 21 Sep 2015 15:17:04 +0200 Subject: [PATCH 5/6] minor bugfix for transf pass after lambda-lifting --- compiler/transf.nim | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/compiler/transf.nim b/compiler/transf.nim index 4ca40ab743..0ea9f7d80d 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -139,23 +139,26 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode = if it.kind == nkCommentStmt: result[i] = PTransNode(it) elif it.kind == nkIdentDefs: - if it.sons[0].kind != nkSym: internalError(it.info, "transformVarSection") - internalAssert(it.len == 3) - var newVar = copySym(it.sons[0].sym) - incl(newVar.flags, sfFromGeneric) - # fixes a strange bug for rodgen: - #include(it.sons[0].sym.flags, sfFromGeneric); - newVar.owner = getCurrOwner(c) - idNodeTablePut(c.transCon.mapping, it.sons[0].sym, newSymNode(newVar)) - var defs = newTransNode(nkIdentDefs, it.info, 3) - if importantComments(): - # keep documentation information: - PNode(defs).comment = it.comment - defs[0] = newSymNode(newVar).PTransNode - defs[1] = it.sons[1].PTransNode - defs[2] = transform(c, it.sons[2]) - newVar.ast = defs[2].PNode - result[i] = defs + if it.sons[0].kind == nkSym: + internalAssert(it.len == 3) + var newVar = copySym(it.sons[0].sym) + incl(newVar.flags, sfFromGeneric) + # fixes a strange bug for rodgen: + #include(it.sons[0].sym.flags, sfFromGeneric); + newVar.owner = getCurrOwner(c) + idNodeTablePut(c.transCon.mapping, it.sons[0].sym, newSymNode(newVar)) + var defs = newTransNode(nkIdentDefs, it.info, 3) + if importantComments(): + # keep documentation information: + PNode(defs).comment = it.comment + defs[0] = newSymNode(newVar).PTransNode + defs[1] = it.sons[1].PTransNode + defs[2] = transform(c, it.sons[2]) + newVar.ast = defs[2].PNode + result[i] = defs + else: + # has been transformed into 'param.x' for closure iterators, so keep it: + result[i] = PTransNode(it) else: if it.kind != nkVarTuple: internalError(it.info, "transformVarSection: not nkVarTuple") From ba4dd92f457b9dd52fd6eddbd3f231b040750b60 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 21 Sep 2015 15:49:34 +0200 Subject: [PATCH 6/6] fixes regression: NimForum compiles again --- compiler/semgnrc.nim | 10 +---- compiler/semtempl.nim | 85 +++++++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 32 deletions(-) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 89b8847f34..620453277c 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -32,12 +32,6 @@ type cursorInBody: bool # only for nimsuggest bracketExpr: PNode -template withBracketExpr(x, body: untyped) = - let old = ctx.bracketExpr - ctx.bracketExpr = x - body - ctx.bracketExpr = old - type TSemGenericFlag = enum withinBind, withinTypeDesc, withinMixin @@ -271,7 +265,7 @@ proc semGenericStmt(c: PContext, n: PNode, result = newNodeI(nkCall, n.info) result.add newIdentNode(getIdent("[]"), n.info) for i in 0 ..< n.len: result.add(n[i]) - withBracketExpr n.sons[0]: + withBracketExpr ctx, n.sons[0]: result = semGenericStmt(c, result, flags, ctx) of nkAsgn, nkFastAsgn: checkSonsLen(n, 2) @@ -291,7 +285,7 @@ proc semGenericStmt(c: PContext, n: PNode, result.add newIdentNode(getIdent("[]="), n.info) for i in 0 ..< a.len: result.add(a[i]) result.add(b) - withBracketExpr a.sons[0]: + withBracketExpr ctx, a.sons[0]: result = semGenericStmt(c, result, flags, ctx) else: for i in countup(0, sonsLen(n) - 1): diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index fc1af72467..2dda8276d8 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -110,6 +110,13 @@ type toBind, toMixin, toInject: IntSet owner: PSym cursorInBody: bool # only for nimsuggest + bracketExpr: PNode + +template withBracketExpr(ctx, x, body: untyped) = + let old = ctx.bracketExpr + ctx.bracketExpr = x + body + ctx.bracketExpr = old proc getIdentNode(c: var TemplCtx, n: PNode): PNode = case n.kind @@ -310,6 +317,18 @@ proc wrapInBind(c: var TemplCtx; n: PNode; opr: string): PNode = else: result = n +proc oprIsRoof(n: PNode): bool = + const roof = "^" + case n.kind + of nkIdent: result = n.ident.s == roof + of nkSym: result = n.sym.name.s == roof + of nkAccQuoted: + if n.len == 1: + result = oprIsRoof(n.sons[0]) + of nkOpenSymChoice, nkClosedSymChoice: + result = oprIsRoof(n.sons[0]) + else: discard + proc semTemplBody(c: var TemplCtx, n: PNode): PNode = result = n semIdeForTemplateOrGenericCheck(n, c.cursorInBody) @@ -452,10 +471,16 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = result.sons[1] = semTemplBody(c, n.sons[1]) of nkPragma: result = onlyReplaceParams(c, n) - of nkBracketExpr, nkCurlyExpr: + of nkBracketExpr: result = newNodeI(nkCall, n.info) - result.add newIdentNode(getIdent(if n.kind == nkBracketExpr:"[]" else:"{}"), - n.info) + result.add newIdentNode(getIdent("[]"), n.info) + for i in 0 ..< n.len: result.add(n[i]) + let n0 = semTemplBody(c, n.sons[0]) + withBracketExpr c, n0: + result = semTemplBodySons(c, result) + of nkCurlyExpr: + result = newNodeI(nkCall, n.info) + result.add newIdentNode(getIdent("{}"), n.info) for i in 0 ..< n.len: result.add(n[i]) result = semTemplBodySons(c, result) of nkAsgn, nkFastAsgn: @@ -465,33 +490,45 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = let k = a.kind case k - of nkBracketExpr, nkCurlyExpr: + of nkBracketExpr: result = newNodeI(nkCall, n.info) - result.add newIdentNode(getIdent(if k == nkBracketExpr:"[]=" else:"{}="), - n.info) + result.add newIdentNode(getIdent("[]="), n.info) for i in 0 ..< a.len: result.add(a[i]) result.add(b) + let a0 = semTemplBody(c, a.sons[0]) + withBracketExpr c, a0: + result = semTemplBodySons(c, result) + of nkCurlyExpr: + result = newNodeI(nkCall, n.info) + result.add newIdentNode(getIdent("{}="), n.info) + for i in 0 ..< a.len: result.add(a[i]) + result.add(b) + result = semTemplBodySons(c, result) else: - result = n - result = semTemplBodySons(c, result) - else: + result = semTemplBodySons(c, n) + of nkCallKinds-{nkPostfix}: + result = semTemplBodySons(c, n) + if c.bracketExpr != nil and n.len == 2 and oprIsRoof(n.sons[0]): + result.add c.bracketExpr + of nkDotExpr, nkAccQuoted: # dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam', # so we use the generic code for nkDotExpr too - if n.kind == nkDotExpr or n.kind == nkAccQuoted: - let s = qualifiedLookUp(c.c, n, {}) - if s != nil: - # do not symchoice a quoted template parameter (bug #2390): - if s.owner == c.owner and s.kind == skParam and - n.kind == nkAccQuoted and n.len == 1: - incl(s.flags, sfUsed) - styleCheckUse(n.info, s) - return newSymNode(s, n.info) - elif contains(c.toBind, s.id): - return symChoice(c.c, n, s, scClosed) - elif contains(c.toMixin, s.name.id): - return symChoice(c.c, n, s, scForceOpen) - else: - return symChoice(c.c, n, s, scOpen) + let s = qualifiedLookUp(c.c, n, {}) + if s != nil: + # do not symchoice a quoted template parameter (bug #2390): + if s.owner == c.owner and s.kind == skParam and + n.kind == nkAccQuoted and n.len == 1: + incl(s.flags, sfUsed) + styleCheckUse(n.info, s) + return newSymNode(s, n.info) + elif contains(c.toBind, s.id): + return symChoice(c.c, n, s, scClosed) + elif contains(c.toMixin, s.name.id): + return symChoice(c.c, n, s, scForceOpen) + else: + return symChoice(c.c, n, s, scOpen) + result = semTemplBodySons(c, n) + else: result = semTemplBodySons(c, n) proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =