123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- %
- % Compiler from Lisp into C. Copyright (C) 1994, Codemist Ltd
- %
- % This code hooks into the end of the Codemist Lisp bytecode compiler.
- %
- global '(s!:c_name s!:c_file s!:lisp_name s!:lisp_file);
- symbolic macro procedure c!:printf u;
- % inspired by the C printf function, but much less general.
- % This macro is to provide the illusion that printf can take an
- % arbitrary number of arguments.
- list('c!:printf1, cadr u, 'list . cddr u);
- symbolic procedure c!:printf1(fmt, args);
- % this is the inner works of print formatting.
- % the special sequences that can occur in format strings are
- % %s use princ (to print a name?)
- % %d use princ (to print a number?)
- % %a use prin
- % %t do a ttab()
- % %v print a variable.... magic for this compiler
- % \n do a terpri()
- % \q princ '!" to display quote marks
- begin
- scalar a, c;
- fmt := explode2 fmt;
- while fmt do <<
- c := car fmt;
- fmt := cdr fmt;
- if c = '!\ and car fmt = '!n then <<
- terpri();
- fmt := cdr fmt >>
- else if c = '!\ and car fmt = '!q then <<
- princ '!";
- fmt := cdr fmt >>
- else if c = '!% then <<
- c := car fmt;
- fmt := cdr fmt;
- a := car args;
- args := cdr args;
- if c = '!v then
- if flagp(a, 'c!:live_across_call) then <<
- princ "stack[";
- princ(-get(a, 'c!:location));
- princ "]" >>
- else princ a
- else if c = '!a then prin a
- else if c = '!t then ttab a
- else princ a >>
- else princ c >>
- end;
- symbolic procedure open_output name;
- !#if common!-lisp!-mode
- open(name, !:direction, !:output);
- !#else
- open(name, 'output);
- !#endif
- symbolic procedure s!:cstart module_name;
- begin
- scalar w;
- verbos nil; % Do not want garbage collection messages mixing in.
- princ "Start of compilation into C for "; prin module_name; terpri();
- w := '!" . explodec module_name;
- s!:c_name := compress append(w, '(!. !c !"));
- s!:lisp_name := compress append(w, '(!. !l !s !p !"));
- s!:c_file := open_output s!:c_name;
- s!:lisp_file := open_output s!:lisp_name;
- if s!:c_file and s!:lisp_file then return t;
- if s!:c_file then close s!:c_file;
- if s!:lisp_file then close s!:lisp_file;
- return nil
- end;
- symbolic procedure s!:cinit u;
- begin
- scalar o;
- o := wrs s!:lisp_file;
- princ "Initform: "; prinl u; terpri();
- wrs o
- end;
- symbolic procedure s!:cend();
- begin
- close s!:c_file; s!:c_file := nil;
- close s!:lisp_file; s!:lisp_file := nil;
- return nil
- end;
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- symbolic procedure s!:cgen(name, nargs, body, env);
- begin
- scalar w, fgg;
- princ "Cgen: "; prin name; terpri();
- princ "nargs: "; prin nargs; terpri();
- if nargs > 10 then <<
- terpri();
- princ "++++++ Functions with > 10 args or &optional, &rest"; terpri();
- princ " arge can not be compiled into C"; terpri();
- return 'failed >>;
- for each l in reverse body do <<
- prin car l; princ ": ";
- w := reverse cdddr l;
- % The very first block may have an arg-count byte on the front, which I want
- % to get rid on.
- if not fgg and nargs > 3 then w := cddr w;
- fgg := t;
- for each x in w do << princ " "; prin x >>;
- princ " ";
- prin cadr l;
- terpri() >>
- end;
- end;
|