Initial commit: Go 1.23 release state
This commit is contained in:
280
test/ken/rob2.go
Normal file
280
test/ken/rob2.go
Normal file
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user