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

Contents of /stack/symbols.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (show annotations)
Mon Aug 18 14:39:16 2003 UTC (20 years, 8 months ago) by masse
Branch: MAIN
Changes since 1.9: +179 -87 lines
File MIME type: text/plain
stack.c (printerr): Modified to accept error type 5.
(check_args): Modified to accept "empty" as argument.
symbols.c: New symbols (sx_72616e646f6d), (seed), (ticks), (push) and (pop).

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, 1, port))
14 return printerr(env);
15
16 if(fprintf(CAR(env->head)->content.p, "\n") < 0) {
17 env->err= 5;
18 return printerr(env);
19 }
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, 1, unknown))
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, 1, unknown))
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, 1, unknown))
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, 2, port, unknown))
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, 2, port, unknown))
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, 3, unknown, unknown, unknown))
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, 1, tcons))
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, 2, unknown, unknown))
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, 1, integer))
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, 2, symb, unknown))
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, 1, symb))
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, 2, string, string)==0) {
280 a_val= CAR(env->head);
281 b_val= CAR(CDR(env->head));
282 protect(a_val); protect(b_val);
283 toss(env); if(env->err) return;
284 toss(env); if(env->err) return;
285 len= strlen(a_val->content.string)+strlen(b_val->content.string)+1;
286 new_string= malloc(len);
287 assert(new_string != NULL);
288 strcpy(new_string, b_val->content.string);
289 strcat(new_string, a_val->content.string);
290 push_cstring(env, new_string);
291 unprotect(a_val); unprotect(b_val);
292 free(new_string);
293
294 return;
295 }
296
297 if(check_args(env, 2, integer, integer)==0) {
298 a= CAR(env->head)->content.i;
299 toss(env); if(env->err) return;
300 b= CAR(env->head)->content.i;
301 toss(env); if(env->err) return;
302 push_int(env, b+a);
303
304 return;
305 }
306
307 if(check_args(env, 2, tfloat, tfloat)==0) {
308 fa= CAR(env->head)->content.f;
309 toss(env); if(env->err) return;
310 fb= CAR(env->head)->content.f;
311 toss(env); if(env->err) return;
312 push_float(env, fb+fa);
313
314 return;
315 }
316
317 if(check_args(env, 2, tfloat, integer)==0) {
318 fa= CAR(env->head)->content.f;
319 toss(env); if(env->err) return;
320 b= CAR(env->head)->content.i;
321 toss(env); if(env->err) return;
322 push_float(env, b+fa);
323
324 return;
325 }
326
327 if(check_args(env, 2, integer, tfloat)==0) {
328 a= CAR(env->head)->content.i;
329 toss(env); if(env->err) return;
330 fb= CAR(env->head)->content.f;
331 toss(env); if(env->err) return;
332 push_float(env, fb+a);
333
334 return;
335 }
336
337 return printerr(env);
338 }
339
340 /* "-" */
341 extern void sx_2d(environment *env)
342 {
343 int a, b;
344 float fa, fb;
345
346 if(check_args(env, 2, integer, integer)==0) {
347 a= CAR(env->head)->content.i;
348 toss(env); if(env->err) return;
349 b= CAR(env->head)->content.i;
350 toss(env); if(env->err) return;
351 push_int(env, b-a);
352
353 return;
354 }
355
356 if(check_args(env, 2, tfloat, tfloat)==0) {
357 fa= CAR(env->head)->content.f;
358 toss(env); if(env->err) return;
359 fb= CAR(env->head)->content.f;
360 toss(env); if(env->err) return;
361 push_float(env, fb-fa);
362
363 return;
364 }
365
366 if(check_args(env, 2, tfloat, integer)==0) {
367 fa= CAR(env->head)->content.f;
368 toss(env); if(env->err) return;
369 b= CAR(env->head)->content.i;
370 toss(env); if(env->err) return;
371 push_float(env, b-fa);
372
373 return;
374 }
375
376 if(check_args(env, 2, integer, tfloat)==0) {
377 a= CAR(env->head)->content.i;
378 toss(env); if(env->err) return;
379 fb= CAR(env->head)->content.f;
380 toss(env); if(env->err) return;
381 push_float(env, fb-a);
382
383 return;
384 }
385
386 return printerr(env);
387 }
388
389 /* ">" */
390 extern void sx_3e(environment *env)
391 {
392 int a, b;
393 float fa, fb;
394
395 if(check_args(env, 2, integer, integer)==0) {
396 a= CAR(env->head)->content.i;
397 toss(env); if(env->err) return;
398 b= CAR(env->head)->content.i;
399 toss(env); if(env->err) return;
400 push_int(env, b>a);
401
402 return;
403 }
404
405 if(check_args(env, 2, tfloat, tfloat)==0) {
406 fa= CAR(env->head)->content.f;
407 toss(env); if(env->err) return;
408 fb= CAR(env->head)->content.f;
409 toss(env); if(env->err) return;
410 push_int(env, fb>fa);
411
412 return;
413 }
414
415 if(check_args(env, 2, tfloat, integer)==0) {
416 fa= CAR(env->head)->content.f;
417 toss(env); if(env->err) return;
418 b= CAR(env->head)->content.i;
419 toss(env); if(env->err) return;
420 push_int(env, b>fa);
421
422 return;
423 }
424
425 if(check_args(env, 2, integer, tfloat)==0) {
426 a= CAR(env->head)->content.i;
427 toss(env); if(env->err) return;
428 fb= CAR(env->head)->content.f;
429 toss(env); if(env->err) return;
430 push_int(env, fb>a);
431
432 return;
433 }
434
435 return printerr(env);
436 }
437
438 /* "<" */
439 extern void sx_3c(environment *env)
440 {
441 swap(env); if(env->err) return;
442 sx_3e(env);
443 }
444
445 /* "<=" */
446 extern void sx_3c3d(environment *env)
447 {
448 sx_3e(env); if(env->err) return;
449 not(env);
450 }
451
452 /* ">=" */
453 extern void sx_3e3d(environment *env)
454 {
455 sx_3c(env); if(env->err) return;
456 not(env);
457 }
458
459 /* "dup"; duplicates an item on the stack */
460 extern void sx_647570(environment *env)
461 {
462 if(check_args(env, 1, unknown))
463 return printerr(env);
464
465 push_val(env, copy_val(env, CAR(env->head)));
466 }
467
468 /* "if", If-Then */
469 extern void sx_6966(environment *env)
470 {
471 int truth;
472
473 if(check_args(env, 2, unknown, integer))
474 return printerr(env);
475
476 swap(env);
477 if(env->err) return;
478
479 truth= CAR(env->head)->content.i;
480
481 toss(env);
482 if(env->err) return;
483
484 if(truth)
485 eval(env);
486 else
487 toss(env);
488 }
489
490 /* If-Then-Else */
491 extern void ifelse(environment *env)
492 {
493 int truth;
494
495 if(check_args(env, 3, unknown, unknown, integer))
496 return printerr(env);
497
498 rot(env);
499 if(env->err) return;
500
501 truth= CAR(env->head)->content.i;
502
503 toss(env);
504 if(env->err) return;
505
506 if(!truth)
507 swap(env);
508 if(env->err) return;
509
510 toss(env);
511 if(env->err) return;
512
513 eval(env);
514 }
515
516 /* "else" */
517 extern void sx_656c7365(environment *env)
518 {
519
520 if(check_args(env, 5, unknown, symb, unknown, symb, integer))
521 return printerr(env);
522
523 /// XXX
524
525 if(CAR(CDR(env->head))->type!=symb
526 || strcmp(CAR(CDR(env->head))->content.sym->id, "then")!=0
527 || CAR(CDR(CDR(CDR(env->head))))->type!=symb
528 || strcmp(CAR(CDR(CDR(CDR(env->head))))->content.sym->id, "if")!=0) {
529 env->err= 2;
530 return printerr(env);
531 }
532
533 swap(env); toss(env); rot(env); toss(env);
534 ifelse(env);
535 }
536
537 extern void then(environment *env)
538 {
539
540 if(check_args(env, 3, unknown, symb, integer))
541 return printerr(env);
542
543 /// XXX
544
545 if(CAR(CDR(env->head))->type!=symb
546 || strcmp(CAR(CDR(env->head))->content.sym->id, "if")!=0) {
547 env->err= 2;
548 return printerr(env);
549 }
550
551 swap(env); toss(env);
552 sx_6966(env);
553 }
554
555 /* "while" */
556 extern void sx_7768696c65(environment *env)
557 {
558 int truth;
559 value *loop, *test;
560
561 if(check_args(env, 2, unknown, integer))
562 return printerr(env);
563
564 loop= CAR(env->head);
565 protect(loop);
566 toss(env); if(env->err) return;
567
568 test= CAR(env->head);
569 protect(test);
570 toss(env); if(env->err) return;
571
572 do {
573 push_val(env, test);
574 eval(env);
575
576 /// XXX
577
578 if(CAR(env->head)->type != integer) {
579 env->err= 2;
580 return printerr(env);
581 }
582
583 truth= CAR(env->head)->content.i;
584 toss(env); if(env->err) return;
585
586 if(truth) {
587 push_val(env, loop);
588 eval(env);
589 } else {
590 toss(env);
591 }
592
593 } while(truth);
594
595 unprotect(loop); unprotect(test);
596 }
597
598
599 /* "for"; for-loop */
600 extern void sx_666f72(environment *env)
601 {
602 value *loop;
603 int foo1, foo2;
604
605 if(check_args(env, 3, unknown, integer, integer))
606 return printerr(env);
607
608 loop= CAR(env->head);
609 protect(loop);
610 toss(env); if(env->err) return;
611
612 foo2= CAR(env->head)->content.i;
613 toss(env); if(env->err) return;
614
615 foo1= CAR(env->head)->content.i;
616 toss(env); if(env->err) return;
617
618 if(foo1<=foo2) {
619 while(foo1<=foo2) {
620 push_int(env, foo1);
621 push_val(env, loop);
622 eval(env); if(env->err) return;
623 foo1++;
624 }
625 } else {
626 while(foo1>=foo2) {
627 push_int(env, foo1);
628 push_val(env, loop);
629 eval(env); if(env->err) return;
630 foo1--;
631 }
632 }
633 unprotect(loop);
634 }
635
636 /* Variant of for-loop
637 Requires a list as first argument */
638 extern void foreach(environment *env)
639 {
640 value *loop, *foo;
641 value *iterator;
642
643 if(check_args(env, 2, unknown, tcons))
644 return printerr(env);
645
646 loop= CAR(env->head);
647 protect(loop);
648 toss(env); if(env->err) return;
649
650 foo= CAR(env->head);
651 protect(foo);
652 toss(env); if(env->err) return;
653
654 iterator= foo;
655
656 while(iterator->type!=empty) {
657 push_val(env, CAR(iterator));
658 push_val(env, loop);
659 eval(env); if(env->err) return;
660
661 /// XXX
662 if (iterator->type == tcons){
663 iterator= CDR(iterator);
664 } else {
665 env->err= 2; /* Improper list */
666 break;
667 }
668 }
669 unprotect(loop); unprotect(foo);
670
671 return printerr(env);
672 }
673
674 /* "to" */
675 extern void to(environment *env)
676 {
677 int ending, start, i;
678 value *iterator, *temp, *end;
679
680 if(check_args(env, 2, integer, integer))
681 return printerr(env);
682
683 end= new_val(env);
684
685 ending= CAR(env->head)->content.i;
686 toss(env); if(env->err) return;
687 start= CAR(env->head)->content.i;
688 toss(env); if(env->err) return;
689
690 push_sym(env, "[");
691
692 if(ending>=start) {
693 for(i= ending; i>=start; i--)
694 push_int(env, i);
695 } else {
696 for(i= ending; i<=start; i++)
697 push_int(env, i);
698 }
699
700 iterator= env->head;
701
702 if(iterator->type==empty
703 || (CAR(iterator)->type==symb
704 && CAR(iterator)->content.sym->id[0]=='[')) {
705 temp= end;
706 toss(env);
707 } else {
708 /* Search for first delimiter */
709 while(CDR(iterator)->type!=empty
710 && (CAR(CDR(iterator))->type!=symb
711 || CAR(CDR(iterator))->content.sym->id[0]!='['))
712 iterator= CDR(iterator);
713
714 /* Extract list */
715 temp= env->head;
716 env->head= CDR(iterator);
717 CDR(iterator)= end;
718
719 if(env->head->type!=empty)
720 toss(env);
721 }
722
723 /* Push list */
724 push_val(env, temp);
725 }
726
727 /* Read a string */
728 extern void readline(environment *env)
729 {
730 readlinestream(env, env->inputstream);
731 }
732
733 /* Read a string from a port */
734 extern void readlineport(environment *env)
735 {
736 FILE *stream;
737
738 if(check_args(env, 1, port))
739 return printerr(env);
740
741 stream=CAR(env->head)->content.p;
742 readlinestream(env, stream); if(env->err) return;
743
744 swap(env); if(env->err) return;
745 toss(env);
746 }
747
748 /* "read"; Read a value and place on stack */
749 extern void sx_72656164(environment *env)
750 {
751 readstream(env, env->inputstream);
752 }
753
754 /* "readport"; Read a value from a port and place on stack */
755 extern void readport(environment *env)
756 {
757 FILE *stream;
758
759 if(check_args(env, 1, port))
760 return printerr(env);
761
762 stream=CAR(env->head)->content.p;
763 readstream(env, stream); if(env->err) return;
764
765 swap(env); if(env->err) return;
766 toss(env);
767 }
768
769 #ifdef __linux__
770 extern void beep(environment *env)
771 {
772 int freq, dur, period, ticks;
773
774 if(check_args(env, 2, integer, integer))
775 return printerr(env);
776
777 dur= CAR(env->head)->content.i;
778 toss(env);
779 freq= CAR(env->head)->content.i;
780 toss(env);
781
782 period= 1193180/freq; /* convert freq from Hz to period
783 length */
784 ticks= dur*.001193180; /* convert duration from µseconds to
785 timer ticks */
786
787 /* ticks=dur/1000; */
788
789 /* if (ioctl(STDOUT_FILENO, KDMKTONE, (125<<16) + 0x637)==0) */
790 switch (ioctl(STDOUT_FILENO, KDMKTONE, (ticks<<16) | period)){
791 case 0:
792 usleep(dur);
793 return;
794 case -1:
795 env->err= 5;
796 return printerr(env);
797 default:
798 abort();
799 }
800 }
801 #endif /* __linux__ */
802
803 /* "wait" */
804 extern void sx_77616974(environment *env)
805 {
806 int dur;
807
808 if(check_args(env, 1, integer))
809 return printerr(env);
810
811 dur= CAR(env->head)->content.i;
812 toss(env);
813
814 usleep(dur);
815 }
816
817
818 /* "*" */
819 extern void sx_2a(environment *env)
820 {
821 int a, b;
822 float fa, fb;
823
824 if(check_args(env, 2, integer, integer)==0) {
825 a= CAR(env->head)->content.i;
826 toss(env); if(env->err) return;
827 b= CAR(env->head)->content.i;
828 toss(env); if(env->err) return;
829 push_int(env, b*a);
830
831 return;
832 }
833
834 if(check_args(env, 2, tfloat, tfloat)==0) {
835 fa= CAR(env->head)->content.f;
836 toss(env); if(env->err) return;
837 fb= CAR(env->head)->content.f;
838 toss(env); if(env->err) return;
839 push_float(env, fb*fa);
840
841 return;
842 }
843
844 if(check_args(env, 2, tfloat, integer)==0) {
845 fa= CAR(env->head)->content.f;
846 toss(env); if(env->err) return;
847 b= CAR(env->head)->content.i;
848 toss(env); if(env->err) return;
849 push_float(env, b*fa);
850
851 return;
852 }
853
854 if(check_args(env, 2, integer, tfloat)==0) {
855 a= CAR(env->head)->content.i;
856 toss(env); if(env->err) return;
857 fb= CAR(env->head)->content.f;
858 toss(env); if(env->err) return;
859 push_float(env, fb*a);
860
861 return;
862 }
863
864 return printerr(env);
865 }
866
867 /* "/" */
868 extern void sx_2f(environment *env)
869 {
870 int a, b;
871 float fa, fb;
872
873 if(check_args(env, 2, integer, integer)==0) {
874 a= CAR(env->head)->content.i;
875 toss(env); if(env->err) return;
876 b= CAR(env->head)->content.i;
877 toss(env); if(env->err) return;
878 push_float(env, b/a);
879
880 return;
881 }
882
883 if(check_args(env, 2, tfloat, tfloat)==0) {
884 fa= CAR(env->head)->content.f;
885 toss(env); if(env->err) return;
886 fb= CAR(env->head)->content.f;
887 toss(env); if(env->err) return;
888 push_float(env, fb/fa);
889
890 return;
891 }
892
893 if(check_args(env, 2, tfloat, integer)==0) {
894 fa= CAR(env->head)->content.f;
895 toss(env); if(env->err) return;
896 b= CAR(env->head)->content.i;
897 toss(env); if(env->err) return;
898 push_float(env, b/fa);
899
900 return;
901 }
902
903 if(check_args(env, 2, integer, tfloat)==0) {
904 a= CAR(env->head)->content.i;
905 toss(env); if(env->err) return;
906 fb= CAR(env->head)->content.f;
907 toss(env); if(env->err) return;
908 push_float(env, fb/a);
909
910 return;
911 }
912
913 return printerr(env);
914 }
915
916 /* "mod" */
917 extern void mod(environment *env)
918 {
919 int a, b;
920
921 if(check_args(env, 2, integer, integer)==0) {
922 a= CAR(env->head)->content.i;
923 toss(env); if(env->err) return;
924 b= CAR(env->head)->content.i;
925 toss(env); if(env->err) return;
926 push_int(env, b%a);
927
928 return;
929 }
930
931 return printerr(env);
932 }
933
934
935 /* "div" */
936 extern void sx_646976(environment *env)
937 {
938 int a, b;
939
940 if(check_args(env, 2, integer, integer))
941 return printerr(env);
942
943 a= CAR(env->head)->content.i;
944 toss(env); if(env->err) return;
945 b= CAR(env->head)->content.i;
946 toss(env); if(env->err) return;
947 push_int(env, (int)b/a);
948 }
949
950
951 extern void setcar(environment *env)
952 {
953
954 if(check_args(env, 2, tcons, unknown))
955 return printerr(env);
956
957 CAR(CAR(CDR(env->head)))=CAR(env->head);
958 toss(env);
959 }
960
961 extern void setcdr(environment *env)
962 {
963
964 if(check_args(env, 2, tcons, unknown))
965 return printerr(env);
966
967 CDR(CAR(CDR(env->head)))=CAR(env->head);
968 toss(env);
969 }
970
971 extern void car(environment *env)
972 {
973
974 if(check_args(env, 1, tcons))
975 return printerr(env);
976
977 CAR(env->head)=CAR(CAR(env->head));
978 }
979
980 extern void cdr(environment *env)
981 {
982
983 if(check_args(env, 1, tcons))
984 return printerr(env);
985
986 CAR(env->head)=CDR(CAR(env->head));
987 }
988
989 extern void cons(environment *env)
990 {
991 value *val;
992
993 if(check_args(env, 2, unknown, unknown))
994 return printerr(env);
995
996 val=new_val(env);
997 val->content.c= malloc(sizeof(pair));
998 assert(val->content.c!=NULL);
999
1000 env->gc_count += sizeof(pair);
1001 val->type=tcons;
1002
1003 CAR(val)= CAR(CDR(env->head));
1004 CDR(val)= CAR(env->head);
1005
1006 push_val(env, val);
1007
1008 swap(env); if(env->err) return;
1009 toss(env); if(env->err) return;
1010 swap(env); if(env->err) return;
1011 toss(env);
1012 }
1013
1014
1015 /* General assoc function */
1016 void assocgen(environment *env, funcp eqfunc)
1017 {
1018 value *key, *item;
1019
1020 /* Needs two values on the stack, the top one must be an association
1021 list */
1022 if(check_args(env, 2, tcons, unknown))
1023 return printerr(env);
1024
1025 key=CAR(CDR(env->head));
1026 item=CAR(env->head);
1027
1028 while(item->type == tcons){
1029 if(CAR(item)->type != tcons){
1030 env->err= 2;
1031 return printerr(env);
1032 }
1033
1034 push_val(env, key);
1035 push_val(env, CAR(CAR(item)));
1036 eqfunc((void*)env); if(env->err) return;
1037
1038 /* Check the result of 'eqfunc' */
1039 if(check_args(env, 1, integer))
1040 return printerr(env);
1041
1042 if(CAR(env->head)->content.i){
1043 toss(env); if(env->err) return;
1044 break;
1045 }
1046 toss(env); if(env->err) return;
1047
1048 if(item->type!=tcons) {
1049 env->err= 2;
1050 return printerr(env);
1051 }
1052
1053 item=CDR(item);
1054 }
1055
1056 if(item->type == tcons){ /* A match was found */
1057 push_val(env, CAR(item));
1058 } else {
1059 push_int(env, 0);
1060 }
1061 swap(env); if(env->err) return;
1062 toss(env); if(env->err) return;
1063 swap(env); if(env->err) return;
1064 toss(env);
1065 }
1066
1067
1068 /* 2: 3 => */
1069 /* 1: [ [ 1 . 2 ] [ 3 . 4 ] ] => 1: [ 3 . 4 ] */
1070 extern void assq(environment *env)
1071 {
1072 assocgen(env, (void*)eq);
1073 }
1074
1075
1076 /* "do" */
1077 extern void sx_646f(environment *env)
1078 {
1079 swap(env); if(env->err) return;
1080 eval(env);
1081 }
1082
1083 /* "open" */
1084 /* 2: "file" */
1085 /* 1: "r" => 1: #<port 0x47114711> */
1086 extern void sx_6f70656e(environment *env)
1087 {
1088 value *new_port;
1089 FILE *stream;
1090
1091 if(check_args(env, 2, string, string))
1092 return printerr(env);
1093
1094 stream=fopen(CAR(CDR(env->head))->content.ptr,
1095 CAR(env->head)->content.ptr);
1096
1097 if(stream == NULL) {
1098 env->err= 5;
1099 return printerr(env);
1100 }
1101
1102 new_port=new_val(env);
1103 new_port->type=port;
1104 new_port->content.p=stream;
1105
1106 push_val(env, new_port);
1107
1108 swap(env); if(env->err) return;
1109 toss(env); if(env->err) return;
1110 swap(env); if(env->err) return;
1111 toss(env);
1112 }
1113
1114
1115 /* "close" */
1116 extern void sx_636c6f7365(environment *env)
1117 {
1118 int ret;
1119
1120 if(check_args(env, 1, port))
1121 return printerr(env);
1122
1123 ret= fclose(CAR(env->head)->content.p);
1124
1125 if(ret != 0){
1126 env->err= 5;
1127 return printerr(env);
1128 }
1129
1130 toss(env);
1131 }
1132
1133
1134 extern void mangle(environment *env)
1135 {
1136 char *new_string;
1137
1138 if(check_args(env, 1, string))
1139 return printerr(env);
1140
1141 new_string= mangle_str(CAR(env->head)->content.string);
1142
1143 toss(env);
1144 if(env->err) return;
1145
1146 push_cstring(env, new_string);
1147 }
1148
1149 /* "fork" */
1150 extern void sx_666f726b(environment *env)
1151 {
1152 push_int(env, fork());
1153 }
1154
1155 /* "waitpid" */
1156 extern void sx_77616974706964(environment *env)
1157 {
1158
1159 if(check_args(env, 1, integer))
1160 return printerr(env);
1161
1162 push_int(env, waitpid(CAR(env->head)->content.i, NULL, 0));
1163 swap(env); toss(env);
1164 }
1165
1166
1167 /* Discard the top element of the stack. */
1168 extern void toss(environment *env)
1169 {
1170
1171 if(check_args(env, 1, unknown))
1172 return printerr(env);
1173
1174 env->head= CDR(env->head); /* Remove the top stack item */
1175 }
1176
1177
1178 /* Quit stack. */
1179 extern void quit(environment *env)
1180 {
1181 int i;
1182
1183 env->head= new_val(env);
1184
1185 if (env->err) return;
1186 for(i= 0; i<HASHTBLSIZE; i++) {
1187 while(env->symbols[i]!= NULL) {
1188 forget_sym(&(env->symbols[i]));
1189 }
1190 env->symbols[i]= NULL;
1191 }
1192
1193 env->gc_limit= 0;
1194 gc_maybe(env);
1195
1196 words(env);
1197
1198 if(env->free_string!=NULL)
1199 free(env->free_string);
1200
1201 #ifdef __linux__
1202 muntrace();
1203 #endif
1204
1205 exit(EXIT_SUCCESS);
1206 }
1207
1208
1209 /* List all defined words */
1210 extern void words(environment *env)
1211 {
1212 symbol *temp;
1213 int i;
1214
1215 for(i= 0; i<HASHTBLSIZE; i++) {
1216 temp= env->symbols[i];
1217 while(temp!=NULL) {
1218 #ifdef DEBUG
1219 if (temp->val != NULL && temp->val->gc.flag.protect)
1220 printf("(protected) ");
1221 #endif /* DEBUG */
1222 printf("%s ", temp->id);
1223 temp= temp->next;
1224 }
1225 }
1226 }
1227
1228
1229 /* Only to be called by itself function printstack. */
1230 void print_st(environment *env, value *stack_head, long counter)
1231 {
1232 if(CDR(stack_head)->type != empty)
1233 print_st(env, CDR(stack_head), counter+1);
1234 printf("%ld: ", counter);
1235 print_val(env, CAR(stack_head), 0, NULL, stdout);
1236 printf("\n");
1237 }
1238
1239
1240 /* Prints the stack. */
1241 extern void printstack(environment *env)
1242 {
1243 if(env->head->type == empty) {
1244 printf("Stack Empty\n");
1245 return;
1246 }
1247
1248 print_st(env, env->head, 1);
1249 }
1250
1251
1252 extern void copying(environment *env)
1253 {
1254 puts(license_message);
1255 }
1256
1257
1258 extern void warranty(environment *env)
1259 {
1260 puts(warranty_message);
1261 }
1262
1263
1264 /* random */
1265 extern void sx_72616e646f6d(environment *env)
1266 {
1267 push_int(env, (int)rand());
1268 }
1269
1270
1271 extern void seed(environment *env)
1272 {
1273 if(check_args(env, 1, integer))
1274 return printerr(env);
1275
1276 srand(CAR(env->head)->content.i);
1277 toss(env);
1278 }
1279
1280
1281 extern void ticks(environment *env)
1282 {
1283 int val;
1284
1285 val= (int)time(NULL);
1286 if(val<0) {
1287 env->err= 5;
1288 return printerr(env);
1289 }
1290
1291 return push_int(env, val);
1292 }
1293
1294
1295 extern void push(environment *env)
1296 {
1297 symbol *sym;
1298 value *oldval;
1299 value *newval;
1300
1301 if(check_args(env, 2, symb, unknown)==0) {
1302 sym= CAR(env->head)->content.sym;
1303 oldval= sym->val;
1304
1305 if(oldval==NULL)
1306 oldval= new_val(env);
1307
1308 sym->val= new_val(env);
1309 sym->val->content.c= malloc(sizeof(pair));
1310 assert(sym->val->content.c!=NULL);
1311 env->gc_count += sizeof(pair);
1312 sym->val->type= tcons;
1313 CDR(sym->val)= oldval;
1314 CAR(sym->val)= CAR(CDR(env->head));
1315 env->head= CDR(CDR(env->head));
1316
1317 return;
1318 }
1319
1320 if(check_args(env, 2, tcons, unknown)==0
1321 || check_args(env, 2, empty, unknown)==0) {
1322 oldval= CAR(env->head);
1323 env->head= CDR(env->head);
1324 newval= new_val(env);
1325 newval->content.c= malloc(sizeof(pair));
1326 assert(newval->content.c!=NULL);
1327 env->gc_count += sizeof(pair);
1328 newval->type= tcons;
1329 CDR(newval)= oldval;
1330 CAR(newval)= CAR(env->head);
1331 env->head= CDR(env->head);
1332 push_val(env, newval);
1333
1334 return;
1335 }
1336
1337 return printerr(env);
1338 }
1339
1340
1341 extern void pop(environment *env)
1342 {
1343 symbol *sym;
1344 value *val;
1345
1346 if(check_args(env, 1, symb)==0) {
1347 sym= CAR(env->head)->content.sym;
1348
1349 if(sym->val==NULL) {
1350 env->err= 3;
1351 return printerr(env);
1352 }
1353
1354 env->head= CDR(env->head);
1355 if(sym->val->type==tcons) {
1356 push_val(env, CAR(sym->val));
1357 sym->val= CDR(sym->val);
1358 } else {
1359 env->err= 2;
1360 return printerr(env);
1361 }
1362
1363 return;
1364 }
1365
1366 if(check_args(env, 1, tcons)==0) {
1367 val= CAR(env->head);
1368 env->head= CDR(env->head);
1369 push_val(env, CAR(val));
1370 return;
1371 }
1372
1373 return printerr(env);
1374 }

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26