Feature: explicit string representation for enum fields
This commit is contained in:
parent
d48ab37495
commit
1a8c6fb49f
9 changed files with 94 additions and 8 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)])
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
16
tests/accept/run/tenumhole.nim
Normal file
16
tests/accept/run/tenumhole.nim
Normal file
|
|
@ -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
|
||||
|
||||
|
||||
17
tests/accept/run/tnamedenumfields.nim
Normal file
17
tests/accept/run/tnamedenumfields.nim
Normal file
|
|
@ -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
|
||||
|
||||
|
||||
2
todo.txt
2
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)
|
||||
|
|
|
|||
11
web/news.txt
11
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue