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