all repos — min @ 41457007e36ed75329baafa3c10b3392cf88be8a

A small but practical concatenative programming language.

Added proper logger (currently only logging debug and errors though).
h3rald h3rald@h3rald.com
Mon, 07 Nov 2016 17:23:06 +0100
commit

41457007e36ed75329baafa3c10b3392cf88be8a

parent

a1baec676ce0944b024991f88fdcecbc69875277

7 files changed, 71 insertions(+), 54 deletions(-)

jump to
M core/interpreter.nimcore/interpreter.nim

@@ -4,7 +4,8 @@ strutils,

critbits, os, oids, - algorithm + algorithm, + logging import value, scope,

@@ -25,13 +26,10 @@ s = s & $item & " "

return s proc debug*(i: In, value: MinValue) = - if i.debugging: - echo $value - stderr.writeLine("-- " & i.dump & $value) + debug(i.dump & $value) proc debug*(i: In, value: string) = - if i.debugging: - stderr.writeLine("-- " & value) + debug(value) template withScope*(i: In, q: MinValue, res:ref MinScope, body: untyped): untyped = let origScope = i.scope

@@ -46,7 +44,7 @@ var scope = newScopeRef(i.scope)

i.withScope(q, scope): body -proc newMinInterpreter*(debugging = false, filename = "input", pwd = ""): MinInterpreter = +proc newMinInterpreter*(filename = "input", pwd = ""): MinInterpreter = var stack:MinStack = newSeq[MinValue](0) var trace:MinStack = newSeq[MinValue](0) var stackcopy:MinStack = newSeq[MinValue](0)

@@ -61,13 +59,12 @@ stack: stack,

trace: trace, stackcopy: stackcopy, scope: scope, - debugging: debugging, currSym: MinValue(column: 1, line: 1, kind: minSymbol, symVal: "") ) return i proc copy*(i: MinInterpreter, filename: string): MinInterpreter = - result = newMinInterpreter(debugging = i.debugging) + result = newMinInterpreter() result.filename = filename result.pwd = filename.parentDir result.stack = i.stack

@@ -78,9 +75,9 @@ result.currSym = MinValue(column: 1, line: 1, kind: minSymbol, symVal: "")

proc formatError(sym: MinValue, message: string): string = if sym.filename.isNil or sym.filename == "": - return "(!) `$1`: $2" % [sym.symVal, message] + return "$1`: $2" % [sym.symVal, message] else: - return "(!) $1($2,$3) `$4`: $5" % [sym.filename, $sym.line, $sym.column, sym.symVal, message] + return "$1($2,$3) `$4`: $5" % [sym.filename, $sym.line, $sym.column, sym.symVal, message] proc formatTrace(sym: MinValue): string = if sym.filename.isNil or sym.filename == "":

@@ -95,7 +92,7 @@ for sym in trace:

stderr.writeLine sym.formatTrace proc error(i: In, message: string) = - stderr.writeLine i.currSym.formatError(message) + error(i.currSym.formatError(message)) proc open*(i: In, stream:Stream, filename: string) = i.filename = filename
M core/parser.nimcore/parser.nim

@@ -6,7 +6,8 @@ streams,

unicode, tables, critbits, - oids + oids, + logging type MinTokenKind* = enum

@@ -98,7 +99,6 @@ scope*: ref MinScope

parser*: MinParser currSym*: MinValue filename*: string - debugging*: bool evaluating*: bool MinParsingError* = ref object of ValueError MinUndefinedError* = ref object of ValueError
M core/utils.nimcore/utils.nim

@@ -1,6 +1,7 @@

import strutils, - critbits + critbits, + logging import parser, value,

@@ -8,6 +9,29 @@ scope,

