all repos — min @ e8aa70f35ae2269b3583cd76ec98a223aa25a0ca

A small but practical concatenative programming language.

Implemented apply operator; prelude again loading all modules.
h3rald h3rald@h3rald.com
Sun, 26 Mar 2017 10:48:30 +0200
commit

e8aa70f35ae2269b3583cd76ec98a223aa25a0ca

parent

68243bde5c29c633eef09420ec8ee0d018b48f06

M core/interpreter.nimcore/interpreter.nim

@@ -110,6 +110,14 @@ i.push e

else: i.push(op.val) +proc apply*(i: In, q: MinValue) = + var i2 = newMinInterpreter("<apply>") + i2.scope = i.scope + i2.withScope(q, q.scope): + for v in q.qVal: + i2.push v + i.push i2.stack.newVal(i.scope) + proc unquote*(i: In, q: var MinValue) = i.withScope(q, q.scope): for v in q.qVal:
M core/value.nimcore/value.nim

@@ -77,4 +77,4 @@ let sym = v.qVal[0]

if sym.isSymbol: return sym.symVal else: - raiseInvalid("Quotation is not a quoted symbol")+ raiseInvalid("Quotation is not a quoted symbol")
M lib/min_lang.nimlib/min_lang.nim

@@ -56,15 +56,6 @@ for s in m.scope.sigils.keys:

q.add s.newVal i.push q.newVal(i.scope) - .symbol("sigils") do (i: In): - var q = newSeq[MinValue](0) - var scope = i.scope - while not scope.isNil: - for s in scope.sigils.keys: - q.add s.newVal - scope = scope.parent - i.push q.newVal(i.scope) - .symbol("from-json") do (i: In): var s: MinValue i.reqString s

@@ -300,41 +291,27 @@ finally:

if hasFinally: i.unquote(final) - # Operations on quotations or strings + # Operations on quotations .symbol("concat") do (i: In): var q1, q2: MinValue - i.reqTwoQuotationsOrStrings q1, q2 - if q1.isString and q2.isString: - let s = q2.strVal & q1.strVal - i.push newVal(s) - else: - let q = q2.qVal & q1.qVal - i.push q.newVal(i.scope) + i.reqTwoQuotations q1, q2 + let q = q2.qVal & q1.qVal + i.push q.newVal(i.scope) .symbol("first") do (i: In): var q: MinValue - i.reqStringOrQuotation q - if q.isQuotation: - if q.qVal.len == 0: - raiseOutOfBounds("Quotation is empty") - i.push q.qVal[0] - elif q.isString: - if q.strVal.len == 0: - raiseOutOfBounds("String is empty") - i.push newVal($q.strVal[0]) + i.reqQuotation q + if q.qVal.len == 0: + raiseOutOfBounds("Quotation is empty") + i.push q.qVal[0] .symbol("rest") do (i: In): var q: MinValue - i.reqStringOrQuotation q - if q.isQuotation: - if q.qVal.len == 0: - raiseOutOfBounds("Quotation is empty") - i.push q.qVal[1..q.qVal.len-1].newVal(i.scope) - elif q.isString: - if q.strVal.len == 0: - raiseOutOfBounds("String is empty") - i.push newVal(q.strVal[1..q.strVal.len-1]) + i.reqQuotation q + if q.qVal.len == 0: + raiseOutOfBounds("Quotation is empty") + i.push q.qVal[1..q.qVal.len-1].newVal(i.scope) .symbol("quote") do (i: In): let a = i.pop

@@ -349,15 +326,13 @@ .symbol("append") do (i: In):

var q: MinValue i.reqQuotation q let v = i.pop - q.qVal.add v - i.push q + i.push newVal(q.qVal & v, i.scope) .symbol("prepend") do (i: In): var q: MinValue i.reqQuotation q let v = i.pop - q.qVal = v & q.qVal - i.push q + i.push newVal(v & q.qVal, i.scope) .symbol("at") do (i: In): var index, q: MinValue

