1 /*
2 * Abuse - dark 2D side-scrolling platform game
3 * Copyright (c) 1995 Crack dot Com
4 * Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5 *
6 * This software was released into the Public Domain. As with most public
7 * domain software, no warranty is made or implied by Crack dot Com, by
8 * Jonathan Clark, or by Sam Hocevar.
9 */
10
11 #if defined HAVE_CONFIG_H
12 # include "config.h"
13 #endif
14
15 #ifdef NO_LIBS
16 #include "fakelib.h"
17 #endif
18
19 #include "lisp.h"
20 #include "lisp_gc.h"
21
22 LObject *l_undefined;
23 LSymbol *true_symbol = NULL, *list_symbol, *string_symbol, *quote_symbol,
24 *backquote_symbol, *comma_symbol, *do_symbol, *in_symbol, *aref_symbol,
25 *if_symbol, *progn_symbol, *car_symbol, *cdr_symbol;
26
27 void *colon_initial_contents, *colon_initial_element,
28 *eq_symbol, *zero_symbol, *eq0_symbol, *load_warning;
29
30 void *if_1progn,*if_2progn,*if_12progn,*not_symbol;
31
comp_optimize(void * list)32 void *comp_optimize(void *list)
33 {
34 void *return_val=list;
35 PtrRef r1(list);
36 if (list)
37 {
38 if (CAR(list)==if_symbol)
39 {
40 void *eval1=lcar(lcdr(lcdr(list)));
41 PtrRef r2(eval1);
42 void *eval2=lcar(lcdr(lcdr(lcdr(list))));
43 PtrRef r3(eval2);
44
45 void *ret=NULL;
46 PtrRef r4(ret);
47 if (lcar(list)==eq_symbol && (lcar(lcdr(list))==zero_symbol)) // simplify (eq 0 x) -> (eq0 x)
48 {
49 push_onto_list(lcar(lcdr(lcdr(list))),ret);
50 push_onto_list(eq0_symbol,ret);
51 return_val=comp_optimize(ret);
52 } else if (lcar(list)==eq_symbol &&
53 (lcar(lcdr(lcdr(list)))==zero_symbol)) //simplify (eq x 0)-> (eq0 x)
54 {
55 push_onto_list(lcar(lcdr(list)),ret);
56 push_onto_list(eq0_symbol,ret);
57 return_val=comp_optimize(ret);
58 } else if (lcar(lcar(lcdr(list)))==not_symbol) // simplify (if (not y) x z) -> (if y z x)
59 {
60 push_onto_list(lcar(lcdr(lcdr(list))),ret);
61 push_onto_list(lcar(lcdr(lcdr(lcdr(list)))),ret);
62 push_onto_list(lcar(lcdr(lcar(lcdr(list)))),ret);
63 push_onto_list(if_symbol,ret);
64 return_val=comp_optimize(ret);
65 }
66 else if (lcar(eval1)==progn_symbol && (eval2==NULL ||
67 item_type(eval2)!=L_CONS_CELL))
68 {
69 push_onto_list(eval2,ret);
70 push_onto_list(lcdr(eval1),ret);
71 push_onto_list(lcar(lcdr(list)),ret);
72 push_onto_list(if_1progn,ret);
73 return_val=comp_optimize(ret);
74 } else if (lcar(eval1)==progn_symbol && lcar(eval2)==progn_symbol)
75 {
76 push_onto_list(lcdr(eval2),ret);
77 push_onto_list(lcdr(eval1),ret);
78 push_onto_list(lcar(lcdr(list)),ret);
79 push_onto_list(if_12progn,ret);
80 return_val=comp_optimize(ret);
81 } else if (lcar(eval2)==progn_symbol)
82 {
83 push_onto_list(lcdr(eval2),ret);
84 push_onto_list(eval1,ret);
85 push_onto_list(lcar(lcdr(list)),ret);
86 push_onto_list(if_2progn,ret);
87 return_val=comp_optimize(ret);
88 }
89
90 }
91 }
92 return return_val;
93 }
94
l_comp_init()95 void l_comp_init()
96 {
97 // This needs to be defined first
98 l_undefined = LSymbol::FindOrCreate(":UNDEFINED");
99
100 // Collection problems result if we don't do this
101 ((LSymbol *)l_undefined)->function = NULL;
102 ((LSymbol *)l_undefined)->value = NULL;
103
104 true_symbol = LSymbol::FindOrCreate("T");
105
106 list_symbol = LSymbol::FindOrCreate("list");
107 string_symbol = LSymbol::FindOrCreate("string");
108 quote_symbol = LSymbol::FindOrCreate("quote");
109 backquote_symbol = LSymbol::FindOrCreate("backquote");
110 comma_symbol = LSymbol::FindOrCreate("comma");
111 in_symbol = LSymbol::FindOrCreate("in");
112 do_symbol = LSymbol::FindOrCreate("do");
113 aref_symbol = LSymbol::FindOrCreate("aref");
114 colon_initial_contents = LSymbol::FindOrCreate(":initial-contents");
115 colon_initial_element = LSymbol::FindOrCreate(":initial-element");
116
117 if_1progn = LSymbol::FindOrCreate("if-1progn");
118 if_2progn = LSymbol::FindOrCreate("if-2progn");
119 if_12progn = LSymbol::FindOrCreate("if-12progn");
120 if_symbol = LSymbol::FindOrCreate("if");
121 progn_symbol = LSymbol::FindOrCreate("progn");
122 not_symbol = LSymbol::FindOrCreate("not");
123 eq_symbol = LSymbol::FindOrCreate("eq");
124 zero_symbol = LSymbol::FindOrCreate("0");
125 eq0_symbol = LSymbol::FindOrCreate("eq0");
126 car_symbol = LSymbol::FindOrCreate("car");
127 cdr_symbol = LSymbol::FindOrCreate("cdr");
128 load_warning = LSymbol::FindOrCreate("load_warning");
129 }
130
131