]> Cypherpunks.ru repositories - gostls13.git/blob - test/ken/rob2.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / ken / rob2.go
1 // run
2
3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Test general operation using s-list.
8 // First Go program ever run (although not in this exact form).
9
10 package main
11
12 import "fmt"
13
14 const nilchar = 0
15
16 type Atom struct {
17         str     string
18         integer int
19         next    *Slist /* in hash bucket */
20 }
21
22 type List struct {
23         car *Slist
24         cdr *Slist
25 }
26
27 type Slist struct {
28         isatom   bool
29         isstring bool
30         //union {
31         atom Atom
32         list List
33         //} u;
34
35 }
36
37 func (this *Slist) Car() *Slist {
38         return this.list.car
39 }
40
41 func (this *Slist) Cdr() *Slist {
42         return this.list.cdr
43 }
44
45 func (this *Slist) String() string {
46         return this.atom.str
47 }
48
49 func (this *Slist) Integer() int {
50         return this.atom.integer
51 }
52
53 func (slist *Slist) Free() {
54         if slist == nil {
55                 return
56         }
57         if slist.isatom {
58                 //              free(slist.String());
59         } else {
60                 slist.Car().Free()
61                 slist.Cdr().Free()
62         }
63         //      free(slist);
64 }
65
66 //Slist* atom(byte *s, int i);
67
68 var token int
69 var peekc int = -1
70 var lineno int32 = 1
71
72 var input string
73 var inputindex int = 0
74 var tokenbuf [100]byte
75 var tokenlen int = 0
76
77 const EOF int = -1
78
79 func main() {
80         var list *Slist
81
82         OpenFile()
83         for {
84                 list = Parse()
85                 if list == nil {
86                         break
87                 }
88                 r := list.Print()
89                 list.Free()
90                 if r != "(defn foo (add 12 34))" {
91                         panic(r)
92                 }
93                 break
94         }
95 }
96
97 func (slist *Slist) PrintOne(doparen bool) string {
98         if slist == nil {
99                 return ""
100         }
101         var r string
102         if slist.isatom {
103                 if slist.isstring {
104                         r = slist.String()
105                 } else {
106                         r = fmt.Sprintf("%v", slist.Integer())
107                 }
108         } else {
109                 if doparen {
110                         r += "("
111                 }
112                 r += slist.Car().PrintOne(true)
113                 if slist.Cdr() != nil {
114                         r += " "
115                         r += slist.Cdr().PrintOne(false)
116                 }
117                 if doparen {
118                         r += ")"
119                 }
120         }
121         return r
122 }
123
124 func (slist *Slist) Print() string {
125         return slist.PrintOne(true)
126 }
127
128 func Get() int {
129         var c int
130
131         if peekc >= 0 {
132                 c = peekc
133                 peekc = -1
134         } else {
135                 c = int(input[inputindex])
136                 inputindex++
137                 if c == '\n' {
138                         lineno = lineno + 1
139                 }
140                 if c == nilchar {
141                         inputindex = inputindex - 1
142                         c = EOF
143                 }
144         }
145         return c
146 }
147
148 func WhiteSpace(c int) bool {
149         return c == ' ' || c == '\t' || c == '\r' || c == '\n'
150 }
151
152 func NextToken() {
153         var i, c int
154
155         tokenbuf[0] = nilchar // clear previous token
156         c = Get()
157         for WhiteSpace(c) {
158                 c = Get()
159         }
160         switch c {
161         case EOF:
162                 token = EOF
163         case '(', ')':
164                 token = c
165                 break
166         default:
167                 for i = 0; i < 100-1; { // sizeof tokenbuf - 1
168                         tokenbuf[i] = byte(c)
169                         i = i + 1
170                         c = Get()
171                         if c == EOF {
172                                 break
173                         }
174                         if WhiteSpace(c) || c == ')' {
175                                 peekc = c
176                                 break
177                         }
178                 }
179                 if i >= 100-1 { // sizeof tokenbuf - 1
180                         panic("atom too long\n")
181                 }
182                 tokenlen = i
183                 tokenbuf[i] = nilchar
184                 if '0' <= tokenbuf[0] && tokenbuf[0] <= '9' {
185                         token = '0'
186                 } else {
187                         token = 'A'
188                 }
189         }
190 }
191
192 func Expect(c int) {
193         if token != c {
194                 print("parse error: expected ", c, "\n")
195                 panic("parse")
196         }
197         NextToken()
198 }
199
200 // Parse a non-parenthesized list up to a closing paren or EOF
201 func ParseList() *Slist {
202         var slist, retval *Slist
203
204         slist = new(Slist)
205         slist.list.car = nil
206         slist.list.cdr = nil
207         slist.isatom = false
208         slist.isstring = false
209
210         retval = slist
211         for {
212                 slist.list.car = Parse()
213                 if token == ')' || token == EOF { // empty cdr
214                         break
215                 }
216                 slist.list.cdr = new(Slist)
217                 slist = slist.list.cdr
218         }
219         return retval
220 }
221
222 func atom(i int) *Slist { // BUG: uses tokenbuf; should take argument)
223         var slist *Slist
224
225         slist = new(Slist)
226         if token == '0' {
227                 slist.atom.integer = i
228                 slist.isstring = false
229         } else {
230                 slist.atom.str = string(tokenbuf[0:tokenlen])
231                 slist.isstring = true
232         }
233         slist.isatom = true
234         return slist
235 }
236
237 func atoi() int { // BUG: uses tokenbuf; should take argument)
238         var v int = 0
239         for i := 0; i < tokenlen && '0' <= tokenbuf[i] && tokenbuf[i] <= '9'; i = i + 1 {
240                 v = 10*v + int(tokenbuf[i]-'0')
241         }
242         return v
243 }
244
245 func Parse() *Slist {
246         var slist *Slist
247
248         if token == EOF || token == ')' {
249                 return nil
250         }
251         if token == '(' {
252                 NextToken()
253                 slist = ParseList()
254                 Expect(')')
255                 return slist
256         } else {
257                 // Atom
258                 switch token {
259                 case EOF:
260                         return nil
261                 case '0':
262                         slist = atom(atoi())
263                 case '"', 'A':
264                         slist = atom(0)
265                 default:
266                         slist = nil
267                         print("unknown token: ", token, "\n")
268                 }
269                 NextToken()
270                 return slist
271         }
272         return nil
273 }
274
275 func OpenFile() {
276         input = "(defn foo (add 12 34))\n\x00"
277         inputindex = 0
278         peekc = -1 // BUG
279         NextToken()
280 }