diff --git a/args.go b/args.go index 5b7c5b4..e7c85e2 100644 --- a/args.go +++ b/args.go @@ -25,9 +25,12 @@ func args() { } defer f.Close() + out, errors := make(chan interface{}), make(chan error) + go defaultInterpreter(out, errors) + c := make(chan token, 32) go lex(bufio.NewReader(f), c) - evalall(c, universe) + evalall(c, out, errors, universe) } func printErrorMsg(message string) { @@ -39,12 +42,27 @@ func die(message string) { os.Exit(2) } +func tcpInterpreter(conn net.Conn, out chan interface{}, errors chan error) { + for { + select { + case v := <-out: + fmt.Fprintln(conn, v) + case err := <-errors: + fmt.Fprintf(conn, "error: %v", err) + } + } +} + func startConnection(conn net.Conn, c, d chan net.Conn) { c <- conn defer func() { d <- conn }() disconnect := func() { fmt.Println("disconnected") } + + out, errors := make(chan interface{}), make(chan error) + go tcpInterpreter(conn, out, errors) + r := bufio.NewReader(conn) for { if _, err := io.WriteString(conn, "> "); err != nil { @@ -69,16 +87,28 @@ func startConnection(conn net.Conn, c, d chan net.Conn) { tokens := make(chan token, 32) go lexs(string(line)+"\n", tokens) - evalall(tokens, universe) + evalall(tokens, out, errors, universe) + } +} + +var activeConnections = make([]net.Conn, 0, 10) + +func removeConnection(conn net.Conn) { + for i, other := range activeConnections { + if conn.RemoteAddr() == other.RemoteAddr() { + activeConnections = append(activeConnections[:i], activeConnections[i+1:]...) + return + } } } func manageConnections(connect, disconnect chan net.Conn) { for { select { - case <-connect: - - case <-disconnect: + case conn := <-connect: + activeConnections = append(activeConnections, conn) + case conn := <-disconnect: + removeConnection(conn) } } } diff --git a/skeam.go b/skeam.go index 84eeda7..cc93c23 100644 --- a/skeam.go +++ b/skeam.go @@ -202,7 +202,7 @@ func eval(v interface{}, env *environment) (interface{}, error) { panic("not reached") } -func evalall(c chan token, env *environment) { +func evalall(c chan token, out chan interface{}, e chan error, env *environment) { for { v, err := parse(c) switch err { @@ -210,15 +210,24 @@ func evalall(c chan token, env *environment) { return case nil: if v, err := eval(v, env); err != nil { - fmt.Println("error:", err) + e <- err return } else { - if v != nil { - fmt.Println(v) - } + out <- v } default: - fmt.Printf("error in eval: %v\n", err) + e <- err + } + } +} + +func defaultInterpreter(out chan interface{}, errors chan error) { + for { + select { + case v := <-out: + fmt.Println(v) + case err := <-errors: + fmt.Printf("error: %v", err) } } } @@ -232,6 +241,9 @@ func main() { return } + out, errors := make(chan interface{}), make(chan error) + go defaultInterpreter(out, errors) + r := bufio.NewReader(os.Stdin) for { fmt.Print("> ") @@ -252,6 +264,6 @@ func main() { c := make(chan token, 32) go lexs(string(line)+"\n", c) - evalall(c, universe) + evalall(c, out, errors, universe) } }