next steps for tyVarargs/tyOpenArray split

This commit is contained in:
Araq 2012-08-14 08:44:26 +02:00
commit 51de278bd4
13 changed files with 44 additions and 31 deletions

View file

@ -659,7 +659,8 @@ const
GenericTypes*: TTypeKinds = {tyGenericInvokation, tyGenericBody, GenericTypes*: TTypeKinds = {tyGenericInvokation, tyGenericBody,
tyGenericParam} tyGenericParam}
StructuralEquivTypes*: TTypeKinds = {tyArrayConstr, tyNil, tyTuple, tyArray, StructuralEquivTypes*: TTypeKinds = {tyArrayConstr, tyNil, tyTuple, tyArray,
tySet, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, tyOpenArray} tySet, tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, tyOpenArray,
tyVarargs}
ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in:: ConcreteTypes*: TTypeKinds = { # types of the expr that may occur in::
# var x = expr # var x = expr
tyBool, tyChar, tyEnum, tyArray, tyObject, tyBool, tyChar, tyEnum, tyArray, tyObject,

View file

@ -78,7 +78,7 @@ proc openArrayLoc(p: BProc, n: PNode): PRope =
var a: TLoc var a: TLoc
initLocExpr(p, n, a) initLocExpr(p, n, a)
case skipTypes(a.t, abstractVar).kind case skipTypes(a.t, abstractVar).kind
of tyOpenArray: of tyOpenArray, tyVarargs:
result = ropef("$1, $1Len0", [rdLoc(a)]) result = ropef("$1, $1Len0", [rdLoc(a)])
of tyString, tySequence: of tyString, tySequence:
if skipTypes(n.typ, abstractInst).kind == tyVar: if skipTypes(n.typ, abstractInst).kind == tyVar:
@ -99,7 +99,7 @@ proc genArg(p: BProc, n: PNode, param: PSym): PRope =
var a: TLoc var a: TLoc
if n.kind == nkStringToCString: if n.kind == nkStringToCString:
result = genArgStringToCString(p, n) result = genArgStringToCString(p, n)
elif skipTypes(param.typ, abstractVar).kind == tyOpenArray: elif skipTypes(param.typ, abstractVar).kind in {tyOpenArray, tyVarargs}:
var n = if n.kind != nkHiddenAddr: n else: n.sons[0] var n = if n.kind != nkHiddenAddr: n else: n.sons[0]
result = openArrayLoc(p, n) result = openArrayLoc(p, n)
elif ccgIntroducedPtr(param): elif ccgIntroducedPtr(param):

View file

@ -264,7 +264,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
lineCg(p, cpsStmts, lineCg(p, cpsStmts,
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1));$n", "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($1));$n",
[rdLoc(dest), rdLoc(src)]) [rdLoc(dest), rdLoc(src)])
of tyOpenArray: of tyOpenArray, tyVarargs:
# open arrays are always on the stack - really? What if a sequence is # open arrays are always on the stack - really? What if a sequence is
# passed to an open array? # passed to an open array?
if needsComplexAssignment(dest.t): if needsComplexAssignment(dest.t):
@ -1071,10 +1071,10 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
of tySet: of tySet:
putIntoDest(p, d, e.typ, ropecg(p.module, "#reprSet($1, $2)", [ putIntoDest(p, d, e.typ, ropecg(p.module, "#reprSet($1, $2)", [
addrLoc(a), genTypeInfo(p.module, t)])) addrLoc(a), genTypeInfo(p.module, t)]))
of tyOpenArray: of tyOpenArray, tyVarargs:
var b: TLoc var b: TLoc
case a.t.kind case a.t.kind
of tyOpenArray: of tyOpenArray, tyVarargs:
putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)])) putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
of tyString, tySequence: of tyString, tySequence:
putIntoDest(p, b, e.typ, putIntoDest(p, b, e.typ,
@ -1111,7 +1111,7 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
if a.kind == nkHiddenAddr: a = a.sons[0] if a.kind == nkHiddenAddr: a = a.sons[0]
var typ = skipTypes(a.Typ, abstractVar) var typ = skipTypes(a.Typ, abstractVar)
case typ.kind case typ.kind
of tyOpenArray: of tyOpenArray, tyVarargs:
if op == mHigh: unaryExpr(p, e, d, "($1Len0-1)") if op == mHigh: unaryExpr(p, e, d, "($1Len0-1)")
else: unaryExpr(p, e, d, "$1Len0") else: unaryExpr(p, e, d, "$1Len0")
of tyCstring: of tyCstring:
@ -1297,7 +1297,8 @@ proc genOrd(p: BProc, e: PNode, d: var TLoc) =
proc genCast(p: BProc, e: PNode, d: var TLoc) = proc genCast(p: BProc, e: PNode, d: var TLoc) =
const const
ValueTypes = {tyTuple, tyObject, tyArray, tyOpenArray, tyArrayConstr} ValueTypes = {tyTuple, tyObject, tyArray, tyOpenArray, tyVarargs,
tyArrayConstr}
# we use whatever C gives us. Except if we have a value-type, we need to go # we use whatever C gives us. Except if we have a value-type, we need to go
# through its address: # through its address:
var a: TLoc var a: TLoc
@ -1739,7 +1740,7 @@ proc expr(p: BProc, e: PNode, d: var TLoc) =
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange) if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange)
case ty.kind case ty.kind
of tyArray, tyArrayConstr: genArrayElem(p, e, d) of tyArray, tyArrayConstr: genArrayElem(p, e, d)
of tyOpenArray: genOpenArrayElem(p, e, d) of tyOpenArray, tyVarargs: genOpenArrayElem(p, e, d)
of tySequence, tyString: genSeqElem(p, e, d) of tySequence, tyString: genSeqElem(p, e, d)
of tyCString: genCStringElem(p, e, d) of tyCString: genCStringElem(p, e, d)
of tyTuple: genTupleElem(p, e, d) of tyTuple: genTupleElem(p, e, d)

