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
29 #include <st-object.h>
31 #include <st-symbol.h>
32 #include <st-character.h>
35 #include <st-unicode.h>
37 static void print_expression (st_node
*expression
);
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
);
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
) {
77 print_tuple (st_oop tuple
)
81 size
= st_smi_value (st_arrayed_object_size (tuple
));
84 for (int i
= 1; i
<= size
; i
++) {
85 print_object (st_array_at (tuple
, i
));
93 print_literal (st_node
*node
)
95 st_assert (node
->type
== ST_LITERAL_NODE
);
97 print_object (node
->literal
.value
);
101 print_return (st_node
*node
)
103 st_assert (node
->type
== ST_RETURN_NODE
);
106 print_expression (node
->retrn
.expression
);
111 print_assign (st_node
*node
)
113 st_assert (node
->type
== ST_ASSIGN_NODE
);
115 print_variable (node
->assign
.assignee
);
117 print_expression (node
->assign
.expression
);
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] = ':';
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
);
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
));
159 print_variable (node
->method
.arguments
);
162 printf ((char *) st_byte_array_bytes (node
->method
.selector
));
167 if (node
->method
.temporaries
!= NULL
) {
170 st_node
*temp
= node
->method
.temporaries
;
171 for (; temp
; temp
= temp
->next
) {
172 print_variable (temp
);
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
)
191 print_expression (stm
);
198 print_block (st_node
*node
)
200 st_assert (node
->type
== ST_BLOCK_NODE
);
204 if (node
->block
.arguments
!= NULL
) {
206 st_node
*arg
= node
->block
.arguments
;
207 for (; arg
; arg
= arg
->next
) {
209 print_variable (arg
);
216 if (node
->block
.temporaries
!= NULL
) {
219 st_node
*temp
= node
->block
.temporaries
;
220 for (; temp
; temp
= temp
->next
) {
221 print_variable (temp
);
228 st_node
*stm
= node
->block
.statements
;
229 for (; stm
; stm
= stm
->next
) {
230 if (stm
->type
== ST_RETURN_NODE
)
233 print_expression (stm
);
235 if (stm
->next
!= NULL
)
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
))
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
))
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
)
271 print_expression (node
->message
.receiver
);
273 if (node
->message
.receiver
->type
== ST_MESSAGE_NODE
&&
274 node
->message
.receiver
->message
.precedence
== ST_KEYWORD_PRECEDENCE
)
278 printf ((char *) st_byte_array_bytes (node
->message
.selector
));
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
))
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
))
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
)
303 print_expression (node
->message
.receiver
);
304 if (node
->message
.receiver
->type
== ST_MESSAGE_NODE
&&
305 node
->message
.receiver
->message
.precedence
== ST_KEYWORD_PRECEDENCE
)
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
)
317 print_expression (arguments
);
318 if (node
->message
.arguments
->type
== ST_MESSAGE_NODE
&&
319 node
->message
.arguments
->message
.precedence
== ST_KEYWORD_PRECEDENCE
)
324 arguments
= arguments
->next
;
326 st_strfreev (keywords
);
332 print_message (node
->next
);
337 print_expression (st_node
*node
)
339 switch (node
->type
) {
341 case ST_LITERAL_NODE
:
342 print_literal (node
);
345 case ST_VARIABLE_NODE
:
346 print_variable (node
);
357 case ST_MESSAGE_NODE
:
358 print_message (node
);
365 st_print_method_node (st_node
*node
)
367 st_assert (node
&& node
->type
== ST_METHOD_NODE
);
373 st_node_new (st_node_type type
)
375 st_node
*node
= st_new0 (st_node
);
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;
389 st_node_list_append (st_node
*list
, st_node
*node
)
402 st_node_list_length (st_node
*list
)
406 for (; l
; l
= l
->next
)
412 st_node_list_at (st_node
*list
, st_uint index
)
416 for (l
= list
; i
< index
; i
++)
422 st_node_destroy (st_node
*node
)
427 switch (node
->type
) {
429 st_node_destroy (node
->method
.arguments
);
430 st_node_destroy (node
->method
.temporaries
);
431 st_node_destroy (node
->method
.statements
);
435 st_node_destroy (node
->block
.arguments
);
436 st_node_destroy (node
->block
.temporaries
);
437 st_node_destroy (node
->block
.statements
);
441 st_node_destroy (node
->assign
.assignee
);
442 st_node_destroy (node
->assign
.expression
);
446 st_node_destroy (node
->retrn
.expression
);
449 case ST_MESSAGE_NODE
:
450 st_node_destroy (node
->message
.receiver
);
451 st_node_destroy (node
->message
.arguments
);
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
);
461 case ST_VARIABLE_NODE
:
463 st_free (node
->variable
.name
);
470 st_node_destroy (node
->next
);