Removed the notion of a "large" context. For simplicity, all contexts
[panda.git] / src / st-node.c
blob7fa8dbe562188612a3047a3d1fd2322748e97164
1 /*
2 * st-node.c
4 * Copyright (c) 2008 Vincent Geddes
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
25 #include <st-node.h>
26 #include <st-array.h>
27 #include <st-array.h>
28 #include <st-types.h>
29 #include <st-object.h>
30 #include <st-float.h>
31 #include <st-symbol.h>
32 #include <st-character.h>
33 #include <string.h>
35 #include <st-unicode.h>
37 static void print_expression (st_node *expression);
39 static void
40 print_variable (st_node *node)
42 st_assert (node->type == ST_VARIABLE_NODE);
44 printf (node->variable.name);
47 static void print_tuple (st_oop tuple);
49 static void
50 print_object (st_oop object)
52 if (st_object_is_smi (object)) {
53 printf ("%li", st_smi_value (object));
55 } else if (st_object_is_symbol (object)) {
57 printf ("#%s", st_byte_array_bytes (object));
58 } else if (st_object_class (object) == ST_STRING_CLASS) {
60 printf ("%s", st_byte_array_bytes (object));
61 } else if (st_object_is_float (object)) {
63 printf ("%f", st_float_value (object));
64 } else if (st_object_class (object) == ST_CHARACTER_CLASS) {
66 char outbuf[6] = { 0 };
67 st_unichar_to_utf8 (st_character_value (object), outbuf);
68 printf ("$%s", outbuf);
69 } else if (st_object_class (object) == ST_ARRAY_CLASS) {
71 print_tuple (object);
76 static void
77 print_tuple (st_oop tuple)
79 int size;
81 size = st_smi_value (st_arrayed_object_size (tuple));
83 printf ("#(");
84 for (int i = 1; i <= size; i++) {
85 print_object (st_array_at (tuple, i));
86 if (i < size)
87 printf (" ");
89 printf (")");
92 static void
93 print_literal (st_node *node)
95 st_assert (node->type == ST_LITERAL_NODE);
97 print_object (node->literal.value);
100 static void
101 print_return (st_node *node)
103 st_assert (node->type == ST_RETURN_NODE);
105 printf ("^ ");
106 print_expression (node->retrn.expression);
110 static void
111 print_assign (st_node *node)
113 st_assert (node->type == ST_ASSIGN_NODE);
115 print_variable (node->assign.assignee);
116 printf (" := ");
117 print_expression (node->assign.expression);
120 static char **
121 extract_keywords (char *selector)
123 int len = strlen (selector);
125 /* hide trailing ':' */
126 selector[len - 1] = 0;
127 char **keywords = st_strsplit (selector, ":", 0);
128 selector[len - 1] = ':';
130 return keywords;
133 static void
134 print_method (st_node *node)
136 st_assert (node->type == ST_METHOD_NODE);
138 if (node->method.precedence == ST_KEYWORD_PRECEDENCE) {
140 char *selector = (char *) st_byte_array_bytes (node->method.selector);
142 char **keywords = extract_keywords (selector);
143 st_node *arguments = node->method.arguments;
145 for (char **keyword = keywords; *keyword; keyword++) {
147 printf ("%s: ", *keyword);
148 print_variable (arguments);
149 printf (" ");
151 arguments = arguments->next;
153 st_strfreev (keywords);
155 } else if (node->method.precedence == ST_BINARY_PRECEDENCE) {
157 printf ((char *) st_byte_array_bytes (node->method.selector));
158 printf (" ");
159 print_variable (node->method.arguments);
160 } else {
162 printf ((char *) st_byte_array_bytes (node->method.selector));
165 printf ("\n");
167 if (node->method.temporaries != NULL) {
169 printf ("| ");
170 st_node *temp = node->method.temporaries;
171 for (; temp; temp = temp->next) {
172 print_variable (temp);
173 printf (" ");
175 printf ("|\n");
178 if (node->method.primitive >= 0) {
180 printf ("<primitive: %i>\n", node->method.primitive);
185 st_node *stm = node->method.statements;
186 for (; stm; stm = stm->next) {
188 if (stm->type == ST_RETURN_NODE)
189 print_return (stm);
190 else
191 print_expression (stm);
193 printf (".\n");
197 static void
198 print_block (st_node *node)
200 st_assert (node->type == ST_BLOCK_NODE);
202 printf ("[ ");
204 if (node->block.arguments != NULL) {
206 st_node *arg = node->block.arguments;
207 for (; arg; arg = arg->next) {
208 printf (":");
209 print_variable (arg);
210 printf (" ");
212 printf ("|");
213 printf (" ");
216 if (node->block.temporaries != NULL) {
218 printf ("| ");
219 st_node *temp = node->block.temporaries;
220 for (; temp; temp = temp->next) {
221 print_variable (temp);
222 printf (" ");
224 printf ("|");
225 printf (" ");
228 st_node *stm = node->block.statements;
229 for (; stm; stm = stm->next) {
230 if (stm->type == ST_RETURN_NODE)
231 print_return (stm);
232 else
233 print_expression (stm);
235 if (stm->next != NULL)
236 printf (". ");
239 printf (" ]");
243 static void
244 print_message (st_node *node)
247 if (node->message.precedence == ST_UNARY_PRECEDENCE) {
249 if (node->message.receiver->type == ST_MESSAGE_NODE &&
250 (node->message.receiver->message.precedence == ST_BINARY_PRECEDENCE ||
251 node->message.receiver->message.precedence == ST_KEYWORD_PRECEDENCE))
252 printf ("(");
254 print_expression (node->message.receiver);
256 if (node->message.receiver->type == ST_MESSAGE_NODE &&
257 (node->message.receiver->message.precedence == ST_BINARY_PRECEDENCE ||
258 node->message.receiver->message.precedence == ST_KEYWORD_PRECEDENCE))
259 printf ("(");
261 printf (" ");
262 printf ((char *) st_byte_array_bytes (node->message.selector));
265 } else if (node->message.precedence == ST_BINARY_PRECEDENCE) {
267 if (node->message.receiver->type == ST_MESSAGE_NODE &&
268 node->message.receiver->message.precedence == ST_KEYWORD_PRECEDENCE)
269 printf ("(");
271 print_expression (node->message.receiver);
273 if (node->message.receiver->type == ST_MESSAGE_NODE &&
274 node->message.receiver->message.precedence == ST_KEYWORD_PRECEDENCE)
275 printf (")");
277 printf (" ");
278 printf ((char *) st_byte_array_bytes (node->message.selector));
279 printf (" ");
281 if (node->message.arguments->type == ST_MESSAGE_NODE &&
282 (node->message.arguments->message.precedence == ST_BINARY_PRECEDENCE ||
283 node->message.arguments->message.precedence == ST_KEYWORD_PRECEDENCE))
284 printf ("(");
286 print_expression (node->message.arguments);
288 if (node->message.arguments->type == ST_MESSAGE_NODE &&
289 (node->message.arguments->message.precedence == ST_BINARY_PRECEDENCE ||
290 node->message.arguments->message.precedence == ST_KEYWORD_PRECEDENCE))
291 printf (")");
293 } else if (node->message.precedence == ST_KEYWORD_PRECEDENCE) {
295 char *selector = (char *) st_byte_array_bytes (node->message.selector);
297 char **keywords = extract_keywords (selector);
298 st_node *arguments = node->message.arguments;
300 if (node->message.receiver->type == ST_MESSAGE_NODE &&
301 node->message.receiver->message.precedence == ST_KEYWORD_PRECEDENCE)
302 printf ("(");
303 print_expression (node->message.receiver);
304 if (node->message.receiver->type == ST_MESSAGE_NODE &&
305 node->message.receiver->message.precedence == ST_KEYWORD_PRECEDENCE)
306 printf (")");
308 printf (" ");
310 for (char **keyword = keywords; *keyword; keyword++) {
312 printf ("%s: ", *keyword);
314 if (node->message.arguments->type == ST_MESSAGE_NODE &&
315 node->message.arguments->message.precedence == ST_KEYWORD_PRECEDENCE)
316 printf ("(");
317 print_expression (arguments);
318 if (node->message.arguments->type == ST_MESSAGE_NODE &&
319 node->message.arguments->message.precedence == ST_KEYWORD_PRECEDENCE)
320 printf (")");
322 printf (" ");
324 arguments = arguments->next;
326 st_strfreev (keywords);
330 if (node->next) {
331 printf (". ");
332 print_message (node->next);
336 static void
337 print_expression (st_node *node)
339 switch (node->type) {
341 case ST_LITERAL_NODE:
342 print_literal (node);
343 break;
345 case ST_VARIABLE_NODE:
346 print_variable (node);
347 break;
349 case ST_ASSIGN_NODE:
350 print_assign (node);
351 break;
353 case ST_BLOCK_NODE:
354 print_block (node);
355 break;
357 case ST_MESSAGE_NODE:
358 print_message (node);
359 break;
364 void
365 st_print_method_node (st_node *node)
367 st_assert (node && node->type == ST_METHOD_NODE);
369 print_method (node);
372 st_node *
373 st_node_new (st_node_type type)
375 st_node *node = st_new0 (st_node);
376 node->type = type;
378 if (node->type == ST_MESSAGE_NODE)
379 node->message.is_statement = false;
381 if (node->type == ST_CASCADE_NODE)
382 node->cascade.is_statement = false;
385 return node;
388 st_node *
389 st_node_list_append (st_node *list, st_node *node)
391 st_node *l = list;
392 if (list == NULL)
393 return node;
394 while (l->next)
395 l = l->next;
396 l->next = node;
397 return list;
401 st_uint
402 st_node_list_length (st_node *list)
404 st_node *l = list;
405 int len = 0;
406 for (; l; l = l->next)
407 ++len;
408 return len;
411 st_node *
412 st_node_list_at (st_node *list, st_uint index)
414 st_uint i = 0;
415 st_node *l;
416 for (l = list; i < index; i++)
417 l = l->next;
418 return l;
421 void
422 st_node_destroy (st_node *node)
424 if (node == NULL)
425 return;
427 switch (node->type) {
428 case ST_METHOD_NODE:
429 st_node_destroy (node->method.arguments);
430 st_node_destroy (node->method.temporaries);
431 st_node_destroy (node->method.statements);
432 break;
434 case ST_BLOCK_NODE:
435 st_node_destroy (node->block.arguments);
436 st_node_destroy (node->block.temporaries);
437 st_node_destroy (node->block.statements);
438 break;
440 case ST_ASSIGN_NODE:
441 st_node_destroy (node->assign.assignee);
442 st_node_destroy (node->assign.expression);
443 break;
445 case ST_RETURN_NODE:
446 st_node_destroy (node->retrn.expression);
447 break;
449 case ST_MESSAGE_NODE:
450 st_node_destroy (node->message.receiver);
451 st_node_destroy (node->message.arguments);
452 break;
454 case ST_CASCADE_NODE:
455 st_node_destroy (node->cascade.receiver);
457 st_list_foreach (node->cascade.messages, (st_list_foreach_func) st_node_destroy);
458 st_list_destroy (node->cascade.messages);
459 break;
461 case ST_VARIABLE_NODE:
463 st_free (node->variable.name);
464 break;
466 default:
467 break;
470 st_node_destroy (node->next);
471 st_free (node);