func run(source lexer.Source) { l := lexer.NewLexer(source) util.Timed("lexing", *debug, func() { util.ReportError(l.Lex(), false) }) p := parser.NewParser(l.Tokens) util.Timed("parsing", *debug, func() { util.ReportError(p.Parse(), false) }) if *ast { bytes, _ := json.MarshalIndent(p, "", " ") fmt.Println(string(bytes)) } else { b := apply(runtime.NewBlock(p.Nodes, runtime.NewScope(nil))) util.Timed("runtime", *debug, func() { _, err := b.Eval() if err != nil { util.ReportError(err, false) } }) } }
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 builtinLoad(context *runtime.FunctionCallContext) (*runtime.Value, error) { if err := runtime.ValidateArguments(context, runtime.StringValue); err != nil { return nil, err } file, err := util.NewFile(context.Args[0].Str) if err != nil { return nil, err } l := lexer.NewLexer(lexer.NewSourceFromFile(file)) util.ReportError(l.Lex(), false) p := parser.NewParser(l.Tokens) util.ReportError(p.Parse(), false) b := runtime.NewBlock(p.Nodes, runtime.NewScope(context.Block.Scope)) result, err := b.Eval() if err != nil { return nil, err } for key, value := range b.Scope.Symbols { if value.Exported { if value.Value.Type == runtime.FunctionValue { value.Value.Function.CustomScope = b.Scope } context.Block.Scope.SetSymbol(b.SymbolName(key), value) } } return result, nil }
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)) } } } } }