minim.nim
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
import streams, tables, parseopt2, strutils import parser, interpreter, primitives, utils, linenoise const version* = "0.1.0" var debugging = false var repl = false const prelude = "prelude.min".slurp.strip let usage* = " MiNiM v" & version & " - a tiny concatenative system programming language" & """ (c) 2014 Fabio Cevasco Usage: minim [options] [filename] Arguments: filename A minim file to interpret (default: STDIN). Options: -e, --evaluate Evaluate a minim program inline -h, --help Print this help -v, --version Print the program version -i, --interactive Starts MiNiM's Read Evel Print Loop""" proc minimStream(s: PStream, filename: string) = var i = newMinInterpreter(debugging) i.eval prelude i.open(s, filename) discard i.parser.getToken() i.interpret() i.close() proc handleReplCtrlC() {.noconv.}= echo "\n-> Exiting..." quit(0) proc minimString*(buffer: string) = minimStream(newStringStream(buffer), "input") proc minimFile*(filename: string) = var stream = newFileStream(filename, fmRead) if stream == nil: stderr.writeln("Error - Cannot read from file: "& filename) stderr.flushFile() minimStream(stream, filename) proc minimFile*(file: TFile, filename="stdin") = var stream = newFileStream(stdin) if stream == nil: stderr.writeln("Error - Cannot read from "& filename) stderr.flushFile() minimStream(stream, filename) proc minimRepl*() = var i = newMinInterpreter(debugging) var s = newStringStream("") i.open(s, "") setControlCHook(handleReplCtrlC) echo "MiNiM v"&version&" - REPL initialized." i.eval prelude echo "Prelude loaded." echo "-> Press Ctrl+C to exit." var line: string while true: stdout.write(": ") line = stdin.readLine() s.writeln(line) i.parser.buf = $i.parser.buf & line i.parser.bufLen = i.parser.buf.len discard i.parser.getToken() try: i.interpret() except: warn getCurrentExceptionMsg() finally: stdout.write "-> " echo i.dump ### var file, str: string = "" for kind, key, val in getopt(): case kind: of cmdArgument: file = key of cmdLongOption, cmdShortOption: case key: of "debug", "d": debugging = true of "evaluate", "e": str = val of "help", "h": echo usage quit(0) of "version", "v": echo version of "interactive", "i": repl = true else: discard if str != "": minimString(str) elif file != "": minimFile file elif repl: minimRepl() quit(0) else: minimFile stdin |