@@ -366,13 +341,10 @@ if q.qVal.len-1 < index.intVal:

raiseOutOfBounds("Insufficient items in quotation") i.push q.qVal[index.intVal.int] - .symbol("length") do (i: In): + .symbol("size") do (i: In): var q: MinValue - i.reqStringOrQuotation q - if q.isQuotation: - i.push q.qVal.len.newVal - elif q.isString: - i.push q.strVal.len.newVal + i.reqQuotation q + i.push q.qVal.len.newVal .symbol("contains") do (i: In): let v = i.pop

@@ -389,6 +361,11 @@ i.push litem

i.unquote(prog) res.add i.pop i.push res.newVal(i.scope) + + .symbol("apply") do (i: In): + var prog: MinValue + i.reqQuotation prog + i.apply prog .symbol("foreach") do (i: In): var prog, list: MinValue

@@ -559,11 +536,7 @@ var s, q: MinValue

i.reqQuotationAndString q, s var strings = newSeq[string](0) for el in q.qVal: - if el.isSymbol: - i.push el - strings.add $$i.pop - else: - strings.add $$el + strings.add $$el let res = s.strVal % strings i.push res.newVal

@@ -714,5 +687,8 @@ i.push("quote".newSym)

.symbol("->") do (i: In): i.push("unquote".newSym) + + .symbol("=>") do (i: In): + i.push("apply".newSym) .finalize("ROOT")
M lib/min_str.nimlib/min_str.nim

@@ -31,6 +31,11 @@ var q, s: MinValue

i.reqStringLikeAndQuotation s, q i.push q.qVal.mapIt($$it).join(s.getString).newVal + .symbol("length") do (i: In): + var s: MinValue + i.reqStringLike s + i.push s.getString.len.newVal + .symbol("lowercase") do (i: In): var s: MinValue i.reqStringLike s
M min.nimblemin.nimble

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

[Package] name = "min" -version = "0.4.0" +version = "0.5.0" author = "Fabio Cevasco" description = "A tiny concatenative programming language and shell." license = "MIT"
M min.vimmin.vim

@@ -11,7 +11,7 @@

setl iskeyword=@,36-39,+,-,/,*,.,:,~,!,48-57,60-65,94-95,192-255 setl iskeyword+=^ -syntax keyword minDefaultSymbol ! != $ & ' * + # - % ^ -> . .. / : < <= == => =~ > >= @ 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 decode define delete dget dictionary? dig1 dig2 dig3 dip dir? dirname div dprint dprint! dset dump-stack dup dupd encode env? error eval even? exists? exit fappend fatal file? filename filter first float float? foreach fperms fread from-json format-error fs fsize fstats ftype fwrite gets get-stack getenv hardlink hidden? id ift ifte import indent info inspect int int? interpolate interval io join k keys length linrec load load-symbol logic loglevel loglevel? lowercase ls ls-r map match md5 mkdir mod module module-symbols module-sigils mtime mv newline not notice now num number? odd? os password pop popd pred prepend print print! prompt publish puts puts! putenv q quotation? quote quote-bind quote-define random 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 warn which while with xor zip contains +syntax keyword minDefaultSymbol ! != $ & ' * + # - % ^ -> . .. / : < <= == => =~ > >= @ 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 decode define delete dget dictionary? dig1 dig2 dig3 dip dir? dirname div dprint dprint! dset dump-stack dup dupd encode env? error eval even? exists? exit fappend fatal file? filename filter first float float? foreach fperms fread from-json format-error fs fsize fstats ftype fwrite gets get-stack getenv hardlink hidden? id ift ifte import indent info inspect int int? interpolate interval io join k keys length linrec load load-symbol logic loglevel loglevel? lowercase ls ls-r map match md5 mkdir mod module module-symbols module-sigils mtime mv newline not notice now num number? odd? os password pop popd pred prepend print print! prompt publish puts puts! putenv q quotation? quote quote-bind quote-define random 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 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 unquote uppercase unzip values version warn which while with xor zip contains syntax match minDefaultSigil ;\<[:@'~!$%&$=<>#^*#+/]; contained
M prelude.minprelude.min

