Implement NTH.
[muddle-interpreter.git] / src / print.c
1 /*
2 Copyright (C) 2017-2018 Keziah Wesley
3
4 You can redistribute and/or modify this file under the terms of the
5 GNU Affero General Public License as published by the Free Software
6 Foundation, either version 3 of the License, or (at your option) any
7 later version.
8
9 This file is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Affero General Public License for more details.
13
14 You should have received a copy of the GNU Affero General Public
15 License along with this file. If not, see
16 <http://www.gnu.org/licenses/>.
17 */
18
19 #include "atom.h"
20 #include "print.h"
21 #include "object.h"
22
23 // TODO: "print" into buffer
24 #include <stdio.h>
25
26 #include <stdint.h>
27
28 static void
29 print_vector_body (const vector_object * o)
30 {
31   const object *p = HEAP_OBJECT (o->val.body);
32   if (!p)
33     return;
34   if (o->val.len)
35     print_object (&p[0]);
36   for (uint32_t i = 1; i < o->val.len; i++)
37     {
38       printf (" ");
39       print_object (&p[i]);
40     }
41 }
42
43 static void
44 print_uvector_body (const uvector_object * o)
45 {
46   const uv_val *p = UV_VAL (o->val.body);
47   if (!p)
48     return;
49   pool_object x;
50   x.type = utype (o);
51   x.rest = 0;
52   if (o->val.len)
53     {
54       x.val = p[0];
55       print_object ((object *) & x);
56     }
57   for (uint32_t i = 1; i < o->val.len; i++)
58     {
59       printf (" ");
60       x.val = p[i];
61       print_object ((object *) & x);
62     }
63 }
64
65 static void
66 print_list_body (const list_object * o)
67 {
68   const pool_object *p = POOL_OBJECT (o->val.head);
69   if (!p)
70     return;
71   print_object ((const object *) p);
72   while ((p = POOL_OBJECT (p->rest)))
73     {
74       printf (" ");
75       print_object ((const object *) p);
76     }
77 }
78
79 void
80 print_object (const object * o)
81 {
82   switch (o->type)
83     {
84     case EVALTYPE_FIX32:
85       printf ("%d", o->fix32.val.n);
86       break;
87     case EVALTYPE_FIX64:
88       printf ("%ld", o->fix64.val.n);
89       break;
90     case EVALTYPE_FALSE:
91       // for now, handle non-primtype print as special case (cf. OBLIST)
92       printf ("#FALSE ");
93       // FALLTHROUGH
94     case EVALTYPE_LIST:
95       printf ("(");
96       print_list_body (&o->list);
97       printf (")");
98       break;
99     case EVALTYPE_FORM:
100       printf ("<");
101       print_list_body (&o->list);
102       printf (">");
103       break;
104     case EVALTYPE_VECTOR:
105       printf ("[");
106       print_vector_body (&o->vector);
107       printf ("]");
108       break;
109     case EVALTYPE_OBLIST:
110       // for now, handle non-primtype print as special case
111       printf ("#OBLIST ");
112       // FALLTHROUGH
113     case EVALTYPE_UVECTOR:
114       printf ("![");
115       print_uvector_body (&o->uvector);
116       printf ("!]");
117       break;
118     case EVALTYPE_ATOM:
119       printf ("%s", atom_pname (o->atom));
120       break;
121     default:
122       fprintf (stderr, "Tried to print the unprintable: 0x%x\n", o->type);
123       assert (0 && "I don't know how to print that");
124     }
125 }