call operator now restoring original quotation.
h3rald h3rald@h3rald.com
Fri, 24 Jun 2016 11:34:56 +0200
5 files changed,
73 insertions(+),
47 deletions(-)
M
core/utils.nim
→
core/utils.nim
@@ -44,13 +44,35 @@ proc newSym*(s: string): MinValue =
return MinValue(kind: minSymbol, symVal: s) proc isStringLike*(s: MinValue): bool = - return s.isSymbol or s.isString + return s.isSymbol or s.isString or (s.isQuotation and s.qVal.len == 1 and s.qVal[0].isSymbol) + +# Error Helpers + +proc raiseInvalid*(msg: string) = + raise MinInvalidError(msg: msg) + +proc raiseUndefined*(msg: string) = + raise MinUndefinedError(msg: msg) + +proc raiseOutOfBounds*(msg: string) = + raise MinOutOfBoundsError(msg: msg) + +proc raiseRuntime*(msg: string, qVal: var seq[MinValue]) = + raise MinRuntimeError(msg: msg, qVal: qVal) proc getString*(v: MinValue): string = if v.isSymbol: return v.symVal elif v.isString: return v.strVal + elif v.isQuotation: + if v.qVal.len == 1: + raiseInvalid("Quotation is not a quoted symbol") + let sym = v.qVal[0] + if sym.isSymbol: + return v.symVal + else: + raiseInvalid("Quotation is not a quoted symbol") proc warn*(s: string) = stderr.writeLine s@@ -94,20 +116,6 @@ shallowCopy varname, value
proc to*(q: MinValue, T: typedesc): T = return cast[T](q.obj) - -# Error Helpers - -proc raiseInvalid*(msg: string) = - raise MinInvalidError(msg: msg) - -proc raiseUndefined*(msg: string) = - raise MinUndefinedError(msg: msg) - -proc raiseOutOfBounds*(msg: string) = - raise MinOutOfBoundsError(msg: msg) - -proc raiseRuntime*(msg: string, qVal: var seq[MinValue]) = - raise MinRuntimeError(msg: msg, qVal: qVal) # Validators@@ -166,7 +174,7 @@ a = i.pop
if not a.isQuotation and not a.isString: raiseInvalid("A quotation or a string is required on the stack") -proc reqStringOrSymbol*(i: var MinInterpreter, a: var MinValue) = +proc reqStringLike*(i: var MinInterpreter, a: var MinValue) = a = i.pop if not a.isStringLike: raiseInvalid("A symbol or a string is required on the stack")
M
lib/min_lang.nim
→
lib/min_lang.nim
@@ -77,7 +77,7 @@ raiseUndefined("Attempting to bind undefined symbol: " & symbol)
.symbol("delete") do (i: In): var sym: MinValue - i.reqStringOrSymbol sym + i.reqStringLike sym let res = i.scope.delSymbol(sym.getString) if not res: raiseUndefined("Attempting to delete undefined symbol: " & sym.getString)@@ -143,28 +143,42 @@ i.withScope(qscope):
i.unquote("<with-program>", qprog) .symbol("call") do (i: In): - var symbols, target: MinValue - i.reqTwoQuotations symbols, target - let vals = symbols.qVal - var q: MinValue - if vals.len == 0: - raiseInvalid("No symbol to call") + var symbol, q: Minvalue + i.reqStringLike symbol + i.reqQuotation q + let s = symbol.getString let origScope = i.scope - i.scope = target.scope - for c in 0..vals.len-1: - if not vals[c].isStringLike: - raiseInvalid("Quotation must contain only symbols or strings") - let symbol = vals[c].getString - let qProc = i.scope.getSymbol(symbol) - if qProc.isNil: - raiseUndefined("Symbol '$1' not found in scope '$2'" % [symbol, i.scope.fullname]) - qProc(i) - if vals.len > 1 and c < vals.len-1: - q = i.pop - if not q.isQuotation: - raiseInvalid("Unable to evaluate symbol '$1'" % [symbol]) - i.scope = q.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]) + sProc(i) i.scope = origScope + # Restore original quotation + i.push @[q] + + #var symbols, target: MinValue + #i.reqTwoQuotations symbols, target + #let vals = symbols.qVal + #var q: MinValue + #if vals.len == 0: + # raiseInvalid("No symbol to call") + #let origScope = i.scope + #i.scope = target.scope + #for c in 0..vals.len-1: + # if not vals[c].isStringLike: + # raiseInvalid("Quotation must contain only symbols or strings") + # let symbol = vals[c].getString + # let qProc = i.scope.getSymbol(symbol) + # if qProc.isNil: + # raiseUndefined("Symbol '$1' not found in scope '$2'" % [symbol, i.scope.fullname]) + # qProc(i) + # if vals.len > 1 and c < vals.len-1: + # q = i.pop + # if not q.isQuotation: + # raiseInvalid("Unable to evaluate symbol '$1'" % [symbol]) + # i.scope = q.scope + #i.scope = origScope .symbol("inspect") do (i: In): var scope: MinValue
M
lib/min_net.nim
→
lib/min_net.nim
@@ -7,9 +7,12 @@ ../core/utils
# Network +proc close(i: In) = + discard + define("net") - .symbol("open-socket") do (i: In): + .symbol("^socket") do (i: In): var q: MinValue i.reqQuotation q # (ipv4 stream tcp)@@ -58,8 +61,8 @@ q.to(Socket).close()
.symbol("listen") do (i: In): var port, q: MinValue - i.reqInt port i.reqObject "socket", q + i.reqInt port var socket = q.to(Socket) socket.bindAddr(Port(port.intVal)) q.qVal.add "0.0.0.0".newSym
M
lib/prelude.min
→
lib/prelude.min
@@ -18,7 +18,7 @@ (getenv) ($) sigil
(system) (!) sigil (run) (&) sigil (load) (@) sigil -(":" split call) (%) sigil +(call) (%) sigil ; Aliases 'define ::@@ -77,11 +77,12 @@ ; Other
(print pop) :print! (put pop) :put! (:ms :q :check (check) (ms sleep q) while) :interval +(call pop) :call! ; Socket constructors -((ipv4 stream tcp) socket) :tcp-socket -((ipv6 stream tcp) socket) :tcp6-socket -((ipv4 dgram tcp) socket) :udp-socket -((ipv6 dgram tcp) socket) :udp6-socket +((ipv4 stream tcp) ^socket) :tcp-socket +((ipv6 stream tcp) ^socket) :tcp6-socket +((ipv4 dgram tcp) ^socket) :udp-socket +((ipv6 dgram tcp) ^socket) :udp6-socket
M
tests/lang.min
→
tests/lang.min
@@ -3,7 +3,7 @@ #test
"lang" describe - (symbols size 179 ==) assert + (symbols size 180 ==) assert (sigils size 10 ==) assert@@ -34,7 +34,7 @@ ; Extend an existing scope
(defmod (#mymath (-) :myminus) => .mymath - 5 2 mymath %myminus 3 ==) assert + 5 2 mymath %myminus pop 3 ==) assert (defmod mymath inspect ("myplus") ==) assert@@ -45,7 +45,7 @@
("2 2 +" "tests/testload.min" fwrite @testload 4 ==) assert "tests/testload.min" rm - (defmod 2 2 mymath %myplus 4 ==) assert + (defmod 2 2 mymath %myplus pop 4 ==) assert (1 2 3 4 getstack (1 2 3 4) ==) assert