json.km 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. type Value enum {
  2. type Object core::Map[String,Value];
  3. type Array core::List[Value];
  4. type Bool core::Bool;
  5. type Number core::NormalFloat;
  6. type String core::String;
  7. type Null;
  8. };
  9. export function Object: &(core::Map[String,Value]) => Value
  10. &(x) => { |Value| { |self::Object| x } };
  11. export function Array: &(core::List[Value]) => Value
  12. &(x) => { |Value| { |self::Array| x } };
  13. export function Bool: &(core::Bool) => Value
  14. &(x) => { |Value| { |self::Bool| x } };
  15. export function Number: &(core::NormalFloat) => Value
  16. &(x) => { |Value| { |self::Number| x } };
  17. export function String: &(core::String) => Value
  18. &(x) => { |Value| { |self::String| x } };
  19. export const Null: Value :=
  20. { |Value| { |Null| () } };
  21. export function stringify:
  22. &(self::Value) => String
  23. &(v) =>
  24. switch v:
  25. case Object object:
  26. object
  27. . { List }
  28. . { Seq }
  29. . { map &(key,value) =>
  30. { "?:?" ({quote key}, {stringify value}) } }
  31. . { join ',' }
  32. . { "{?}" },
  33. case Array array:
  34. array
  35. . { Seq }
  36. . { map stringify }
  37. . { join ',' }
  38. . { "[?]" },
  39. case Bool bool:
  40. switch bool:
  41. case Yes: 'true',
  42. case No: 'false',
  43. end,
  44. case Number number:
  45. { String number },
  46. case String string:
  47. { quote string },
  48. case Null:
  49. 'null',
  50. end;
  51. export function parse:
  52. &(String) => Result[self::Value,Error]
  53. &(input) =>
  54. let process := { ValueParser () },
  55. switch { process input }:
  56. case Success (value, remaining):
  57. if (remaining.{length} = 0):
  58. { Success value },
  59. else:
  60. let pos := (input.{length} - remaining.{length}),
  61. { Failure { Error 'redundant input after parsed content'
  62. . { &(msg) => { "? (at position ?)" (msg, pos.{String}) } } } },
  63. case Failure (err, remaining):
  64. let all := input.{length},
  65. let rest := remaining.{length},
  66. let pos := if (rest > 0): (all -! rest), else: (all -! 1),
  67. { Failure (err wrap &(msg) => { "? (at position ?)" (msg, pos.{String}) }) },
  68. end;