Changeset 6daaf222a907a885ffd45c90aad48f9c5a72cbc8

User picture

Commiter: Charles Childers

Author: Charles Childers

Parent: 41b7e22d56

(2010/04/12 19:56) About 2 years ago

sync against hg repo for gonga

Affected files

Updated vm/gonga/devs.go Download diff

41b7e22d569cd24b0438c59e7282a78712f5f5e06daaf222a907a885ffd45c90aad48f9c5a72cbc8
17
)
17
)
18
18
19
type Input struct {
19
type Input struct {
20
	io.Reader
20
	io.ReadCloser
21
	Next *Input
21
	Next *Input
22
}
22
}
23
23
...
...
37
var sockets = make(map[int]*socket, 4)
37
var sockets = make(map[int]*socket, 4)
38
var nsockets int
38
var nsockets int
39
39
40
func IncludeFile(filename string) (io.Reader, os.Error) {
41
	r, err := os.Open(filename, os.O_RDONLY, 0)
42
	if err != nil {
43
		return nil, err
44
	}
45
	br := bufio.NewReader(r)
46
	return io.Reader(br), err
47
}
48
49
func LoadDump(filename string, size int) (img []int, err os.Error) {
40
func LoadDump(filename string, size int) (img []int, err os.Error) {
50
	r, err := os.Open(filename, os.O_RDONLY, 0)
41
	r, err := os.Open(filename, os.O_RDONLY, 0)
51
	if err != nil {
42
	if err != nil {
...
...
107
98
108
	case port[1] == 1: // Input
99
	case port[1] == 1: // Input
109
	readInput:
100
	readInput:
110
		switch _, err = vm.Input.Read(c[0:]); err {
101
		if _, err = vm.Input.Read(c[0:]); err == os.EOF {
111
		case os.EOF:
102
			vm.Input.Close()
112
			vm.Input = vm.Input.Next
103
			vm.Input = vm.Input.Next
113
			if vm.Input != nil {
104
			if vm.Input != nil {
114
				goto readInput
105
				goto readInput
115
			}
106
			}
116
		case nil:
107
		} else if err == nil {
117
			port[1] = int(c[0])
108
			port[1] = int(c[0])
118
		}
109
		}
119
110
...
...
145
		case 1: // Write dump
136
		case 1: // Write dump
146
			vm.WriteDump(vm.dump)
137
			vm.WriteDump(vm.dump)
147
		case 2: // Include file
138
		case 2: // Include file
148
			if f, err := IncludeFile(readA(vm.img, tos)); err == nil {
139
			name := readA(vm.img, tos)
140
			if f, err := os.Open(name, os.O_RDONLY, 0); err == nil {
149
				vm.Input = &Input{f, vm.Input}
141
				vm.Input = &Input{f, vm.Input}
150
			}
142
			}
151
		case -1: // Open file
143
		case -1: // Open file
...
...
217
				port[5] = int(t)
209
				port[5] = int(t)
218
			}
210
			}
219
		case -9: // Bye!
211
		case -9: // Bye!
220
			vm.EndOk <- true
212
			vm.Err <- nil
221
		default:
213
		default:
222
			port[5] = 0
214
			port[5] = 0
223
		}
215
		}
...
...
233
		case -3: // Listen from socket
225
		case -3: // Listen from socket
234
			a := fmt.Sprint(":", sockets[tos].port)
226
			a := fmt.Sprint(":", sockets[tos].port)
235
			if l, err := net.Listen("tcp", a); err == nil {
227
			if l, err := net.Listen("tcp", a); err == nil {
236
				*(*sockets[tos]).listener = l
228
				(*sockets[tos]).listener = &l
237
			}
229
			}
238
		case -4: // Wait for conn
230
		case -4: // Wait for conn
239
			l := sockets[tos].listener
231
			l := sockets[tos].listener
240
			if c, err := l.Accept(); err == nil {
232
			if c, err := l.Accept(); err == nil {
241
				*(*sockets[tos]).conn = c
233
				(*sockets[tos]).conn = &c
242
			}
234
			}
243
		case -5: // Close socket
235
		case -5: // Close socket
244
			l := sockets[tos].listener
236
			l := sockets[tos].listener
...
...
264
		spdec = 1
256
		spdec = 1
265
	}
257
	}
266
	if err != nil {
258
	if err != nil {
267
		vm.EndOk <- false
259
		panic(err)
268
	}
260
	}
269
	port[0] = 1
261
	port[0] = 1
270
	return
262
	return

Updated vm/gonga/gonga.go Download diff

