summary refs log tree commit diff stats
path: root/doc/tut2.txt
diff options
context:
space:
mode:
authorGrzegorz Adam Hankiewicz <gradha@imap.cc>2013-01-21 21:43:34 +0100
committerGrzegorz Adam Hankiewicz <gradha@imap.cc>2013-01-22 00:24:43 +0100
commitacc394ca239b1a1ae864017c22aae8660b655053 (patch)
tree8e9ccb3f897a34f03c14d28e6762f7445203d3dc /doc/tut2.txt
parentd0bd5d5cc3407e14ff37590077ec40441be26c84 (diff)
downloadNim-acc394ca239b1a1ae864017c22aae8660b655053.tar.gz
Adds some documentation related to exceptions.
Diffstat (limited to 'doc/tut2.txt')
-rwxr-xr-xdoc/tut2.txt14
1 files changed, 14 insertions, 0 deletions
diff --git a/doc/tut2.txt b/doc/tut2.txt
index 9f9dbe2db..4a4ef1757 100755
--- a/doc/tut2.txt
+++ b/doc/tut2.txt
@@ -433,6 +433,20 @@ handled, it is propagated through the call stack. This means that often
 the rest of the procedure - that is not within a ``finally`` clause -
 is not executed (if an exception occurs).
 
+If you need to *access* the actual exception object or message inside an
+``except`` branch you can use the getCurrentException() and
+getCurrentExceptionMsg() procs from the `system <system.html>`_ module.
+Example:
+
+.. code-block:: nimrod
+  try:
+    doSomethingHere()
+  except:
+    let
+      e = getCurrentException()
+      msg = getCurrentExceptionMsg()
+    echo "Got exception ", repr(e), " with message ", msg
+
 
 Exception hierarchy
 -------------------
background-color: transparent; padding-left: 5px; padding-right: 5px; } span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#
#
#           The Nim Compiler
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

# this unit handles Nim sets; it implements symbolic sets

import
  ast, astalgo, lineinfos, bitsets, types, options

proc inSet*(s: PNode, elem: PNode): bool =
  assert s.kind == nkCurly
  if s.kind != nkCurly:
    #internalError(s.info, "inSet")
    return false
  for i in 0 ..< sonsLen(s):
    if s.sons[i].kind == nkRange:
      if leValue(s.sons[i].sons[0], elem) and
          leValue(elem, s.sons[i].sons[1]):
        return true
    else:
      if sameValue(s.sons[i], elem):
        return true
  result = false

proc overlap*(a, b: PNode): bool =
  if a.kind == nkRange:
    if b.kind == nkRange:
      # X..Y and C..D overlap iff (X <= D and C <= Y)
      result = leValue(a.sons[0], b.sons[1]) and
               leValue(b.sons[0], a.sons[1])
    else:
      result = leValue(a.sons[0], b) and leValue(b, a.sons[1])
  else:
    if b.kind == nkRange:
      result = leValue(b.sons[0], a) and leValue(a, b.sons[1])
    else:
      result = sameValue(a, b)

proc someInSet*(s: PNode, a, b: PNode): bool =
  # checks if some element of a..b is in the set s
  assert s.kind == nkCurly
  if s.kind != nkCurly:
    #internalError(s.info, "SomeInSet")
    return false
  for i in 0 ..< sonsLen(s):
    if s.sons[i].kind == nkRange:
      if leValue(s.sons[i].sons[0], b) and leValue(b, s.sons[i].sons[1]) or
          leValue(s.sons[i].sons[0], a) and leValue(a, s.sons[i].sons[1]):
        return true
    else:
      # a <= elem <= b
      if leValue(a, s.sons[i]) and leValue(s.sons[i], b):
        return true
  result = false

proc toBitSet*(conf: ConfigRef; s: PNode, b: var TBitSet) =
  var first, j: BiggestInt
  first = firstOrd(conf, s.typ.sons[0])
  bitSetInit(b, int(getSize(conf, s.typ)))
  for i in 0 ..< sonsLen(s):
    if s.sons[i].kind == nkRange:
      j = getOrdValue(s.sons[i].sons[0], first)
      while j <= getOrdValue(s.sons[i].sons[1], first):
        bitSetIncl(b, j - first)
        inc(j)
    else:
      bitSetIncl(b, getOrdValue(s.sons[i], first) - first)

proc toTreeSet*(conf: ConfigRef; s: TBitSet, settype: PType, info: TLineInfo): PNode =
  var
    a, b, e, first: BiggestInt # a, b are interval borders
    elemType: PType
    n: PNode
  elemType = settype.sons[0]
  first = firstOrd(conf, elemType)
  result = newNodeI(nkCurly, info)
  result.typ = settype
  result.info = info
  e = 0
  while e < len(s) * ElemSize:
    if bitSetIn(s, e):
      a = e
      b = e
      while true:
        inc(b)
        if (b >= len(s) * ElemSize) or not bitSetIn(s, b): break
      dec(b)
      let aa = newIntTypeNode(nkIntLit, a + first, elemType)
      aa.info = info
      if a == b:
        addSon(result, aa)
      else:
        n = newNodeI(nkRange, info)
        n.typ = elemType
        addSon(n, aa)
        let bb = newIntTypeNode(nkIntLit, b + first, elemType)
        bb.info = info
        addSon(n, bb)
        addSon(result, n)
      e = b
    inc(e)

template nodeSetOp(a, b: PNode, op: untyped) {.dirty.} =
  var x, y: TBitSet
  toBitSet(conf, a, x)
  toBitSet(conf, b, y)
  op(x, y)
  result = toTreeSet(conf, x, a.typ, a.info)

proc unionSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetUnion)
proc diffSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetDiff)
proc intersectSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetIntersect)
proc symdiffSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetSymDiff)

proc containsSets*(conf: ConfigRef; a, b: PNode): bool =
  var x, y: TBitSet
  toBitSet(conf, a, x)
  toBitSet(conf, b, y)
  result = bitSetContains(x, y)

proc equalSets*(conf: ConfigRef; a, b: PNode): bool =
  var x, y: TBitSet
  toBitSet(conf, a, x)
  toBitSet(conf, b, y)
  result = bitSetEquals(x, y)

proc complement*(conf: ConfigRef; a: PNode): PNode =
  var x: TBitSet
  toBitSet(conf, a, x)
  for i in 0 .. high(x): x[i] = not x[i]
  result = toTreeSet(conf, x, a.typ, a.info)

proc deduplicate*(conf: ConfigRef; a: PNode): PNode =
  var x: TBitSet
  toBitSet(conf, a, x)
  result = toTreeSet(conf, x, a.typ, a.info)

proc cardSet*(conf: ConfigRef; a: PNode): BiggestInt =
  var x: TBitSet
  toBitSet(conf, a, x)
  result = bitSetCard(x)

proc setHasRange*(s: PNode): bool =
  assert s.kind == nkCurly
  if s.kind != nkCurly:
    return false
  for i in 0 ..< sonsLen(s):
    if s.sons[i].kind == nkRange:
      return true
  result = false

proc emptyRange*(a, b: PNode): bool =
  result = not leValue(a, b)  # a > b iff not (a <= b)