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

Reply via email to