View file

@ -171,7 +171,7 @@ proc mapType(typ: PType): TCTypeKind =
of tyBool: result = ctBool of tyBool: result = ctBool
of tyChar: result = ctChar of tyChar: result = ctChar
of tySet: result = mapSetType(typ) of tySet: result = mapSetType(typ)
of tyOpenArray, tyArrayConstr, tyArray: result = ctArray of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctArray
of tyObject, tyTuple: result = ctStruct of tyObject, tyTuple: result = ctStruct
of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal, of tyGenericBody, tyGenericInst, tyGenericParam, tyDistinct, tyOrdinal,
tyConst, tyMutable, tyIter, tyTypeDesc: tyConst, tyMutable, tyIter, tyTypeDesc:
@ -190,7 +190,7 @@ proc mapType(typ: PType): TCTypeKind =
of tyPtr, tyVar, tyRef: of tyPtr, tyVar, tyRef:
var base = skipTypes(typ.sons[0], abstractInst) var base = skipTypes(typ.sons[0], abstractInst)
case base.kind case base.kind
of tyOpenArray, tyArrayConstr, tyArray: result = ctArray of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctArray
else: result = ctPtr else: result = ctPtr
of tyPointer: result = ctPtr of tyPointer: result = ctPtr
of tySequence: result = ctNimSeq of tySequence: result = ctNimSeq
@ -300,7 +300,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
var arr = param.typ var arr = param.typ
if arr.kind == tyVar: arr = arr.sons[0] if arr.kind == tyVar: arr = arr.sons[0]
var j = 0 var j = 0
while arr.Kind == tyOpenArray: while arr.Kind in {tyOpenArray, tyVarargs}:
# this fixes the 'sort' bug: # this fixes the 'sort' bug:
if param.typ.kind == tyVar: param.loc.s = OnUnknown if param.typ.kind == tyVar: param.loc.s = OnUnknown
# need to pass hidden parameter: # need to pass hidden parameter:
@ -507,7 +507,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope =
case t.Kind case t.Kind
of tyRef, tyPtr, tyVar: of tyRef, tyPtr, tyVar:
et = getUniqueType(t.sons[0]) et = getUniqueType(t.sons[0])
if et.kind in {tyArrayConstr, tyArray, tyOpenArray}: if et.kind in {tyArrayConstr, tyArray, tyOpenArray, tyVarargs}:
# this is correct! sets have no proper base type, so we treat # this is correct! sets have no proper base type, so we treat
# ``var set[char]`` in `getParamTypeDesc` # ``var set[char]`` in `getParamTypeDesc`
et = getUniqueType(elemType(et)) et = getUniqueType(elemType(et))
@ -528,7 +528,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope =
# else we have a strong dependency :-( # else we have a strong dependency :-(
result = con(getTypeDescAux(m, et, check), "*") result = con(getTypeDescAux(m, et, check), "*")
IdTablePut(m.typeCache, t, result) IdTablePut(m.typeCache, t, result)
of tyOpenArray: of tyOpenArray, tyVarargs:
et = getUniqueType(t.sons[0]) et = getUniqueType(t.sons[0])
result = con(getTypeDescAux(m, et, check), "*") result = con(getTypeDescAux(m, et, check), "*")
IdTablePut(m.typeCache, t, result) IdTablePut(m.typeCache, t, result)

View file

@ -393,7 +393,7 @@ proc allocParam(p: BProc, s: PSym) =
proc localDebugInfo(p: BProc, s: PSym) = proc localDebugInfo(p: BProc, s: PSym) =
if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return
# XXX work around a bug: No type information for open arrays possible: # XXX work around a bug: No type information for open arrays possible:
if skipTypes(s.typ, abstractVar).kind == tyOpenArray: return if skipTypes(s.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: return
var a = con("&", s.loc.r) var a = con("&", s.loc.r)
if (s.kind == skParam) and ccgIntroducedPtr(s): a = s.loc.r if (s.kind == skParam) and ccgIntroducedPtr(s): a = s.loc.r
lineF(p, cpsInit, lineF(p, cpsInit,

View file

@ -91,7 +91,7 @@ proc initProc(p: var TProc, globals: PGlobals, module: BModule, procDef: PNode,
const const
MappedToObject = {tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray, MappedToObject = {tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray,
tySet, tyVar, tyRef, tyPtr, tyBigNum} tySet, tyVar, tyRef, tyPtr, tyBigNum, tyVarargs}
proc mapType(typ: PType): TEcmasTypeKind = proc mapType(typ: PType): TEcmasTypeKind =
var t = skipTypes(typ, abstractInst) var t = skipTypes(typ, abstractInst)
@ -104,7 +104,7 @@ proc mapType(typ: PType): TEcmasTypeKind =
of tyPointer: of tyPointer:
# treat a tyPointer like a typed pointer to an array of bytes # treat a tyPointer like a typed pointer to an array of bytes
result = etyInt result = etyInt
of tyRange, tyDistinct, tyOrdinal, tyConst, tyMutable, tyIter, tyVarargs, of tyRange, tyDistinct, tyOrdinal, tyConst, tyMutable, tyIter,
tyProxy: tyProxy:
result = mapType(t.sons[0]) result = mapType(t.sons[0])
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt
@ -112,7 +112,8 @@ proc mapType(typ: PType): TEcmasTypeKind =
of tyFloat..tyFloat128: result = etyFloat of tyFloat..tyFloat128: result = etyFloat
of tySet: result = etyObject # map a set to a table of tySet: result = etyObject # map a set to a table
of tyString, tySequence: result = etyInt # little hack to get right semantics of tyString, tySequence: result = etyInt # little hack to get right semantics
of tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray, tyBigNum: of tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray, tyBigNum,
tyVarargs:
result = etyObject result = etyObject
of tyNil: result = etyNull of tyNil: result = etyNull
of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, tyNone, of tyGenericInst, tyGenericParam, tyGenericBody, tyGenericInvokation, tyNone,
@ -861,7 +862,8 @@ proc genArrayAccess(p: var TProc, n: PNode, r: var TCompRes) =
var ty = skipTypes(n.sons[0].typ, abstractVarRange) var ty = skipTypes(n.sons[0].typ, abstractVarRange)
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange) if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange)
case ty.kind case ty.kind
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString: of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString,
tyVarargs:
genArrayAddr(p, n, r) genArrayAddr(p, n, r)
of tyTuple: of tyTuple:
genFieldAddr(p, n, r) genFieldAddr(p, n, r)
@ -903,7 +905,8 @@ proc genAddr(p: var TProc, n: PNode, r: var TCompRes) =
var ty = skipTypes(n.sons[0].typ, abstractVarRange) var ty = skipTypes(n.sons[0].typ, abstractVarRange)
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange) if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange)
case ty.kind case ty.kind
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString: of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString,
tyVarargs:
genArrayAddr(p, n, r) genArrayAddr(p, n, r)
of tyTuple: of tyTuple:
genFieldAddr(p, n, r) genFieldAddr(p, n, r)

View file

