shim.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* m2compiler-V3 runtime shim (C).
  2. *
  3. * Bridges Modula-2 external procedures to the host. Memory layout
  4. * matches the compiler's: a STRING (ARRAY OF CHAR) value is a
  5. * descriptor [0] = LONGCARD element count, then the bytes; the
  6. * compiler passes the descriptor's address as an `l`.
  7. *
  8. * Linked with every V3 program image.
  9. */
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. /* Write the contents of a string descriptor to fd 1. Returns the
  14. number of bytes written. */
  15. long m2write(long *desc)
  16. {
  17. long n = desc[0];
  18. if (n > 0)
  19. write(1, (char *)(desc + 1), (size_t)n);
  20. return n;
  21. }
  22. /* Write a newline to fd 1. */
  23. long m2writeln(void)
  24. {
  25. write(1, "\n", 1);
  26. return 0;
  27. }
  28. /* Read one character from stdin (0 at EOF). */
  29. long m2readchar(void)
  30. {
  31. int c = getchar();
  32. return (c == EOF) ? 0 : c;
  33. }
  34. /* Read a signed decimal integer from stdin, skipping leading
  35. whitespace. The first non-digit after the number is consumed. */
  36. long m2readint(void)
  37. {
  38. long v = 0;
  39. int c;
  40. int neg = 0;
  41. do { c = getchar(); } while (c == ' ' || c == '\t' ||
  42. c == '\n' || c == '\r');
  43. if (c == '-') { neg = 1; c = getchar(); }
  44. while (c >= '0' && c <= '9') {
  45. v = v * 10 + (c - '0');
  46. c = getchar();
  47. }
  48. return neg ? -v : v;
  49. }
  50. /* Set a string descriptor's logical length (header). */
  51. long m2setlen(long *desc, long n)
  52. {
  53. desc[0] = n;
  54. return n;
  55. }
  56. /* Write a single character (byte) to fd 1. */
  57. long m2writechar(long c)
  58. {
  59. char ch = (char)c;
  60. write(1, &ch, 1);
  61. return 0;
  62. }
  63. /* Write a signed decimal integer to fd 1. */
  64. long m2writeint(long v)
  65. {
  66. char buf[32];
  67. int i = 0;
  68. int neg = 0;
  69. unsigned long u;
  70. if (v < 0) { neg = 1; u = (unsigned long)(-v); }
  71. else u = (unsigned long)v;
  72. do { buf[i++] = (char)('0' + (u % 10)); u /= 10; } while (u != 0);
  73. if (neg) buf[i++] = '-';
  74. while (i > 0)
  75. write(1, &buf[--i], 1);
  76. return 0;
  77. }
  78. /* Terminate the process. */
  79. long m2exit(long code)
  80. {
  81. exit((int)code);
  82. return 0;
  83. }