/* SHS: Syntactically Homogeneous Shell * Copyright (C) 2019 Aidan Hahn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package main import ( "fmt" "bufio" "strconv" "git.callpipe.com/aidan/shs/ast" "git.callpipe.com/aidan/shs/log" ) const ( def_prompt string = "λ" ) func setLogLvl() { loglvl := os.Getenv("SH_LOGGING") if loglvl != "" { llvl, ok := strconv.ParseInt(loglvl, 10, 8) if !ok { log.Log(log.Err, "couldnt parse log level", "init") } else { log.SetLogLvl(llvl) } } } func main() { debug := os.Getenv("SH_DEBUG_MODE") hist := os.Getenv("SH_HIST_FILE") prompt := os.Getenv("SHS_SH_PROMPT") var vars ast.VarTable var funcs ast.VarTable useHist := false var histFile os.File var err error if hist != "" { useHist = true histFile, err = os.OpenFile(histFile, os.O_RDWR|os.O_CREATE, 0755) if err != nil { useHist = false log.Log(log.ERR, "coudlnt open histfile: " + err, "init") } } if prompt == "" { prompt = def_prompt } // TODO: is bufio right for this? reader := bufio.NewReader(os.Stdin) for { setLogLvl() fmt.Print(prompt + " ") text, err := reader.ReadString('\n') if err != nil { log.Log(log.ERR, "couldnt read user input: " + err, "repl") } // TODO: replace with a regex text = strings.Replace(text, "\r\n", "", -1) text = strings.Replace(text, "\n", "", -1) if useHist { _, err = histFile.Write([]byte(text + "\n")) if err != nil { log.Log(log.DEBUG, "couldnt write to histfile: " + err, "repl") } } userInput := ast.Lex(text) if userInput == nil { // errors handled in Lex // TODO: return an error instead continue } if debug != "" { log.PrintSExprsIndividually(userInput) } result := userInput.Eval(funcs, vars) fmt.Println(result.String() + "\n") } }