/[cvs]/stack/symbols.c
ViewVC logotype

Contents of /stack/symbols.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (show annotations)
Wed Aug 13 11:58:00 2003 UTC (20 years, 9 months ago) by masse
Branch: MAIN
Changes since 1.8: +114 -442 lines
File MIME type: text/plain
messages.h: Removed "\n" at the end of messages.
stack.c, stack.h (printerr): Made function smarter.
stack.c, symbols.c: Made better use of "check_args" and "printerr".

1 #include "stack.h"
2 #include "messages.h"
3
4 /* Print newline. */
5 extern void nl(environment *env)
6 {
7 printf("\n");
8 }
9
10 /* Print a newline to a port */
11 extern void nlport(environment *env)
12 {
13 if(check_args(env, port, empty))
14 return printerr(env);
15
16 if(fprintf(CAR(env->head)->content.p, "\n") < 0){
17 perror("nl");
18 env->err= 5;
19 return;
20 }
21 toss(env);
22 }
23
24 /* Gets the type of a value */
25 extern void type(environment *env)
26 {
27
28 if(check_args(env, unknown, empty))
29 return printerr(env);
30
31 switch(CAR(env->head)->type){
32 case empty:
33 push_sym(env, "empty");
34 break;
35 case unknown:
36 push_sym(env, "unknown");
37 break;
38 case integer:
39 push_sym(env, "integer");
40 break;
41 case tfloat:
42 push_sym(env, "float");
43 break;
44 case string:
45 push_sym(env, "string");
46 break;
47 case symb:
48 push_sym(env, "symbol");
49 break;
50 case func:
51 push_sym(env, "function");
52 break;
53 case tcons:
54 push_sym(env, "pair");
55 break;
56 case port:
57 push_sym(env, "port");
58 break;
59 }
60 swap(env);
61 if (env->err) return;
62 toss(env);
63 }
64
65 /* Print the top element of the stack but don't discard it */
66 extern void print_(environment *env)
67 {
68
69 if(check_args(env, unknown, empty))
70 return printerr(env);
71
72 print_val(env, CAR(env->head), 0, NULL, stdout);
73 if(env->err) return;
74 nl(env);
75 }
76
77 /* Prints the top element of the stack */
78 extern void print(environment *env)
79 {
80 print_(env);
81 if(env->err) return;
82 toss(env);
83 }
84
85 /* Print the top element of the stack without quotes, but don't
86 discard it. */
87 extern void princ_(environment *env)
88 {
89
90 if(check_args(env, unknown, empty))
91 return printerr(env);
92
93 print_val(env, CAR(env->head), 1, NULL, stdout);
94 }
95
96 /* Prints the top element of the stack without quotes. */
97 extern void princ(environment *env)
98 {
99 princ_(env);
100 if(env->err) return;
101 toss(env);
102 }
103
104 /* Print a value to a port, but don't discard it */
105 extern void printport_(environment *env)
106 {
107
108 if(check_args(env, port, unknown, empty))
109 return printerr(env);
110
111 print_val(env, CAR(CDR(env->head)), 0, NULL, CAR(env->head)->content.p);
112 if(env->err) return;
113 nlport(env);
114 }
115
116 /* Print a value to a port */
117 extern void printport(environment *env)
118 {
119 printport_(env);
120 if(env->err) return;
121 toss(env);
122 }
123
124 /* Print, without quotes, to a port, a value, but don't discard it. */
125 extern void princport_(environment *env)
126 {
127
128 if(check_args(env, port, unknown, empty))
129 return printerr(env);
130
131 print_val(env, CAR(CDR(env->head)), 1, NULL, CAR(env->head)->content.p);
132 toss(env); if(env->err) return;
133 }
134
135 /* Print, without quotes, to a port, the top element. */
136 extern void princport(environment *env)
137 {
138 princport_(env);
139 if(env->err) return;
140 toss(env);
141 }
142
143 /* Rotate the first three elements on the stack. */
144 extern void rot(environment *env)
145 {
146 value *temp= env->head;
147
148 if(check_args(env, unknown, unknown, unknown, empty))
149 return printerr(env);
150
151 env->head= CDR(CDR(env->head));
152 CDR(CDR(temp))= CDR(env->head);
153 CDR(env->head)= temp;
154 }
155
156 /* Relocate elements of the list on the stack. */
157 extern void expand(environment *env)
158 {
159 value *temp, *new_head;
160
161 if(check_args(env, tcons, empty))
162 return printerr(env);
163
164 rev(env);
165
166 if(env->err)
167 return;
168
169 /* The first list element is the new stack head */
170 new_head= temp= CAR(env->head);
171
172 toss(env);
173
174 /// XXX
175 /* Find the end of the list */
176 while(CDR(temp)->type != empty) {
177 if (CDR(temp)->type == tcons)
178 temp= CDR(temp);
179 else {
180 env->err= 2; /* Improper list */
181 return printerr(env);
182 }
183 }
184
185 /* Connect the tail of the list with the old stack head */
186 CDR(temp)= env->head;
187 env->head= new_head; /* ...and voila! */
188
189 }
190
191 /* Compares two elements by reference. */
192 extern void eq(environment *env)
193 {
194 void *left, *right;
195
196 if(check_args(env, unknown, unknown, empty))
197 return printerr(env);
198
199 left= CAR(env->head)->content.ptr;
200 right= CAR(CDR(env->head))->content.ptr;
201 toss(env); toss(env);
202
203 push_int(env, left==right);
204 }
205
206 /* Negates the top element on the stack. */
207 extern void not(environment *env)
208 {
209 int val;
210
211 if(check_args(env, integer, empty))
212 return printerr(env);
213
214 val= CAR(env->head)->content.i;
215 toss(env);
216 push_int(env, !val);
217 }
218
219 /* Compares the two top elements on the stack and return 0 if they're the
220 same. */
221 extern void neq(environment *env)
222 {
223 eq(env);
224 not(env);
225 }
226
227 extern void def(environment *env)
228 {
229 symbol *sym;
230
231 /* Needs two values on the stack, the top one must be a symbol */
232 if(check_args(env, symb, unknown, empty))
233 return printerr(env);
234
235 /* long names are a pain */
236 sym= CAR(env->head)->content.sym;
237
238 /* Bind the symbol to the value */
239 sym->val= CAR(CDR(env->head));
240
241 toss(env); toss(env);
242 }
243
244 /* Clear stack */
245 extern void clear(environment *env)
246 {
247 env->head= new_val(env);
248 }
249
250 /* Forgets a symbol (remove it from the hash table) */
251 extern void forget(environment *env)
252 {
253 char* sym_id;
254
255 if(check_args(env, symb, empty))
256 return printerr(env);
257
258 sym_id= CAR(env->head)->content.sym->id;
259 toss(env);
260
261 return forget_sym(hash(env->symbols, sym_id));
262 }
263
264 /* Returns the current error number to the stack */
265 extern void errn(environment *env)
266 {
267 push_int(env, env->err);
268 }
269
270 /* "+" */
271 extern void sx_2b(environment *env)
272 {
273 int a, b;
274 float fa, fb;
275 size_t len;
276 char* new_string;
277 value *a_val, *b_val;
278
279 if(check_args(env, unknown, unknown, empty))
280 return printerr(env);
281
282 if(check_args(env, string, string, empty)==0) {
283 a_val= CAR(env->head);
284 b_val= CAR(CDR(env->head));
285 protect(a_val); protect(b_val);
286 toss(env); if(env->err) return;
287 toss(env); if(env->err) return;
288 len= strlen(a_val->content.string)+strlen(b_val->content.string)+1;
289 new_string= malloc(len);
290 assert(new_string != NULL);
291 strcpy(new_string, b_val->content.string);
292 strcat(new_string, a_val->content.string);
293 push_cstring(env, new_string);
294 unprotect(a_val); unprotect(b_val);
295 free(new_string);
296
297 return;
298 }
299
300 if(check_args(env, integer, integer, empty)==0) {
301 a= CAR(env->head)->content.i;
302 toss(env); if(env->err) return;
303 b= CAR(env->head)->content.i;
304 toss(env); if(env->err) return;
305 push_int(env, b+a);
306
307 return;
308 }
309
310 if(check_args(env, tfloat, tfloat, empty)==0) {
311 fa= CAR(env->head)->content.f;
312 toss(env); if(env->err) return;
313 fb= CAR(env->head)->content.f;
314 toss(env); if(env->err) return;
315 push_float(env, fb+fa);
316
317 return;
318 }
319
320 if(check_args(env, tfloat, integer, empty)==0) {
321 fa= CAR(env->head)->content.f;
322 toss(env); if(env->err) return;
323 b= CAR(env->head)->content.i;
324 toss(env); if(env->err) return;
325 push_float(env, b+fa);
326
327 return;
328 }
329
330 if(check_args(env, integer, tfloat, empty)==0) {
331 a= CAR(env->head)->content.i;
332 toss(env); if(env->err) return;
333 fb= CAR(env->head)->content.f;
334 toss(env); if(env->err) return;
335 push_float(env, fb+a);
336
337 return;
338 }
339
340 return printerr(env);
341 }
342
343 /* "-" */
344 extern void sx_2d(environment *env)
345 {
346 int a, b;
347 float fa, fb;
348
349 if(check_args(env, unknown, unknown, empty))
350 return printerr(env);
351
352 if(check_args(env, integer, integer, empty)==0) {
353 a= CAR(env->head)->content.i;
354 toss(env); if(env->err) return;
355 b= CAR(env->head)->content.i;
356 toss(env); if(env->err) return;
357 push_int(env, b-a);
358
359 return;
360 }
361
362 if(check_args(env, tfloat, tfloat, empty)==0) {
363 fa= CAR(env->head)->content.f;
364 toss(env); if(env->err) return;
365 fb= CAR(env->head)->content.f;
366 toss(env); if(env->err) return;
367 push_float(env, fb-fa);
368
369 return;
370 }
371
372 if(check_args(env, tfloat, integer, empty)==0) {
373 fa= CAR(env->head)->content.f;
374 toss(env); if(env->err) return;
375 b= CAR(env->head)->content.i;
376 toss(env); if(env->err) return;
377 push_float(env, b-fa);
378
379 return;
380 }
381
382 if(check_args(env, integer, tfloat, empty)==0) {
383 a= CAR(env->head)->content.i;
384 toss(env); if(env->err) return;
385 fb= CAR(env->head)->content.f;
386 toss(env); if(env->err) return;
387 push_float(env, fb-a);
388
389 return;
390 }
391
392 return printerr(env);
393 }
394
395 /* ">" */
396 extern void sx_3e(environment *env)
397 {
398 int a, b;
399 float fa, fb;
400
401 if(check_args(env, unknown, unknown, empty))
402 return printerr(env);
403
404 if(check_args(env, integer, integer, empty)==0) {
405 a= CAR(env->head)->content.i;
406 toss(env); if(env->err) return;
407 b= CAR(env->head)->content.i;
408 toss(env); if(env->err) return;
409 push_int(env, b>a);
410
411 return;
412 }
413
414 if(check_args(env, tfloat, tfloat, empty)==0) {
415 fa= CAR(env->head)->content.f;
416 toss(env); if(env->err) return;
417 fb= CAR(env->head)->content.f;
418 toss(env); if(env->err) return;
419 push_int(env, fb>fa);
420
421 return;
422 }
423
424 if(check_args(env, tfloat, integer, empty)==0) {
425 fa= CAR(env->head)->content.f;
426 toss(env); if(env->err) return;
427 b= CAR(env->head)->content.i;
428 toss(env); if(env->err) return;
429 push_int(env, b>fa);
430
431 return;
432 }
433
434 if(check_args(env, integer, tfloat, empty)==0) {
435 a= CAR(env->head)->content.i;
436 toss(env); if(env->err) return;
437 fb= CAR(env->head)->content.f;
438 toss(env); if(env->err) return;
439 push_int(env, fb>a);
440
441 return;
442 }
443
444 return printerr(env);
445 }
446
447 /* "<" */
448 extern void sx_3c(environment *env)
449 {
450 swap(env); if(env->err) return;
451 sx_3e(env);
452 }
453
454 /* "<=" */
455 extern void sx_3c3d(environment *env)
456 {
457 sx_3e(env); if(env->err) return;
458 not(env);
459 }
460
461 /* ">=" */
462 extern void sx_3e3d(environment *env)
463 {
464 sx_3c(env); if(env->err) return;
465 not(env);
466 }
467
468 /* "dup"; duplicates an item on the stack */
469 extern void sx_647570(environment *env)
470 {
471 if(check_args(env, unknown, empty))
472 return printerr(env);
473
474 push_val(env, copy_val(env, CAR(env->head)));
475 }
476
477 /* "if", If-Then */
478 extern void sx_6966(environment *env)
479 {
480 int truth;
481
482 if(check_args(env, unknown, integer, empty))
483 return printerr(env);
484
485 swap(env);
486 if(env->err) return;
487
488 truth= CAR(env->head)->content.i;
489
490 toss(env);
491 if(env->err) return;
492
493 if(truth)
494 eval(env);
495 else
496 toss(env);
497 }
498
499 /* If-Then-Else */
500 extern void ifelse(environment *env)
501 {
502 int truth;
503
504 if(check_args(env, unknown, unknown, integer, empty))
505 return printerr(env);
506
507 rot(env);
508 if(env->err) return;
509
510 truth= CAR(env->head)->content.i;
511
512 toss(env);
513 if(env->err) return;
514
515 if(!truth)
516 swap(env);
517 if(env->err) return;
518
519 toss(env);
520 if(env->err) return;
521
522 eval(env);
523 }
524
525 /* "else" */
526 extern void sx_656c7365(environment *env)
527 {
528
529 if(check_args(env, unknown, symb, unknown, symb, integer, empty))
530 return printerr(env);
531
532 /// XXX
533
534 if(CAR(CDR(env->head))->type!=symb
535 || strcmp(CAR(CDR(env->head))->content.sym->id, "then")!=0
536 || CAR(CDR(CDR(CDR(env->head))))->type!=symb
537 || strcmp(CAR(CDR(CDR(CDR(env->head))))->content.sym->id, "if")!=0) {
538 env->err= 2;
539 return printerr(env);
540 }
541
542 swap(env); toss(env); rot(env); toss(env);
543 ifelse(env);
544 }
545
546 extern void then(environment *env)
547 {
548
549 if(check_args(env, unknown, symb, integer, empty))
550 return printerr(env);
551
552 /// XXX
553
554 if(CAR(CDR(env->head))->type!=symb
555 || strcmp(CAR(CDR(env->head))->content.sym->id, "if")!=0) {
556 env->err= 2;
557 return printerr(env);
558 }
559
560 swap(env); toss(env);
561 sx_6966(env);
562 }
563
564 /* "while" */
565 extern void sx_7768696c65(environment *env)
566 {
567 int truth;
568 value *loop, *test;
569
570 if(check_args(env, unknown, integer, empty))
571 return printerr(env);
572
573 loop= CAR(env->head);
574 protect(loop);
575 toss(env); if(env->err) return;
576
577 test= CAR(env->head);
578 protect(test);
579 toss(env); if(env->err) return;
580
581 do {
582 push_val(env, test);
583 eval(env);
584
585 /// XXX
586
587 if(CAR(env->head)->type != integer) {
588 env->err= 2;
589 return printerr(env);
590 }
591
592 truth= CAR(env->head)->content.i;
593 toss(env); if(env->err) return;
594
595 if(truth) {
596 push_val(env, loop);
597 eval(env);
598 } else {
599 toss(env);
600 }
601
602 } while(truth);
603
604 unprotect(loop); unprotect(test);
605 }
606
607
608 /* "for"; for-loop */
609 extern void sx_666f72(environment *env)
610 {
611 value *loop;
612 int foo1, foo2;
613
614 if(check_args(env, unknown, integer, integer, empty))
615 return printerr(env);
616
617 loop= CAR(env->head);
618 protect(loop);
619 toss(env); if(env->err) return;
620
621 foo2= CAR(env->head)->content.i;
622 toss(env); if(env->err) return;
623
624 foo1= CAR(env->head)->content.i;
625 toss(env); if(env->err) return;
626
627 if(foo1<=foo2) {
628 while(foo1<=foo2) {
629 push_int(env, foo1);
630 push_val(env, loop);
631 eval(env); if(env->err) return;
632 foo1++;
633 }
634 } else {
635 while(foo1>=foo2) {
636 push_int(env, foo1);
637 push_val(env, loop);
638 eval(env); if(env->err) return;
639 foo1--;
640 }
641 }
642 unprotect(loop);
643 }
644
645 /* Variant of for-loop
646 Requires a list as first argument */
647 extern void foreach(environment *env)
648 {
649 value *loop, *foo;
650 value *iterator;
651
652 if(check_args(env, unknown, tcons, empty))
653 return printerr(env);
654
655 loop= CAR(env->head);
656 protect(loop);
657 toss(env); if(env->err) return;
658
659 foo= CAR(env->head);
660 protect(foo);
661 toss(env); if(env->err) return;
662
663 iterator= foo;
664
665 while(iterator->type!=empty) {
666 push_val(env, CAR(iterator));
667 push_val(env, loop);
668 eval(env); if(env->err) return;
669
670 /// XXX
671 if (iterator->type == tcons){
672 iterator= CDR(iterator);
673 } else {
674 env->err= 2; /* Improper list */
675 break;
676 }
677 }
678 unprotect(loop); unprotect(foo);
679
680 return printerr(env);
681 }
682
683 /* "to" */
684 extern void to(environment *env)
685 {
686 int ending, start, i;
687 value *iterator, *temp, *end;
688
689 if(check_args(env, integer, integer, empty))
690 return printerr(env);
691
692 end= new_val(env);
693
694 ending= CAR(env->head)->content.i;
695 toss(env); if(env->err) return;
696 start= CAR(env->head)->content.i;
697 toss(env); if(env->err) return;
698
699 push_sym(env, "[");
700
701 if(ending>=start) {
702 for(i= ending; i>=start; i--)
703 push_int(env, i);
704 } else {
705 for(i= ending; i<=start; i++)
706 push_int(env, i);
707 }
708
709 iterator= env->head;
710
711 if(iterator->type==empty
712 || (CAR(iterator)->type==symb
713 && CAR(iterator)->content.sym->id[0]=='[')) {
714 temp= end;
715 toss(env);
716 } else {
717 /* Search for first delimiter */
718 while(CDR(iterator)->type!=empty
719 && (CAR(CDR(iterator))->type!=symb
720 || CAR(CDR(iterator))->content.sym->id[0]!='['))
721 iterator= CDR(iterator);
722
723 /* Extract list */
724 temp= env->head;
725 env->head= CDR(iterator);
726 CDR(iterator)= end;
727
728 if(env->head->type!=empty)
729 toss(env);
730 }
731
732 /* Push list */
733 push_val(env, temp);
734 }
735
736 /* Read a string */
737 extern void readline(environment *env)
738 {
739 readlinestream(env, env->inputstream);
740 }
741
742 /* Read a string from a port */
743 extern void readlineport(environment *env)
744 {
745 FILE *stream;
746
747 if(check_args(env, port, empty))
748 return printerr(env);
749
750 stream=CAR(env->head)->content.p;
751 readlinestream(env, stream); if(env->err) return;
752
753 swap(env); if(env->err) return;
754 toss(env);
755 }
756
757 /* "read"; Read a value and place on stack */
758 extern void sx_72656164(environment *env)
759 {
760 readstream(env, env->inputstream);
761 }
762
763 /* "readport"; Read a value from a port and place on stack */
764 extern void readport(environment *env)
765 {
766 FILE *stream;
767
768 if(check_args(env, port, empty))
769 return printerr(env);
770
771 stream=CAR(env->head)->content.p;
772 readstream(env, stream); if(env->err) return;
773
774 swap(env); if(env->err) return;
775 toss(env);
776 }
777
778 #ifdef __linux__
779 extern void beep(environment *env)
780 {
781 int freq, dur, period, ticks;
782
783 if(check_args(env, integer, integer, empty))
784 return printerr(env);
785
786 dur= CAR(env->head)->content.i;
787 toss(env);
788 freq= CAR(env->head)->content.i;
789 toss(env);
790
791 period= 1193180/freq; /* convert freq from Hz to period
792 length */
793 ticks= dur*.001193180; /* convert duration from µseconds to
794 timer ticks */
795
796 /* ticks=dur/1000; */
797
798 /* if (ioctl(STDOUT_FILENO, KDMKTONE, (125<<16) + 0x637)==0) */
799 switch (ioctl(STDOUT_FILENO, KDMKTONE, (ticks<<16) | period)){
800 case 0:
801 usleep(dur);
802 return;
803 case -1:
804 perror("beep");
805 env->err= 5;
806 return;
807 default:
808 abort();
809 }
810 }
811 #endif /* __linux__ */
812
813 /* "wait" */
814 extern void sx_77616974(environment *env)
815 {
816 int dur;
817
818 if(check_args(env, integer, empty))
819 return printerr(env);
820
821 dur= CAR(env->head)->content.i;
822 toss(env);
823
824 usleep(dur);
825 }
826
827
828 /* "*" */
829 extern void sx_2a(environment *env)
830 {
831 int a, b;
832 float fa, fb;
833
834 if(check_args(env, unknown, unknown, empty))
835 return printerr(env);
836
837 if(check_args(env, integer, integer, empty)==0) {
838 a= CAR(env->head)->content.i;
839 toss(env); if(env->err) return;
840 b= CAR(env->head)->content.i;
841 toss(env); if(env->err) return;
842 push_int(env, b*a);
843
844 return;
845 }
846
847 if(check_args(env, tfloat, tfloat, empty)==0) {
848 fa= CAR(env->head)->content.f;
849 toss(env); if(env->err) return;
850 fb= CAR(env->head)->content.f;
851 toss(env); if(env->err) return;
852 push_float(env, fb*fa);
853
854 return;
855 }
856
857 if(check_args(env, tfloat, integer, empty)==0) {
858 fa= CAR(env->head)->content.f;
859 toss(env); if(env->err) return;
860 b= CAR(env->head)->content.i;
861 toss(env); if(env->err) return;
862 push_float(env, b*fa);
863
864 return;
865 }
866
867 if(check_args(env, integer, tfloat, empty)==0) {
868 a= CAR(env->head)->content.i;
869 toss(env); if(env->err) return;
870 fb= CAR(env->head)->content.f;
871 toss(env); if(env->err) return;
872 push_float(env, fb*a);
873
874 return;
875 }
876
877 return printerr(env);
878 }
879
880 /* "/" */
881 extern void sx_2f(environment *env)
882 {
883 int a, b;
884 float fa, fb;
885
886 if(check_args(env, unknown, unknown, empty))
887 return printerr(env);
888
889 if(check_args(env, integer, integer, empty)==0) {
890 a= CAR(env->head)->content.i;
891 toss(env); if(env->err) return;
892 b= CAR(env->head)->content.i;
893 toss(env); if(env->err) return;
894 push_float(env, b/a);
895
896 return;
897 }
898
899 if(check_args(env, tfloat, tfloat, empty)==0) {
900 fa= CAR(env->head)->content.f;
901 toss(env); if(env->err) return;
902 fb= CAR(env->head)->content.f;
903 toss(env); if(env->err) return;
904 push_float(env, fb/fa);
905
906 return;
907 }
908
909 if(check_args(env, tfloat, integer, empty)==0) {
910 fa= CAR(env->head)->content.f;
911 toss(env); if(env->err) return;
912 b= CAR(env->head)->content.i;
913 toss(env); if(env->err) return;
914 push_float(env, b/fa);
915
916 return;
917 }
918
919 if(check_args(env, integer, tfloat, empty)==0) {
920 a= CAR(env->head)->content.i;
921 toss(env); if(env->err) return;
922 fb= CAR(env->head)->content.f;
923 toss(env); if(env->err) return;
924 push_float(env, fb/a);
925
926 return;
927 }
928
929 return printerr(env);
930 }
931
932 /* "mod" */
933 extern void mod(environment *env)
934 {
935 int a, b;
936
937 if(check_args(env, unknown, unknown, empty))
938 return printerr(env);
939
940 if(check_args(env, integer, integer, empty)==0) {
941 a= CAR(env->head)->content.i;
942 toss(env); if(env->err) return;
943 b= CAR(env->head)->content.i;
944 toss(env); if(env->err) return;
945 push_int(env, b%a);
946
947 return;
948 }
949
950 return printerr(env);
951 }
952
953
954 /* "div" */
955 extern void sx_646976(environment *env)
956 {
957 int a, b;
958
959 if(check_args(env, integer, integer, empty))
960 return printerr(env);
961
962 a= CAR(env->head)->content.i;
963 toss(env); if(env->err) return;
964 b= CAR(env->head)->content.i;
965 toss(env); if(env->err) return;
966 push_int(env, (int)b/a);
967 }
968
969
970 extern void setcar(environment *env)
971 {
972
973 if(check_args(env, tcons, unknown, empty))
974 return printerr(env);
975
976 CAR(CAR(CDR(env->head)))=CAR(env->head);
977 toss(env);
978 }
979
980 extern void setcdr(environment *env)
981 {
982
983 if(check_args(env, tcons, unknown, empty))
984 return printerr(env);
985
986 CDR(CAR(CDR(env->head)))=CAR(env->head);
987 toss(env);
988 }
989
990 extern void car(environment *env)
991 {
992
993 if(check_args(env, tcons, empty))
994 return printerr(env);
995
996 CAR(env->head)=CAR(CAR(env->head));
997 }
998
999 extern void cdr(environment *env)
1000 {
1001
1002 if(check_args(env, tcons, empty))
1003 return printerr(env);
1004
1005 CAR(env->head)=CDR(CAR(env->head));
1006 }
1007
1008 extern void cons(environment *env)
1009 {
1010 value *val;
1011
1012 if(check_args(env, unknown, unknown, empty))
1013 return printerr(env);
1014
1015 val=new_val(env);
1016 val->content.c= malloc(sizeof(pair));
1017 assert(val->content.c!=NULL);
1018
1019 env->gc_count += sizeof(pair);
1020 val->type=tcons;
1021
1022 CAR(val)= CAR(CDR(env->head));
1023 CDR(val)= CAR(env->head);
1024
1025 push_val(env, val);
1026
1027 swap(env); if(env->err) return;
1028 toss(env); if(env->err) return;
1029 swap(env); if(env->err) return;
1030 toss(env);
1031 }
1032
1033
1034 /* General assoc function */
1035 void assocgen(environment *env, funcp eqfunc)
1036 {
1037 value *key, *item;
1038
1039 /* Needs two values on the stack, the top one must be an association
1040 list */
1041 if(check_args(env, tcons, unknown, empty))
1042 return printerr(env);
1043
1044 key=CAR(CDR(env->head));
1045 item=CAR(env->head);
1046
1047 while(item->type == tcons){
1048 if(CAR(item)->type != tcons){
1049 env->err= 2;
1050 return printerr(env);
1051 }
1052
1053 push_val(env, key);
1054 push_val(env, CAR(CAR(item)));
1055 eqfunc((void*)env); if(env->err) return;
1056
1057 /* Check the result of 'eqfunc' */
1058 if(check_args(env, integer, empty))
1059 return printerr(env);
1060
1061 if(CAR(env->head)->content.i){
1062 toss(env); if(env->err) return;
1063 break;
1064 }
1065 toss(env); if(env->err) return;
1066
1067 if(item->type!=tcons) {
1068 env->err= 2;
1069 return printerr(env);
1070 }
1071
1072 item=CDR(item);
1073 }
1074
1075 if(item->type == tcons){ /* A match was found */
1076 push_val(env, CAR(item));
1077 } else {
1078 push_int(env, 0);
1079 }
1080 swap(env); if(env->err) return;
1081 toss(env); if(env->err) return;
1082 swap(env); if(env->err) return;
1083 toss(env);
1084 }
1085
1086
1087 /* 2: 3 => */
1088 /* 1: [ [ 1 . 2 ] [ 3 . 4 ] ] => 1: [ 3 . 4 ] */
1089 extern void assq(environment *env)
1090 {
1091 assocgen(env, (void*)eq);
1092 }
1093
1094
1095 /* "do" */
1096 extern void sx_646f(environment *env)
1097 {
1098 swap(env); if(env->err) return;
1099 eval(env);
1100 }
1101
1102 /* "open" */
1103 /* 2: "file" */
1104 /* 1: "r" => 1: #<port 0x47114711> */
1105 extern void sx_6f70656e(environment *env)
1106 {
1107 value *new_port;
1108 FILE *stream;
1109
1110 if(check_args(env, string, string, empty))
1111 return printerr(env);
1112
1113 stream=fopen(CAR(CDR(env->head))->content.ptr,
1114 CAR(env->head)->content.ptr);
1115
1116 if(stream == NULL) {
1117 perror("open");
1118 env->err= 5;
1119 return;
1120 }
1121
1122 new_port=new_val(env);
1123 new_port->type=port;
1124 new_port->content.p=stream;
1125
1126 push_val(env, new_port);
1127
1128 swap(env); if(env->err) return;
1129 toss(env); if(env->err) return;
1130 swap(env); if(env->err) return;
1131 toss(env);
1132 }
1133
1134
1135 /* "close" */
1136 extern void sx_636c6f7365(environment *env)
1137 {
1138 int ret;
1139
1140 if(check_args(env, port, empty))
1141 return printerr(env);
1142
1143 ret= fclose(CAR(env->head)->content.p);
1144
1145 if(ret != 0){
1146 perror("close");
1147 env->err= 5;
1148 return;
1149 }
1150
1151 toss(env);
1152 }
1153
1154
1155 extern void mangle(environment *env)
1156 {
1157 char *new_string;
1158
1159 if(check_args(env, string, empty))
1160 return printerr(env);
1161
1162 new_string= mangle_str(CAR(env->head)->content.string);
1163
1164 toss(env);
1165 if(env->err) return;
1166
1167 push_cstring(env, new_string);
1168 }
1169
1170 /* "fork" */
1171 extern void sx_666f726b(environment *env)
1172 {
1173 push_int(env, fork());
1174 }
1175
1176 /* "waitpid" */
1177 extern void sx_77616974706964(environment *env)
1178 {
1179
1180 if(check_args(env, integer, empty))
1181 return printerr(env);
1182
1183 push_int(env, waitpid(CAR(env->head)->content.i, NULL, 0));
1184 swap(env); toss(env);
1185 }
1186
1187
1188 /* Discard the top element of the stack. */
1189 extern void toss(environment *env)
1190 {
1191
1192 if(check_args(env, unknown, empty))
1193 return printerr(env);
1194
1195 env->head= CDR(env->head); /* Remove the top stack item */
1196 }
1197
1198
1199 /* Quit stack. */
1200 extern void quit(environment *env)
1201 {
1202 int i;
1203
1204 env->head= new_val(env);
1205
1206 if (env->err) return;
1207 for(i= 0; i<HASHTBLSIZE; i++) {
1208 while(env->symbols[i]!= NULL) {
1209 forget_sym(&(env->symbols[i]));
1210 }
1211 env->symbols[i]= NULL;
1212 }
1213
1214 env->gc_limit= 0;
1215 gc_maybe(env);
1216
1217 words(env);
1218
1219 if(env->free_string!=NULL)
1220 free(env->free_string);
1221
1222 #ifdef __linux__
1223 muntrace();
1224 #endif
1225
1226 exit(EXIT_SUCCESS);
1227 }
1228
1229
1230 /* List all defined words */
1231 extern void words(environment *env)
1232 {
1233 symbol *temp;
1234 int i;
1235
1236 for(i= 0; i<HASHTBLSIZE; i++) {
1237 temp= env->symbols[i];
1238 while(temp!=NULL) {
1239 #ifdef DEBUG
1240 if (temp->val != NULL && temp->val->gc.flag.protect)
1241 printf("(protected) ");
1242 #endif /* DEBUG */
1243 printf("%s ", temp->id);
1244 temp= temp->next;
1245 }
1246 }
1247 }
1248
1249
1250 /* Only to be called by itself function printstack. */
1251 void print_st(environment *env, value *stack_head, long counter)
1252 {
1253 if(CDR(stack_head)->type != empty)
1254 print_st(env, CDR(stack_head), counter+1);
1255 printf("%ld: ", counter);
1256 print_val(env, CAR(stack_head), 0, NULL, stdout);
1257 printf("\n");
1258 }
1259
1260
1261 /* Prints the stack. */
1262 extern void printstack(environment *env)
1263 {
1264 if(env->head->type == empty) {
1265 printf("Stack Empty\n");
1266 return;
1267 }
1268
1269 print_st(env, env->head, 1);
1270 }
1271
1272
1273 extern void copying(environment *env)
1274 {
1275 puts(license_message);
1276 }
1277
1278
1279 extern void warranty(environment *env)
1280 {
1281 puts(warranty_message);
1282 }

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26