parent
0d75723f91
commit
6ff8752be5
52 changed files with 464 additions and 324 deletions
|
|
@ -273,7 +273,7 @@ type
|
|||
tfNoSideEffect, # procedure type does not allow side effects
|
||||
tfFinal, # is the object final?
|
||||
tfAcyclic, # type is acyclic (for GC optimization)
|
||||
tfEnumHasWholes, # enum cannot be mapped into a range
|
||||
tfEnumHasHoles, # enum cannot be mapped into a range
|
||||
tfShallow # type can be shallow copied on assignment
|
||||
|
||||
TTypeFlags* = set[TTypeFlag]
|
||||
|
|
|
|||
|
|
@ -669,37 +669,34 @@ proc genTupleInfo(m: BModule, typ: PType, name: PRope) =
|
|||
[expr, toRope(length)])
|
||||
appf(m.s[cfsTypeInit3], "$1->node = &$2;$n", [name, tmp])
|
||||
|
||||
proc genEnumInfo(m: BModule, typ: PType, name: PRope) =
|
||||
var
|
||||
nodePtrs, elemNode, enumNames, enumArray, counter, specialCases: PRope
|
||||
length, firstNimNode: int
|
||||
field: PSym
|
||||
proc genEnumInfo(m: BModule, typ: PType, name: PRope) =
|
||||
# Type information for enumerations is quite heavy, so we do some
|
||||
# optimizations here: The ``typ`` field is never set, as it is redundant
|
||||
# anyway. We generate a cstring array and a loop over it. Exceptional
|
||||
# positions will be reset after the loop.
|
||||
genTypeInfoAux(m, typ, name)
|
||||
nodePtrs = getTempName()
|
||||
length = sonsLen(typ.n)
|
||||
var nodePtrs = getTempName()
|
||||
var length = sonsLen(typ.n)
|
||||
appf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n",
|
||||
[nodePtrs, toRope(length)])
|
||||
enumNames = nil
|
||||
specialCases = nil
|
||||
firstNimNode = m.typeNodes
|
||||
var enumNames, specialCases: PRope
|
||||
var firstNimNode = m.typeNodes
|
||||
var hasHoles = false
|
||||
for i in countup(0, length - 1):
|
||||
assert(typ.n.sons[i].kind == nkSym)
|
||||
field = typ.n.sons[i].sym
|
||||
elemNode = getNimNode(m)
|
||||
var field = typ.n.sons[i].sym
|
||||
var elemNode = getNimNode(m)
|
||||
if field.ast == nil:
|
||||
# no explicit string literal for the enum field, so use field.name:
|
||||
app(enumNames, makeCString(field.name.s))
|
||||
else:
|
||||
app(enumNames, makeCString(field.ast.strVal))
|
||||
if i < length - 1: app(enumNames, ", " & tnl)
|
||||
if field.position != i:
|
||||
if field.position != i or tfEnumHasHoles in typ.flags:
|
||||
appf(specialCases, "$1.offset = $2;$n", [elemNode, toRope(field.position)])
|
||||
enumArray = getTempName()
|
||||
counter = getTempName()
|
||||
hasHoles = true
|
||||
var enumArray = getTempName()
|
||||
var counter = getTempName()
|
||||
appf(m.s[cfsTypeInit1], "NI $1;$n", [counter])
|
||||
appf(m.s[cfsTypeInit1], "static char* NIM_CONST $1[$2] = {$n$3};$n",
|
||||
[enumArray, toRope(length), enumNames])
|
||||
|
|
@ -711,6 +708,9 @@ proc genEnumInfo(m: BModule, typ: PType, name: PRope) =
|
|||
appf(m.s[cfsTypeInit3],
|
||||
"$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n$4->node = &$1;$n",
|
||||
[getNimNode(m), toRope(length), nodePtrs, name])
|
||||
if hasHoles:
|
||||
# 1 << 2 is {ntfEnumHole}
|
||||
appf(m.s[cfsTypeInit3], "$1->flags = 1<<2;$n", [name])
|
||||
|
||||
proc genSetInfo(m: BModule, typ: PType, name: PRope) =
|
||||
assert(typ.sons[0] != nil)
|
||||
|
|
|
|||
|
|
@ -297,8 +297,11 @@ proc getName(n: PNode, splitAfter: int = - 1): string =
|
|||
of nkPragmaExpr: result = getName(n.sons[0], splitAfter)
|
||||
of nkSym: result = esc(n.sym.name.s, splitAfter)
|
||||
of nkIdent: result = esc(n.ident.s, splitAfter)
|
||||
of nkAccQuoted: result = esc("`") & getName(n.sons[0], splitAfter) & esc("`")
|
||||
else:
|
||||
of nkAccQuoted:
|
||||
result = esc("`")
|
||||
for i in 0.. <n.len: result.add(getName(n[i], splitAfter))
|
||||
result.add esc("`")
|
||||
else:
|
||||
internalError(n.info, "getName()")
|
||||
result = ""
|
||||
|
||||
|
|
@ -308,8 +311,10 @@ proc getRstName(n: PNode): PRstNode =
|
|||
of nkPragmaExpr: result = getRstName(n.sons[0])
|
||||
of nkSym: result = newRstNode(rnLeaf, n.sym.name.s)
|
||||
of nkIdent: result = newRstNode(rnLeaf, n.ident.s)
|
||||
of nkAccQuoted: result = getRstName(n.sons[0])
|
||||
else:
|
||||
of nkAccQuoted:
|
||||
result = getRstName(n.sons[0])
|
||||
for i in 1 .. <n.len: result.text.add(getRstName(n[i]).text)
|
||||
else:
|
||||
internalError(n.info, "getRstName()")
|
||||
result = nil
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ const
|
|||
linkerExe: "llvm-gcc",
|
||||
linkTmpl: "$options $buildgui $builddll -o $exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
debug: "", pic: "-fPIC",
|
||||
debug: "",
|
||||
pic: "-fPIC",
|
||||
asmStmtFrmt: "asm($1);$n",
|
||||
props: {hasSwitchRange, hasComputedGoto, hasCpp}),
|
||||
(name: "clang",
|
||||
|
|
@ -83,7 +84,8 @@ const
|
|||
linkerExe: "clang",
|
||||
linkTmpl: "$options $buildgui $builddll -o $exefile $objfiles",
|
||||
includeCmd: " -I",
|
||||
debug: "", pic: "-fPIC",
|
||||
debug: "",
|
||||
pic: "-fPIC",
|
||||
asmStmtFrmt: "asm($1);$n",
|
||||
props: {hasSwitchRange, hasComputedGoto, hasCpp}),
|
||||
(name: "lcc",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,24 @@
|
|||
import
|
||||
ast, astalgo, idents, semdata, types, msgs, options, rodread, renderer
|
||||
|
||||
proc considerAcc*(n: PNode): PIdent =
|
||||
case n.kind
|
||||
of nkIdent: result = n.ident
|
||||
of nkSym: result = n.sym.name
|
||||
of nkAccQuoted:
|
||||
case n.len
|
||||
of 0: GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
of 1: result = considerAcc(n.sons[0])
|
||||
else:
|
||||
var id = ""
|
||||
for i in 0.. <n.len:
|
||||
if n.sons[i].kind != nkIdent:
|
||||
GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
id.add(n.sons[i].ident.s)
|
||||
result = getIdent(id)
|
||||
else:
|
||||
GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
|
||||
type
|
||||
TOverloadIterMode* = enum
|
||||
oimDone, oimNoQualifier, oimSelfModule, oimOtherModule, oimSymChoice,
|
||||
|
|
@ -87,13 +105,15 @@ proc addInterfaceOverloadableSymAt*(c: PContext, sym: PSym, at: int) =
|
|||
proc lookUp*(c: PContext, n: PNode): PSym =
|
||||
# Looks up a symbol. Generates an error in case of nil.
|
||||
case n.kind
|
||||
of nkAccQuoted:
|
||||
result = lookup(c, n.sons[0])
|
||||
of nkSym:
|
||||
result = n.sym
|
||||
of nkIdent:
|
||||
of nkIdent:
|
||||
result = SymtabGet(c.Tab, n.ident)
|
||||
if result == nil: GlobalError(n.info, errUndeclaredIdentifier, n.ident.s)
|
||||
of nkSym:
|
||||
result = n.sym
|
||||
of nkAccQuoted:
|
||||
var ident = considerAcc(n)
|
||||
result = SymtabGet(c.Tab, ident)
|
||||
if result == nil: GlobalError(n.info, errUndeclaredIdentifier, ident.s)
|
||||
else: InternalError(n.info, "lookUp")
|
||||
if IntSetContains(c.AmbiguousSymbols, result.id):
|
||||
LocalError(n.info, errUseQualifier, result.name.s)
|
||||
|
|
@ -102,16 +122,17 @@ proc lookUp*(c: PContext, n: PNode): PSym =
|
|||
type
|
||||
TLookupFlag* = enum
|
||||
checkAmbiguity, checkUndeclared
|
||||
|
||||
|
||||
proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
|
||||
case n.kind
|
||||
of nkIdent:
|
||||
result = SymtabGet(c.Tab, n.ident)
|
||||
of nkIdent, nkAccQuoted:
|
||||
var ident = considerAcc(n)
|
||||
result = SymtabGet(c.Tab, ident)
|
||||
if result == nil and checkUndeclared in flags:
|
||||
GlobalError(n.info, errUndeclaredIdentifier, n.ident.s)
|
||||
GlobalError(n.info, errUndeclaredIdentifier, ident.s)
|
||||
elif checkAmbiguity in flags and result != nil and
|
||||
IntSetContains(c.AmbiguousSymbols, result.id):
|
||||
LocalError(n.info, errUseQualifier, n.ident.s)
|
||||
LocalError(n.info, errUseQualifier, ident.s)
|
||||
of nkSym:
|
||||
result = n.sym
|
||||
if checkAmbiguity in flags and IntSetContains(c.AmbiguousSymbols,
|
||||
|
|
@ -122,11 +143,10 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
|
|||
var m = qualifiedLookUp(c, n.sons[0], flags*{checkUndeclared})
|
||||
if (m != nil) and (m.kind == skModule):
|
||||
var ident: PIdent = nil
|
||||
if (n.sons[1].kind == nkIdent):
|
||||
if n.sons[1].kind == nkIdent:
|
||||
ident = n.sons[1].ident
|
||||
elif (n.sons[1].kind == nkAccQuoted) and
|
||||
(n.sons[1].sons[0].kind == nkIdent):
|
||||
ident = n.sons[1].sons[0].ident
|
||||
elif n.sons[1].kind == nkAccQuoted:
|
||||
ident = considerAcc(n.sons[1])
|
||||
if ident != nil:
|
||||
if m == c.module:
|
||||
result = StrTableGet(c.tab.stack[ModuleTablePos], ident)
|
||||
|
|
@ -137,21 +157,20 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
|
|||
elif checkUndeclared in flags:
|
||||
GlobalError(n.sons[1].info, errIdentifierExpected,
|
||||
renderTree(n.sons[1]))
|
||||
of nkAccQuoted:
|
||||
result = QualifiedLookup(c, n.sons[0], flags)
|
||||
else:
|
||||
else:
|
||||
result = nil
|
||||
if (result != nil) and (result.kind == skStub): loadStub(result)
|
||||
if result != nil and result.kind == skStub: loadStub(result)
|
||||
|
||||
proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
||||
case n.kind
|
||||
of nkIdent:
|
||||
of nkIdent, nkAccQuoted:
|
||||
var ident = considerAcc(n)
|
||||
o.stackPtr = c.tab.tos
|
||||
o.mode = oimNoQualifier
|
||||
while result == nil:
|
||||
while result == nil:
|
||||
dec(o.stackPtr)
|
||||
if o.stackPtr < 0: break
|
||||
result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], n.ident)
|
||||
if o.stackPtr < 0: break
|
||||
result = InitIdentIter(o.it, c.tab.stack[o.stackPtr], ident)
|
||||
of nkSym:
|
||||
result = n.sym
|
||||
o.mode = oimDone
|
||||
|
|
@ -162,9 +181,8 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
|||
var ident: PIdent = nil
|
||||
if n.sons[1].kind == nkIdent:
|
||||
ident = n.sons[1].ident
|
||||
elif n.sons[1].kind == nkAccQuoted and
|
||||
n.sons[1].sons[0].kind == nkIdent:
|
||||
ident = n.sons[1].sons[0].ident
|
||||
elif n.sons[1].kind == nkAccQuoted:
|
||||
ident = considerAcc(n.sons[1])
|
||||
if ident != nil:
|
||||
if o.m == c.module:
|
||||
# a module may access its private members:
|
||||
|
|
@ -175,8 +193,6 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
|||
else:
|
||||
GlobalError(n.sons[1].info, errIdentifierExpected,
|
||||
renderTree(n.sons[1]))
|
||||
of nkAccQuoted:
|
||||
result = InitOverloadIter(o, c, n.sons[0])
|
||||
of nkSymChoice:
|
||||
o.mode = oimSymChoice
|
||||
result = n.sons[0].sym
|
||||
|
|
@ -191,9 +207,7 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
|
|||
of oimDone:
|
||||
result = nil
|
||||
of oimNoQualifier:
|
||||
if n.kind == nkAccQuoted:
|
||||
result = nextOverloadIter(o, c, n.sons[0])
|
||||
elif o.stackPtr >= 0:
|
||||
if o.stackPtr >= 0:
|
||||
result = nextIdentIter(o.it, c.tab.stack[o.stackPtr])
|
||||
while result == nil:
|
||||
dec(o.stackPtr)
|
||||
|
|
|
|||
|
|
@ -73,33 +73,11 @@ Files: "lib/wrappers/x11/*.nim"
|
|||
Files: "lib/wrappers/zip/*.nim"
|
||||
Files: "lib/wrappers/zip/libzip_all.c"
|
||||
|
||||
Files: "lib/oldwrappers/*.nim"
|
||||
|
||||
Files: "lib/oldwrappers/cairo/*.nim"
|
||||
Files: "lib/oldwrappers/gtk/*.nim"
|
||||
Files: "lib/oldwrappers/lua/*.nim"
|
||||
Files: "lib/oldwrappers/opengl/*.nim"
|
||||
Files: "lib/oldwrappers/pcre/*.nim"
|
||||
Files: "lib/oldwrappers/pcre/pcre_all.c"
|
||||
Files: "lib/oldwrappers/sdl/*.nim"
|
||||
Files: "lib/oldwrappers/x11/*.nim"
|
||||
Files: "lib/oldwrappers/zip/*.nim"
|
||||
Files: "lib/oldwrappers/zip/libzip_all.c"
|
||||
|
||||
Files: "lib/windows/*.nim"
|
||||
Files: "lib/posix/*.nim"
|
||||
Files: "lib/ecmas/*.nim"
|
||||
|
||||
[Other]
|
||||
Files: "tests/*.nim"
|
||||
Files: "tests/*.html"
|
||||
Files: "tests/*.txt"
|
||||
Files: "tests/*.cfg"
|
||||
Files: "tests/*.tmpl"
|
||||
Files: "tests/accept/run/*.nim"
|
||||
Files: "tests/accept/compile/*.nim"
|
||||
Files: "tests/reject/*.nim"
|
||||
|
||||
Files: "examples/*.nim"
|
||||
Files: "examples/*.html"
|
||||
Files: "examples/*.txt"
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ proc optInd*(p: var TParser, n: PNode)
|
|||
proc indAndComment*(p: var TParser, n: PNode)
|
||||
proc setBaseFlags*(n: PNode, base: TNumericalBase)
|
||||
proc parseSymbol*(p: var TParser): PNode
|
||||
proc accExpr*(p: var TParser): PNode
|
||||
# implementation
|
||||
|
||||
proc initParser(p: var TParser) =
|
||||
|
|
@ -173,60 +172,33 @@ proc parseSymbol(p: var TParser): PNode =
|
|||
of tkAccent:
|
||||
result = newNodeP(nkAccQuoted, p)
|
||||
getTok(p)
|
||||
var id = ""
|
||||
while true:
|
||||
case p.tok.tokType
|
||||
of tkBracketLe:
|
||||
id.add("[]")
|
||||
add(result, newIdentNodeP(getIdent"[]", p))
|
||||
getTok(p)
|
||||
eat(p, tkBracketRi)
|
||||
of tkEquals:
|
||||
id.add('=')
|
||||
add(result, newIdentNodeP(getIdent"=", p))
|
||||
getTok(p)
|
||||
of tkParLe:
|
||||
id.add("()")
|
||||
of tkParLe:
|
||||
add(result, newIdentNodeP(getIdent"()", p))
|
||||
getTok(p)
|
||||
eat(p, tkParRi)
|
||||
of tokKeywordLow..tokKeywordHigh, tkSymbol, tkOpr, tkDotDot:
|
||||
id.add(p.tok.ident.s)
|
||||
add(result, newIdentNodeP(p.tok.ident, p))
|
||||
getTok(p)
|
||||
of tkIntLit..tkCharLit:
|
||||
id.add(tokToStr(p.tok))
|
||||
add(result, newIdentNodeP(getIdent(tokToStr(p.tok)), p))
|
||||
getTok(p)
|
||||
else:
|
||||
if id.len == 0: parMessage(p, errIdentifierExpected, tokToStr(p.tok))
|
||||
if result.len == 0: parMessage(p, errIdentifierExpected, tokToStr(p.tok))
|
||||
break
|
||||
add(result, newIdentNodeP(getIdent(id), p))
|
||||
eat(p, tkAccent)
|
||||
else:
|
||||
parMessage(p, errIdentifierExpected, tokToStr(p.tok))
|
||||
result = ast.emptyNode
|
||||
|
||||
proc accExpr(p: var TParser): PNode =
|
||||
result = newNodeP(nkAccQuoted, p)
|
||||
getTok(p) # skip `
|
||||
var x = ast.emptyNode
|
||||
var y = ast.emptyNode
|
||||
case p.tok.tokType
|
||||
of tkSymbol, tkOpr, tokKeywordLow..tokKeywordHigh:
|
||||
x = newIdentNodeP(p.tok.ident, p)
|
||||
getTok(p)
|
||||
else:
|
||||
parMessage(p, errIdentifierExpected, tokToStr(p.tok))
|
||||
if p.tok.tokType == tkDot:
|
||||
getTok(p)
|
||||
case p.tok.tokType
|
||||
of tkSymbol, tkOpr, tokKeywordLow..tokKeywordHigh:
|
||||
y = newNodeP(nkDotExpr, p)
|
||||
addSon(y, x)
|
||||
addSon(y, newIdentNodeP(p.tok.ident, p))
|
||||
getTok(p)
|
||||
x = y
|
||||
else:
|
||||
parMessage(p, errIdentifierExpected, tokToStr(p.tok))
|
||||
addSon(result, x)
|
||||
eat(p, tkAccent)
|
||||
|
||||
proc indexExpr(p: var TParser): PNode =
|
||||
result = parseExpr(p)
|
||||
|
||||
|
|
@ -379,7 +351,7 @@ proc identOrLiteral(p: var TParser): PNode =
|
|||
getTok(p)
|
||||
result = parseGStrLit(p, result)
|
||||
of tkAccent:
|
||||
result = accExpr(p) # literals
|
||||
result = parseSymbol(p) # literals
|
||||
of tkIntLit:
|
||||
result = newIntNodeP(nkIntLit, p.tok.iNumber, p)
|
||||
setBaseFlags(result, p.tok.base)
|
||||
|
|
|
|||
|
|
@ -369,7 +369,7 @@ proc lsub(n: PNode): int =
|
|||
of nkPragmaExpr: result = lsub(n.sons[0]) + lcomma(n, 1)
|
||||
of nkRange: result = lsons(n) + 2
|
||||
of nkDerefExpr: result = lsub(n.sons[0]) + 2
|
||||
of nkAccQuoted: result = lsub(n.sons[0]) + 2
|
||||
of nkAccQuoted: result = lsons(n) + 2
|
||||
of nkIfExpr:
|
||||
result = lsub(n.sons[0].sons[0]) + lsub(n.sons[0].sons[1]) + lsons(n, 1) +
|
||||
len("if_:_")
|
||||
|
|
@ -823,9 +823,12 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
|||
gsub(g, n.sons[0])
|
||||
putWithSpace(g, tkHat, "^")
|
||||
# unfortunately this requires a space, because ^. would be only one operator
|
||||
of nkAccQuoted:
|
||||
of nkAccQuoted:
|
||||
put(g, tkAccent, "`")
|
||||
gsub(g, n.sons[0])
|
||||
if n.len > 0: gsub(g, n.sons[0])
|
||||
for i in 0 .. <n.len:
|
||||
put(g, tkSpaces, Space)
|
||||
gsub(g, n.sons[i])
|
||||
put(g, tkAccent, "`")
|
||||
of nkIfExpr:
|
||||
putWithSpace(g, tkIf, "if")
|
||||
|
|
|
|||
|
|
@ -18,16 +18,6 @@ import
|
|||
proc semPass*(): TPass
|
||||
# implementation
|
||||
|
||||
proc considerAcc(n: PNode): PIdent =
|
||||
var x = n
|
||||
if x.kind == nkAccQuoted: x = x.sons[0]
|
||||
case x.kind
|
||||
of nkIdent: result = x.ident
|
||||
of nkSym: result = x.sym.name
|
||||
else:
|
||||
GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
result = nil
|
||||
|
||||
proc isTopLevel(c: PContext): bool {.inline.} =
|
||||
result = c.tab.tos <= 2
|
||||
|
||||
|
|
@ -35,7 +25,8 @@ proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
|
|||
result = newSym(kind, considerAcc(n), getCurrOwner())
|
||||
result.info = n.info
|
||||
|
||||
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym
|
||||
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
||||
allowed: TSymFlags): PSym
|
||||
# identifier with visability
|
||||
proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
|
||||
allowed: TSymFlags): PSym
|
||||
|
|
@ -120,20 +111,13 @@ proc typeMismatch(n: PNode, formal, actual: PType) =
|
|||
|
||||
proc fitNode(c: PContext, formal: PType, arg: PNode): PNode =
|
||||
result = IndexTypesMatch(c, formal, arg.typ, arg)
|
||||
if result == nil:
|
||||
if result == nil:
|
||||
#debug(arg)
|
||||
typeMismatch(arg, formal, arg.typ)
|
||||
|
||||
proc forceBool(c: PContext, n: PNode): PNode =
|
||||
result = fitNode(c, getSysType(tyBool), n)
|
||||
if result == nil: result = n
|
||||
when false:
|
||||
result = t
|
||||
if (t.Typ == nil) or
|
||||
(skipTypes(t.Typ, {tyGenericInst, tyVar, tyOrdinal}).kind != tyBool):
|
||||
var a = ConvertTo(c, getSysType(tyBool), t)
|
||||
if a != nil: result = a
|
||||
else: LocalError(t.Info, errExprMustBeBool)
|
||||
|
||||
proc semConstBoolExpr(c: PContext, n: PNode): PNode =
|
||||
result = fitNode(c, getSysType(tyBool), semExprWithType(c, n))
|
||||
|
|
|
|||
|
|
@ -501,14 +501,17 @@ proc semEcho(c: PContext, n: PNode): PNode =
|
|||
n.sons[i] = semExpr(c, buildStringify(c, arg))
|
||||
result = n
|
||||
|
||||
proc lookUpForDefined(c: PContext, i: PIdent, onlyCurrentScope: bool): PSym =
|
||||
if onlyCurrentScope:
|
||||
result = SymtabLocalGet(c.tab, i)
|
||||
else:
|
||||
result = SymtabGet(c.Tab, i) # no need for stub loading
|
||||
|
||||
proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym =
|
||||
case n.kind
|
||||
of nkIdent:
|
||||
if onlyCurrentScope:
|
||||
result = SymtabLocalGet(c.tab, n.ident)
|
||||
else:
|
||||
result = SymtabGet(c.Tab, n.ident) # no need for stub loading
|
||||
of nkDotExpr:
|
||||
result = LookupForDefined(c, n.ident, onlyCurrentScope)
|
||||
of nkDotExpr:
|
||||
result = nil
|
||||
if onlyCurrentScope: return
|
||||
checkSonsLen(n, 2)
|
||||
|
|
@ -522,9 +525,8 @@ proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym =
|
|||
result = StrTableGet(m.tab, ident)
|
||||
else:
|
||||
GlobalError(n.sons[1].info, errIdentifierExpected, "")
|
||||
of nkAccQuoted:
|
||||
checkSonsLen(n, 1)
|
||||
result = lookupForDefined(c, n.sons[0], onlyCurrentScope)
|
||||
of nkAccQuoted:
|
||||
result = lookupForDefined(c, considerAcc(n), onlyCurrentScope)
|
||||
else:
|
||||
GlobalError(n.info, errIdentifierExpected, renderTree(n))
|
||||
result = nil
|
||||
|
|
@ -955,17 +957,16 @@ proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode =
|
|||
else:
|
||||
GlobalError(n.info, errInvalidExpressionX,
|
||||
renderTree(a, {renderNoComments}))
|
||||
|
||||
|
||||
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
result = n
|
||||
if gCmd == cmdIdeTools:
|
||||
suggestExpr(c, n)
|
||||
if gCmd == cmdIdeTools: suggestExpr(c, n)
|
||||
if nfSem in n.flags: return
|
||||
case n.kind # atoms:
|
||||
of nkIdent:
|
||||
case n.kind
|
||||
of nkIdent, nkAccQuoted:
|
||||
var s = lookUp(c, n)
|
||||
result = semSym(c, n, s, flags)
|
||||
of nkSym:
|
||||
of nkSym:
|
||||
# because of the changed symbol binding, this does not mean that we
|
||||
# don't have to check the symbol for semantics here again!
|
||||
result = semSym(c, n, n.sym, flags)
|
||||
|
|
@ -1062,9 +1063,6 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
|||
checkSonsLen(n, 1)
|
||||
n.sons[0] = semExpr(c, n.sons[0], flags)
|
||||
of nkCast: result = semCast(c, n)
|
||||
of nkAccQuoted:
|
||||
checkSonsLen(n, 1)
|
||||
result = semExpr(c, n.sons[0])
|
||||
of nkIfExpr: result = semIfExpr(c, n)
|
||||
of nkStmtListExpr: result = semStmtListExpr(c, n)
|
||||
of nkBlockExpr: result = semBlockExpr(c, n)
|
||||
|
|
|
|||
|
|
@ -53,17 +53,12 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode =
|
|||
proc getIdentNode(n: PNode): PNode =
|
||||
case n.kind
|
||||
of nkPostfix: result = getIdentNode(n.sons[1])
|
||||
of nkPragmaExpr, nkAccQuoted: result = getIdentNode(n.sons[0])
|
||||
of nkIdent: result = n
|
||||
of nkPragmaExpr: result = getIdentNode(n.sons[0])
|
||||
of nkIdent, nkAccQuoted: result = n
|
||||
else:
|
||||
illFormedAst(n)
|
||||
result = n
|
||||
|
||||
# of nkAccQuoted:
|
||||
# s = lookUp(c, n)
|
||||
# if withinBind in flags: result = symChoice(c, n, s)
|
||||
# else: result = semGenericStmtSymbol(c, n, s)
|
||||
|
||||
proc semGenericStmt(c: PContext, n: PNode,
|
||||
flags: TSemGenericFlags = {}): PNode =
|
||||
result = n
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ proc semWhile(c: PContext, n: PNode): PNode =
|
|||
|
||||
proc toCover(t: PType): biggestInt =
|
||||
var t2 = skipTypes(t, abstractVarRange)
|
||||
if t2.kind == tyEnum and enumHasWholes(t2):
|
||||
if t2.kind == tyEnum and enumHasHoles(t2):
|
||||
result = sonsLen(t2.n)
|
||||
else:
|
||||
result = lengthOrd(skipTypes(t, abstractVar))
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
|||
else:
|
||||
x = getOrdValue(v)
|
||||
if i != 1:
|
||||
if (x != counter): incl(result.flags, tfEnumHasWholes)
|
||||
if (x != counter): incl(result.flags, tfEnumHasHoles)
|
||||
if x < counter:
|
||||
GlobalError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s)
|
||||
e.ast = strVal # might be nil
|
||||
|
|
@ -128,7 +128,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
|||
if not (a.typ.kind in
|
||||
{tyInt..tyInt64, tyEnum, tyBool, tyChar, tyFloat..tyFloat128}):
|
||||
GlobalError(n.info, errOrdinalTypeExpected)
|
||||
if enumHasWholes(a.typ):
|
||||
if enumHasHoles(a.typ):
|
||||
GlobalError(n.info, errEnumXHasHoles, a.typ.sym.name.s)
|
||||
if not leValue(a, b): GlobalError(n.Info, errRangeIsEmpty)
|
||||
addSon(result.n, a)
|
||||
|
|
@ -155,7 +155,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
|||
if indx.kind != tyGenericParam:
|
||||
if not isOrdinalType(indx):
|
||||
GlobalError(n.sons[1].info, errOrdinalTypeExpected)
|
||||
if enumHasWholes(indx):
|
||||
if enumHasHoles(indx):
|
||||
GlobalError(n.sons[1].info, errEnumXHasHoles, indx.sym.name.s)
|
||||
base = semTypeNode(c, n.sons[2], nil)
|
||||
addSon(result, base)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ type
|
|||
proc equalParams*(a, b: PNode): TParamsEquality
|
||||
# returns whether the parameter lists of the procs a, b are exactly the same
|
||||
proc isOrdinalType*(t: PType): bool
|
||||
proc enumHasWholes*(t: PType): bool
|
||||
proc enumHasHoles*(t: PType): bool
|
||||
const
|
||||
abstractPtrs* = {tyVar, tyPtr, tyRef, tyGenericInst, tyDistinct, tyOrdinal}
|
||||
abstractVar* = {tyVar, tyGenericInst, tyDistinct, tyOrdinal}
|
||||
|
|
@ -193,10 +193,10 @@ proc isOrdinalType(t: PType): bool =
|
|||
result = (t.Kind in {tyChar, tyInt..tyInt64, tyBool, tyEnum}) or
|
||||
(t.Kind in {tyRange, tyOrdinal}) and isOrdinalType(t.sons[0])
|
||||
|
||||
proc enumHasWholes(t: PType): bool =
|
||||
proc enumHasHoles(t: PType): bool =
|
||||
var b = t
|
||||
while b.kind == tyRange: b = b.sons[0]
|
||||
result = (b.Kind == tyEnum) and (tfEnumHasWholes in b.flags)
|
||||
result = b.Kind == tyEnum and tfEnumHasHoles in b.flags
|
||||
|
||||
proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter,
|
||||
closure: PObject): bool
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue