mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-17 14:31:15 +00:00
Cleaned up the circular dependecies and remaining issues
Changed: The []= operator for strings and sequences is now capable of splicing
This commit is contained in:
@@ -230,7 +230,7 @@ proc parseStmt*(s: string): stmt {.magic: "ParseStmtToAst".}
|
||||
## Compiles the passed string to its AST representation.
|
||||
## Expects one or more statements.
|
||||
|
||||
proc getAst*(macroOrTemplate: expr): expr {.magic: "ExpandMacroToAst".}
|
||||
proc getAst*(macroOrTemplate: expr): expr {.magic: "ExpandToAst".}
|
||||
## Obtains the AST nodes returned from a macro or template invocation.
|
||||
## Example:
|
||||
##
|
||||
|
||||
@@ -56,7 +56,7 @@ template test*(name: expr, body: stmt): stmt =
|
||||
|
||||
finally:
|
||||
TestTeardownIMPL()
|
||||
echo "[" & $TestStatusIMPL & "] " & name
|
||||
echo "[" & $TestStatusIMPL & "] " & name & "\n"
|
||||
|
||||
proc checkpoint*(msg: string) =
|
||||
checkpoints.add(msg)
|
||||
@@ -77,19 +77,8 @@ macro check*(conditions: stmt): stmt =
|
||||
if not Exp:
|
||||
checkpoint(lineInfoLit & ": Check failed: " & expLit)
|
||||
fail()
|
||||
|
||||
# XXX: If we don't create a string literal node below, the compiler
|
||||
# will SEGFAULT in a rather strange fashion:
|
||||
#
|
||||
# rewrite(e, e.toStrLit, e.toStrLit) is ok, but
|
||||
#
|
||||
# rewrite(e, e.lineinfo, e.toStrLit) or
|
||||
# rewrite(e, "anything", e.toStrLit) are not
|
||||
#
|
||||
# It may have something to do with the dummyContext hack in
|
||||
# evals.nim/evalTemplate
|
||||
#
|
||||
result = getAst(rewrite(e, newStrLitNode(e.lineinfo), e.toStrLit))
|
||||
|
||||
result = getAst(rewrite(e, e.lineinfo, e.toStrLit))
|
||||
|
||||
case conditions.kind
|
||||
of nnkCall, nnkCommand, nnkMacroStmt:
|
||||
@@ -110,7 +99,7 @@ macro check*(conditions: stmt): stmt =
|
||||
|
||||
result = getAst(rewrite(
|
||||
op[0], op[1], op[2],
|
||||
newStrLitNode(op.lineinfo),
|
||||
op.lineinfo,
|
||||
op.toStrLit,
|
||||
op[1].toStrLit,
|
||||
op[2].toStrLit))
|
||||
@@ -153,5 +142,5 @@ macro expect*(exp: stmt): stmt =
|
||||
for i in countup(1, expectCall.len - 1):
|
||||
errorTypes.add(expectCall[i])
|
||||
|
||||
result = getAst(expectBody(errorTypes, newStrLitNode(exp.lineinfo), body))
|
||||
result = getAst(expectBody(errorTypes, exp.lineinfo, body))
|
||||
|
||||
|
||||
@@ -857,28 +857,6 @@ proc insert*[T](x: var seq[T], item: T, i = 0) {.noSideEffect.} =
|
||||
dec(j)
|
||||
x[i] = item
|
||||
|
||||
template spliceImpl(x, start, count, elements: expr): stmt =
|
||||
var
|
||||
shift = elements.len - count
|
||||
newLen = x.len + shift
|
||||
totalShifted = x.len - (start + count)
|
||||
firstShifted = newLen - totalShifted
|
||||
|
||||
if shift > 0:
|
||||
setLen(x, newLen)
|
||||
|
||||
for i in countup(firstShifted, newLen - 1):
|
||||
shallowCopy(x[i], x[i-shift])
|
||||
|
||||
for c in countup(0, elements.len - 1):
|
||||
x[start + c] = elements[c]
|
||||
|
||||
if shift < 0:
|
||||
setLen(x, newLen)
|
||||
|
||||
proc splice*[T](x: var seq[T], start, count: int, elements: openarray[T] = []) =
|
||||
spliceImpl(x, start, count, elements)
|
||||
|
||||
proc repr*[T](x: T): string {.magic: "Repr", noSideEffect.}
|
||||
## takes any Nimrod variable and returns its string representation. It
|
||||
## works even for complex data graphs with cycles. This is a great
|
||||
@@ -1943,6 +1921,26 @@ proc `[]`*(s: string, x: TSlice[int]): string {.inline.} =
|
||||
## slice operation for strings. Negative indexes are supported.
|
||||
result = s.substr(x.a-|s, x.b-|s)
|
||||
|
||||
template spliceImpl(x, start, endp, spliced: expr): stmt =
|
||||
var
|
||||
count = endp - start + 1
|
||||
shift = spliced.len - count
|
||||
newLen = x.len + shift
|
||||
totalShifted = x.len - (start + count)
|
||||
firstShifted = newLen - totalShifted
|
||||
|
||||
if shift > 0:
|
||||
setLen(x, newLen)
|
||||
|
||||
for i in countdown(newLen - 1, firstShifted):
|
||||
shallowCopy(x[i], x[i-shift])
|
||||
|
||||
for c in countup(0, spliced.len - 1):
|
||||
x[start + c] = spliced[c]
|
||||
|
||||
if shift < 0:
|
||||
setLen(x, newLen)
|
||||
|
||||
proc `[]=`*(s: var string, x: TSlice[int], b: string) =
|
||||
## slice assignment for strings. Negative indexes are supported.
|
||||
var a = x.a-|s
|
||||
@@ -1950,7 +1948,7 @@ proc `[]=`*(s: var string, x: TSlice[int], b: string) =
|
||||
if L == b.len:
|
||||
for i in 0 .. <L: s[i+a] = b[i]
|
||||
else:
|
||||
raise newException(EOutOfRange, "differing lengths for slice assignment")
|
||||
spliceImpl(s, x.a, x.b, b)
|
||||
|
||||
proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[int]): seq[T] =
|
||||
## slice operation for arrays. Negative indexes are NOT supported because
|
||||
@@ -2004,7 +2002,7 @@ proc `[]=`*[T](s: var seq[T], x: TSlice[int], b: openArray[T]) =
|
||||
if L == b.len:
|
||||
for i in 0 .. <L: s[i+a] = b[i]
|
||||
else:
|
||||
raise newException(EOutOfRange, "differing lengths for slice assignment")
|
||||
spliceImpl(s, x.a, x.b, b)
|
||||
|
||||
proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo".}
|
||||
## get type information for `x`. Ordinary code should not use this, but
|
||||
|
||||
Reference in New Issue
Block a user