all repos — min @ 0ce5ec4ab6763c180130f18fd849d99e590b5822

A small but practical concatenative programming language.

Fixed unhandled exceptions.
h3rald h3rald@h3rald.com
Sun, 28 Aug 2016 18:25:41 +0200
commit

0ce5ec4ab6763c180130f18fd849d99e590b5822

parent

4e466d65c0ec6e946bb3ebddc8c6d3ac4c1e3cee

4 files changed, 48 insertions(+), 15 deletions(-)

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

@@ -21,6 +21,16 @@ if scope.symbols.hasKey(key):

return scope.symbols[key] elif scope.parent.isNotNil: return scope.parent.getSymbol(key) + else: + raiseUndefined("Symbol '$1' not found." % key) + +proc hasSymbol*(scope: ref MinScope, key: string): bool = + if scope.symbols.hasKey(key): + return true + elif scope.parent.isNotNil: + return scope.parent.hasSymbol(key) + else: + return false proc delSymbol*(scope: ref MinScope, key: string): bool {.discardable.}= if scope.symbols.hasKey(key):

@@ -39,11 +49,21 @@ # Go up the scope chain and attempt to find the symbol

if scope.parent.isNotNil: result = scope.parent.setSymbol(key, value) -proc getSigil*(scope: ref MinScope, key: string): MinOperator {.gcsafe.}= +proc getSigil*(scope: ref MinScope, key: string): MinOperator = if scope.sigils.hasKey(key): return scope.sigils[key] elif scope.parent.isNotNil: return scope.parent.getSigil(key) + else: + raiseUndefined("Sigil '$1' not found." % key) + +proc hasSigil*(scope: ref MinScope, key: string): bool = + if scope.sigils.hasKey(key): + return true + elif scope.parent.isNotNil: + return scope.parent.hasSigil(key) + else: + return false proc dump*(i: MinInterpreter): string = var s = ""

@@ -146,8 +166,9 @@ if not i.evaluating:

i.currSym = val let symbol = val.symVal let sigil = "" & symbol[0] - let symbolProc = i.scope.getSymbol(symbol) - if symbolProc.isNotNil: + let found = i.scope.hasSymbol(symbol) + if found: + let symbolProc = i.scope.getSymbol(symbol) if i.unsafe: let stack = i.copystack try:

@@ -159,8 +180,9 @@ else:

i.execute: i.symbolProc else: - let sigilProc = i.scope.getSigil(sigil) - if symbol.len > 1 and sigilProc.isNotNil: + let found = i.scope.hasSigil(sigil) + if symbol.len > 1 and found: + let sigilProc = i.scope.getSigil(sigil) let sym = symbol[1..symbol.len-1] i.stack.add(MinValue(kind: minString, strVal: sym)) if i.unsafe:
M lib/min_lang.nimlib/min_lang.nim

@@ -115,7 +115,15 @@ i.debug "[import] $1:$2" % [i.scope.name, sym]

i.scope.symbols[sym] = val .sigil("'") do (i: In): - i.push(@[MinValue(kind: minSymbol, symVal: i.pop.strVal)].newVal) + var s: MinValue + i.reqString s + i.push(@[MinValue(kind: minSymbol, symVal: s.strVal)].newVal) + + .sigil("#") do (i: In): + var s: MinValue + i.reqString s + i.push s + i.push "import".newSym .symbol("sigil") do (i: In): var q1, q2: MinValue

@@ -123,7 +131,7 @@ i.reqTwoQuotations q1, q2

if q1.qVal.len == 1 and q1.qVal[0].kind == minSymbol: var symbol = q1.qVal[0].symVal if symbol.len == 1: - if i.scope.getSigil(symbol).isNotNil: + if i.scope.hasSigil(symbol): raiseInvalid("Sigil '$1' already exists" % [symbol]) i.scope.sigils[symbol] = proc(i: In) = i.evaluating = true

@@ -162,8 +170,6 @@ let s = symbol.getString

let origScope = i.scope i.scope = q.scope let sProc = i.scope.getSymbol(s) - if sProc.isNil: - raiseUndefined("Symbol '$1' not found in scope '$2'" % [s, i.scope.fullname]) # Restore original quotation sProc(i) i.scope = origScope
M lib/prelude.minlib/prelude.min

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

-(import) (#) sigil - ; Imports #str #io
M minim.nimminim.nim

@@ -39,7 +39,7 @@ Options:

-e, --evaluate Evaluate a minim program inline -h, --help Print this help -v, --version Print the program version - -i, --interactive Start MiNiM's Read Eval Print Loop""" + -i, --interactive Start MiNiM Shell""" var CURRSCOPE*: ref MinScope

@@ -56,8 +56,9 @@ linenoiseAddCompletion completions, words.join(" ") & sep & s

proc prompt(s: string): string = var res = linenoise(s) - discard $linenoiseHistoryAdd(res) - return $res + if not res.isNil: + discard $linenoiseHistoryAdd(res) + return $res proc stdLib(i: In) =

@@ -111,6 +112,9 @@ when USE_LINENOISE:

CURRSCOPE = i.scope linenoiseSetCompletionCallback completionCallback line = prompt(": ") + if line.isNil: + echo "-> Exiting..." + quit(0) i.parser.buf = $i.parser.buf & $line i.parser.bufLen = i.parser.buf.len discard i.parser.getToken()

@@ -119,7 +123,10 @@ i.interpret()

except: warn getCurrentExceptionMsg() finally: - echo "-> ($1)" % i.dump.strip + if i.stack.len > 0: + echo("[$1] -> $2" % [$i.stack.len, $i.stack[i.stack.len - 1]]) + else: + echo "[0]" proc minimRepl*(debugging = false) = var i = newMinInterpreter(debugging)