41b7e22d569cd24b0438c59e7282a78712f5f5e06daaf222a907a885ffd45c90aad48f9c5a72cbc8
15
15
16
var Usage = func() {
16
var Usage = func() {
17
	fmt.Fprint(os.Stderr, `
17
	fmt.Fprint(os.Stderr, `
18
Gonga is the Go version of the Ngaro virtual machine.
18
Gonga usage:
19
	gonga [options] [image file]
19
20
20
Usage:
21
Gonga is the Go version of the Ngaro virtual machine.
21
	gonga [options] [image file] [-w input file(s)]
22
22
23
It will run the image file specified in the command line.
23
If no image file is specified in the command line
24
By default, gongaImage will be loaded, retroImage if that
24
gongaImage will be loaded, retroImage if that fails.
25
fails. Input files can be added preceeding the file name
26
with -w. They will be read in inverse order (LIFO).
27
25
28
Options:
26
Options:
29
`)
27
`)
...
...
33
var shrink = flag.Bool("shrink", false, "shrink image dump file")
31
var shrink = flag.Bool("shrink", false, "shrink image dump file")
34
var size = flag.Int("s", 50000, "image size")
32
var size = flag.Int("s", 50000, "image size")
35
var dump = flag.String("d", "retro.img", "image dump file")
33
var dump = flag.String("d", "retro.img", "image dump file")
36
var retroImage = [...]int{}
34
35
type withFiles []*os.File
36
37
func (wf *withFiles) String() string {
38
	return fmt.Sprint(*wf)
39
}
40
41
func (wf *withFiles) Set(value string) bool {
42
	var nwf withFiles
43
	if wf == nil {
44
		nwf = make(withFiles, 1)
45
	} else {
46
		nwf = make(withFiles, len(*wf)+1)
47
		copy(nwf, *wf)
48
	}
49
	if f, err := os.Open(value, os.O_RDONLY, 0666); err != nil {
50
		return false
51
	} else {
52
		nwf[len(nwf)-1] = f
53
		(*wf) = nwf
54
	}
55
	return true
56
}
37
57
38
func main() {
58
func main() {
59
	var wf withFiles
60
	flag.Var(&wf, "w", "input files")
39
	flag.Usage = Usage
61
	flag.Usage = Usage
40
	flag.Parse()
62
	flag.Parse()
63
41
	ngaro.ShrinkImage = *shrink
64
	ngaro.ShrinkImage = *shrink
42
	ngaro.ClearScreen = func() { fmt.Printf("\033[2J\033[1;1H") }
65
	ngaro.ClearScreen = func() { fmt.Printf("\033[2J\033[1;1H") }
43
66
44
	var img []int
67
	var img []int
45
	var err os.Error
68
	var err os.Error
46
	if flag.NArg() == 0 {
69
47
		img = &retroImage
70
	switch flag.NArg() {
48
	}
71
	case 0:
49
	with := false
50
	input := &ngaro.Input{os.Stdin, nil}
51
	for i := 0; i < flag.NArg(); i++ {
52
		if with {
53
			if flag.Arg(i) == "-" {
54
				input = &ngaro.Input{os.Stdin, input}
55
			} else if f, err := os.Open(flag.Arg(i), os.O_RDONLY, 0666); err != nil {
56
				panic("Wrong input file: ", flag.Arg(i))
57
			} else {
58
				input = &ngaro.Input{f, input}
59
			}
60
			with = false
61
		} else if flag.Arg(i) == "-w" || flag.Arg(i) == "--with" {
62
			with = true
63
		} else if len(img) != 0 {
64
			panic("Too many arguments")
65
		} else if img, err = ngaro.LoadDump(flag.Arg(i), *size); err != nil {
66
			panic("Wrong image file: ", flag.Arg(i))
67
		}
68
	}
69
	if len(img) == 0 {
70
		img, err = ngaro.LoadDump("gongaImage", *size)
72
		img, err = ngaro.LoadDump("gongaImage", *size)
71
		if err != nil {
73
		if err != nil {
72
			img, err = ngaro.LoadDump("retroImage", *size)
74
			img, err = ngaro.LoadDump("retroImage", *size)
73
		}
75
		}
74
		if err != nil {
76
	case 1:
75
			panic("Image file not found")
77
		img, err = ngaro.LoadDump(flag.Arg(0), *size)
76
		}
78
	default:
79
		fmt.Fprint(os.Stderr, "too many arguments\n")
80
		flag.Usage()
81
		os.Exit(2)
82
	}
83
84
	if err != nil {
85
		fmt.Fprint(os.Stderr, "error starting gonga: ", err.String())
86
		os.Exit(1)
87
	}
88
89
	// push os.Stdin to the bottom of the input stack
90
	input := &ngaro.Input{os.Stdin, nil}
91
	// and add "with" (-w) files
92
	for i, _ := range wf {
93
		input = &ngaro.Input{wf[len(wf)-1-i], input}
77
	}
94
	}
95
78
	vm := ngaro.NewVM(img, *dump, input, os.Stdout)
96
	vm := ngaro.NewVM(img, *dump, input, os.Stdout)
79
97
80
	if ok := <-vm.EndOk; !ok {
98
	// <-vm.Err blocks until the vm dies
99
	if err = <-vm.Err; err != nil && err != os.EOF {
100
		fmt.Fprint(os.Stderr, "GONGA IS DEAD! "+err.String())
81
		os.Exit(1)
101
		os.Exit(1)
82
	}
102
	}
83
}
103
}

Updated vm/gonga/Makefile Download diff

41b7e22d569cd24b0438c59e7282a78712f5f5e06daaf222a907a885ffd45c90aad48f9c5a72cbc8
14
	sed -n '/EOF:gonga.retro/q;/gonga.retro/,$$p' ngaro.go > $@
14
	sed -n '/EOF:gonga.retro/q;/gonga.retro/,$$p' ngaro.go > $@
15
15
16
gongaImage: gonga retroImage gonga.retro
16
gongaImage: gonga retroImage gonga.retro
17
	echo 'save bye' | ./gonga -shrink -d gongaImage retroImage -w gonga.retro
17
	echo save bye | ./gonga -shrink -d gongaImage -w gonga.retro retroImage > /dev/null
18
18
19
include $(GOROOT)/src/Make.pkg
19
include $(GOROOT)/src/Make.pkg

Updated vm/gonga/ngaro.go Download diff

41b7e22d569cd24b0438c59e7282a78712f5f5e06daaf222a907a885ffd45c90aad48f9c5a72cbc8
146
	channel map[int]chan int
146
	channel map[int]chan int
147
	Input   *Input
147
	Input   *Input
148
	Output
148
	Output
149
	EndOk chan bool
149
	Err chan os.Error
150
}
150
}
151
151
152
func ftoi(f float) int { return *(*int)(unsafe.Pointer(&f)) }
152
func ftoi(f float) int { return *(*int)(unsafe.Pointer(&f)) }
...
...
158
	var tos int