@ -692,7 +692,8 @@ proc evalHigh(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[1], {}) result = evalAux(c, n.sons[1], {})
if isSpecial(result): return if isSpecial(result): return
case skipTypes(n.sons[1].typ, abstractVar).kind case skipTypes(n.sons[1].typ, abstractVar).kind
of tyOpenArray, tySequence: result = newIntNodeT(sonsLen(result)-1, n) of tyOpenArray, tySequence, tyVarargs:
result = newIntNodeT(sonsLen(result)-1, n)
of tyString: result = newIntNodeT(len(result.strVal) - 1, n) of tyString: result = newIntNodeT(len(result.strVal) - 1, n)
else: InternalError(n.info, "evalHigh") else: InternalError(n.info, "evalHigh")

View file

@ -224,7 +224,7 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
restoreOldStyleType(n.sons[1]) restoreOldStyleType(n.sons[1])
var typ = skipTypes(n.sons[1].typ, abstractVarRange) var typ = skipTypes(n.sons[1].typ, abstractVarRange)
case typ.Kind case typ.Kind
of tySequence, tyString, tyOpenArray: of tySequence, tyString, tyOpenArray, tyVarargs:
n.typ = getSysType(tyInt) n.typ = getSysType(tyInt)
of tyArrayConstr, tyArray: of tyArrayConstr, tyArray:
n.typ = n.sons[1].typ.sons[0] # indextype n.typ = n.sons[1].typ.sons[0] # indextype
@ -383,7 +383,7 @@ proc fixAbstractType(c: PContext, n: PNode) =
of nkHiddenStdConv, nkHiddenSubConv: of nkHiddenStdConv, nkHiddenSubConv:
if it.sons[1].kind == nkBracket: if it.sons[1].kind == nkBracket:
it.sons[1] = semArrayConstr(c, it.sons[1]) it.sons[1] = semArrayConstr(c, it.sons[1])
if skipTypes(it.typ, abstractVar).kind == tyOpenArray: if skipTypes(it.typ, abstractVar).kind in {tyOpenArray, tyVarargs}:
#if n.sons[0].kind == nkSym and IdentEq(n.sons[0].sym.name, "[]="): #if n.sons[0].kind == nkSym and IdentEq(n.sons[0].sym.name, "[]="):
# debug(n) # debug(n)
@ -454,6 +454,7 @@ proc isAssignable(c: PContext, n: PNode): TAssignableResult =
result = isAssignable(c, n.sons[0]) result = isAssignable(c, n.sons[0])
of nkHiddenStdConv, nkHiddenSubConv, nkConv: of nkHiddenStdConv, nkHiddenSubConv, nkConv:
# Object and tuple conversions are still addressable, so we skip them # Object and tuple conversions are still addressable, so we skip them
# XXX why is 'tyOpenArray' allowed here?
if skipTypes(n.typ, abstractPtrs).kind in {tyOpenArray, tyTuple, tyObject}: if skipTypes(n.typ, abstractPtrs).kind in {tyOpenArray, tyTuple, tyObject}:
result = isAssignable(c, n.sons[1]) result = isAssignable(c, n.sons[1])
elif compareTypes(n.typ, n.sons[1].typ, dcEqIgnoreDistinct): elif compareTypes(n.typ, n.sons[1].typ, dcEqIgnoreDistinct):
@ -943,7 +944,8 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
n.sons[0] = semExprWithType(c, n.sons[0]) n.sons[0] = semExprWithType(c, n.sons[0])
var arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyPtr, tyRef}) var arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyPtr, tyRef})
case arr.kind case arr.kind
of tyArray, tyOpenArray, tyArrayConstr, tySequence, tyString, tyCString: of tyArray, tyOpenArray, tyVarargs, tyArrayConstr, tySequence, tyString,
tyCString:
checkSonsLen(n, 2) checkSonsLen(n, 2)
n.sons[0] = makeDeref(n.sons[0]) n.sons[0] = makeDeref(n.sons[0])
for i in countup(1, sonsLen(n) - 1): for i in countup(1, sonsLen(n) - 1):

View file

@ -467,7 +467,7 @@ proc foldConv*(n, a: PNode): PNode =
else: else:
result = a result = a
result.typ = n.typ result.typ = n.typ
of tyOpenArray, tyProc: of tyOpenArray, tyVarargs, tyProc:
nil nil
else: else:
result = a result = a
@ -588,7 +588,7 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
result = newIntNodeT(firstOrd(n.sons[1].typ), n) result = newIntNodeT(firstOrd(n.sons[1].typ), n)
of mHigh: of mHigh:
if skipTypes(n.sons[1].typ, abstractVar).kind notin if skipTypes(n.sons[1].typ, abstractVar).kind notin
{tyOpenArray, tySequence, tyString}: {tyOpenArray, tyVarargs, tySequence, tyString}:
result = newIntNodeT(lastOrd(skipTypes(n[1].typ, abstractVar)), n) result = newIntNodeT(lastOrd(skipTypes(n[1].typ, abstractVar)), n)
else: else:
var a = getArrayConstr(m, n.sons[1]) var a = getArrayConstr(m, n.sons[1])

