go rob2 源码

  • 2022-07-15
  • 浏览 (819)

golang rob2 代码

文件路径:/test/ken/rob2.go

// 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()
}

相关信息

go 源码目录

相关文章

go array 源码

go chan 源码

go chan1 源码

go complit 源码

go convert 源码

go cplx0 源码

go cplx1 源码

go cplx2 源码

go cplx3 源码

go cplx4 源码

0  赞