@@ -4,10 +4,10 @@ 'io import

'logic import 'num import 'sys import -;'stack import -;'time import -;'fs import -;'crypto import +'stack import +'time import +'fs import +'crypto import ; Unsealed symbols () :startup
M tests/all.mintests/all.min

@@ -1,9 +1,3 @@

-; Import optional module -'stack import -'time import -'fs import -'crypto import - ; Load test files 'lang load 'stack load
M tests/lang.mintests/lang.min

@@ -2,8 +2,8 @@ 'test load

'test import newline -symbols length :total-symbols -sigils length :total-sigils +symbols size :total-symbols +sigils size :total-sigils "Total Symbols: $1" (total-symbols) % puts! "Total Sigils: $1" (total-sigils) % puts! newline

@@ -23,7 +23,7 @@ ((1 2 3 4 5 6)) :test-data

( :item - "_$1" (item) % :namesym + "_$1" (item) => % :namesym (item dup *) namesym define namesym ROOT publish ) :def

@@ -87,7 +87,7 @@

(0 (1 2 3) prepend (0 1 2 3) ==) assert ((1 2 3 4) 2 at 3 ==) assert - ((1 2 3) length 3 ==) assert + ((1 2 3) size 3 ==) assert ((1 2 3 4) 5 contains false ==) assert ((1 2 3 4) 2 contains) assert
M tests/stack.mintests/stack.min

@@ -13,7 +13,7 @@ (1 dup get-stack (1 1) ==) assert

(3 2 (1 +) dip + 6 ==) assert - ((1) (2 swap append) sip concat (1 2 1 2) ==) assert + ((1) (2 swap append) sip concat (1 2 1) ==) assert (1 (2 3) cons (1 2 3) ==) assert
M tests/str.mintests/str.min

@@ -5,6 +5,8 @@ "str" describe

(" test " strip "test" ==) assert + ("test" length 4 ==) assert + ("a,b,c" "," split ("a" "b" "c") ==) assert ("test #1" "[0-9]" search ("1") ==) assert
M tests/sys.mintests/sys.min

@@ -25,7 +25,7 @@ ('dir2 ls 'dirname map ("dir2") ==) assert

('dir1 rmdir 'dir2 rmdir 'dir1 dir? 'dir2 dir? or false ==) assert - ("systest" mkdir . ls . "/systest" concat contains) assert + ("systest" mkdir . ls (. "systest") => "/" join contains) assert ("systest" cd . "systest" match) assert .. cd

@@ -52,14 +52,14 @@ ("test.txt" "test2.txt" cp "test2.txt" file?) assert

("test.txt" "test1.txt" mv "test1.txt" file?) assert - ("test2.txt" rm "test1.txt" rm . ls . "/test1.txt" concat contains :t1 . ls "test2" contains t1 and false ==) assert + ("test2.txt" rm "test1.txt" rm . ls (. "test1.txt") => "/" join contains :t1 . ls "test2" contains t1 and false ==) assert ("systest" cd "TEST" "test.txt" fwrite "TEST1" "test1.txt" fwrite "TEST2" "test2.txt" fwrite "TEST3" "test3.txt" fwrite - . ls "test.zip" zip . ls . "/test.zip" concat contains) assert + . ls "test.zip" zip . ls (. "test.zip") => "/" join contains) assert ("test.zip" "extracted" unzip "extracted" ls "extracted/test1.txt" contains) assert

@@ -67,7 +67,7 @@ "extracted" ls 'rm foreach

. ls 'rm foreach .. cd - ("systest" rmdir . ls . "/systest" concat contains false ==) assert + ("systest" rmdir . ls (. "systest") => "/" join contains false ==) assert