all repos — min @ 13cc78a8e730572bcde7c529c288f2374437359a

A small but practical concatenative programming language.

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