summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-01-11 01:09:48 +0100
committerAraq <rumpf_a@web.de>2011-01-11 01:09:48 +0100
commit1a8c6fb49fd9e12168895266c0067240e2bcb897 (patch)
tree2facb8bc368d121ebaf63a9e113283af63e182e8
parentd48ab374959eed4c5acbbb38e7ea86a011854102 (diff)
downloadNim-1a8c6fb49fd9e12168895266c0067240e2bcb897.tar.gz
Feature: explicit string representation for enum fields
-rwxr-xr-xdoc/manual.txt18
-rwxr-xr-xrod/ccgtypes.nim10
-rwxr-xr-xrod/semfold.nim6
-rwxr-xr-xrod/semtypes.nim20
-rwxr-xr-xtests/accept/run/spec.csv2
-rw-r--r--tests/accept/run/tenumhole.nim16
-rw-r--r--tests/accept/run/tnamedenumfields.nim17
-rwxr-xr-xtodo.txt2
-rwxr-xr-xweb/news.txt11
9 files changed, 94 insertions, 8 deletions
diff --git a/doc/manual.txt b/doc/manual.txt
index 11b18bdb1..6671d5875 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -634,6 +634,24 @@ enums as an index type for arrays. The procedures ``inc``, ``dec``, ``succ``
 and ``pred`` are not available for them either.

 

 

+The compiler supports the built-in stringify operator ``$`` for enumerations.

+The stringify's result can be controlled by specifying the string values to

+use explicitely:

+

+.. code-block:: nimrod

+

+  type

+    TMyEnum = enum

+      valueA = (0, "my value A"),

+      valueB = "value B",

+      valueC = 2,

+      valueD = (3, "abc")

+

+As can be seen from the example, it is possible to both specify a field's 

+ordinal value and its string value by using a tuple construction. It is also

+possible to only specify one of them.

+

