func main() { flag.Usage = usage flag.Parse() if len(flag.Args()) > 0 { var file *util.File util.Timed("file reading", *debug, func() { os.Chdir(filepath.Dir(flag.Arg(0))) f, err := util.NewFile(filepath.Base(flag.Arg(0))) if err != nil { util.ReportError(err, false) } file = f }) run(lexer.NewSourceFromFile(file)) } else if *runRepl { s := repl.NewReplSession(apply(runtime.NewBlock(nil, runtime.NewScope(nil)))) s.Run() } else { bytes, err := ioutil.ReadAll(os.Stdin) if err != nil { util.ReportError(err, false) } run(lexer.NewSourceFromString("<stdin>", string(bytes))) } }
func (s *ReplSession) Run() { line := liner.NewLiner() defer line.Close() line.SetCtrlCAborts(true) line.SetCompleter(s.completer) if f, err := os.Open(history); err == nil { line.ReadHistory(f) f.Close() } for { prompt := "> " if s.depth > 0 { prompt += "(" + strconv.Itoa(s.depth) + ") " } data, err := line.Prompt(prompt) if err != nil { if err == liner.ErrPromptAborted { return } util.ReportError(err, false) } line.AppendHistory(data) if f, err := os.Create(history); err == nil { line.WriteHistory(f) f.Close() } l := lexer.NewLexer(lexer.NewSourceFromString("<repl>", data)) err = l.Lex() if err != nil { util.ReportError(err, true) } else { for _, t := range l.Tokens { s.tokens = append(s.tokens, t) s.depth += t.DepthModifier() } if s.depth <= 0 { p := parser.NewParser(s.tokens) err := p.Parse() s.tokens = nil s.depth = 0 if err != nil { util.ReportError(err, true) continue } for _, node := range p.Nodes { result, err := s.block.EvalNode(node) if err != nil { util.ReportError(err, true) continue } data := util.Yellow("===> " + result.String()) if resultType(result) != "" { data += " " + util.Yellow("("+resultType(result)+")") } fmt.Println(data) s.block.Scope.SetSymbolLocally("_", runtime.NewSymbol(result)) } } } } }