View file

@ -1028,7 +1028,7 @@ proc instantiateDestructor*(c: PContext, typ: PType): bool =
return t.destructor notin [AnalyzingDestructor, DestructorIsTrivial] return t.destructor notin [AnalyzingDestructor, DestructorIsTrivial]
case t.kind case t.kind
of tySequence, tyArray, tyArrayConstr, tyOpenArray: of tySequence, tyArray, tyArrayConstr, tyOpenArray, tyVarargs:
if instantiateDestructor(c, t.sons[0]): if instantiateDestructor(c, t.sons[0]):
if rangeDestructorProc == nil: if rangeDestructorProc == nil:
rangeDestructorProc = SymtabGet(c.tab, getIdent"nimDestroyRange") rangeDestructorProc = SymtabGet(c.tab, getIdent"nimDestroyRange")

View file

@ -409,6 +409,10 @@ proc typeRel(c: var TCandidate, f, a: PType): TTypeRelation =
elif typeRel(c, base(f), a.sons[0]) >= isGeneric: elif typeRel(c, base(f), a.sons[0]) >= isGeneric:
result = isConvertible result = isConvertible
else: nil else: nil
of tyVarargs:
if a.Kind == tyVarargs:
result = typeRel(c, base(f), base(a))
if result < isGeneric: result = isNone
of tySequence: of tySequence:
case a.Kind case a.Kind
of tyNil: of tyNil:

View file

@ -355,7 +355,7 @@ proc transformConv(c: PTransf, n: PNode): PTransNode =
result[2] = copyTree(dest.n.sons[1]).PTransNode result[2] = copyTree(dest.n.sons[1]).PTransNode
else: else:
result = transformSons(c, n) result = transformSons(c, n)
of tyOpenArray: of tyOpenArray, tyVarargs:
result = transform(c, n.sons[1]) result = transform(c, n.sons[1])
of tyCString: of tyCString:
if source.kind == tyString: if source.kind == tyString:
@ -407,7 +407,7 @@ type
proc putArgInto(arg: PNode, formal: PType): TPutArgInto = proc putArgInto(arg: PNode, formal: PType): TPutArgInto =
# This analyses how to treat the mapping "formal <-> arg" in an # This analyses how to treat the mapping "formal <-> arg" in an
# inline context. # inline context.
if skipTypes(formal, abstractInst).kind == tyOpenArray: if skipTypes(formal, abstractInst).kind in {tyOpenArray, tyVarargs}:
return paDirectMapping # XXX really correct? return paDirectMapping # XXX really correct?
# what if ``arg`` has side-effects? # what if ``arg`` has side-effects?
case arg.kind case arg.kind

View file

@ -330,7 +330,8 @@ proc canFormAcycleAux(marker: var TIntSet, typ: PType, startId: int): bool =
var t = skipTypes(typ, abstractInst) var t = skipTypes(typ, abstractInst)
if tfAcyclic in t.flags: return if tfAcyclic in t.flags: return
case t.kind case t.kind
of tyTuple, tyObject, tyRef, tySequence, tyArray, tyArrayConstr, tyOpenArray: of tyTuple, tyObject, tyRef, tySequence, tyArray, tyArrayConstr, tyOpenArray,
tyVarargs:
if not ContainsOrIncl(marker, t.id): if not ContainsOrIncl(marker, t.id):
for i in countup(0, sonsLen(t) - 1): for i in countup(0, sonsLen(t) - 1):
result = canFormAcycleAux(marker, t.sons[i], startId) result = canFormAcycleAux(marker, t.sons[i], startId)
@ -499,7 +500,7 @@ proc base(t: PType): PType =
proc firstOrd(t: PType): biggestInt = proc firstOrd(t: PType): biggestInt =
case t.kind case t.kind
of tyBool, tyChar, tySequence, tyOpenArray, tyString: result = 0 of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs: result = 0
of tySet, tyVar: result = firstOrd(t.sons[0]) of tySet, tyVar: result = firstOrd(t.sons[0])
of tyArray, tyArrayConstr: result = firstOrd(t.sons[0]) of tyArray, tyArrayConstr: result = firstOrd(t.sons[0])
of tyRange: of tyRange: