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

Contents of /stack/symbols.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (show annotations)
Mon Aug 11 14:31:48 2003 UTC (20 years, 9 months ago) by masse
Branch: MAIN
Changes since 1.5: +279 -249 lines
File MIME type: text/plain
(check_args) New function to ease the checking of parameters.

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

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26