9149741847bccd51b5cdb496788fa76aa3f58004
[mes.git] / src / lib.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * Mes --- Maxwell Equations of Software
3  * Copyright © 2016,2017,2018 Jan Nieuwenhuizen <janneke@gnu.org>
4  *
5  * This file is part of Mes.
6  *
7  * Mes is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or (at
10  * your option) any later version.
11  *
12  * Mes is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 int g_depth;
22 SCM fdisplay_ (SCM, int, int);
23
24 SCM
25 display_helper (SCM x, int cont, char* sep, int fd, int write_p)
26 {
27   fputs (sep, fd);
28   if (g_depth == 0) return cell_unspecified;
29   g_depth = g_depth - 1;
30   
31   switch (TYPE (x))
32     {
33     case TCHAR:
34       {
35         if (!write_p)
36           fputc (VALUE (x), fd);
37         else
38           {
39             fputs ("#\\", fd);
40             switch (VALUE (x))
41               {
42               case '\0': fputs ("nul", fd); break;
43               case '\a': fputs ("alarm", fd); break;
44               case '\b': fputs ("backspace", fd); break;
45               case '\t': fputs ("tab", fd); break;
46               case '\n': fputs ("newline", fd); break;
47               case '\v': fputs ("vtab", fd); break;
48               case '\f': fputs ("page", fd); break;
49               case '\r': fputs ("return", fd); break;
50               case ' ': fputs ("space", fd); break;
51               default: fputc (VALUE (x), fd);
52               }
53           }
54         break;
55       }
56     case TCLOSURE:
57       {
58         fputs ("#<closure ", fd);
59         //display_helper (CDR (x), cont, "", fd, 0);
60         fputs (">", fd);
61         break;
62       }
63     case TFUNCTION:
64       {
65         fputs ("#<procedure ", fd);
66         char const *p = "?";
67         if (FUNCTION (x).name != 0)
68           p = FUNCTION (x).name;
69         fputs (p, fd);
70         fputs ("[", fd);
71         fputs (itoa (CDR (x)), fd);
72         fputs (",", fd);
73         fputs (itoa (x), fd);
74         fputs ("]>", fd);
75         break;
76       }
77     case TMACRO:
78       {
79         fputs ("#<macro ", fd);
80         display_helper (CDR (x), cont, "", fd, 0);
81         fputs (">", fd);
82         break;
83       }
84     case TVARIABLE:
85       {
86         fputs ("#<variable ", fd);
87         if (VARIABLE_GLOBAL_P (x) == cell_t)
88           fputs ("*global* ", fd);
89         display_helper (CAR (VARIABLE (x)), cont, "", fd, 0);
90         fputs (">", fd);
91         break;
92       }
93     case TNUMBER:
94       {
95         fputs (itoa (VALUE (x)), fd);
96         break;
97       }
98     case TPAIR:
99       {
100         if (!cont) fputs ("(", fd);
101         if (CAR (x) == cell_closure)
102           fputs ("*closure* ", fd);
103         else
104         if (CAAR (x) == cell_closure)
105           fputs ("(*closure* ...) ", fd);
106         else
107         if (CAR (x) == cell_circular)
108           {
109             fputs ("(*circ* . ", fd);
110             int i = 0;
111             x = CDR (x);
112             while (x != cell_nil && i++ < 10)
113               {
114                 g_depth = 1;
115                 display_helper (CAAR (x), 0, "", fd, write_p); fputs (" ", fd);
116                 //fdisplay_ (CAAR (x), fd, write_p); fputs (" ", fd);
117                 x = CDR (x);
118               }
119             fputs (" ...)", fd);
120           }
121         else
122           {
123             if (x && x != cell_nil) fdisplay_ (CAR (x), fd, write_p);
124             if (CDR (x) && TYPE (CDR (x)) == TPAIR)
125               display_helper (CDR (x), 1, " ", fd, write_p);
126             else if (CDR (x) && CDR (x) != cell_nil)
127               {
128                 if (TYPE (CDR (x)) != TPAIR)
129                   fputs (" . ", fd);
130                 fdisplay_ (CDR (x), fd, write_p);
131               }
132           }
133         if (!cont) fputs (")", fd);
134         break;
135       }
136     case TKEYWORD:
137     case TSPECIAL:
138     case TSTRING:
139     case TSYMBOL:
140       {
141         if (TYPE (x) == TKEYWORD) fputs ("#:", fd);
142         if (write_p && TYPE (x) == TSTRING) fputc ('"', fd);
143         SCM t = CAR (x);
144         while (t && t != cell_nil)
145           {
146             switch (write_p ? VALUE (CAR (t)) : 0)
147               {
148               case '\t': fputs ("\\t", fd); break;
149               case '\n': fputs ("\\n", fd); break;
150               case '\\': fputs ("\\\\", fd); break;
151               case '"': fputs ("\\\"", fd); break;
152               default: fputc (VALUE (CAR (t)), fd);
153               }
154             t = CDR (t);
155           }
156         if (write_p && TYPE (x) == TSTRING) fputc ('"', fd);
157         break;
158       }
159     case TVECTOR:
160       {
161         fputs ("#(", fd);
162         SCM t = CAR (x);
163         for (int i = 0; i < LENGTH (x); i++)
164           {
165             if (i) fputc (' ', fd);
166             fdisplay_ (VECTOR (x) + i, fd, write_p);
167           }
168         fputc (')', fd);
169         break;
170       }
171     default:
172       {
173         fputs ("<", fd);
174         fputs (itoa (TYPE (x)), fd);
175         fputs (":", fd);
176         fputs (itoa (x), fd);
177         fputs (">", fd);
178         break;
179       }
180     }
181   return 0;
182 }
183
184 SCM
185 display_ (SCM x)
186 {
187   g_depth = 5;
188   return display_helper (x, 0, "", g_stdout, 0);
189 }
190
191 SCM
192 display_error_ (SCM x)
193 {
194   g_depth = 5;
195   return display_helper (x, 0, "", STDERR, 0);
196 }
197
198 SCM
199 display_port_ (SCM x, SCM p)
200 {
201   assert (TYPE (p) == TNUMBER);
202   return fdisplay_ (x, VALUE (p), 0);
203 }
204
205 SCM
206 write_ (SCM x)
207 {
208   g_depth = 5;
209   return display_helper (x, 0, "", g_stdout, 1);
210 }
211
212 SCM
213 write_error_ (SCM x)
214 {
215   g_depth = 5;
216   return display_helper (x, 0, "", STDERR, 1);
217 }
218
219 SCM
220 write_port_ (SCM x, SCM p)
221 {
222   assert (TYPE (p) == TNUMBER);
223   return fdisplay_ (x, VALUE (p), 1);
224 }
225
226 SCM
227 fdisplay_ (SCM x, int fd, int write_p) ///((internal))
228 {
229   g_depth = 5;
230   return display_helper (x, 0, "", fd, write_p);
231 }
232
233 SCM
234 exit_ (SCM x) ///((name . "exit"))
235 {
236   assert (TYPE (x) == TNUMBER);
237   exit (VALUE (x));
238 }
239
240 SCM
241 xassq (SCM x, SCM a) ///for speed in core only
242 {
243   while (a != cell_nil && x != CDAR (a)) a = CDR (a);
244   return a != cell_nil ? CAR (a) : cell_f;
245 }