all repos — min @ 9616781b776e00ddc7c55ac6a43ca78254fc3eb9

A small but practical concatenative programming language.

Fixed lexical scoping; added publish operator.
h3rald h3rald@h3rald.com
Mon, 10 Oct 2016 18:03:43 +0200
commit

9616781b776e00ddc7c55ac6a43ca78254fc3eb9

parent

6864ca1b051fd9e73bd154d1d666481dbe99bd52

5 files changed, 50 insertions(+), 24 deletions(-)

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

@@ -96,11 +96,9 @@ template createScope*(i: In, id: string, q: MinValue, body: untyped): untyped =

q.scope = new MinScope q.scope.name = id q.scope.parent = i.scope - #i.debug "[scope] " & q.scope.fullname let scope = i.scope i.scope = q.scope body - #i.debug "[scope] " & scope.fullname i.scope = scope template withScope*(i: In, q: MinValue, body: untyped): untyped =

@@ -110,6 +108,17 @@ i.scope = q.scope

body #i.debug "[scope] " & scope.fullname i.scope = origScope + +template addScope*(i: In, id: string, q: MinValue, body: untyped): untyped = + var added = new MinScope + added.name = id + if q.scope.isNil: + q.scope = i.scope + added.parent = q.scope + let scope = i.scope + i.scope = added + body + i.scope = scope proc copystack*(i: MinInterpreter): MinStack = return i.stack

@@ -169,14 +178,17 @@ i.parser.close();

proc push*(i: In, val: MinValue) {.gcsafe.} -proc apply*(i: In, op: MinOperator) = +proc apply*(i: In, op: MinOperator, name="apply") = case op.kind of minProcOp: op.prc(i) of minValOp: if op.val.kind == minQuotation: - for e in op.val.qVal: - i.push e + var q = op.val + i.addScope("apply", q): + #echo "a1: ", i.scope.fullname + for e in q.qVal: + i.push e else: i.push(op.val)

@@ -193,13 +205,13 @@ let sym = i.scope.getSymbol(symbol)

if i.unsafe: let stack = i.copystack try: - i.apply(sym) + i.apply(sym, "symbol:" & symbol) except: i.stack = stack raise else: i.execute: - i.apply(sym) + i.apply(sym, "symbol:" & symbol) else: let found = i.scope.hasSigil(sigil) if symbol.len > 1 and found:

@@ -209,15 +221,15 @@ i.stack.add(MinValue(kind: minString, strVal: sym))

if i.unsafe: let stack = i.copystack try: - i.apply(sig) + i.apply(sig,"sigil:" & sym) except: i.stack = stack raise else: i.execute: - i.apply(sig) + i.apply(sig, "sigil:" & sym) else: - raiseUndefined("Undefined symbol: '"&val.symVal&"'") + raiseUndefined("Undefined symbol '$1' in scope '$2'" % [val.symVal, i.scope.fullname]) else: i.stack.add(val)
M core/utils.nimcore/utils.nim

@@ -120,6 +120,12 @@ a = i.pop

if not a.isString or not q.isQuotation: raiseInvalid("A string and a quotation are required on the stack") +proc reqQuotationAndStringLike*(i: var MinInterpreter, q, a: var MinValue) = + q = i.pop + a = i.pop + if not a.isStringLike or not q.isQuotation: + raiseInvalid("A quotation and a string or a symbol are required on the stack") + proc reqStringOrQuotation*(i: var MinInterpreter, a: var MinValue) = a = i.pop if not a.isQuotation and not a.isString:
M lib/min_lang.nimlib/min_lang.nim

@@ -3,7 +3,8 @@ critbits,

strutils, os, json, - algorithm + algorithm, + oids import ../core/consts, ../core/parser,

@@ -163,14 +164,12 @@ var symbol: string

if not q1.isQuotation: q1 = @[q1].newVal symbol = sym.getString - if not symbol.match "^[a-zA-Z0-9+._-][a-zA-Z0-9/!?+*._-]*$": + if not symbol.match "^[a-zA-Z0-9_][a-zA-Z0-9/!?+*._-]*$": raiseInvalid("Symbol identifier '$1' contains invalid characters." % symbol) - i.debug "[define] " & symbol & " = " & $q1 - #let p = proc(i: In) = - # i.push q1.qVal - #i.scope.symbols[symbol] = MinOperator(kind: minProcOp, prc: p) + i.debug "[define] (scope: $1) $2 = $3" % [i.scope.name, symbol, $q1] if i.scope.symbols.hasKey(symbol) and i.scope.symbols[symbol].sealed: - raiseUndefined("Attempting to redefined sealed symbol '$1'" % symbol) + raiseUndefined("Attempting to redefine sealed symbol '$1' on scope '$2'" % [symbol, i.scope.name]) + i.newScope("$1#$2" % [symbol, $genOid()], q1) i.scope.symbols[symbol] = MinOperator(kind: minValOp, val: q1, sealed: false) .symbol("bind") do (i: In):

