c_utils.g 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # This file is part of asmc, a bootstrapping OS with minimal seed
  2. # Copyright (C) 2018-2019 Giovanni Mascellani <gio@debian.org>
  3. # https://gitlab.com/giomasce/asmc
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. # You should have received a copy of the GNU General Public License
  13. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. fun c_strtoll 2 {
  15. $s
  16. $end
  17. @s 1 param = ;
  18. @end 0 param = ;
  19. $base
  20. @base 10 = ;
  21. $value
  22. @value i64_init = ;
  23. $pos
  24. @pos 0 = ;
  25. $c
  26. @c s pos + **c = ;
  27. if c '0' == {
  28. @pos pos 1 + = ;
  29. @c s pos + **c = ;
  30. if c 'x' == c 'X' == || {
  31. @base 16 = ;
  32. @pos pos 1 + = ;
  33. } else {
  34. @base 8 = ;
  35. }
  36. }
  37. $long_base
  38. @long_base i64_init = ;
  39. long_base base i64_from_u32 ;
  40. $long_digit
  41. @long_digit i64_init = ;
  42. $cont
  43. @cont 1 = ;
  44. while cont {
  45. $stop
  46. @stop 1 = ;
  47. @c s pos + **c = ;
  48. $digit
  49. if '0' c <= c '9' <= && {
  50. @digit c '0' - = ;
  51. @stop 0 = ;
  52. }
  53. if 'a' c <= c 'f' <= && {
  54. @digit c 'a' - 10 + = ;
  55. @stop 0 = ;
  56. }
  57. if 'A' c <= c 'F' <= && {
  58. @digit c 'A' - 10 + = ;
  59. @stop 0 = ;
  60. }
  61. if stop {
  62. @cont 0 = ;
  63. } else {
  64. digit base < "c_strtoll: invalid digit for current base" digit base assert_msg_int_int ;
  65. long_digit digit i64_from_u32 ;
  66. value long_base i64_mul ;
  67. value long_digit i64_add ;
  68. @pos pos 1 + = ;
  69. }
  70. }
  71. long_base i64_destroy ;
  72. long_digit i64_destroy ;
  73. end s pos + = ;
  74. value ret ;
  75. }