158
	var tos int
159
	var data, addr [stackDepth + 2]int
159
	var data, addr [stackDepth + 2]int
160
	sp = 2 // to avoid underflows
160
	sp = 2 // to avoid underflows
161
	defer func() {
162
		if v := recover(); v != nil {
163
			if err, ok := v.(os.Error); ok {
164
				vm.Err <- err
165
			} else {
166
				vm.Err <- os.NewError("unknown error:"+fmt.Sprint(v))
167
			}
168
		}
169
	}()
161
	for ; ip < len(vm.img); ip++ {
170
	for ; ip < len(vm.img); ip++ {
162
		switch vm.img[ip] {
171
		switch vm.img[ip] {
163
		case Nop:
172
		case Nop:
...
...
336
				vm.img[a] = int(c[0])
345
				vm.img[a] = int(c[0])
337
				a++
346
				a++
338
			}
347
			}
339
			if err == os.EOF {
348
			if err == os.EOF && vm.Input != nil {
349
				vm.Input.Close()
340
				vm.Input = vm.Input.Next
350
				vm.Input = vm.Input.Next
341
				if vm.Input != nil {
351
				goto readInput
342
					goto readInput
352
			}
343
				} else {
353
			if err != nil {
344
					vm.EndOk <- true
354
				panic(err)
345
				}
346
			}
355
			}
347
			vm.img[a] = 0
356
			vm.img[a] = 0
348
			sp -= 2
357
			sp -= 2
349
		case IOstring + Out:
358
		case IOstring + Out:
350
			for i := tos; i < len(vm.img); i++ {
359
			i := tos
351
				if vm.img[i] == 0 {
360
			for ; i < len(vm.img) && vm.img[i] != 0; i++ {
352
					break
353
				}
354
				fmt.Fprintf(vm.Output, "%c", byte(vm.img[i]))
355
			}
361
			}
362
			fmt.Fprint(vm.Output, string(vm.img[tos:i]))
356
			sp--
363
			sp--
357
364
358
		default:
365
		default:
...
...
368
	}
375
	}
369
}
376
}
370
377
378
// NewVM returns a Ngaro virtual machine running the image given
379
// in img. Dump files will be saved with the name 'dump'.
380
// The input is an io.ReadCloser inside a ngaro.Input structure
381
// The Output is an io.Writer
371
func NewVM(img []int, dump string, in *Input, out Output) *NgaroVM {
382
func NewVM(img []int, dump string, in *Input, out Output) *NgaroVM {
372
	vm := NgaroVM{
383
	vm := NgaroVM{
373
		dump:    dump,
384
		dump:    dump,
374
		channel: make(map[int]chan int),
385
		channel: make(map[int]chan int),
375
		Input:   in,
386
		Input:   in,
376
		Output:  out,
387
		Output:  out,
377
		EndOk:   make(chan bool),
388
		Err:     make(chan os.Error),
378
		img:     img,
389
		img:     img,
379
	}
390
	}
380
	go vm.core(0)
391
	go vm.core(0)