 
 asNum = (n) ->
   if Math.abs(n) < BASE then new CheckedInt n else LongInt.fromNative n
+
+# ----
+
+# The `num` function provides the public interface.
+
+num = (n = 0) ->
+  switch typeof n
+    when 'number'
+      num.fromNative n
+    when 'string'
+      num.parse n
+    else
+      if n instanceof NumberBase
+        n
+      else
+        throw new Error "expected a number, got #{n}"
+
+num.fromNative = (n) ->
+  throw new Error "expected an integer, got #{n}" unless n == Math.floor n
+  asNum n
+
+num.parse = (n) ->
+  unless /^[+-]?\d+$/.test n
+    throw new Error "expected an integer literal, got '#{n}'"
+
+  [s, m] = switch n[0]
+    when '-' then [-1, n[1..]]
+    when '+' then [ 1, n[1..]]
+    else          [ 1, n]
+
+  if m.length <= BASE_LENGTH
+    new CheckedInt parseInt n
+  else
+    parsed = (to) ->
+      if to > 0
+        from = Math.max 0, to - BASE_LENGTH
+        seq.conj parseInt(m[from...to]), -> parsed from
+      else
+        null
+
+    new LongInt s, parsed m.length
+
 
 # ----
 


  constructor: (@val = 0) ->

  neg: -> new CheckedInt -@val

  abs: -> new CheckedInt Math.abs @val

  sgn: -> if @val < 0 then -1 else if @val > 0 then 1 else 0

  sqrt: -> new CheckedInt Math.floor Math.sqrt @val

  cmp__: (other) ->
    if @val < other.val then -1 else if @val > other.val then 1 else 0

class LongInt extends NumberBase
  constructor: (sign, @digits) -> @sign = if @digits? then sign else 0

  neg__: -> new LongInt -@sign, @digits

  abs__: -> new LongInt 1, @digits

  sgn__: -> @sign

  zeroes = BASE.toString()[1..]

