all repos — min @ 86d07a58bc050eadd2a99961e462498f91b21b90

A small but practical concatenative programming language.

Creating new logger only if necessary
Fabio Cevasco h3rald@h3rald.com
Thu, 02 Nov 2017 08:13:12 +0100
commit

86d07a58bc050eadd2a99961e462498f91b21b90

parent

681cd25d2bd3325262a6b8d3ce2d82c43d776564

1 files changed, 92 insertions(+), 91 deletions(-)

jump to
M min.nimmin.nim

@@ -1,5 +1,5 @@

when not defined(windows): - {.passL: "-rdynamic".} + {.passL: “-rdynamic”.} import streams, critbits,

@@ -47,9 +47,10 @@ value,

scope, min_lang -const PRELUDE* = "prelude.min".slurp.strip +const PRELUDE* = “prelude.min”.slurp.strip -newNiftyLogger().addHandler() +if logging.getHandlers().len == 0: + newNiftyLogger().addHandler() proc getExecs(): seq[string] = var res = newSeq[string](0)

@@ -58,68 +59,68 @@ for c, s in walkDir(dir, true):

if (c == pcFile or c == pcLinkToFile) and not res.contains(s): res.add s getFiles(getCurrentDir()) - for dir in "PATH".getEnv.split(PathSep): + for dir in “PATH”.getEnv.split(PathSep): getFiles(dir) res.sort(system.cmp) return res proc getCompletions(ed: LineEditor, symbols: seq[string]): seq[string] = - var words = ed.lineText.split(" ") + var words = ed.lineText.split(“ “) var word: string if words.len == 0: word = ed.lineText else: word = words[words.len-1] - if word.startsWith("'"): - return symbols.mapIt("'" & $it) - elif word.startsWith("~"): - return symbols.mapIt("~" & $it) - if word.startsWith("@"): - return symbols.mapIt("@" & $it) - if word.startsWith("#"): - return symbols.mapIt("#" & $it) - if word.startsWith(">"): - return symbols.mapIt(">" & $it) - if word.startsWith("*"): - return symbols.mapIt("*" & $it) - if word.startsWith("("): - return symbols.mapIt("(" & $it) - if word.startsWith("<"): - return toSeq(MINSYMBOLS.readFile.parseJson.pairs).mapIt("<" & $it[0]) - if word.startsWith("$"): - return toSeq(envPairs()).mapIt("$" & $it[0]) - if word.startsWith("!"): - return getExecs().mapIt("!" & $it) - if word.startsWith("&"): - return getExecs().mapIt("&" & $it) - if word.startsWith("\""): + if word.startsWith(“’”): + return symbols.mapIt(“’” & $it) + elif word.startsWith(“~”): + return symbols.mapIt(“~” & $it) + if word.startsWith(“@“): + return symbols.mapIt(“@“ & $it) + if word.startsWith(“#”): + return symbols.mapIt(“#” & $it) + if word.startsWith(“>”): + return symbols.mapIt(“>” & $it) + if word.startsWith(“*”): + return symbols.mapIt(“*” & $it) + if word.startsWith(“(“): + return symbols.mapIt(“(“ & $it) + if word.startsWith(“<“): + return toSeq(MINSYMBOLS.readFile.parseJson.pairs).mapIt(“<“ & $it[0]) + if word.startsWith(“$”): + return toSeq(envPairs()).mapIt(“$” & $it[0]) + if word.startsWith(“!”): + return getExecs().mapIt(“!” & $it) + if word.startsWith(“&”): + return getExecs().mapIt(“&” & $it) + if word.startsWith(“\””): var f = word[1..^1] - if f == "": - f = getCurrentDir().replace("\\", "/") - return toSeq(walkDir(f, true)).mapIt("\"$1" % it.path.replace("\\", "/")) + if f == “”: + f = getCurrentDir().replace(“\\”, “/“) + return toSeq(walkDir(f, true)).mapIt(“\”$1” % it.path.replace(“\\”, “/“)) elif f.dirExists: - f = f.replace("\\", "/") - if f[f.len-1] != '/': - f = f & "/" - return toSeq(walkDir(f, true)).mapIt("\"$1$2" % [f, it.path.replace("\\", "/")]) + f = f.replace(“\\”, “/“) + if f[f.len-1] != ‘/‘: + f = f & “/“ + return toSeq(walkDir(f, true)).mapIt(“\”$1$2” % [f, it.path.replace(“\\”, “/“)]) else: var dir: string - if f.contains("/") or dir.contains("\\"): + if f.contains(“/“) or dir.contains(“\\”): dir = f.parentDir let file = f.extractFileName - return toSeq(walkDir(dir, true)).filterIt(it.path.toLowerAscii.startsWith(file.toLowerAscii)).mapIt("\"$1/$2" % [dir, it.path.replace("\\", "/")]) + return toSeq(walkDir(dir, true)).filterIt(it.path.toLowerAscii.startsWith(file.toLowerAscii)).mapIt(“\”$1/$2” % [dir, it.path.replace(“\\”, “/“)]) else: dir = getCurrentDir() - return toSeq(walkDir(dir, true)).filterIt(it.path.toLowerAscii.startsWith(f.toLowerAscii)).mapIt("\"$1" % [it.path.replace("\\", "/")]) + return toSeq(walkDir(dir, true)).filterIt(it.path.toLowerAscii.startsWith(f.toLowerAscii)).mapIt(“\”$1” % [it.path.replace(“\\”, “/“)]) return symbols proc stdLib*(i: In) = if not MINSYMBOLS.fileExists: - MINSYMBOLS.writeFile("{}") + MINSYMBOLS.writeFile(“{}”) if not MINHISTORY.fileExists: - MINHISTORY.writeFile("") + MINHISTORY.writeFile(“”) if not MINRC.fileExists: - MINRC.writeFile("") + MINRC.writeFile(“”) i.lang_module i.stack_module i.seq_module

@@ -133,19 +134,19 @@ i.fs_module

when not defined(lite): i.crypto_module i.math_module - i.eval PRELUDE, "<prelude>" + i.eval PRELUDE, “<prelude>” i.eval MINRC.readFile() - i.eval "\"prompt\" unseal" + i.eval “\”prompt\” unseal” type LibProc = proc(i: In) {.nimcall.} proc dynLib*(i: In) = discard MINLIBS.existsOrCreateDir - for library in walkFiles(MINLIBS & "/*"): + for library in walkFiles(MINLIBS & “/*”): var modname = library.splitFile.name var libfile = library.splitFile.name & library.splitFile.ext - if modname.len > 3 and modname[0..2] == "lib": + if modname.len > 3 and modname[0..2] == “lib”: modname = modname[3..modname.len-1] let dll = library.loadLib() if dll != nil:

@@ -153,11 +154,11 @@ let modsym = dll.symAddr(modname)

if modsym != nil: let modproc = cast[LibProc](dll.symAddr(modname)) i.modproc() - info("[$1] Dynamic module loaded successfully: $2" % [libfile, modname]) + info(“[$1] Dynamic module loaded successfully: $2” % [libfile, modname]) else: - warn("[$1] Library does not contain symbol $2" % [libfile, modname]) + warn(“[$1] Library does not contain symbol $2” % [libfile, modname]) else: - warn("Unable to load dynamic library: " & libfile) + warn(“Unable to load dynamic library: “ & libfile) proc interpret*(i: In, s: Stream) = i.stdLib()

@@ -176,27 +177,27 @@ i.pwd = filename.parentDir

i.interpret(s) proc minString*(buffer: string) = - minStream(newStringStream(buffer), "input") + minStream(newStringStream(buffer), “input”) proc minFile*(filename: string) = var fileLines = newSeq[string](0) - var contents = "" + var contents = “” try: fileLines = filename.readFile().splitLines() except: - fatal("Cannot read from file: "& filename) + fatal(“Cannot read from file: “& filename) quit(3) - if fileLines[0].len >= 2 and fileLines[0][0..1] == "#!": - contents = fileLines[1..fileLines.len-1].join("\n") + if fileLines[0].len >= 2 and fileLines[0][0..1] == “#!”: + contents = fileLines[1..fileLines.len-1].join(“\n”) else: - contents = fileLines.join("\n") + contents = fileLines.join(“\n”) minStream(newStringStream(contents), filename) -proc minFile*(file: File, filename="stdin") = +proc minFile*(file: File, filename=“stdin”) = var stream = newFileStream(stdin) if stream == nil: - fatal("Cannot read from file: "& filename) + fatal(“Cannot read from file: “& filename) quit(3) minStream(stream, filename)

@@ -206,28 +207,28 @@ return

if i.stack.len > 0: let n = $i.stack.len if res.isQuotation and res.qVal.len > 1: - echo "{$1} -> (" % n + echo “{$1} -> (“ % n for item in res.qVal: - echo " " & $item - echo " ".repeat(n.len) & " )" + echo “ “ & $item + echo “ “.repeat(n.len) & “ )” else: - echo "{$1} -> $2" % [$i.stack.len, $i.stack[i.stack.len - 1]] + echo “{$1} -> $2” % [$i.stack.len, $i.stack[i.stack.len - 1]] proc minRepl*(i: var MinInterpreter) = i.stdLib() i.dynLib() - var s = newStringStream("") - i.open(s, "<repl>") + var s = newStringStream(“”) + i.open(s, “<repl>”) var line: string - #echo "$1 v$2" % [appname, version] + #echo “$1 v$2” % [appname, version] var ed = initEditor(historyFile = MINHISTORY) while true: let symbols = toSeq(i.scope.symbols.keys) ed.completionCallback = proc(ed: LineEditor): seq[string] = return ed.getCompletions(symbols) # evaluate prompt - i.push("prompt".newSym) - let vals = i.expect("string") + i.push(“prompt”.newSym) + let vals = i.expect(“string”) let v = vals[0] let prompt = v.getString() line = ed.readLine(prompt)

@@ -241,7 +242,7 @@ except:

discard proc minRepl*() = - var i = newMinInterpreter(filename = "<repl>") + var i = newMinInterpreter(filename = “<repl>”) i.minRepl when isMainModule:

@@ -249,9 +250,9 @@

var REPL = false var INSTALL = false var UNINSTALL = false - var libfile = "" + var libfile = “” - let usage* = """ $1 v$2 - a tiny concatenative shell and programming language + let usage* = “”” $1 v$2 - a tiny concatenative shell and programming language (c) 2014-2017 Fabio Cevasco Usage:

@@ -260,14 +261,14 @@

Arguments: filename A $1 file to interpret (default: STDIN). Options: - --install:<lib> Install dynamic library file <lib> - --uninstall:<lib> Uninstall dynamic library file <lib> - -e, --evaluate Evaluate a $1 program inline - -h, --help Print this help - -v, --version Print the program version - -i, --interactive Start $1 shell""" % [appname, version] + —install:<lib> Install dynamic library file <lib> + —uninstall:<lib> Uninstall dynamic library file <lib> + -e, —evaluate Evaluate a $1 program inline + -h, —help Print this help + -v, —version Print the program version + -i, —interactive Start $1 shell””” % [appname, version] - var file, s: string = "" + var file, s: string = “” setLogFilter(lvlNotice) for kind, key, val in getopt():

@@ -276,23 +277,23 @@ of cmdArgument:

file = key of cmdLongOption, cmdShortOption: case key: - of "log", "l": + of “log”, “l”: var val = val setLogLevel(val) - of "evaluate", "e": + of “evaluate”, “e”: s = val - of "help", "h": + of “help”, “h”: echo usage quit(0) - of "version", "v": + of “version”, “v”: echo version quit(0) - of "interactive", "i": + of “interactive”, “i”: REPL = true - of "install": + of “install”: INSTALL = true libfile = val - of "uninstall": + of “uninstall”: UNINSTALL = true libfile = val else:

@@ -300,34 +301,34 @@ discard

else: discard - if s != "": + if s != “”: minString(s) - elif file != "": + elif file != “”: minFile file elif INSTALL: if not libfile.existsFile: - fatal("Dynamic library file not found:" & libfile) + fatal(“Dynamic library file not found:” & libfile) quit(4) try: libfile.copyFile(MINLIBS/libfile.extractFilename) except: - fatal("Unable to install library file: " & libfile) + fatal(“Unable to install library file: “ & libfile) quit(5) - notice("Dynamic linbrary installed successfully: " & libfile.extractFilename) + notice(“Dynamic linbrary installed successfully: “ & libfile.extractFilename) quit(0) elif UNINSTALL: if not (MINLIBS/libfile.extractFilename).existsFile: - fatal("Dynamic library file not found:" & libfile) + fatal(“Dynamic library file not found:” & libfile) quit(4) try: removeFile(MINLIBS/libfile.extractFilename) except: - fatal("Unable to uninstall library file: " & libfile) + fatal(“Unable to uninstall library file: “ & libfile) quit(6) - notice("Dynamic linbrary uninstalled successfully: " & libfile.extractFilename) + notice(“Dynamic linbrary uninstalled successfully: “ & libfile.extractFilename) quit(0) elif REPL: minRepl() quit(0) else: - minFile stdin, "stdin" + minFile stdin, “stdin”