+

 Subrange types

 ~~~~~~~~~~~~~~

 A `subrange`:idx: type is a range of values from an ordinal type (the base

diff --git a/rod/ccgtypes.nim b/rod/ccgtypes.nim
index ca5b3990e..43b4f173d 100755
--- a/rod/ccgtypes.nim
+++ b/rod/ccgtypes.nim
@@ -1,14 +1,14 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2009 Andreas Rumpf
+#        (c) Copyright 2011 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
 #
 
 #var
-#  newDummyVar: int; // just to check the symbol file mechanism
+#  newDummyVar: int # just to check the symbol file mechanism
 
 # ------------------------- Name Mangling --------------------------------
 
@@ -688,7 +688,11 @@ proc genEnumInfo(m: BModule, typ: PType, name: PRope) =
     assert(typ.n.sons[i].kind == nkSym)
     field = typ.n.sons[i].sym
     elemNode = getNimNode(m)
-    app(enumNames, makeCString(field.name.s))
+    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: 
       appf(specialCases, "$1.offset = $2;$n", [elemNode, toRope(field.position)])
diff --git a/rod/semfold.nim b/rod/semfold.nim
index a447ac66f..91d6ea3bc 100755
--- a/rod/semfold.nim
+++ b/rod/semfold.nim
@@ -58,7 +58,11 @@ proc ordinalValToString(a: PNode): string =
     for i in countup(0, sonsLen(n) - 1): 
       if n.sons[i].kind != nkSym: InternalError(a.info, "ordinalValToString")
       var field = n.sons[i].sym
-      if field.position == x: return field.name.s
+      if field.position == x: 
+        if field.ast == nil: 
+          return field.name.s
+        else:
+          return field.ast.strVal
     InternalError(a.info, "no symbol for ordinal value: " & $x)
   else:
     result = $x
diff --git a/rod/semtypes.nim b/rod/semtypes.nim
index 8083227fd..ccba76a21 100755
--- a/rod/semtypes.nim
+++ b/rod/semtypes.nim
@@ -1,7 +1,7 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2010 Andreas Rumpf
+#        (c) Copyright 2011 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -25,7 +25,6 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
     counter, x: BiggestInt
     e: PSym
     base: PType
-    v: PNode
   counter = 0
   base = nil
   result = newOrPrevType(tyEnum, prev, c)
@@ -41,12 +40,25 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
     case n.sons[i].kind
     of nkEnumFieldDef: 
       e = newSymS(skEnumField, n.sons[i].sons[0], c)
-      v = semConstExpr(c, n.sons[i].sons[1])
-      x = getOrdValue(v)
+      var v = semConstExpr(c, n.sons[i].sons[1])
+      var strVal: PNode = nil
+      case skipTypes(v.typ, abstractInst).kind 
+      of tyTuple: 
+        if sonsLen(v) != 2: liMessage(v.info, errWrongNumberOfVariables)
+        strVal = v.sons[1] # second tuple part is the string value
+        if skipTypes(strVal.typ, abstractInst).kind notin {tyString, tyCstring}:
+          liMessage(strVal.info, errStringLiteralExpected)
+        x = getOrdValue(v.sons[0]) # first tuple part is the ordinal
+      of tyString, tyCstring:
+        strVal = v
+        x = counter
+      else:
+        x = getOrdValue(v)
       if i != 1: 
         if (x != counter): incl(result.flags, tfEnumHasWholes)
         if x < counter: 
           liMessage(n.sons[i].info, errInvalidOrderInEnumX, e.name.s)
+      e.ast = strVal # might be nil
       counter = x
     of nkSym: 
       e = n.sons[i].sym
diff --git a/tests/accept/run/spec.csv b/tests/accept/run/spec.csv
index 980301bd0..7a3d2bd98 100755
--- a/tests/accept/run/spec.csv
+++ b/tests/accept/run/spec.csv
@@ -20,6 +20,7 @@ tcontinuexc.nim;ECcaught
 tcopy.nim;TEMP=C:\Programs\xyz\bin
 tcurrncy.nim;25
 temit.nim;509
+tenumhole;my value A1my value Bconc2valueCabc4abc
 texcsub.nim;caught!
 texplicitgeneric1.nim;Key: 12 value: 12Key: 13 value: 13 Key: A value: 12 Key: B value: 13
 tfinally.nim;came here 3
@@ -44,6 +45,7 @@ tmultim1.nim;7
 tmultim2.nim;collide: unit, thing collide: unit, thing collide: thing, unit
 tmultim3.nim;Hi derived!
 tmultim4.nim;hello
+tnamedenumfields;my value A0my value Bconc1valueCabc3abc
 tnestif.nim;i == 2
 tnestprc.nim;10
 toop1.nim;34[]o 5
diff --git a/tests/accept/run/tenumhole.nim b/tests/accept/run/tenumhole.nim
new file mode 100644
index 000000000..75fb74592
--- /dev/null
+++ b/tests/accept/run/tenumhole.nim
@@ -0,0 +1,16 @@
+
+const
+  strValB = "my value B"
+
+type
+  TMyEnum = enum
+    valueA = (1, "my value A"),
+    valueB = strValB & "conc",
+    valueC,
+    valueD = (4, "abc")
+ 
+# trick the optimizer with a variable:
+var x = valueD
+echo valueA, ord(valueA), valueB, ord(valueB), valueC, valueD, ord(valueD), x
+
+
diff --git a/tests/accept/run/tnamedenumfields.nim b/tests/accept/run/tnamedenumfields.nim
new file mode 100644
index 000000000..6012cf1eb
--- /dev/null
+++ b/tests/accept/run/tnamedenumfields.nim
@@ -0,0 +1,17 @@
+
+const
+  strValB = "my value B"
+
+type
+  TMyEnum = enum
+    valueA = (0, "my value A"),
+    valueB = strValB & "conc",
+    valueC,
+    valueD = (3, "abc"),
+    valueE = 4
+
+# trick the optimizer with a variable:
+var x = valueD
+echo valueA, ord(valueA), valueB, ord(valueB), valueC, valueD, ord(valueD), x
+
+
diff --git a/todo.txt b/todo.txt
index 95a92b4e5..cf50f4144 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,5 +1,7 @@
 - we need a way to disable tests
 - deprecate ^ and make it available as operator
+- test branch coverage
+- checked exceptions
 
 
 High priority (version 0.9.0)
diff --git a/web/news.txt b/web/news.txt
index d81a4b8aa..f421f0f70 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -23,6 +23,13 @@ Bugfixes
   anymore. 
 
 
+Changes affecting backwards compatibility
+-----------------------------------------
+
+- Operators starting with ``^`` are now right-associative and have the highest 
+  priority.
+
+
 Additions
 ---------
 
@@ -37,6 +44,10 @@ Additions
 - Added ``emit`` pragma for direct code generator control.
 - Additional operations were added to the ``complex`` module. 
 - Added ``strutils.formatFloat``,  ``strutils.formatBiggestFloat``.
+- A field in an ``enum`` may be given an explicit string representation. 
+  This yields more maintainable code than using a constant 
+  ``array[TMyEnum, string]`` mapping.
+
 
 
 2010-10-20 Version 0.8.10 released