36877ecffd/vm/gonga/devs.go
Commiter: Charles Childers
Author: Charles Childers
Revision: 36877ecffd
File Size: 2.91 KB
(March 12, 2010 23:46 UTC) About 2 years ago
fix for stack depth query in gonga (thanks yiyus)
// Original Ngaro Virtual Machine and Uki framework:
// Copyright (C) 2008, 2009, 2010 Charles Childers
// Go port
// Copyright 2009, 2010 JGL
// Public Domain or LICENSE file
package ngaro
import (
"io"
"bufio"
"os"
B "encoding/binary"
)
type Input struct {
io.Reader
Next *Input
}
type Output io.Writer
var ClearScreen func() = func() {}
func IncludeFile(filename string) io.Reader {
r, err := os.Open(filename, os.O_RDONLY, 0)
if err != nil {
return nil
}
br := bufio.NewReader(r)
return io.Reader(br)
}
func LoadDump(filename string, img []int, start int) int {
r, err := os.Open(filename, os.O_RDONLY, 0)
if err != nil {
return 0
}
br := bufio.NewReader(r)
var ui uint32
var i int
for i, _ = range img[start:] {
if err := B.Read(br, B.LittleEndian, &ui); err != nil {
break
}
img[i] = int(ui)
}
return i
}
func (vm *NgaroVM) WriteDump(filename string) {
w, err := os.Open(filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
return
}
for _, i := range vm.img {
if err = B.Write(w, B.LittleEndian, uint32(i)); err != nil {
break
}
}
}
func (vm *NgaroVM) Channel(id int) chan int {
if c, ok := vm.channel[id]; ok {
return c
}
vm.channel[id] = make(chan int)
return vm.channel[id]
}
func readA(data []int, a int) string {
var w int
for w = a; w < len(data) && data[w] != 0; w++ {
}
return string(data[a:w])
}
func (vm *NgaroVM) wait(port *[nports]int, tos int, depth int) (spdec int) {
var c [1]byte
switch {
case port[0] == 1:
return
case port[1] == 1: // Input
if _, err := vm.Input.Read(c[0:]); err != nil {
if err == os.EOF {
vm.Input = vm.Input.Next
} else {
vm.EndOk <- false
return
}
}
port[1] = int(c[0])
case port[1] > 1: // Receive from (or delete) channel
if port[2] == port[1] {
vm.channel[port[1]] = nil, false
port[1] = 0
port[2] = 0
} else {
port[1] = <-vm.Channel(port[1])
}
case port[2] == 1: // Output
c[0] = byte(tos)
if tos < 0 {
ClearScreen()
} else if _, err := vm.Output.Write(c[0:]); err != nil {
vm.EndOk <- false
return
}
port[2] = 0
spdec = 1
case port[2] > 1: // Send to channel
vm.Channel(port[2]) <- tos
port[2] = 0
spdec = 1
case port[4] != 0: // Files
switch port[4] {
case 1: // Write dump
vm.WriteDump(vm.dump)
case 2: // Include file
if f := IncludeFile(readA(vm.img, tos)); f != nil {
vm.Input = &Input{f, vm.Input}
}
}
// TODO: -1 to -7 (file system)
port[4] = 0
case port[5] != 0: // Capabilities
// TODO: case -8 (seconds from epoch)
switch port[5] {
case -1: // Image size
port[5] = len(vm.img)
case -5: // Stack depth
port[5] = depth
case -6: // Address stack depth
port[5] = stackDepth
case -9: // Bye!
vm.EndOk <- true
default:
port[5] = 0
}
// TODO: port[6] (canvas)
// TODO: port[7] (mouse)
// TODO: port[8] (sockets)
case port[13] == 1:
go vm.core(tos)
port[13] = 0
spdec = 1
}
port[0] = 1
return
} |