feat(call) Implemented call symbol and % sigil.
h3rald h3rald@h3rald.com
Sun, 29 May 2016 12:21:42 +0200
6 files changed,
50 insertions(+),
20 deletions(-)
M
core/utils.nim
→
core/utils.nim
@@ -37,6 +37,15 @@
proc newVal*(s: bool): MinValue = return MinValue(kind: minBool, boolVal: s) +proc isStringLike*(s: MinValue): bool = + return s.isSymbol or s.isString + +proc getString*(v: MinValue): string = + if v.isSymbol: + return v.symVal + elif v.isString: + return v.strVal + proc warn*(s: string) = stderr.writeLine s
M
lib/io.nim
→
lib/io.nim
@@ -13,11 +13,11 @@
.symbol("newline") do (i: In): echo "" - .symbol("puts") do (i: In): + .symbol("put") do (i: In): let a = i.peek echo $$a - .symbol("gets") do (i: In): + .symbol("get") do (i: In): i.push newVal(stdin.readLine()) .symbol("print") do (i: In):
M
lib/lang.nim
→
lib/lang.nim
@@ -103,8 +103,8 @@ for sym, val in mdl.scope.symbols.pairs:
i.debug "[$1 - import] $2:$3" % [i.scope.parent.name, i.scope.name, sym] i.scope.parent.symbols[sym] = val - .sigil("'") do (i: In): - i.push(@[MinValue(kind: minSymbol, symVal: i.pop.strVal)].newVal) + #.sigil("'") do (i: In): + # i.push(@[MinValue(kind: minSymbol, symVal: i.pop.strVal)].newVal) .symbol("sigil") do (i: In): var q1 = i.pop@@ -141,6 +141,26 @@ if s.isString:
i.load s.strVal else: i.error(errIncorrect, "A string is required on the stack") + + + .symbol("call") do (i: In): + let fqn = i.pop + if fqn.isQuotation: + let vals = fqn.qVal + var q: MinValue + if vals.len == 0: + i.error(errIncorrect, "No symbol to call") + for c in 0..vals.len-1: + if not vals[c].isStringLike: + i.error(errIncorrect, "Quotation must contain only symbols or strings") + i.scope.getSymbol(vals[c].getString)(i) + if vals.len > 1 and c < vals.len-1: + q = i.pop + if not q.isQuotation: + i.error(errIncorrect, "Unable to evaluate symbol '$1'" % [vals[c-1].getString]) + else: + i.error(errIncorrect, "A quotation is required on the stack") + # Operations on the whole stack
M
lib/prelude.min
→
lib/prelude.min
@@ -10,13 +10,15 @@ #sys
#time ; Common sigils -(bind) (:) sigil -(let) (.) sigil -(getenv) ($) sigil -(system) (!) sigil -(run) (&) sigil -(module) (=) sigil -(load) (@) sigil +(quote) (') sigil +(bind) (:) sigil +(let) (.) sigil +(getenv) ($) sigil +(system) (!) sigil +(run) (&) sigil +(module) (=) sigil +(load) (@) sigil +(":" split call) (%) sigil ; Aliases 'bind ::@@ -24,15 +26,13 @@ 'let :.
'module := 'import :# 'exit :quit -'concat :, -'print :% '== :eq '!= :noteq '> :gt '< :lt '>= :gte '<= :lte -'puts :echo +'put :echo 'system :! 'run :& 'getenv :$@@ -45,7 +45,6 @@ 'unquote :->
'filter :select 'clear :empty 'cons :prepend -'match :~ ; Mathematical Operators (1 +) :succ@@ -74,5 +73,5 @@ ((() cons cons cons) dip swap i) :bury3
; Other (print pop) :print! -(puts pop) :puts! +(put pop) :put!
M
lib/str.nim
→
lib/str.nim
@@ -11,9 +11,11 @@
.symbol("split") do (i: In): let sep = i.pop let s = i.pop + var q = newSeq[MinValue](0) if s.isString and sep.isString: for e in s.strVal.split(sep.strVal): - i.push e.newVal + q.add e.newVal + i.push q.newVal else: i.error errIncorrect, "Two strings are required on the stack"
M
tests/test.min
→
tests/test.min
@@ -6,7 +6,7 @@
;; describe ( .name - "Testing: " print! name puts! + "Testing: " print! name put! padding () ) :describe@@ -37,12 +37,12 @@ results (
total succ :total (ok !=) (failed succ :failed) () ifte ) map - padding total print! " tests executed - " print! failed print! " failed." puts! + padding total print! " tests executed - " print! failed print! " failed." put! ( ' .result result (ok !=) - (padding "FAILED: " print! result puts!) + (padding "FAILED: " print! result put!) () ifte )