Submissions by Harley tagged repl

Back at it

A submission for Code @Home 225

I'm not going to attempt every day, but I'll try to post here a bit again. I've more-or-less been lazy about submitting here. In any case, maybe this will motivate others to remember to submit again.

Mostly I've worked on GoForth the last couple of months. It's been pretty fun hitting 100% test coverage and benchmarking most implemented words. As an example:

BenchmarkCoreWordsStackSwapCodeWord-2            2000000               638 ns/op
BenchmarkCoreWordsStackSwapFastCodeWord-2        5000000               339 ns/op

BenchmarkCoreWordsStackRotCodeWord-2             2000000               837 ns/op
BenchmarkCoreWordsStackRotFastCodeWord-2         5000000               270 ns/op 

This shows a stack swap time performing 1.8x as fast and a stack rotation performing 3.1x as fast. This one speedup was taken across any operation that was popping from the stack and then pushing a result. In most cases, an item is popped if needed, and then the top item is changed in place (or in the case of unary operators, changed in place without any push/pop.)

I also now have a basic REPL. It was surprisingly short:

package main

import (
    "fmt"

    "forth"
)

func main() {
    reader := make(chan rune)
    quit := make(chan bool)
    f := forth.NewForth()
    f.SetStdInOut()
    f.Reader(reader, quit)

    fmt.Println("Welcome to an example REPL.\nType die and press enter to exit")
    var s string
    for {
        fmt.Scan(&s)

        // Just a simple break out of the repl
        if s == "die" {
            break
        }

        for _, v := range s {
            reader <- v
        }

        reader <- ' '
    }
}

This will read from input, execute any words in the dictionary, and exit when you type " die" (without quotes and the leading space) and press enter.

Next up will likely be things like branching words and figuring out a good method for doing that.