more test made green

the lambda lifting was trying too hard to ignore generic prods
isGenericRoutine was producing false-negatives and only
this allowed for some of the warning and error messages
to be triggered.

some files with mixed line endings were fixed
This commit is contained in:
Zahary Karadjov 2013-05-26 21:06:39 +03:00
commit 911e6e710f
6 changed files with 96 additions and 89 deletions

View file

@ -1285,7 +1285,8 @@ proc getStrOrChar*(a: PNode): string =
proc isGenericRoutine*(s: PSym): bool = proc isGenericRoutine*(s: PSym): bool =
case s.kind case s.kind
of skProc, skTemplate, skMacro, skIterator, skMethod, skConverter: of skProc, skTemplate, skMacro, skIterator, skMethod, skConverter:
result = sfFromGeneric in s.flags result = sfFromGeneric in s.flags or
(s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty)
else: nil else: nil
proc isRoutine*(s: PSym): bool {.inline.} = proc isRoutine*(s: PSym): bool {.inline.} =

View file

@ -220,7 +220,7 @@ proc getHiddenParam(routine: PSym): PSym =
proc isInnerProc(s, outerProc: PSym): bool {.inline.} = proc isInnerProc(s, outerProc: PSym): bool {.inline.} =
result = s.kind in {skProc, skMethod, skConverter} and result = s.kind in {skProc, skMethod, skConverter} and
s.owner == outerProc and not isGenericRoutine(s) s.owner == outerProc
#s.typ.callConv == ccClosure #s.typ.callConv == ccClosure
proc addClosureParam(i: PInnerContext, e: PEnv) = proc addClosureParam(i: PInnerContext, e: PEnv) =

View file

