131589c9fbfaea55da93978e0835c61e7910d84d
[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         fputs ("#\\", fd);
36         fputc (VALUE (x), fd);
37         break;
38       }
39     case TCLOSURE:
40       {
41         fputs ("#<closure ", fd);
42         display_helper (CDR (x), cont, "", fd, 0);
43         fputs (">", fd);
44         break;
45       }
46     case TFUNCTION:
47       {
48         fputs ("#<procedure ", fd);
49         char const *p = "?";
50         if (FUNCTION (x).name != 0)
51           p = FUNCTION (x).name;
52         fputs (p, fd);
53         fputs ("[", fd);
54         fputs (itoa (CDR (x)), fd);
55         fputs (",", fd);
56         fputs (itoa (x), fd);
57         fputs ("]>", fd);
58         break;
59       }
60     case TMACRO:
61       {
62         fputs ("#<macro ", fd);
63         display_helper (CDR (x), cont, "", fd, 0);
64         fputs (">", fd);
65         break;
66       }
67     case TNUMBER:
68       {
69         fputs (itoa (VALUE (x)), fd);
70         break;
71       }
72     case TPAIR:
73       {
74         if (!cont) fputs ("(", fd);
75         if (CAR (x) == cell_circular)
76           {
77             fputs ("(*circ* . ", fd);
78             int i = 0;
79             x = CDR (x);
80             while (x != cell_nil && i++ < 10)
81               {
82                 fdisplay_ (CAAR (x), fd, write_p); fputs (" ", fd);
83                 x = CDR (x);
84               }
85             fputs (" ...)", fd);
86           }
87         else
88           {
89             if (x && x != cell_nil) fdisplay_ (CAR (x), fd, write_p);
90             if (CDR (x) && TYPE (CDR (x)) == TPAIR)
91               display_helper (CDR (x), 1, " ", fd, write_p);
92             else if (CDR (x) && CDR (x) != cell_nil)
93               {
94                 if (TYPE (CDR (x)) != TPAIR)
95                   fputs (" . ", fd);
96                 fdisplay_ (CDR (x), fd, write_p);
97               }
98           }
99         if (!cont) fputs (")", fd);
100         break;
101       }
102     case TSPECIAL:
103     case TSTRING:
104     case TSYMBOL:
105       {
106         if (write_p && TYPE (x) == TSTRING) fputc ('"', fd);
107         SCM t = CAR (x);
108         while (t && t != cell_nil)
109           {
110             fputc (VALUE (CAR (t)), fd);
111             t = CDR (t);
112           }
113         if (write_p && TYPE (x) == TSTRING) fputc ('"', fd);
114         break;
115       }
116     case TVECTOR:
117       {
118         fputs ("#(", fd);
119         SCM t = CAR (x);
120         for (int i = 0; i < LENGTH (x); i++)
121           {
122             if (i) fputc (' ', fd);
123             fdisplay_ (VECTOR (x) + i, fd, write_p);
124           }
125         fputc (')', fd);
126         break;
127       }
128     default:
129       {
130         fputs ("<", fd);
131         fputs (itoa (TYPE (x)), fd);
132         fputs (":", fd);
133         fputs (itoa (x), fd);
134         fputs (">", fd);
135         break;
136       }
137     }
138   return 0;
139 }
140
141 SCM
142 display_ (SCM x)
143 {
144   g_depth = 5;
145   return display_helper (x, 0, "", g_stdout, 0);
146 }
147
148 SCM
149 display_error_ (SCM x)
150 {
151   g_depth = 5;
152   return display_helper (x, 0, "", STDERR, 0);
153 }
154
155 SCM
156 display_port_ (SCM x, SCM p)
157 {
158   assert (TYPE (p) == TNUMBER);
159   return fdisplay_ (x, VALUE (p), 0);
160 }
161
162 SCM
163 write_ (SCM x)
164 {
165   g_depth = 5;
166   return display_helper (x, 0, "", g_stdout, 1);
167 }
168
169 SCM
170 write_error_ (SCM x)
171 {
172   g_depth = 5;
173   return display_helper (x, 0, "", STDERR, 1);
174 }
175
176 SCM
177 write_port_ (SCM x, SCM p)
178 {
179   assert (TYPE (p) == TNUMBER);
180   return fdisplay_ (x, VALUE (p), 1);
181 }
182
183 SCM
184 fdisplay_ (SCM x, int fd, int write_p) ///((internal))
185 {
186   g_depth = 5;
187   return display_helper (x, 0, "", fd, write_p);
188 }
189
190 SCM
191 exit_ (SCM x) ///((name . "exit"))
192 {
193   assert (TYPE (x) == TNUMBER);
194   exit (VALUE (x));
195 }
196
197 SCM
198 xassq (SCM x, SCM a) ///for speed in core only
199 {
200   while (a != cell_nil && x != CDAR (a)) a = CDR (a);
201   return a != cell_nil ? CAR (a) : cell_f;
202 }