@@ -270,6 +269,15 @@ for v in qprog.qVal:

i.push v i.scope = scope + .symbol("publish") do (i: In): + var qscope, str: MinValue + i.reqQuotationAndStringLike qscope, str + let sym = str.getString + #TODO Check for sealed + if qscope.scope.symbols.hasKey(sym) and qscope.scope.symbols[sym].sealed: + raiseUndefined("Attempting to redefine sealed symbol '$1' on scope '$2'" % [sym, qscope.scope.name]) + qscope.scope.symbols[sym] = i.scope.getSymbol(sym) + .symbol("source") do (i: In): var s: MinValue i.reqStringLike s

@@ -479,7 +487,7 @@

.symbol("map") do (i: In): var prog, list: MinValue i.reqTwoQuotations prog, list - i.push newVal(newSeq[MinValue](0)) + #i.push newVal(newSeq[MinValue](0)) var res = newSeq[MinValue](0) for litem in list.qVal: i.push litem

@@ -607,7 +615,7 @@ .symbol("dget") do (i: In):

var d, k: MinValue i.reqStringLike k i.reqDictionary d - i.push d + #i.push d i.push d.dget(k) .symbol("dset") do (i: In):

@@ -628,18 +636,18 @@ var d: MinValue

i.reqDictionary d for v in d.qVal: echo "$1: $2" % [$v.qVal[0], $v.qVal[1]] - i.push d + #i.push d .symbol("keys") do (i: In): var d: MinValue i.reqDictionary d - i.push d + #i.push d i.push d.keys .symbol("values") do (i: In): var d: MinValue i.reqDictionary d - i.push d + #i.push d i.push d.values .symbol("interpolate") do (i: In):
M minim.vimminim.vim

@@ -12,7 +12,7 @@ setl iskeyword+=?,$,+,*,/,%,=,>,<,&,-,',.,:,~,!

setl iskeyword+=^ setl iskeyword+=@ -syntax keyword minimDefaultSymbol ! != $ & ' * + - % ^ -> . .. / : < <= == => =~ > >= @ ROOT aes and append apply 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 define* delete dget dictionary? dig1 dig2 dig3 dip dir? dirname div dprint dprint! dset dump-stack dup dupd echo encode encrypt env? eq eval even? exit fappend file? filename filter first float float? foreach fperms fread from-json fs fsize fstats ftype fwrite gets get-stack getenv gt gte hardlink hidden? i id ifte import include indent inspect int int? interpolate interval io join k keys length linrec load load-symbol logic lowercase ls ls-r lt lte map match md5 mkdir mod module mtime mv newline not noteq now num number? odd? or os password pop popd pred prepend print print! prompt puts puts! putenv q quit quotation? quote raise regex remove-symbol repeat replace rest rm rmdir run save-symbol scope scope? seal search select set-stack sha1 sha224 sha256 sha384 sha512 sigils sip size 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 unit unquote uppercase unzip values version which while with xor zap zip contains +syntax keyword minimDefaultSymbol ! != $ & ' * + - % ^ -> . .. / : < <= == => =~ > >= @ ROOT aes and append apply 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 define* delete dget dictionary? dig1 dig2 dig3 dip dir? dirname div dprint dprint! dset dump-stack dup dupd echo encode encrypt env? eq eval even? exit fappend file? filename filter first float float? foreach fperms fread from-json fs fsize fstats ftype fwrite gets get-stack getenv gt gte hardlink hidden? i id ifte import include indent inspect int int? interpolate interval io join k keys length linrec load load-symbol logic lowercase ls ls-r lt lte map match md5 mkdir mod module mtime mv newline not noteq now num number? odd? or os password pop popd pred prepend print print! prompt publish puts puts! putenv q quit quotation? quote raise regex remove-symbol repeat replace rest rm rmdir run save-symbol scope scope? seal search select set-stack sha1 sha224 sha256 sha384 sha512 sigils sip size 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 unit unquote uppercase unzip values version which while with xor zap zip contains syntax match minimDefaultSigil ;\<[:@'~!$%&$=<>^*]; contained
M prelude.minprelude.min

@@ -74,4 +74,4 @@

; Load all stored symbols stored-symbols ('load-symbol ROOT with) foreach -startup +'startup ROOT with