mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-08 22:13:29 +00:00
fixes #22286 ref https://forum.nim-lang.org/t/10642 For backwards compatibilities, we might need to keep the changes under a preview compiler flag. Let's see how many packags it break. **TODO** in the following PRs - [ ] Turn the `var T` destructors warning into an error with `nimPreviewNonVarDestructor` --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
377 lines
7.6 KiB
Nim
377 lines
7.6 KiB
Nim
discard """
|
|
nimoutFull: true
|
|
cmd: '''nim c -r --warnings:off --hints:off --mm:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off --assertions:off --expandArc:extractConfig --expandArc:mergeShadowScope --expandArc:check $file'''
|
|
nimout: '''
|
|
--expandArc: newTarget
|
|
|
|
var
|
|
splat
|
|
:tmp
|
|
:tmp_1
|
|
splat = splitDrive do:
|
|
let blitTmp = path
|
|
blitTmp
|
|
:tmp = splat.drive
|
|
`=wasMoved`(splat.drive)
|
|
:tmp_1 = splat.path_1
|
|
`=wasMoved`(splat.path_1)
|
|
result = (
|
|
let blitTmp_1 = :tmp
|
|
blitTmp_1,
|
|
let blitTmp_2 = :tmp_1
|
|
blitTmp_2)
|
|
`=destroy`(splat)
|
|
-- end of expandArc ------------------------
|
|
--expandArc: delete
|
|
|
|
var
|
|
sibling
|
|
saved
|
|
`=copy`(sibling, target.parent.left)
|
|
`=copy`(saved, sibling.right)
|
|
`=copy`(sibling.right, saved.left)
|
|
`=sink`(sibling.parent, saved)
|
|
`=destroy`(sibling)
|
|
-- end of expandArc ------------------------
|
|
--expandArc: p1
|
|
|
|
var
|
|
lresult
|
|
lvalue
|
|
lnext
|
|
tmpTupleAsgn
|
|
lresult = @[123]
|
|
tmpTupleAsgn = (
|
|
let blitTmp = lresult
|
|
blitTmp, ";")
|
|
lvalue = tmpTupleAsgn[0]
|
|
lnext = tmpTupleAsgn[1]
|
|
`=sink`(result.value, move lvalue)
|
|
`=destroy`(lnext)
|
|
`=destroy_1`(lvalue)
|
|
-- end of expandArc ------------------------
|
|
--expandArc: tt
|
|
|
|
var
|
|
it_cursor
|
|
a
|
|
:tmpD
|
|
:tmpD_1
|
|
:tmpD_2
|
|
try:
|
|
it_cursor = x
|
|
a = (
|
|
:tmpD = `=dup`(it_cursor.key)
|
|
:tmpD,
|
|
:tmpD_1 = `=dup`(it_cursor.val)
|
|
:tmpD_1)
|
|
echo [
|
|
:tmpD_2 = `$$`(a)
|
|
:tmpD_2]
|
|
finally:
|
|
`=destroy`(:tmpD_2)
|
|
`=destroy_1`(a)
|
|
-- end of expandArc ------------------------
|
|
--expandArc: extractConfig
|
|
|
|
var lan_ip
|
|
try:
|
|
lan_ip = ""
|
|
block :tmp:
|
|
var line
|
|
var i = 0
|
|
let L = len(txt)
|
|
block :tmp_1:
|
|
while i < L:
|
|
var splitted
|
|
try:
|
|
line = txt[i]
|
|
splitted = split(line, " ", -1)
|
|
if splitted[0] == "opt":
|
|
`=copy`(lan_ip, splitted[1])
|
|
echo [lan_ip]
|
|
echo [splitted[1]]
|
|
{.push, overflowChecks: false.}
|
|
inc(i, 1)
|
|
{.pop.}
|
|
finally:
|
|
`=destroy`(splitted)
|
|
finally:
|
|
`=destroy_1`(lan_ip)
|
|
-- end of expandArc ------------------------
|
|
--expandArc: mergeShadowScope
|
|
|
|
var shadowScope
|
|
`=copy`(shadowScope, c.currentScope)
|
|
rawCloseScope(c)
|
|
block :tmp:
|
|
var sym
|
|
var i = 0
|
|
let L = len(shadowScope.symbols)
|
|
block :tmp_1:
|
|
while i < L:
|
|
var :tmpD
|
|
sym = shadowScope.symbols[i]
|
|
addInterfaceDecl(c):
|
|
:tmpD = `=dup`(sym)
|
|
:tmpD
|
|
{.push, overflowChecks: false.}
|
|
inc(i, 1)
|
|
{.pop.}
|
|
`=destroy`(shadowScope)
|
|
-- end of expandArc ------------------------
|
|
--expandArc: check
|
|
|
|
var par
|
|
this.isValid = fileExists(this.value)
|
|
if dirExists(this.value):
|
|
var :tmpD
|
|
par = (dir:
|
|
:tmpD = `=dup`(this.value)
|
|
:tmpD, front: "") else:
|
|
var
|
|
:tmpD_1
|
|
:tmpD_2
|
|
:tmpD_3
|
|
par = (dir_1: parentDir(this.value), front_1:
|
|
:tmpD_1 = `=dup`(
|
|
:tmpD_3 = splitDrive do:
|
|
:tmpD_2 = `=dup`(this.value)
|
|
:tmpD_2
|
|
:tmpD_3.path)
|
|
:tmpD_1)
|
|
`=destroy`(:tmpD_3)
|
|
if dirExists(par.dir):
|
|
`=sink`(this.matchDirs, getSubDirs(par.dir, par.front))
|
|
else:
|
|
`=sink`(this.matchDirs, [])
|
|
`=destroy`(par)
|
|
-- end of expandArc ------------------------
|
|
--expandArc: check
|
|
|
|
check(this)
|
|
-- end of expandArc ------------------------
|
|
(package: "", ext: "meo")
|
|
doing shady stuff...
|
|
3
|
|
6
|
|
(@[1], @[2])
|
|
192.168.0.1
|
|
192.168.0.1
|
|
192.168.0.1
|
|
192.168.0.1
|
|
'''
|
|
"""
|
|
|
|
import os, std/private/ntpath
|
|
|
|
type Target = tuple[package, ext: string]
|
|
|
|
proc newTarget*(path: string): Target =
|
|
let splat = path.splitDrive
|
|
result = (package: splat.drive, ext: splat.path)
|
|
|
|
echo newTarget("meo")
|
|
|
|
type
|
|
Node = ref object
|
|
left, right, parent: Node
|
|
value: int
|
|
|
|
proc delete(target: var Node) =
|
|
var sibling = target.parent.left # b3
|
|
var saved = sibling.right # b3.right -> r4
|
|
|
|
sibling.right = saved.left # b3.right -> r4.left = nil
|
|
sibling.parent = saved # b3.parent -> r5 = r4
|
|
|
|
#[after this proc:
|
|
b 5
|
|
/ \
|
|
b 3 b 6
|
|
]#
|
|
|
|
|
|
#[before:
|
|
r 5
|
|
/ \
|
|
b 3 b 6 - to delete
|
|
/ \
|
|
empty r 4
|
|
]#
|
|
proc main =
|
|
var five = Node(value: 5)
|
|
|
|
var six = Node(value: 6)
|
|
six.parent = five
|
|
five.right = six
|
|
|
|
var three = Node(value: 3)
|
|
three.parent = five
|
|
five.left = three
|
|
|
|
var four = Node(value: 4)
|
|
four.parent = three
|
|
three.right = four
|
|
|
|
echo "doing shady stuff..."
|
|
delete(six)
|
|
# need both of these echos
|
|
echo five.left.value
|
|
echo five.right.value
|
|
|
|
main()
|
|
|
|
type
|
|
Maybe = object
|
|
value: seq[int]
|
|
|
|
proc p1(): Maybe =
|
|
let lresult = @[123]
|
|
var lvalue: seq[int]
|
|
var lnext: string
|
|
(lvalue, lnext) = (lresult, ";")
|
|
|
|
result.value = move lvalue
|
|
|
|
proc tissue15130 =
|
|
doAssert p1().value == @[123]
|
|
|
|
tissue15130()
|
|
|
|
type
|
|
KeyValue = tuple[key, val: seq[int]]
|
|
|
|
proc tt(x: KeyValue) =
|
|
var it = x
|
|
let a = (it.key, it.val)
|
|
echo a
|
|
|
|
proc encodedQuery =
|
|
var query: seq[KeyValue]
|
|
query.add (key: @[1], val: @[2])
|
|
|
|
for elem in query:
|
|
elem.tt()
|
|
|
|
encodedQuery()
|
|
|
|
# bug #15147
|
|
|
|
proc s(input: string): (string, string) =
|
|
result = (";", "")
|
|
|
|
proc charmatch(input: string): (string, string) =
|
|
result = ("123", input[0 .. input.high])
|
|
|
|
proc plus(input: string) =
|
|
var
|
|
lvalue, rvalue: string # cursors
|
|
lnext: string # must be cursor!!!
|
|
rnext: string # cursor
|
|
let lresult = charmatch(input)
|
|
(lvalue, lnext) = lresult
|
|
|
|
let rresult = s(lnext)
|
|
(rvalue, rnext) = rresult
|
|
|
|
plus("123;")
|
|
|
|
func substrEq(s: string, pos: int, substr: string): bool =
|
|
var i = 0
|
|
var length = substr.len
|
|
while i < length and pos+i < s.len and s[pos+i] == substr[i]:
|
|
inc i
|
|
return i == length
|
|
|
|
template stringHasSep(s: string, index: int, sep: string): bool =
|
|
s.substrEq(index, sep)
|
|
|
|
template splitCommon(s, sep, maxsplit, sepLen) =
|
|
var last = 0
|
|
var splits = maxsplit
|
|
|
|
while last <= len(s):
|
|
var first = last
|
|
while last < len(s) and not stringHasSep(s, last, sep):
|
|
inc(last)
|
|
if splits == 0: last = len(s)
|
|
yield substr(s, first, last-1)
|
|
if splits == 0: break
|
|
dec(splits)
|
|
inc(last, sepLen)
|
|
|
|
iterator split(s: string, sep: string, maxsplit = -1): string =
|
|
splitCommon(s, sep, maxsplit, sep.len)
|
|
|
|
template accResult(iter: untyped) =
|
|
result = @[]
|
|
for x in iter: add(result, x)
|
|
|
|
func split*(s: string, sep: string, maxsplit = -1): seq[string] =
|
|
accResult(split(s, sep, maxsplit))
|
|
|
|
|
|
let txt = @["opt 192.168.0.1", "static_lease 192.168.0.1"]
|
|
|
|
# bug #17033
|
|
|
|
proc extractConfig() =
|
|
var lan_ip = ""
|
|
|
|
for line in txt:
|
|
let splitted = line.split(" ")
|
|
if splitted[0] == "opt":
|
|
lan_ip = splitted[1] # "borrow" is conditional and inside a loop.
|
|
# Not good enough...
|
|
# we need a flag that live-ranges are disjoint
|
|
echo lan_ip
|
|
echo splitted[1] # Without this line everything works
|
|
|
|
extractConfig()
|
|
|
|
|
|
type
|
|
Symbol = ref object
|
|
name: string
|
|
|
|
Scope = ref object
|
|
parent: Scope
|
|
symbols: seq[Symbol]
|
|
|
|
PContext = ref object
|
|
currentScope: Scope
|
|
|
|
proc rawCloseScope(c: PContext) =
|
|
c.currentScope = c.currentScope.parent
|
|
|
|
proc addInterfaceDecl(c: PContext; s: Symbol) =
|
|
c.currentScope.symbols.add s
|
|
|
|
proc mergeShadowScope*(c: PContext) =
|
|
let shadowScope = c.currentScope
|
|
c.rawCloseScope
|
|
for sym in shadowScope.symbols:
|
|
c.addInterfaceDecl(sym)
|
|
|
|
mergeShadowScope(PContext(currentScope: Scope(parent: Scope())))
|
|
|
|
type
|
|
Foo = ref object
|
|
isValid*: bool
|
|
value*: string
|
|
matchDirs*: seq[string]
|
|
|
|
proc getSubDirs(parent, front: string): seq[string] = @[]
|
|
|
|
method check(this: Foo) {.base.} =
|
|
this.isValid = fileExists(this.value)
|
|
let par = if dirExists(this.value): (dir: this.value, front: "")
|
|
else: (dir: parentDir(this.value), front: splitDrive(this.value).path)
|
|
if dirExists(par.dir):
|
|
this.matchDirs = getSubDirs(par.dir, par.front)
|
|
else:
|
|
this.matchDirs = @[]
|
|
|
|
check(Foo())
|