diff options
author | Araq <rumpf_a@web.de> | 2011-01-11 01:09:48 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-01-11 01:09:48 +0100 |
commit | 1a8c6fb49fd9e12168895266c0067240e2bcb897 (patch) | |
tree | 2facb8bc368d121ebaf63a9e113283af63e182e8 | |
parent | d48ab374959eed4c5acbbb38e7ea86a011854102 (diff) | |
download | Nim-1a8c6fb49fd9e12168895266c0067240e2bcb897.tar.gz |
Feature: explicit string representation for enum fields
-rwxr-xr-x | doc/manual.txt | 18 | ||||
-rwxr-xr-x | rod/ccgtypes.nim | 10 | ||||
-rwxr-xr-x | rod/semfold.nim | 6 | ||||
-rwxr-xr-x | rod/semtypes.nim | 20 | ||||
-rwxr-xr-x | tests/accept/run/spec.csv | 2 | ||||
-rw-r--r-- | tests/accept/run/tenumhole.nim | 16 | ||||
-rw-r--r-- | tests/accept/run/tnamedenumfields.nim | 17 | ||||
-rwxr-xr-x | todo.txt | 2 | ||||
-rwxr-xr-x | web/news.txt | 11 |
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 |