@ -91,17 +91,8 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) =
addDecl(c, result) addDecl(c, result)
pushProcCon(c, result) pushProcCon(c, result)
# add params to scope # add params to scope
let origFormalParams = result.typ.n for i in 1 .. <result.typ.n.len:
result.typ.n = newNodeI(nkFormalParams, var param = result.typ.n.sons[i].sym
origFormalParams.info,
origFormalParams.len)
result.typ.n.sons[0] = copyNode(origFormalParams.sons[0])
for i in 1 .. <result.typ.len:
let origParam = origFormalParams[i].sym
var param = copySym(origParam)
result.typ.n.sons[i] = newSymNode(param)
param.typ = result.typ.sons[i]
param.ast = origParam.ast
param.owner = result param.owner = result
addParamOrResult(c, param, result.kind) addParamOrResult(c, param, result.kind)
# debug result.typ.n # debug result.typ.n
@ -150,6 +141,15 @@ proc instGenericContainer(c: PContext, n: PNode, header: PType): PType =
proc fixupProcType(c: PContext, genericType: PType, proc fixupProcType(c: PContext, genericType: PType,
inst: TInstantiation): PType = inst: TInstantiation): PType =
# XXX: This is starting to look suspiciously like ReplaceTypeVarsT
# there are few apparent differences, but maybe the code could be
# moved over.
# * the code here uses the new genericSym.position property when
# doing lookups.
# * the handling of tyTypeDesc seems suspicious in ReplaceTypeVarsT
# typedesc params were previously handled in the second pass of
# semParamList
# * void (nkEmpty) params doesn't seem to be stripped in ReplaceTypeVarsT
result = genericType result = genericType
if result == nil: return if result == nil: return
@ -167,7 +167,8 @@ proc fixupProcType(c: PContext, genericType: PType,
if genericType.sons == nil: return if genericType.sons == nil: return
var head = 0 var head = 0
for i in 0 .. <genericType.sons.len: for i in 0 .. <genericType.sons.len:
var changed = fixupProcType(c, genericType.sons[i], inst) let origType = genericType.sons[i]
var changed = fixupProcType(c, origType, inst)
if changed != genericType.sons[i]: if changed != genericType.sons[i]:
var changed = changed.skipIntLit var changed = changed.skipIntLit
if result == genericType: if result == genericType:
@ -194,7 +195,11 @@ proc fixupProcType(c: PContext, genericType: PType,
if result.n != nil: if result.n != nil:
if result.n.kind == nkRecList: if result.n.kind == nkRecList:
result.n.sons[head].typ = changed for son in result.n.sons:
if son.typ == origType:
son.typ = changed
son.sym = copySym(son.sym, true)
son.sym.typ = changed
if result.n.kind == nkFormalParams: if result.n.kind == nkFormalParams:
if i != 0: if i != 0:
let origParam = result.n.sons[head].sym let origParam = result.n.sons[head].sym
@ -205,14 +210,14 @@ proc fixupProcType(c: PContext, genericType: PType,
# won't be advanced on empty (void) nodes # won't be advanced on empty (void) nodes
inc head inc head
of tyGenericInvokation: of tyGenericInvokation:
result = newTypeWithSons(c, tyGenericInvokation, genericType.sons) result = newTypeWithSons(c, tyGenericInvokation, genericType.sons)
for i in 1 .. <genericType.sons.len: for i in 1 .. <genericType.sons.len:
result.sons[i] = fixupProcType(c, result.sons[i], inst) result.sons[i] = fixupProcType(c, result.sons[i], inst)
result = instGenericContainer(c, getInfoContext(-1), result) result = instGenericContainer(c, getInfoContext(-1), result)
else:
nil else: nil
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
info: TLineInfo): PSym = info: TLineInfo): PSym =

View file

@ -374,7 +374,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
# for ``{}`` we want to trigger the type mismatch in ``fitNode``: # for ``{}`` we want to trigger the type mismatch in ``fitNode``:
if r.kind != nkCurly or len(r) == 0: if r.kind != nkCurly or len(r) == 0:
checkMinSonsLen(t, 1) checkMinSonsLen(t, 1)
branch.sons[i] = fitNode(c, t.sons[0].typ, r) branch.sons[i] = skipConv(fitNode(c, t.sons[0].typ, r))
inc(covered) inc(covered)
else: else:
# constant sets have special rules # constant sets have special rules

View file

@ -1,52 +1,52 @@
type type
TBase = object of TObject TBase = object of TObject
x, y: int x, y: int
TSubclassKind = enum ka, kb, kc, kd, ke, kf TSubclassKind = enum ka, kb, kc, kd, ke, kf
TSubclass = object of TBase TSubclass = object of TBase
case c: TSubclassKind case c: TSubclassKind
of ka, kb, kc, kd: of ka, kb, kc, kd:
a, b: int a, b: int
of ke: of ke:
d, e, f: char d, e, f: char
else: nil else: nil
n: bool n: bool
type type
TMyObject = object of TObject TMyObject = object of TObject
case disp: range[0..4]: case disp: range[0..4]
of 0: arg: char of 0: arg: char
of 1: s: string of 1: s: string
else: wtf: bool else: wtf: bool
var var
x: TMyObject x: TMyObject
var var
global: int global: int
var var
s: string s: string
r: float = 0.0 r: float = 0.0
i: int = 500 + 400 i: int = 500 + 400
case i case i
of 500..999: write(stdout, "ha!\n") of 500..999: write(stdout, "ha!\n")
of 1000..3000, 12: write(stdout, "ganz schön groß\n") of 1000..3000, 12: write(stdout, "ganz schön groß\n")
of 1, 2, 3: write(stdout, "1 2 oder 3\n") of 1, 2, 3: write(stdout, "1 2 oder 3\n")
else: write(stdout, "sollte nicht passieren\n") else: write(stdout, "sollte nicht passieren\n")
case readLine(stdin) case readLine(stdin)
of "Rumpf": write(stdout, "Hallo Meister!\n") of "Rumpf": write(stdout, "Hallo Meister!\n")
of "Andreas": write(stdout, "Hallo Meister!\n") of "Andreas": write(stdout, "Hallo Meister!\n")
else: write(stdout, "Nicht mein Meister!\n") else: write(stdout, "Nicht mein Meister!\n")
global = global + 1 global = global + 1
write(stdout, "Hallo wie heißt du? \n") write(stdout, "Hallo wie heißt du? \n")
s = readLine(stdin) s = readLine(stdin)
i = 0 i = 0
while i < len(s): while i < len(s):
if s[i] == 'c': write(stdout, "'c' in deinem Namen gefunden\n") if s[i] == 'c': write(stdout, "'c' in deinem Namen gefunden\n")
i = i + 1 i = i + 1
write(stdout, "Du heißt " & s) write(stdout, "Du heißt " & s)

View file

@ -1,30 +1,30 @@
# Test overloading of procs when used as function pointers # Test overloading of procs when used as function pointers
import strutils import strutils
proc parseInt(x: float): int {.noSideEffect.} = nil proc parseInt(x: float): int {.noSideEffect.} = nil
proc parseInt(x: bool): int {.noSideEffect.} = nil proc parseInt(x: bool): int {.noSideEffect.} = nil
proc parseInt(x: float32): int {.noSideEffect.} = nil proc parseInt(x: float32): int {.noSideEffect.} = nil
proc parseInt(x: int8): int {.noSideEffect.} = nil proc parseInt(x: int8): int {.noSideEffect.} = nil
proc parseInt(x: TFile): int {.noSideEffect.} = nil proc parseInt(x: TFile): int {.noSideEffect.} = nil
proc parseInt(x: char): int {.noSideEffect.} = nil proc parseInt(x: char): int {.noSideEffect.} = nil
proc parseInt(x: int16): int {.noSideEffect.} = nil proc parseInt(x: int16): int {.noSideEffect.} = nil
type type
TParseInt = proc (x: string): int {.noSideEffect.} TParseInt = proc (x: string): int {.noSideEffect.}
var var
q = TParseInt(parseInt) q = TParseInt(parseInt)
p: TParseInt = parseInt p: TParseInt = parseInt
proc takeParseInt(x: proc (y: string): int {.noSideEffect.}): int = proc takeParseInt(x: proc (y: string): int {.noSideEffect.}): int =
result = x("123") result = x("123")
echo "Give a list of numbers (separated by spaces): " echo "Give a list of numbers (separated by spaces): "
var x = stdin.readline.split.map(parseInt).max var x = stdin.readline.split.map(parseInt).max
echo x, " is the maximum!" echo x, " is the maximum!"
echo "another number: ", takeParseInt(parseInt) echo "another number: ", takeParseInt(parseInt)
type type
TFoo[a,b] = object TFoo[a,b] = object
@ -33,3 +33,4 @@ type
proc bar[a,b](f: TFoo[a,b], x: a) = echo(x, " ", f.lorem, f.ipsum) proc bar[a,b](f: TFoo[a,b], x: a) = echo(x, " ", f.lorem, f.ipsum)
proc bar[a,b](f: TFoo[a,b], x: b) = echo(x, " ", f.lorem, f.ipsum) proc bar[a,b](f: TFoo[a,b], x: b) = echo(x, " ", f.lorem, f.ipsum)