nat.h 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. // Copyright © 2019 Ariadne Devos
  3. #ifndef _sHT_LEX_NAT_H
  4. #define _sHT_LEX_NAT_H
  5. #include <limits.h>
  6. #include <stdint.h>
  7. #include <sHT/logic/failbit.h>
  8. #include <sHT/logic/arithmetic.h>
  9. struct sHT_decimal_u32
  10. {
  11. sHT_with_failbit
  12. size_t end;
  13. /* On AMD64 SystemV, the third argument and second return
  14. value are mapped to the same register -- no register
  15. shuffling is necessary.
  16. TODO: ARM, etc. */
  17. sHT_overflowing
  18. uint_least32_t val;
  19. };
  20. /** Parse a natural, decimal number
  21. The first character is skipped,
  22. the first digit is taken to be `val`.
  23. On overflow, `sHT_bad(ret.end)`.
  24. Requires:
  25. (a): SliceCap(read ^ set, length, from)
  26. (b): 0 < length < failbit_limit(size_t)
  27. (c): nonspec: 0 ≤ first < 10
  28. Definitions:
  29. - end := maximalise k : { k | 1 ≤ k ≤ length },
  30. match decimal* from 1 k
  31. - d (k : nat, 0 ≤ k < end) :=
  32. match k
  33. | 0 ⇒ first
  34. | S _ ⇒ decimal->nat (from [k])
  35. (* Capability:
  36. k < end, end < length
  37. ⇒ (1) k < length
  38. Satisfied by (a), 0 ≤ k, (1) *)
  39. end
  40. - nonspec: value := string->nat end d
  41. Ensures:
  42. (w): 0 ≤ fail_value(size_t, ret.end) ≤ length
  43. (x): nonspec: fail_value(size_t, ret.end) = end
  44. (y): nonspec: value ∈ \bounds(ret.value) ↔ good(size_t, ret.end)
  45. (z): value = ret.val */
  46. __attribute__((pure))
  47. struct sHT_decimal_u32
  48. sHT_decimal_u32_c1(size_t length, const unsigned char from[length], uint_least32_t first);
  49. #endif