OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [go.test/] [test/] [ken/] [rob2.go] - Rev 700

Compare with Previous | Blame | View Log

// $G $D/$F.go && $L $F.$A && ./$A.out

// 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.

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

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.