semfold.nim 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # this module folds constants; used by semantic checking phase
  10. # and evaluation phase
  11. import
  12. strutils, options, ast, trees, nimsets,
  13. platform, math, msgs, idents, renderer, types,
  14. commands, magicsys, modulegraphs, strtabs, lineinfos
  15. proc errorType*(g: ModuleGraph): PType =
  16. ## creates a type representing an error state
  17. result = newType(tyError, g.owners[^1])
  18. result.flags.incl tfCheckedForDestructor
  19. proc newIntNodeT*(intVal: Int128, n: PNode; g: ModuleGraph): PNode =
  20. result = newIntTypeNode(intVal, n.typ)
  21. # See bug #6989. 'pred' et al only produce an int literal type if the
  22. # original type was 'int', not a distinct int etc.
  23. if n.typ.kind == tyInt:
  24. # access cache for the int lit type
  25. result.typ = getIntLitType(g, result)
  26. result.info = n.info
  27. proc newFloatNodeT*(floatVal: BiggestFloat, n: PNode; g: ModuleGraph): PNode =
  28. if n.typ.skipTypes(abstractInst).kind == tyFloat32:
  29. result = newFloatNode(nkFloat32Lit, floatVal)
  30. else:
  31. result = newFloatNode(nkFloatLit, floatVal)
  32. result.typ = n.typ
  33. result.info = n.info
  34. proc newStrNodeT*(strVal: string, n: PNode; g: ModuleGraph): PNode =
  35. result = newStrNode(nkStrLit, strVal)
  36. result.typ = n.typ
  37. result.info = n.info
  38. proc getConstExpr*(m: PSym, n: PNode; g: ModuleGraph): PNode
  39. # evaluates the constant expression or returns nil if it is no constant
  40. # expression
  41. proc evalOp*(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode
  42. proc checkInRange(conf: ConfigRef; n: PNode, res: Int128): bool =
  43. res in firstOrd(conf, n.typ)..lastOrd(conf, n.typ)
  44. proc foldAdd(a, b: Int128, n: PNode; g: ModuleGraph): PNode =
  45. let res = a + b
  46. if checkInRange(g.config, n, res):
  47. result = newIntNodeT(res, n, g)
  48. proc foldSub(a, b: Int128, n: PNode; g: ModuleGraph): PNode =
  49. let res = a - b
  50. if checkInRange(g.config, n, res):
  51. result = newIntNodeT(res, n, g)
  52. proc foldUnarySub(a: Int128, n: PNode, g: ModuleGraph): PNode =
  53. if a != firstOrd(g.config, n.typ):
  54. result = newIntNodeT(-a, n, g)
  55. proc foldAbs(a: Int128, n: PNode; g: ModuleGraph): PNode =
  56. if a != firstOrd(g.config, n.typ):
  57. result = newIntNodeT(abs(a), n, g)
  58. proc foldMul(a, b: Int128, n: PNode; g: ModuleGraph): PNode =
  59. let res = a * b
  60. if checkInRange(g.config, n, res):
  61. return newIntNodeT(res, n, g)
  62. proc ordinalValToString*(a: PNode; g: ModuleGraph): string =
  63. # because $ has the param ordinal[T], `a` is not necessarily an enum, but an
  64. # ordinal
  65. var x = getInt(a)
  66. var t = skipTypes(a.typ, abstractRange)
  67. case t.kind
  68. of tyChar:
  69. result = $chr(toInt64(x) and 0xff)
  70. of tyEnum:
  71. var n = t.n
  72. for i in 0..<n.len:
  73. if n[i].kind != nkSym: internalError(g.config, a.info, "ordinalValToString")
  74. var field = n[i].sym
  75. if field.position == x:
  76. if field.ast == nil:
  77. return field.name.s
  78. else:
  79. return field.ast.strVal
  80. localError(g.config, a.info,
  81. "Cannot convert int literal to $1. The value is invalid." %
  82. [typeToString(t)])
  83. else:
  84. result = $x
  85. proc isFloatRange(t: PType): bool {.inline.} =
  86. result = t.kind == tyRange and t[0].kind in {tyFloat..tyFloat128}
  87. proc isIntRange(t: PType): bool {.inline.} =
  88. result = t.kind == tyRange and t[0].kind in {
  89. tyInt..tyInt64, tyUInt8..tyUInt32}
  90. proc pickIntRange(a, b: PType): PType =
  91. if isIntRange(a): result = a
  92. elif isIntRange(b): result = b
  93. else: result = a
  94. proc isIntRangeOrLit(t: PType): bool =
  95. result = isIntRange(t) or isIntLit(t)
  96. proc makeRange(typ: PType, first, last: BiggestInt; g: ModuleGraph): PType =
  97. let minA = min(first, last)
  98. let maxA = max(first, last)
  99. let lowerNode = newIntNode(nkIntLit, minA)
  100. if typ.kind == tyInt and minA == maxA:
  101. result = getIntLitType(g, lowerNode)
  102. elif typ.kind in {tyUInt, tyUInt64}:
  103. # these are not ordinal types, so you get no subrange type for these:
  104. result = typ
  105. else:
  106. var n = newNode(nkRange)
  107. n.add lowerNode
  108. n.add newIntNode(nkIntLit, maxA)
  109. result = newType(tyRange, typ.owner)
  110. result.n = n
  111. addSonSkipIntLit(result, skipTypes(typ, {tyRange}))
  112. proc makeRangeF(typ: PType, first, last: BiggestFloat; g: ModuleGraph): PType =
  113. var n = newNode(nkRange)
  114. n.add newFloatNode(nkFloatLit, min(first.float, last.float))
  115. n.add newFloatNode(nkFloatLit, max(first.float, last.float))
  116. result = newType(tyRange, typ.owner)
  117. result.n = n
  118. addSonSkipIntLit(result, skipTypes(typ, {tyRange}))
  119. proc fitLiteral(c: ConfigRef, n: PNode): PNode {.deprecated: "no substitute".} =
  120. # Trim the literal value in order to make it fit in the destination type
  121. if n == nil:
  122. # `n` may be nil if the overflow check kicks in
  123. return
  124. doAssert n.kind in {nkIntLit, nkCharLit}
  125. result = n
  126. let typ = n.typ.skipTypes(abstractRange)
  127. if typ.kind in tyUInt..tyUInt32:
  128. result.intVal = result.intVal and castToInt64(lastOrd(c, typ))
  129. proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
  130. # b and c may be nil
  131. result = nil
  132. case m
  133. of mOrd: result = newIntNodeT(getOrdValue(a), n, g)
  134. of mChr: result = newIntNodeT(getInt(a), n, g)
  135. of mUnaryMinusI, mUnaryMinusI64: result = foldUnarySub(getInt(a), n, g)
  136. of mUnaryMinusF64: result = newFloatNodeT(-getFloat(a), n, g)
  137. of mNot: result = newIntNodeT(One - getInt(a), n, g)
  138. of mCard: result = newIntNodeT(toInt128(nimsets.cardSet(g.config, a)), n, g)
  139. of mBitnotI:
  140. if n.typ.isUnsigned:
  141. result = newIntNodeT(bitnot(getInt(a)).maskBytes(int(n.typ.size)), n, g)
  142. else:
  143. result = newIntNodeT(bitnot(getInt(a)), n, g)
  144. of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, g)
  145. of mLengthSeq, mLengthOpenArray, mLengthStr:
  146. if a.kind == nkNilLit:
  147. result = newIntNodeT(Zero, n, g)
  148. elif a.kind in {nkStrLit..nkTripleStrLit}:
  149. result = newIntNodeT(toInt128(a.strVal.len), n, g)
  150. else:
  151. result = newIntNodeT(toInt128(a.len), n, g)
  152. of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
  153. # XXX: Hides overflow/underflow
  154. of mAbsI: result = foldAbs(getInt(a), n, g)
  155. of mSucc: result = foldAdd(getOrdValue(a), getInt(b), n, g)
  156. of mPred: result = foldSub(getOrdValue(a), getInt(b), n, g)
  157. of mAddI: result = foldAdd(getInt(a), getInt(b), n, g)
  158. of mSubI: result = foldSub(getInt(a), getInt(b), n, g)
  159. of mMulI: result = foldMul(getInt(a), getInt(b), n, g)
  160. of mMinI:
  161. let argA = getInt(a)
  162. let argB = getInt(b)
  163. result = newIntNodeT(if argA < argB: argA else: argB, n, g)
  164. of mMaxI:
  165. let argA = getInt(a)
  166. let argB = getInt(b)
  167. result = newIntNodeT(if argA > argB: argA else: argB, n, g)
  168. of mShlI:
  169. case skipTypes(n.typ, abstractRange).kind
  170. of tyInt8: result = newIntNodeT(toInt128(toInt8(getInt(a)) shl toInt64(getInt(b))), n, g)
  171. of tyInt16: result = newIntNodeT(toInt128(toInt16(getInt(a)) shl toInt64(getInt(b))), n, g)
  172. of tyInt32: result = newIntNodeT(toInt128(toInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
  173. of tyInt64: result = newIntNodeT(toInt128(toInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
  174. of tyInt:
  175. if g.config.target.intSize == 4:
  176. result = newIntNodeT(toInt128(toInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
  177. else:
  178. result = newIntNodeT(toInt128(toInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
  179. of tyUInt8: result = newIntNodeT(toInt128(toUInt8(getInt(a)) shl toInt64(getInt(b))), n, g)
  180. of tyUInt16: result = newIntNodeT(toInt128(toUInt16(getInt(a)) shl toInt64(getInt(b))), n, g)
  181. of tyUInt32: result = newIntNodeT(toInt128(toUInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
  182. of tyUInt64: result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
  183. of tyUInt:
  184. if g.config.target.intSize == 4:
  185. result = newIntNodeT(toInt128(toUInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
  186. else:
  187. result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
  188. else: internalError(g.config, n.info, "constant folding for shl")
  189. of mShrI:
  190. var a = cast[uint64](getInt(a))
  191. let b = cast[uint64](getInt(b))
  192. # To support the ``-d:nimOldShiftRight`` flag, we need to mask the
  193. # signed integers to cut off the extended sign bit in the internal
  194. # representation.
  195. if 0'u64 < b: # do not cut off the sign extension, when there is
  196. # no bit shifting happening.
  197. case skipTypes(n.typ, abstractRange).kind
  198. of tyInt8: a = a and 0xff'u64
  199. of tyInt16: a = a and 0xffff'u64
  200. of tyInt32: a = a and 0xffffffff'u64
  201. of tyInt:
  202. if g.config.target.intSize == 4:
  203. a = a and 0xffffffff'u64
  204. else:
  205. # unsigned and 64 bit integers don't need masking
  206. discard
  207. let c = cast[BiggestInt](a shr b)
  208. result = newIntNodeT(toInt128(c), n, g)
  209. of mAshrI:
  210. case skipTypes(n.typ, abstractRange).kind
  211. of tyInt8: result = newIntNodeT(toInt128(ashr(toInt8(getInt(a)), toInt8(getInt(b)))), n, g)
  212. of tyInt16: result = newIntNodeT(toInt128(ashr(toInt16(getInt(a)), toInt16(getInt(b)))), n, g)
  213. of tyInt32: result = newIntNodeT(toInt128(ashr(toInt32(getInt(a)), toInt32(getInt(b)))), n, g)
  214. of tyInt64, tyInt:
  215. result = newIntNodeT(toInt128(ashr(toInt64(getInt(a)), toInt64(getInt(b)))), n, g)
  216. else: internalError(g.config, n.info, "constant folding for ashr")
  217. of mDivI:
  218. let argA = getInt(a)
  219. let argB = getInt(b)
  220. if argB != Zero and (argA != firstOrd(g.config, n.typ) or argB != NegOne):
  221. result = newIntNodeT(argA div argB, n, g)
  222. of mModI:
  223. let argA = getInt(a)
  224. let argB = getInt(b)
  225. if argB != Zero and (argA != firstOrd(g.config, n.typ) or argB != NegOne):
  226. result = newIntNodeT(argA mod argB, n, g)
  227. of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n, g)
  228. of mSubF64: result = newFloatNodeT(getFloat(a) - getFloat(b), n, g)
  229. of mMulF64: result = newFloatNodeT(getFloat(a) * getFloat(b), n, g)
  230. of mDivF64:
  231. result = newFloatNodeT(getFloat(a) / getFloat(b), n, g)
  232. of mIsNil: result = newIntNodeT(toInt128(ord(a.kind == nkNilLit)), n, g)
  233. of mLtI, mLtB, mLtEnum, mLtCh:
  234. result = newIntNodeT(toInt128(ord(getOrdValue(a) < getOrdValue(b))), n, g)
  235. of mLeI, mLeB, mLeEnum, mLeCh:
  236. result = newIntNodeT(toInt128(ord(getOrdValue(a) <= getOrdValue(b))), n, g)
  237. of mEqI, mEqB, mEqEnum, mEqCh:
  238. result = newIntNodeT(toInt128(ord(getOrdValue(a) == getOrdValue(b))), n, g)
  239. of mLtF64: result = newIntNodeT(toInt128(ord(getFloat(a) < getFloat(b))), n, g)
  240. of mLeF64: result = newIntNodeT(toInt128(ord(getFloat(a) <= getFloat(b))), n, g)
  241. of mEqF64: result = newIntNodeT(toInt128(ord(getFloat(a) == getFloat(b))), n, g)
  242. of mLtStr: result = newIntNodeT(toInt128(ord(getStr(a) < getStr(b))), n, g)
  243. of mLeStr: result = newIntNodeT(toInt128(ord(getStr(a) <= getStr(b))), n, g)
  244. of mEqStr: result = newIntNodeT(toInt128(ord(getStr(a) == getStr(b))), n, g)
  245. of mLtU:
  246. result = newIntNodeT(toInt128(ord(`<%`(toInt64(getOrdValue(a)), toInt64(getOrdValue(b))))), n, g)
  247. of mLeU:
  248. result = newIntNodeT(toInt128(ord(`<=%`(toInt64(getOrdValue(a)), toInt64(getOrdValue(b))))), n, g)
  249. of mBitandI, mAnd: result = newIntNodeT(bitand(a.getInt, b.getInt), n, g)
  250. of mBitorI, mOr: result = newIntNodeT(bitor(getInt(a), getInt(b)), n, g)
  251. of mBitxorI, mXor: result = newIntNodeT(bitxor(getInt(a), getInt(b)), n, g)
  252. of mAddU:
  253. let val = maskBytes(getInt(a) + getInt(b), int(n.typ.size))
  254. result = newIntNodeT(val, n, g)
  255. of mSubU:
  256. let val = maskBytes(getInt(a) - getInt(b), int(n.typ.size))
  257. result = newIntNodeT(val, n, g)
  258. # echo "subU: ", val, " n: ", n, " result: ", val
  259. of mMulU:
  260. let val = maskBytes(getInt(a) * getInt(b), int(n.typ.size))
  261. result = newIntNodeT(val, n, g)
  262. of mModU:
  263. let argA = maskBytes(getInt(a), int(a.typ.size))
  264. let argB = maskBytes(getInt(b), int(a.typ.size))
  265. if argB != Zero:
  266. result = newIntNodeT(argA mod argB, n, g)
  267. of mDivU:
  268. let argA = maskBytes(getInt(a), int(a.typ.size))
  269. let argB = maskBytes(getInt(b), int(a.typ.size))
  270. if argB != Zero:
  271. result = newIntNodeT(argA div argB, n, g)
  272. of mLeSet: result = newIntNodeT(toInt128(ord(containsSets(g.config, a, b))), n, g)
  273. of mEqSet: result = newIntNodeT(toInt128(ord(equalSets(g.config, a, b))), n, g)
  274. of mLtSet:
  275. result = newIntNodeT(toInt128(ord(
  276. containsSets(g.config, a, b) and not equalSets(g.config, a, b))), n, g)
  277. of mMulSet:
  278. result = nimsets.intersectSets(g.config, a, b)
  279. result.info = n.info
  280. of mPlusSet:
  281. result = nimsets.unionSets(g.config, a, b)
  282. result.info = n.info
  283. of mMinusSet:
  284. result = nimsets.diffSets(g.config, a, b)
  285. result.info = n.info
  286. of mConStrStr: result = newStrNodeT(getStrOrChar(a) & getStrOrChar(b), n, g)
  287. of mInSet: result = newIntNodeT(toInt128(ord(inSet(a, b))), n, g)
  288. of mRepr:
  289. # BUGFIX: we cannot eval mRepr here for reasons that I forgot.
  290. discard
  291. of mIntToStr, mInt64ToStr: result = newStrNodeT($(getOrdValue(a)), n, g)
  292. of mBoolToStr:
  293. if getOrdValue(a) == 0: result = newStrNodeT("false", n, g)
  294. else: result = newStrNodeT("true", n, g)
  295. of mFloatToStr: result = newStrNodeT($getFloat(a), n, g)
  296. of mCStrToStr, mCharToStr:
  297. if a.kind == nkBracket:
  298. var s = ""
  299. for b in a.sons:
  300. s.add b.getStrOrChar
  301. result = newStrNodeT(s, n, g)
  302. else:
  303. result = newStrNodeT(getStrOrChar(a), n, g)
  304. of mStrToStr: result = newStrNodeT(getStrOrChar(a), n, g)
  305. of mEnumToStr: result = newStrNodeT(ordinalValToString(a, g), n, g)
  306. of mArrToSeq:
  307. result = copyTree(a)
  308. result.typ = n.typ
  309. of mCompileOption:
  310. result = newIntNodeT(toInt128(ord(commands.testCompileOption(g.config, a.getStr, n.info))), n, g)
  311. of mCompileOptionArg:
  312. result = newIntNodeT(toInt128(ord(
  313. testCompileOptionArg(g.config, getStr(a), getStr(b), n.info))), n, g)
  314. of mEqProc:
  315. result = newIntNodeT(toInt128(ord(
  316. exprStructuralEquivalent(a, b, strictSymEquality=true))), n, g)
  317. else: discard
  318. proc getConstIfExpr(c: PSym, n: PNode; g: ModuleGraph): PNode =
  319. result = nil
  320. for i in 0..<n.len:
  321. var it = n[i]
  322. if it.len == 2:
  323. var e = getConstExpr(c, it[0], g)
  324. if e == nil: return nil
  325. if getOrdValue(e) != 0:
  326. if result == nil:
  327. result = getConstExpr(c, it[1], g)
  328. if result == nil: return
  329. elif it.len == 1:
  330. if result == nil: result = getConstExpr(c, it[0], g)
  331. else: internalError(g.config, it.info, "getConstIfExpr()")
  332. proc leValueConv*(a, b: PNode): bool =
  333. result = false
  334. case a.kind
  335. of nkCharLit..nkUInt64Lit:
  336. case b.kind
  337. of nkCharLit..nkUInt64Lit: result = a.getInt <= b.getInt
  338. of nkFloatLit..nkFloat128Lit: result = a.intVal <= round(b.floatVal).int
  339. else: result = false #internalError(a.info, "leValueConv")
  340. of nkFloatLit..nkFloat128Lit:
  341. case b.kind
  342. of nkFloatLit..nkFloat128Lit: result = a.floatVal <= b.floatVal
  343. of nkCharLit..nkUInt64Lit: result = a.floatVal <= toFloat64(b.getInt)
  344. else: result = false # internalError(a.info, "leValueConv")
  345. else: result = false # internalError(a.info, "leValueConv")
  346. proc magicCall(m: PSym, n: PNode; g: ModuleGraph): PNode =
  347. if n.len <= 1: return
  348. var s = n[0].sym
  349. var a = getConstExpr(m, n[1], g)
  350. var b, c: PNode
  351. if a == nil: return
  352. if n.len > 2:
  353. b = getConstExpr(m, n[2], g)
  354. if b == nil: return
  355. if n.len > 3:
  356. c = getConstExpr(m, n[3], g)
  357. if c == nil: return
  358. result = evalOp(s.magic, n, a, b, c, g)
  359. proc getAppType(n: PNode; g: ModuleGraph): PNode =
  360. if g.config.globalOptions.contains(optGenDynLib):
  361. result = newStrNodeT("lib", n, g)
  362. elif g.config.globalOptions.contains(optGenStaticLib):
  363. result = newStrNodeT("staticlib", n, g)
  364. elif g.config.globalOptions.contains(optGenGuiApp):
  365. result = newStrNodeT("gui", n, g)
  366. else:
  367. result = newStrNodeT("console", n, g)
  368. proc rangeCheck(n: PNode, value: Int128; g: ModuleGraph) =
  369. if value < firstOrd(g.config, n.typ) or value > lastOrd(g.config, n.typ):
  370. localError(g.config, n.info, "cannot convert " & $value &
  371. " to " & typeToString(n.typ))
  372. proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
  373. let dstTyp = skipTypes(n.typ, abstractRange - {tyTypeDesc})
  374. let srcTyp = skipTypes(a.typ, abstractRange - {tyTypeDesc})
  375. # if srcTyp.kind == tyUInt64 and "FFFFFF" in $n:
  376. # echo "n: ", n, " a: ", a
  377. # echo "from: ", srcTyp, " to: ", dstTyp, " check: ", check
  378. # echo getInt(a)
  379. # echo high(int64)
  380. # writeStackTrace()
  381. case dstTyp.kind
  382. of tyBool:
  383. case srcTyp.kind
  384. of tyFloat..tyFloat64:
  385. result = newIntNodeT(toInt128(getFloat(a) != 0.0), n, g)
  386. of tyChar, tyUInt..tyUInt64, tyInt..tyInt64:
  387. result = newIntNodeT(toInt128(a.getOrdValue != 0), n, g)
  388. of tyBool, tyEnum: # xxx shouldn't we disallow `tyEnum`?
  389. result = a
  390. result.typ = n.typ
  391. else: doAssert false, $srcTyp.kind
  392. of tyInt..tyInt64, tyUInt..tyUInt64:
  393. case srcTyp.kind
  394. of tyFloat..tyFloat64:
  395. result = newIntNodeT(toInt128(getFloat(a)), n, g)
  396. of tyChar, tyUInt..tyUInt64, tyInt..tyInt64:
  397. var val = a.getOrdValue
  398. if check: rangeCheck(n, val, g)
  399. result = newIntNodeT(val, n, g)
  400. if dstTyp.kind in {tyUInt..tyUInt64}:
  401. result.transitionIntKind(nkUIntLit)
  402. else:
  403. result = a
  404. result.typ = n.typ
  405. if check and result.kind in {nkCharLit..nkUInt64Lit}:
  406. rangeCheck(n, getInt(result), g)
  407. of tyFloat..tyFloat64:
  408. case srcTyp.kind
  409. of tyInt..tyInt64, tyEnum, tyBool, tyChar:
  410. result = newFloatNodeT(toFloat64(getOrdValue(a)), n, g)
  411. else:
  412. result = a
  413. result.typ = n.typ
  414. of tyOpenArray, tyVarargs, tyProc, tyPointer:
  415. discard
  416. else:
  417. result = a
  418. result.typ = n.typ
  419. proc getArrayConstr(m: PSym, n: PNode; g: ModuleGraph): PNode =
  420. if n.kind == nkBracket:
  421. result = n
  422. else:
  423. result = getConstExpr(m, n, g)
  424. if result == nil: result = n
  425. proc foldArrayAccess(m: PSym, n: PNode; g: ModuleGraph): PNode =
  426. var x = getConstExpr(m, n[0], g)
  427. if x == nil or x.typ.skipTypes({tyGenericInst, tyAlias, tySink}).kind == tyTypeDesc:
  428. return
  429. var y = getConstExpr(m, n[1], g)
  430. if y == nil: return
  431. var idx = toInt64(getOrdValue(y))
  432. case x.kind
  433. of nkPar, nkTupleConstr:
  434. if idx >= 0 and idx < x.len:
  435. result = x.sons[idx]
  436. if result.kind == nkExprColonExpr: result = result[1]
  437. else:
  438. localError(g.config, n.info, formatErrorIndexBound(idx, x.len-1) & $n)
  439. of nkBracket:
  440. idx -= toInt64(firstOrd(g.config, x.typ))
  441. if idx >= 0 and idx < x.len: result = x[int(idx)]
  442. else: localError(g.config, n.info, formatErrorIndexBound(idx, x.len-1) & $n)
  443. of nkStrLit..nkTripleStrLit:
  444. result = newNodeIT(nkCharLit, x.info, n.typ)
  445. if idx >= 0 and idx < x.strVal.len:
  446. result.intVal = ord(x.strVal[int(idx)])
  447. else:
  448. localError(g.config, n.info, formatErrorIndexBound(idx, x.strVal.len-1) & $n)
  449. else: discard
  450. proc foldFieldAccess(m: PSym, n: PNode; g: ModuleGraph): PNode =
  451. # a real field access; proc calls have already been transformed
  452. var x = getConstExpr(m, n[0], g)
  453. if x == nil or x.kind notin {nkObjConstr, nkPar, nkTupleConstr}: return
  454. var field = n[1].sym
  455. for i in ord(x.kind == nkObjConstr)..<x.len:
  456. var it = x[i]
  457. if it.kind != nkExprColonExpr:
  458. # lookup per index:
  459. result = x[field.position]
  460. if result.kind == nkExprColonExpr: result = result[1]
  461. return
  462. if it[0].sym.name.id == field.name.id:
  463. result = x[i][1]
  464. return
  465. localError(g.config, n.info, "field not found: " & field.name.s)
  466. proc foldConStrStr(m: PSym, n: PNode; g: ModuleGraph): PNode =
  467. result = newNodeIT(nkStrLit, n.info, n.typ)
  468. result.strVal = ""
  469. for i in 1..<n.len:
  470. let a = getConstExpr(m, n[i], g)
  471. if a == nil: return nil
  472. result.strVal.add(getStrOrChar(a))
  473. proc newSymNodeTypeDesc*(s: PSym; info: TLineInfo): PNode =
  474. result = newSymNode(s, info)
  475. if s.typ.kind != tyTypeDesc:
  476. result.typ = newType(tyTypeDesc, s.owner)
  477. result.typ.addSonSkipIntLit(s.typ)
  478. else:
  479. result.typ = s.typ
  480. proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
  481. result = nil
  482. case n.kind
  483. of nkSym:
  484. var s = n.sym
  485. case s.kind
  486. of skEnumField:
  487. result = newIntNodeT(toInt128(s.position), n, g)
  488. of skConst:
  489. case s.magic
  490. of mIsMainModule: result = newIntNodeT(toInt128(ord(sfMainModule in m.flags)), n, g)
  491. of mCompileDate: result = newStrNodeT(getDateStr(), n, g)
  492. of mCompileTime: result = newStrNodeT(getClockStr(), n, g)
  493. of mCpuEndian: result = newIntNodeT(toInt128(ord(CPU[g.config.target.targetCPU].endian)), n, g)
  494. of mHostOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.targetOS].name), n, g)
  495. of mHostCPU: result = newStrNodeT(platform.CPU[g.config.target.targetCPU].name.toLowerAscii, n, g)
  496. of mBuildOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.hostOS].name), n, g)
  497. of mBuildCPU: result = newStrNodeT(platform.CPU[g.config.target.hostCPU].name.toLowerAscii, n, g)
  498. of mAppType: result = getAppType(n, g)
  499. of mIntDefine:
  500. if isDefined(g.config, s.name.s):
  501. try:
  502. result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseInt), n, g)
  503. except ValueError:
  504. localError(g.config, s.info,
  505. "{.intdefine.} const was set to an invalid integer: '" &
  506. g.config.symbols[s.name.s] & "'")
  507. else:
  508. result = copyTree(s.ast)
  509. of mStrDefine:
  510. if isDefined(g.config, s.name.s):
  511. result = newStrNodeT(g.config.symbols[s.name.s], n, g)
  512. else:
  513. result = copyTree(s.ast)
  514. of mBoolDefine:
  515. if isDefined(g.config, s.name.s):
  516. try:
  517. result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseBool.int), n, g)
  518. except ValueError:
  519. localError(g.config, s.info,
  520. "{.booldefine.} const was set to an invalid bool: '" &
  521. g.config.symbols[s.name.s] & "'")
  522. else:
  523. result = copyTree(s.ast)
  524. else:
  525. result = copyTree(s.ast)
  526. of skProc, skFunc, skMethod:
  527. result = n
  528. of skParam:
  529. if s.typ != nil and s.typ.kind == tyTypeDesc:
  530. result = newSymNodeTypeDesc(s, n.info)
  531. of skType:
  532. # XXX gensym'ed symbols can come here and cannot be resolved. This is
  533. # dirty, but correct.
  534. if s.typ != nil:
  535. result = newSymNodeTypeDesc(s, n.info)
  536. of skGenericParam:
  537. if s.typ.kind == tyStatic:
  538. if s.typ.n != nil and tfUnresolved notin s.typ.flags:
  539. result = s.typ.n
  540. result.typ = s.typ.base
  541. elif s.typ.isIntLit:
  542. result = s.typ.n
  543. else:
  544. result = newSymNodeTypeDesc(s, n.info)
  545. else: discard
  546. of nkCharLit..nkNilLit:
  547. result = copyNode(n)
  548. of nkIfExpr:
  549. result = getConstIfExpr(m, n, g)
  550. of nkCallKinds:
  551. if n[0].kind != nkSym: return
  552. var s = n[0].sym
  553. if s.kind != skProc and s.kind != skFunc: return
  554. try:
  555. case s.magic
  556. of mNone:
  557. # If it has no sideEffect, it should be evaluated. But not here.
  558. return
  559. of mLow:
  560. if skipTypes(n[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
  561. result = newFloatNodeT(firstFloat(n[1].typ), n, g)
  562. else:
  563. result = newIntNodeT(firstOrd(g.config, n[1].typ), n, g)
  564. of mHigh:
  565. if skipTypes(n[1].typ, abstractVar+{tyUserTypeClassInst}).kind notin
  566. {tySequence, tyString, tyCString, tyOpenArray, tyVarargs}:
  567. if skipTypes(n[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
  568. result = newFloatNodeT(lastFloat(n[1].typ), n, g)
  569. else:
  570. result = newIntNodeT(lastOrd(g.config, skipTypes(n[1].typ, abstractVar)), n, g)
  571. else:
  572. var a = getArrayConstr(m, n[1], g)
  573. if a.kind == nkBracket:
  574. # we can optimize it away:
  575. result = newIntNodeT(toInt128(a.len-1), n, g)
  576. of mLengthOpenArray:
  577. var a = getArrayConstr(m, n[1], g)
  578. if a.kind == nkBracket:
  579. # we can optimize it away! This fixes the bug ``len(134)``.
  580. result = newIntNodeT(toInt128(a.len), n, g)
  581. else:
  582. result = magicCall(m, n, g)
  583. of mLengthArray:
  584. # It doesn't matter if the argument is const or not for mLengthArray.
  585. # This fixes bug #544.
  586. result = newIntNodeT(lengthOrd(g.config, n[1].typ), n, g)
  587. of mSizeOf:
  588. result = foldSizeOf(g.config, n, nil)
  589. of mAlignOf:
  590. result = foldAlignOf(g.config, n, nil)
  591. of mOffsetOf:
  592. result = foldOffsetOf(g.config, n, nil)
  593. of mAstToStr:
  594. result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, g)
  595. of mConStrStr:
  596. result = foldConStrStr(m, n, g)
  597. of mIs:
  598. # The only kind of mIs node that comes here is one depending on some
  599. # generic parameter and that's (hopefully) handled at instantiation time
  600. discard
  601. else:
  602. result = magicCall(m, n, g)
  603. except OverflowDefect:
  604. localError(g.config, n.info, "over- or underflow")
  605. except DivByZeroDefect:
  606. localError(g.config, n.info, "division by zero")
  607. of nkAddr:
  608. var a = getConstExpr(m, n[0], g)
  609. if a != nil:
  610. result = n
  611. n[0] = a
  612. of nkBracket, nkCurly:
  613. result = copyNode(n)
  614. for i, son in n.pairs:
  615. var a = getConstExpr(m, son, g)
  616. if a == nil: return nil
  617. result.add a
  618. incl(result.flags, nfAllConst)
  619. of nkRange:
  620. var a = getConstExpr(m, n[0], g)
  621. if a == nil: return
  622. var b = getConstExpr(m, n[1], g)
  623. if b == nil: return
  624. result = copyNode(n)
  625. result.add a
  626. result.add b
  627. #of nkObjConstr:
  628. # result = copyTree(n)
  629. # for i in 1..<n.len:
  630. # var a = getConstExpr(m, n[i][1])
  631. # if a == nil: return nil
  632. # result[i][1] = a
  633. # incl(result.flags, nfAllConst)
  634. of nkPar, nkTupleConstr:
  635. # tuple constructor
  636. result = copyNode(n)
  637. if (n.len > 0) and (n[0].kind == nkExprColonExpr):
  638. for i, expr in n.pairs:
  639. let exprNew = copyNode(expr) # nkExprColonExpr
  640. exprNew.add expr[0]
  641. let a = getConstExpr(m, expr[1], g)
  642. if a == nil: return nil
  643. exprNew.add a
  644. result.add exprNew
  645. else:
  646. for i, expr in n.pairs:
  647. let a = getConstExpr(m, expr, g)
  648. if a == nil: return nil
  649. result.add a
  650. incl(result.flags, nfAllConst)
  651. of nkChckRangeF, nkChckRange64, nkChckRange:
  652. var a = getConstExpr(m, n[0], g)
  653. if a == nil: return
  654. if leValueConv(n[1], a) and leValueConv(a, n[2]):
  655. result = a # a <= x and x <= b
  656. result.typ = n.typ
  657. else:
  658. localError(g.config, n.info,
  659. "conversion from $1 to $2 is invalid" %
  660. [typeToString(n[0].typ), typeToString(n.typ)])
  661. of nkStringToCString, nkCStringToString:
  662. var a = getConstExpr(m, n[0], g)
  663. if a == nil: return
  664. result = a
  665. result.typ = n.typ
  666. of nkHiddenStdConv, nkHiddenSubConv, nkConv:
  667. var a = getConstExpr(m, n[1], g)
  668. if a == nil: return
  669. result = foldConv(n, a, g, check=true)
  670. of nkCast:
  671. var a = getConstExpr(m, n[1], g)
  672. if a == nil: return
  673. if n.typ != nil and n.typ.kind in NilableTypes:
  674. # we allow compile-time 'cast' for pointer types:
  675. result = a
  676. result.typ = n.typ
  677. of nkBracketExpr: result = foldArrayAccess(m, n, g)
  678. of nkDotExpr: result = foldFieldAccess(m, n, g)
  679. of nkCheckedFieldExpr:
  680. result = foldFieldAccess(m, n[0], g)
  681. of nkStmtListExpr:
  682. var i = 0
  683. while i <= n.len - 2:
  684. if n[i].kind in {nkComesFrom, nkCommentStmt, nkEmpty}: i.inc
  685. else: break
  686. if i == n.len - 1:
  687. result = getConstExpr(m, n[i], g)
  688. else:
  689. discard