summaryrefslogtreecommitdiffstats
path: root/test/ken/rob2.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/ken/rob2.go')
-rw-r--r--test/ken/rob2.go280
1 files changed, 280 insertions, 0 deletions
diff --git a/test/ken/rob2.go b/test/ken/rob2.go
new file mode 100644
index 0000000..4b4410e
--- /dev/null
+++ b/test/ken/rob2.go
@@ -0,0 +1,280 @@
+// run
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test general operation using s-list.
+// First Go program ever run (although not in this exact form).
+
+package main
+
+import "fmt"
+
+const nilchar = 0
+
+type Atom struct {
+ str string
+ integer int
+ next *Slist /* in hash bucket */
+}
+
+type List struct {
+ car *Slist
+ cdr *Slist
+}
+
+type Slist struct {
+ isatom bool
+ isstring bool
+ //union {
+ atom Atom
+ list List
+ //} u;
+
+}
+
+func (this *Slist) Car() *Slist {
+ return this.list.car
+}
+
+func (this *Slist) Cdr() *Slist {
+ return this.list.cdr
+}
+
+func (this *Slist) String() string {
+ return this.atom.str
+}
+
+func (this *Slist) Integer() int {
+ return this.atom.integer
+}
+
+func (slist *Slist) Free() {
+ if slist == nil {
+ return
+ }
+ if slist.isatom {
+ // free(slist.String());
+ } else {
+ slist.Car().Free()
+ slist.Cdr().Free()
+ }
+ // free(slist);
+}
+
+//Slist* atom(byte *s, int i);
+
+var token int
+var peekc int = -1
+var lineno int32 = 1
+
+var input string
+var inputindex int = 0
+var tokenbuf [100]byte
+var tokenlen int = 0
+
+const EOF int = -1
+
+func main() {
+ var list *Slist
+
+ OpenFile()
+ for {
+ list = Parse()
+ if list == nil {
+ break
+ }
+ r := list.Print()
+ list.Free()
+ if r != "(defn foo (add 12 34))" {
+ panic(r)
+ }
+ break
+ }
+}
+
+func (slist *Slist) PrintOne(doparen bool) string {
+ if slist == nil {
+ return ""
+ }
+ var r string
+ if slist.isatom {
+ if slist.isstring {
+ r = slist.String()
+ } else {
+ r = fmt.Sprintf("%v", slist.Integer())
+ }
+ } else {
+ if doparen {
+ r += "("
+ }
+ r += slist.Car().PrintOne(true)
+ if slist.Cdr() != nil {
+ r += " "
+ r += slist.Cdr().PrintOne(false)
+ }
+ if doparen {
+ r += ")"
+ }
+ }
+ return r
+}
+
+func (slist *Slist) Print() string {
+ return slist.PrintOne(true)
+}
+
+func Get() int {
+ var c int
+
+ if peekc >= 0 {
+ c = peekc
+ peekc = -1
+ } else {
+ c = int(input[inputindex])
+ inputindex++
+ if c == '\n' {
+ lineno = lineno + 1
+ }
+ if c == nilchar {
+ inputindex = inputindex - 1
+ c = EOF
+ }
+ }
+ return c
+}
+
+func WhiteSpace(c int) bool {
+ return c == ' ' || c == '\t' || c == '\r' || c == '\n'
+}
+
+func NextToken() {
+ var i, c int
+
+ tokenbuf[0] = nilchar // clear previous token
+ c = Get()
+ for WhiteSpace(c) {
+ c = Get()
+ }
+ switch c {
+ case EOF:
+ token = EOF
+ case '(', ')':
+ token = c
+ break
+ default:
+ for i = 0; i < 100-1; { // sizeof tokenbuf - 1
+ tokenbuf[i] = byte(c)
+ i = i + 1
+ c = Get()
+ if c == EOF {
+ break
+ }
+ if WhiteSpace(c) || c == ')' {
+ peekc = c
+ break
+ }
+ }
+ if i >= 100-1 { // sizeof tokenbuf - 1
+ panic("atom too long\n")
+ }
+ tokenlen = i
+ tokenbuf[i] = nilchar
+ if '0' <= tokenbuf[0] && tokenbuf[0] <= '9' {
+ token = '0'
+ } else {
+ token = 'A'
+ }
+ }
+}
+
+func Expect(c int) {
+ if token != c {
+ print("parse error: expected ", c, "\n")
+ panic("parse")
+ }
+ NextToken()
+}
+
+// Parse a non-parenthesized list up to a closing paren or EOF
+func ParseList() *Slist {
+ var slist, retval *Slist
+
+ slist = new(Slist)
+ slist.list.car = nil
+ slist.list.cdr = nil
+ slist.isatom = false
+ slist.isstring = false
+
+ retval = slist
+ for {
+ slist.list.car = Parse()
+ if token == ')' || token == EOF { // empty cdr
+ break
+ }
+ slist.list.cdr = new(Slist)
+ slist = slist.list.cdr
+ }
+ return retval
+}
+
+func atom(i int) *Slist { // BUG: uses tokenbuf; should take argument)
+ var slist *Slist
+
+ slist = new(Slist)
+ if token == '0' {
+ slist.atom.integer = i
+ slist.isstring = false
+ } else {
+ slist.atom.str = string(tokenbuf[0:tokenlen])
+ slist.isstring = true
+ }
+ slist.isatom = true
+ return slist
+}
+
+func atoi() int { // BUG: uses tokenbuf; should take argument)
+ var v int = 0
+ for i := 0; i < tokenlen && '0' <= tokenbuf[i] && tokenbuf[i] <= '9'; i = i + 1 {
+ v = 10*v + int(tokenbuf[i]-'0')
+ }
+ return v
+}
+
+func Parse() *Slist {
+ var slist *Slist
+
+ if token == EOF || token == ')' {
+ return nil
+ }
+ if token == '(' {
+ NextToken()
+ slist = ParseList()
+ Expect(')')
+ return slist
+ } else {
+ // Atom
+ switch token {
+ case EOF:
+ return nil
+ case '0':
+ slist = atom(atoi())
+ case '"', 'A':
+ slist = atom(0)
+ default:
+ slist = nil
+ print("unknown token: ", token, "\n")
+ }
+ NextToken()
+ return slist
+ }
+ return nil
+}
+
+func OpenFile() {
+ input = "(defn foo (add 12 34))\n\x00"
+ inputindex = 0
+ peekc = -1 // BUG
+ NextToken()
+}