compc.red 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. %
  2. % Compiler from Lisp into C. Copyright (C) 1994, Codemist Ltd
  3. %
  4. % This code hooks into the end of the Codemist Lisp bytecode compiler.
  5. %
  6. global '(s!:c_name s!:c_file s!:lisp_name s!:lisp_file);
  7. symbolic macro procedure c!:printf u;
  8. % inspired by the C printf function, but much less general.
  9. % This macro is to provide the illusion that printf can take an
  10. % arbitrary number of arguments.
  11. list('c!:printf1, cadr u, 'list . cddr u);
  12. symbolic procedure c!:printf1(fmt, args);
  13. % this is the inner works of print formatting.
  14. % the special sequences that can occur in format strings are
  15. % %s use princ (to print a name?)
  16. % %d use princ (to print a number?)
  17. % %a use prin
  18. % %t do a ttab()
  19. % %v print a variable.... magic for this compiler
  20. % \n do a terpri()
  21. % \q princ '!" to display quote marks
  22. begin
  23. scalar a, c;
  24. fmt := explode2 fmt;
  25. while fmt do <<
  26. c := car fmt;
  27. fmt := cdr fmt;
  28. if c = '!\ and car fmt = '!n then <<
  29. terpri();
  30. fmt := cdr fmt >>
  31. else if c = '!\ and car fmt = '!q then <<
  32. princ '!";
  33. fmt := cdr fmt >>
  34. else if c = '!% then <<
  35. c := car fmt;
  36. fmt := cdr fmt;
  37. a := car args;
  38. args := cdr args;
  39. if c = '!v then
  40. if flagp(a, 'c!:live_across_call) then <<
  41. princ "stack[";
  42. princ(-get(a, 'c!:location));
  43. princ "]" >>
  44. else princ a
  45. else if c = '!a then prin a
  46. else if c = '!t then ttab a
  47. else princ a >>
  48. else princ c >>
  49. end;
  50. symbolic procedure open_output name;
  51. !#if common!-lisp!-mode
  52. open(name, !:direction, !:output);
  53. !#else
  54. open(name, 'output);
  55. !#endif
  56. symbolic procedure s!:cstart module_name;
  57. begin
  58. scalar w;
  59. verbos nil; % Do not want garbage collection messages mixing in.
  60. princ "Start of compilation into C for "; prin module_name; terpri();
  61. w := '!" . explodec module_name;
  62. s!:c_name := compress append(w, '(!. !c !"));
  63. s!:lisp_name := compress append(w, '(!. !l !s !p !"));
  64. s!:c_file := open_output s!:c_name;
  65. s!:lisp_file := open_output s!:lisp_name;
  66. if s!:c_file and s!:lisp_file then return t;
  67. if s!:c_file then close s!:c_file;
  68. if s!:lisp_file then close s!:lisp_file;
  69. return nil
  70. end;
  71. symbolic procedure s!:cinit u;
  72. begin
  73. scalar o;
  74. o := wrs s!:lisp_file;
  75. princ "Initform: "; prinl u; terpri();
  76. wrs o
  77. end;
  78. symbolic procedure s!:cend();
  79. begin
  80. close s!:c_file; s!:c_file := nil;
  81. close s!:lisp_file; s!:lisp_file := nil;
  82. return nil
  83. end;
  84. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  85. symbolic procedure s!:cgen(name, nargs, body, env);
  86. begin
  87. scalar w, fgg;
  88. princ "Cgen: "; prin name; terpri();
  89. princ "nargs: "; prin nargs; terpri();
  90. if nargs > 10 then <<
  91. terpri();
  92. princ "++++++ Functions with > 10 args or &optional, &rest"; terpri();
  93. princ " arge can not be compiled into C"; terpri();
  94. return 'failed >>;
  95. for each l in reverse body do <<
  96. prin car l; princ ": ";
  97. w := reverse cdddr l;
  98. % The very first block may have an arg-count byte on the front, which I want
  99. % to get rid on.
  100. if not fgg and nargs > 3 then w := cddr w;
  101. fgg := t;
  102. for each x in w do << princ " "; prin x >>;
  103. princ " ";
  104. prin cadr l;
  105. terpri() >>
  106. end;
  107. end;