interpreter # Library methods + +proc logLevel*(val: var string): string {.discardable.} = + var lvl: Level + case val: + of "debug": + lvl = lvlDebug + of "info": + lvl = lvlInfo + of "notice": + lvl = lvlNotice + of "warn": + lvl = lvlWarn + of "error": + lvl = lvlError + of "fatal": + lvl = lvlFatal + of "none": + lvl = lvlNone + else: + val = "warn" + lvl = lvlWarn + setLogFilter(lvl) + return val proc define*(i: In, name: string): ref MinScope = var scope = new MinScope
M lib/min_lang.nimlib/min_lang.nim

@@ -158,13 +158,12 @@ .symbol("to-json") do (i: In):

var q: MinValue i.reqQuotation q i.push(($(%q)).newVal) - - .symbol("debug?") do (i: In): - i.push i.debugging.newVal - .symbol("debug") do (i: In): - i.debugging = not i.debugging - echo "Debugging: $1" % [$i.debugging] + .symbol("loglevel") do (i: In): + var s: MinValue + i.reqStringLike s + var str = s.getString + echo "Log level: ", logLevel(str) # Language constructs
M minim.nimminim.nim

@@ -6,7 +6,8 @@ strutils,

os, json, sequtils, - algorithm + algorithm, + logging import core/linedit, core/consts,

@@ -36,6 +37,9 @@ scope,

min_lang const PRELUDE* = "prelude.min".slurp.strip + +var LOGGER* = newConsoleLogger() +LOGGER.addHandler() proc getExecs(): seq[string] = var res = newSeq[string](0)

@@ -116,18 +120,6 @@ i.crypto_module

i.eval PRELUDE, "<prelude>" i.eval MINIMRC.readFile() -proc minimStream(s: Stream, filename: string, debugging = false) = - var i = newMinInterpreter(debugging) - i.pwd = filename.parentDir - i.stdLib() - i.open(s, filename) - discard i.parser.getToken() - try: - i.interpret() - except: - discard - i.close() - proc interpret*(i: In, s: Stream) = i.stdLib() i.open(s, i.filename)

@@ -138,22 +130,27 @@ except:

discard i.close() -proc minimString*(buffer: string, debugging = false) = - minimStream(newStringStream(buffer), "input", debugging) +proc minimStream(s: Stream, filename: string) = + var i = newMinInterpreter() + i.pwd = filename.parentDir + i.interpret(s) -proc minimFile*(filename: string, debugging = false) = +proc minimString*(buffer: string) = + minimStream(newStringStream(buffer), "input") + +proc minimFile*(filename: string) = var stream = newFileStream(filename, fmRead) if stream == nil: stderr.writeLine("Error - Cannot read from file: "& filename) stderr.flushFile() - minimStream(stream, filename, debugging) + minimStream(stream, filename) -proc minimFile*(file: File, filename="stdin", debugging = false) = +proc minimFile*(file: File, filename="stdin") = var stream = newFileStream(stdin) if stream == nil: stderr.writeLine("Error - Cannot read from "& filename) stderr.flushFile() - minimStream(stream, filename, debugging) + minimStream(stream, filename) proc printResult(i: In, res: MinValue) = if res.isNil:

@@ -193,14 +190,13 @@ i.printResult i.interpret()

except: discard -proc minimRepl*(debugging = false) = - var i = newMinInterpreter(debugging) +proc minimRepl*() = + var i = newMinInterpreter() i.minimRepl when isMainModule: var REPL = false - var DEBUGGING = false let usage* = """ $1 v$2 - a tiny concatenative shell and programming language (c) 2014-2016 Fabio Cevasco

@@ -217,6 +213,7 @@ -v, --version Print the program version

-i, --interactive Start $1 shell""" % [appname, version] var file, s: string = "" + setLogFilter(lvlWarn) for kind, key, val in getopt(): case kind:

@@ -224,8 +221,9 @@ of cmdArgument:

file = key of cmdLongOption, cmdShortOption: case key: - of "debug", "d": - DEBUGGING = true + of "log", "l": + var val = val + logLevel(val) of "evaluate", "e": s = val of "help", "h":

@@ -242,11 +240,11 @@ else:

