shim.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. /* Write the contents of a string descriptor to fd 1. Returns the
  13. number of bytes written. */
  14. long m2write(long *desc)
  15. {
  16. long n = desc[0];
  17. if (n > 0)
  18. write(1, (char *)(desc + 1), (size_t)n);
  19. return n;
  20. }
  21. /* Write a newline to fd 1. */
  22. long m2writeln(void)
  23. {
  24. write(1, "\n", 1);
  25. return 0;
  26. }
  27. /* Set a string descriptor's logical length (header). */
  28. long m2setlen(long *desc, long n)
  29. {
  30. desc[0] = n;
  31. return n;
  32. }
  33. /* Write a single character (byte) to fd 1. */
  34. long m2writechar(long c)
  35. {
  36. char ch = (char)c;
  37. write(1, &ch, 1);
  38. return 0;
  39. }
  40. /* Write a signed decimal integer to fd 1. */
  41. long m2writeint(long v)
  42. {
  43. char buf[32];
  44. int i = 0;
  45. int neg = 0;
  46. unsigned long u;
  47. if (v < 0) { neg = 1; u = (unsigned long)(-v); }
  48. else u = (unsigned long)v;
  49. do { buf[i++] = (char)('0' + (u % 10)); u /= 10; } while (u != 0);
  50. if (neg) buf[i++] = '-';
  51. while (i > 0)
  52. write(1, &buf[--i], 1);
  53. return 0;
  54. }
  55. /* Terminate the process. */
  56. long m2exit(long code)
  57. {
  58. exit((int)code);
  59. return 0;
  60. }