123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- package main
- import (
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- // "sort"
- )
- import "src.eruta.nl/beoran/attl"
- import "github.com/peterh/liner"
- func runLine(env *attl.Environment, in string) *attl.Error {
- parsed, err := attl.Parse(in)
- if err != nil {
- return err
- }
- if parsed == nil {
- return attl.ErrorFromString("No parse results")
- }
- val, eff := parsed.Eval(env)
- if val != nil {
- env.Printi(">>${1}\n", val)
- } else {
- env.Printi(">>nil\n")
- }
- err, ok := eff.(*attl.Error)
- if ok {
- return err
- }
- return nil
- }
- func runLines(env *attl.Environment, line *liner.State) error {
- buf := ""
- for {
- if in, err := line.Prompt("> "); err == nil {
- first := ';'
- if len(in) > 0 {
- first = rune(in[0])
- }
- if first == '\\' {
- buf = buf + "\n" + in[1:len(in)]
- } else {
- if len(buf) > 0 {
- buf = buf + "\n" + in
- } else {
- buf = in + "\n"
- }
- rerr := runLine(env, buf)
- buf = ""
- if rerr != nil {
- env.Printi("Error ${1}: \n", attl.String(rerr.Message))
- }
- }
- line.AppendHistory(in)
- } else if err == liner.ErrPromptAborted {
- env.Printi("Aborted\n")
- return nil
- } else if err == io.EOF {
- return nil
- } else {
- env.Printi("Error reading line: ${1}\n", attl.ErrorFromError(err))
- }
- }
- return nil
- }
- func runFile(env *attl.Environment, name string) *attl.Error {
- fin, err := os.Open(name)
- if err != nil {
- return attl.ErrorFromError(err)
- }
- defer fin.Close()
- buf, err := ioutil.ReadAll(fin)
- if err != nil {
- return attl.ErrorFromError(err)
- }
- in := string(buf)
- parsed, rerr := attl.Parse(in)
- if rerr != nil {
- return rerr
- }
- if parsed == nil {
- return attl.ErrorFromString("Parse result is empty.")
- }
- args := attl.List{}
- for _, a := range os.Args {
- args = append(args, attl.String(a))
- }
- _, reff := parsed.Eval(env, args...)
- rerr, ok := reff.(*attl.Error)
- if ok {
- return rerr
- }
- return nil
- }
- func main() {
- // console := muesli.NewStdConsole()
- env := &attl.Environment{}
- env.Out = os.Stdout
- env.Push()
- env.RegisterBuiltins()
- env.RegisterTuringCompleteBuiltins()
- line := liner.NewLiner()
- defer line.Close()
- line.SetCtrlCAborts(true)
- home, _ := os.UserHomeDir()
- historyName := filepath.Join(home, ".attl_history")
- if f, err := os.Open(historyName); err == nil {
- line.ReadHistory(f)
- f.Close()
- }
- if len(os.Args) > 1 {
- for _, name := range os.Args {
- rerr := runFile(env, name)
- if rerr != nil {
- sname := attl.String(name)
- env.Printi("error in ${1}: ${2}\n", sname,
- rerr)
- }
- }
- return
- }
- line.SetWordCompleter(func(line string, pos int) (head string, c []string, tail string) {
- return attl.WordCompleter(*env, line, pos)
- })
- runLines(env, line)
- if f, err := os.Create(historyName); err != nil {
- env.Printi("Error writing history file: ${1}\n", attl.ErrorFromError(err))
- } else {
- line.WriteHistory(f)
- f.Close()
- }
- }
|