discard if s != "": - minimString(s, DEBUGGING) + minimString(s) elif file != "": - minimFile file, DEBUGGING + minimFile file elif REPL: - minimRepl DEBUGGING + minimRepl() quit(0) else: - minimFile stdin, "stdin", DEBUGGING + minimFile stdin, "stdin"
M minim.vimminim.vim

@@ -8,15 +8,15 @@ if exists("b:current_syntax")

finish endif -setl iskeyword+=?,$,+,*,/,%,=,>,<,&,-,',.,:,~,! +setl iskeyword+=?,$,+,#,*,/,%,=,>,<,&,-,',.,:,~,! setl iskeyword+=^ setl iskeyword+=@ -syntax keyword minimDefaultSymbol ! != $ & ' * + - % ^ -> . .. / : < <= == => =~ > >= @ ROOT aes and append ask at atime b bind bool bool? bury1 bury2 bury3 c call call! capitalize case cd chmod choose clear-stack column-print concat confirm cons cp cpu crypto ctime datetime ddel debug debug? decode decrypt define delete dget dictionary? dig1 dig2 dig3 dip dir? dirname div dprint dprint! dset dump-stack dup dupd encode encrypt env? eval even? exit fappend file? filename filter first float float? foreach fperms fread from-json format-error fs fsize fstats ftype fwrite gets get-stack getenv hardlink hidden? ifte import indent inspect int int? interpolate interval io join k keys length linrec load load-symbol logic lowercase ls ls-r map match md5 mkdir mod module mtime mv newline not now num number? odd? os password pop popd pred print print! prompt publish puts puts! putenv q quotation? quote raise regex remove-symbol repeat replace rest rm rmdir run save-symbol scope scope? seal search set-stack sha1 sha224 sha256 sha384 sha512 sigils sip sleep sort source split startup stored-symbols str string string? strip succ swap swapd swons symbols symlink symlink? sys system take tformat time timeinfo times timestamp titleize to-json try unquote uppercase unzip values version which while with xor zip contains +syntax keyword minimDefaultSymbol ! != $ & ' * + # - % ^ -> . .. / : < <= == => =~ > >= @ ROOT aes and append ask at atime b bind bool bool? bury1 bury2 bury3 c call call! capitalize case cd chmod choose clear-stack column-print concat confirm cons cp cpu crypto ctime datetime ddel decode decrypt define delete dget dictionary? dig1 dig2 dig3 dip dir? dirname div dprint dprint! dset dump-stack dup dupd encode encrypt env? eval even? exit fappend file? filename filter first float float? foreach fperms fread from-json format-error fs fsize fstats ftype fwrite gets get-stack getenv hardlink hidden? ifte import indent inspect int int? interpolate interval io join k keys length linrec load load-symbol logic loglevel lowercase ls ls-r map match md5 mkdir mod module mtime mv newline not now num number? odd? os password pop popd pred print print! prompt publish puts puts! putenv q quotation? quote quote-bind quote-define raise regex remove-symbol repeat replace rest rm rmdir run save-symbol scope scope? seal search set-stack sha1 sha224 sha256 sha384 sha512 sigils sip sleep sort source split startup stored-symbols str string string? strip succ swap swapd swons symbols symlink symlink? sys system take tformat time timeinfo times timestamp titleize to-json try unquote uppercase unzip values version which while with xor zip contains -syntax match minimDefaultSigil ;\<[:@'~!$%&$=<>^*]; contained -syntax match minimSpecialSymbols ;[:@'~!$%&$=<>^*]; contained +syntax match minimDefaultSigil ;\<[:@'~!$%&$=<>^*#]; contained +syntax match minimSpecialSymbols ;[:@'~!$%&$=<>^*#]; contained syntax match minimQuote ;\<[']; syntax match minimBinding ;@;
M tests/lang.mintests/lang.min

@@ -10,7 +10,6 @@ newline

"lang" describe - (debug? false ==) assert (1 id 1 ==) assert (1 pop get-stack () ==) assert