Skip to content

Commit

Permalink
FEAT: adding function ENUM for making standard enumeration objects fr…
Browse files Browse the repository at this point in the history
…om given specification

See the included test file for usage examples.
  • Loading branch information
Oldes committed Oct 4, 2018
1 parent 7c07c7b commit c5cfb69
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/boot/errors.r
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ Script: [
; face-reused: [{Face object reused (in more than one pane):} :arg1]

invalid-handle: {invalid handle}
invalid-value-for: [{invalid value} :arg1 {for:} :arg2]

]

Math: [
Expand Down
3 changes: 3 additions & 0 deletions src/boot/sysobj.r
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ standard: context [
none
]

enum: none ; is defined later in %mezz-func.r file

error: context [ ; Template used for all errors:
code: 0
type: 'user
Expand Down Expand Up @@ -284,6 +286,7 @@ standard: context [
none
]

bincode: none
utype: none
font: none ; mezz-graphics.h
para: none ; mezz-graphics.h
Expand Down
57 changes: 57 additions & 0 deletions src/mezz/mezz-func.r
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,60 @@ task: func [
][
make task! copy/deep reduce [spec body]
]

enum: function [
"Creates enumeration object from given specification"
spec [block!] "Specification with names and values."
title [string! word!] "Enumeration name"
][
enum-value: 0
spec: copy spec
parse spec [any [
pos: word! insert enum-value (
change pos to set-word! pos/1
enum-value: enum-value + 1
)
| some set-word! pos: [
integer! | issue! | binary! | char!
] (
if error? try [
enum-value: to integer! pos/1
pos: change pos enum-value
enum-value: enum-value + 1
][
cause-error 'Script 'invalid-data reduce [pos]
]
) :pos
| pos: 1 skip (
cause-error 'Script 'invalid-data reduce [pos]
)
]
]
enum: make system/standard/enum spec
enum/title*: title
enum
]

system/standard/enum: context [
title*: none
assert: func[
"Checks if value exists as an enumeration. Throws error if not."
value [integer!]
][
unless find values-of self value [
cause-error 'Script 'invalid-value-for reduce [value title*]
]
true
]
name: func[
"Returns name of the emumeration by its value if value exists, else none."
value [integer!]
/local pos
][
all [
pos: find values-of self value
pick words-of self index? pos
]
]
;@@ add some other accessor functions?
]
1 change: 1 addition & 0 deletions src/tests/run-tests.r3
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ wrap load %units/rsa-test.r3
wrap load %units/dh-test.r3
wrap load %units/port-test.r3
wrap load %units/checksum-test.r3
wrap load %units/enum-test.r3

wrap load %units/crash-test.r3

Expand Down
52 changes: 52 additions & 0 deletions src/tests/units/enum-test.r3
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
Rebol [
Title: "Rebol enum test script"
Author: "Oldes"
File: %enum-test.red
Tabs: 4
Needs: [%../quick-test-module.r3]
]

~~~start-file~~~ "Enum"

===start-group=== "Basic enumeration"
--test-- "enum with basic specification"
*FX-DX8: enum [
CHORUS
COMPRESSOR
DISTORTION
ECHO
FLANGER
GARGLE
I3DL2REVERB
PARAMEQ
REVERB
] "DX8 effect ID"

--assert object? *FX-DX8
--assert 0 = *FX-DX8/CHORUS
--assert 8 = *FX-DX8/REVERB
--assert found? find [ECHO FLANGER] *FX-DX8/name 4


--test-- "enum with mixed specification"
*family: enum [
Alice: 1
Boban
Bolek
Lolek: #{FF}
Brian
] 'Just-Some-Names

--assert object? *family
--assert 'Boban = *family/name 2
--assert 'Lolek = *family/name 255
--assert none? *family/name 13
--assert true? *family/assert 1
--assert 256 = *family/Brian
--assert error? err: try [*family/assert 13]
--assert err/arg1 = 13
--assert err/arg2 = 'Just-Some-Names

===end-group===

~~~end-file~~~

0 comments on commit c5cfb69

Please sign in to comment.