This might be a flawed solution, but I need to stop thinking
about this, and I think it is reasonably close to what you
wanted.
Notes:
1. I based this off of my interpretation of the dictionary. It
deviates from J's implementation in a variety of areas. In most
cases my implementation provides a superset of the features
of J's built-in numeric parser (because I am using J where the
interpreter's implementation seems to be built upon a custom
state machine). However:
a. I make no attempt to use the most concise type to
represent a number. In other words, I take no steps to
ensure that 1.0 is boolean. I expect that this would be messy,
for me to add.
b. J supports 16b_bee. I do not, in this version. This should
not be too difficult to add. But I did not feel like doing that right now.
2. I am using '_.' in my results, because I could not think of
any better option for treating that case.
3. Any error or assertion failure should be interpreted as an ill-formed number.
4. The design is roughly based on that of recursive descent parsers.
NB. core numeric implementation
alfnum=: '0123456789abcdefghijklmnopqrstuvwxyz'
enquote=: '''',,&''''
refdig=: alfnum enquote@:{.~ >./@:>:@i.~&alfnum
digits=: refdig,'i.',enquote
decimal=: (ass...@e.&'0123456789' ] '10#.',digits )@;@{.
extend=: (ass...@e.&'0123456789' ] '10x#.',digits)@;@{.
arbitrary=:(ass...@e.&alfnum ] digits )@;@{: NB. note:
{: instead of {.
NB. parsing
split=:1 :0
(0;(0 10#:<.10*".;._2]0 :0);< <;._1 m)&;:@;
)
NO=: assert bind 0
sel=:2 :0
'ndx opts'=.y
x`''@.((;:opts) i. ndx&{)
)
NB. fractions
tkn1=: ' .r' split
0.6 1.1
2.2 1
3.2 3.2
3 3
)
numb1=: no`decimal`decimal`num...@.#@tkn1
numb1e=: numb1d`numb1r sel (1;'.r')
numb1d=: '(', decimal,')+(%10)#.|.', digits@,~&'0'@>@{:
numb1r=: '(', extend, ')%',ext...@{:
NB. negative sign
tkn2=: ' _' split
1.1 2.1
2.2 2.2
2 2
)
numb2=: no`inf`num...@.#@tkn2
numb2e=: '_.'"_`('-_'"_)`('-',nu...@}.) sel (1;'._')
inf=: numb1`('_'"_)@.('_'={.@;)
NB. exponential (scientific notation)
tkn3=: ' e'split
0.6 1.1
2.2 1
3.2 3.2
3 3
)
numb3=: no`numb2`no`num...@.#@tkn3
numb3e=: ('(',nu...@{.,')*10^',nu...@{:) sel (1;'e')
NB. Complex
tkn4=: ' a dr j'split
0.6 0.6 0.6 1.1
2.2 2.2 3.2 1
3 3 4.2 4.2
4.2 4.2 4.2 4.2
4 4 4 4
)
numb4=: no`numb3`no`num...@.#@tkn4
numb4e=: numb4j`numb4ad`numb4ar sel (1;'j ad ar')
numb4j=: '(',nu...@{.,')j.',nu...@{:
numb4ar=: 'j./(',nu...@{.,')*1 2 o.',nu...@{:
numb4ad=: 'j./(',nu...@{.,')*1 2 o.180%~o.',nu...@{:
NB. other exponentials and extended precision
tkn5=: ' px'split
0.6 1.1
2.2 1
3.2 3.2
3 3
)
numb5=: no`numb4`extend`num...@.#@tkn5
numb5e=: num5p`num5x sel (1;'p x')
numb5p=: '(',nu...@{.,')*(o.1)^',nu...@{:
numb5x=: '(',nu...@{.,')*^',nu...@{:
NB. arbitrary bases
tkn6=: ' b'split
0.6 1.1
2.2 1
3.2 3.2
3 3
)
numb6=: no`numb5`no`num...@.#@tkn6
numb6e=: ('(',nu...@{.,')#.',arbitrary) sel (1;'b')
NB. vectors
tkn7=: '/ 'split
0 1.1
0.2 1
)
numb7=: [:;('(',[,'),',])&.>/@:(numb6&.>)@tkn7
require'strings'
pc_rdm0=: nu...@tolower
--
Raul
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm