all repos — min @ 5f300518c6a46b1ec6204560d275af247851c0bf

A small but practical concatenative programming language.

Implemented proper dget.
h3rald h3rald@h3rald.com
Fri, 01 Jun 2018 22:07:05 +0200
commit

5f300518c6a46b1ec6204560d275af247851c0bf

parent

7d5ed196a7f42f455f6edac406465c51c0912c15

M core/interpreter.nimcore/interpreter.nim

@@ -26,7 +26,7 @@ s = s & $item & " "

return s proc debug*(i: In, value: MinValue) {.extern:"min_exported_symbol_$1".}= - debug("{" & i.dump & $value & "}") + debug("(" & i.dump & $value & ")") proc debug*(i: In, value: string) {.extern:"min_exported_symbol_$1_2".}= debug(value)

@@ -154,6 +154,24 @@ i.currSym = i2.currSym

i.trace = i2.trace raise i.push i2.stack.newVal(i.scope) + +proc call*(i: In, q: var MinValue): MinValue {.gcsafe, extern:"min_exported_symbol_$1".}= + var i2 = newMinInterpreter("<call>") + i2.trace = i.trace + i2.scope = i.scope + try: + i2.withScope(q): + for v in q.qVal: + if (v.kind == minQuotation): + var v2 = v + i2.dequote(v2) + else: + i2.push v + except: + i.currSym = i2.currSym + i.trace = i2.trace + raise + return i2.stack.newVal(i2.scope) proc push*(i: In, val: MinValue) {.gcsafe, extern:"min_exported_symbol_$1".}= if val.kind == minSymbol:
M core/utils.nimcore/utils.nim

@@ -47,15 +47,27 @@ scope.previous.symbols[name] = MinOperator(kind: minProcOp, prc: op)

# Dictionary Methods -proc dget*(q: MinValue, s: MinValue): MinValue {.extern:"min_exported_symbol_$1".}= +proc dget*(i: In, q: MinValue, s: MinValue): MinValue {.extern:"min_exported_symbol_$1".}= if not q.isDictionary: raiseInvalid("Value is not a dictionary") - return q.dVal[s.getString].val + var val = q.dVal[s.getString].val + return i.call(val) + +proc dget*(i: In, q: MinValue, s: string): MinValue {.extern:"min_exported_symbol_$1_2".}= + if not q.isDictionary: + raiseInvalid("Value is not a dictionary") + var val = q.dVal[s].val + return i.call(val) proc dhas*(q: MinValue, s: MinValue): bool {.extern:"min_exported_symbol_$1".}= if not q.isDictionary: raiseInvalid("Value is not a dictionary") return q.dVal.contains(s.getString) + +proc dhas*(q: MinValue, s: string): bool {.extern:"min_exported_symbol_$1_2".}= + if not q.isDictionary: + raiseInvalid("Value is not a dictionary") + return q.dVal.contains(s) proc ddel*(i: In, p: var MinValue, s: MinValue): MinValue {.discardable, extern:"min_exported_symbol_$1".} = if not p.isDictionary:

@@ -63,6 +75,12 @@ raiseInvalid("Value is not a dictionary")

excl(p.scope.symbols, s.getString) return p +proc ddel*(i: In, p: var MinValue, s: string): MinValue {.discardable, extern:"min_exported_symbol_$1_2".} = + if not p.isDictionary: + raiseInvalid("Value is not a dictionary") + excl(p.scope.symbols, s) + return p + proc dset*(i: In, p: MinValue, s: MinValue, m: MinValue): MinValue {.discardable, extern:"min_exported_symbol_$1".}= if not p.isDictionary: raiseInvalid("Value is not a dictionary")

@@ -70,6 +88,15 @@ var q = m

if not q.isQuotation: q = @[q].newVal(i.scope) p.scope.symbols[s.getString] = MinOperator(kind: minValOp, val: q, sealed: false) + return p + +proc dset*(i: In, p: MinValue, s: string, m: MinValue): MinValue {.discardable, extern:"min_exported_symbol_$1_2".}= + if not p.isDictionary: + raiseInvalid("Value is not a dictionary") + var q = m + if not q.isQuotation: + q = @[q].newVal(i.scope) + p.scope.symbols[s] = MinOperator(kind: minValOp, val: q, sealed: false) return p proc keys*(i: In, q: MinValue): MinValue {.extern:"min_exported_symbol_$1".}=
M lib/min_dict.nimlib/min_dict.nim

@@ -21,8 +21,7 @@ def.symbol("dget") do (i: In):

let vals = i.expect("'sym", "dict") let k = vals[0] let d = vals[1] - var val = d.dget(k) - i.dequote val # Dictionary values are always quoted + i.push i.dget(d, k) def.symbol("dset") do (i: In): let vals = i.expect("'sym", "a", "dict")

@@ -54,7 +53,7 @@ var d = vals[1]

var res = newDict(i.scope) for k in q.qVal: if d.dhas(k): - i.dset(res, k, d.dget(k)) + i.dset(res, k, i.dget(d, k)) i.push res def.sigil("?") do (i: In):
M lib/min_http.nimlib/min_http.nim

@@ -30,26 +30,26 @@ let cli = newCli()

var body = "".newVal var rawHeaders, meth, url: MinValue var headers = newHttpHeaders() - if not req.dhas("method".newVal): + if not req.dhas("method"): raiseInvalid("Request method not specified") - if not req.dhas("url".newVal): + if not req.dhas("url"): raiseInvalid("Request URL not specified") - if req.dhas("headers".newVal): - rawHeaders = req.dget("headers".newVal) + if req.dhas("headers"): + rawHeaders = i.dget(req, "headers") if not rawHeaders.isDictionary: raiseInvalid("Headers must be specified as a dictionary") for v in rawHeaders.qVal: headers[v.qVal[0].getString] = v.qVal[1].getString - if req.dhas("body".newVal): - body = req.dget("body".newVal) - meth = req.dget("method".newVal) - url = req.dget("url".newVal) + if req.dhas("body"): + body = i.dget(req, "body") + meth = i.dget(req, "method") + url = i.dget(req, "url") let resp = cli.request(url = url.getString, httpMethod = meth.getString, body = body.getString, headers = headers) var res = newVal(newSeq[MinValue](), i.scope) - res = i.dset(res, "version".newVal, resp.version.newVal) - res = i.dset(res, "status".newVal, resp.status[0..2].parseInt.newVal) - res = i.dset(res, "headers".newVal, i.newVal(resp.headers)) - res = i.dset(res, "body".newVal, resp.body.newVal) + res = i.dset(res, "version", resp.version.newVal) + res = i.dset(res, "status", resp.status[0..2].parseInt.newVal) + res = i.dset(res, "headers", i.newVal(resp.headers)) + res = i.dset(res, "body", resp.body.newVal) i.push res def.symbol("get-content") do (i: In):

@@ -68,15 +68,15 @@

def.symbol("start-server") do (ii: In): let vals = ii.expect "dict" let cfg = vals[0] - if not cfg.dhas("port".newVal): + if not cfg.dhas("port"): raiseInvalid("Port not specified.") - if not cfg.dhas("handler".newVal): + if not cfg.dhas("handler"): raiseInvalid("Handler quotation not specified.") - let port = cfg.dget("port".newVal) - var qhandler = cfg.dget("handler".newVal) + let port = ii.dget(cfg, "port") + var qhandler = ii.dget(cfg, "handler") var address = "".newVal - if cfg.dhas("address".newVal): - address = cfg.dget("address".newVal) + if cfg.dhas("address"): + address = ii.dget(cfg, "address") if not qhandler.isQuotation: raiseInvalid("Handler is not a quotation.") if not port.isInt:

@@ -86,33 +86,33 @@ var i {.threadvar.}: MinInterpreter

i = ii proc handler(req: Request) {.async, gcsafe.} = var qreq = newSeq[MinValue]().newVal(i.scope) - qreq = i.dset(qreq, "url".newVal, newVal($req.url)) - qreq = i.dset(qreq, "headers".newVal, i.newVal(req.headers)) - qreq = i.dset(qreq, "method".newVal, newVal($req.reqMethod)) - qreq = i.dset(qreq, "hostname".newVal, newVal($req.hostname)) - qreq = i.dset(qreq, "version".newVal, newVal("$1.$2" % [$req.protocol.major, $req.protocol.minor])) - qreq = i.dset(qreq, "body".newVal, newVal($req.body)) + qreq = i.dset(qreq, "url", newVal($req.url)) + qreq = i.dset(qreq, "headers", i.newVal(req.headers)) + qreq = i.dset(qreq, "method", newVal($req.reqMethod)) + qreq = i.dset(qreq, "hostname", newVal($req.hostname)) + qreq = i.dset(qreq, "version", newVal("$1.$2" % [$req.protocol.major, $req.protocol.minor])) + qreq = i.dset(qreq, "body", newVal($req.body)) i.push qreq i.dequote qhandler let qres = i.pop var body = "".newVal var rawHeaders = newSeq[MinValue]().newVal(i.scope) - var v = "1.1".newVal + var v = "1.1" var status = 200.newVal if not qres.isDictionary(): raiseInvalid("Response is not a dictionary.") - if qres.dhas("status".newVal): - status = qres.dget("status".newVal) + if qres.dhas("status"): + status = i.dget(qres, "status") if not status.isInt and status.intVal < 600: raiseInvalid("Invalid status code: $1." % $status) - if qres.dhas("body".newVal): - body = qres.dget("body".newVal) + if qres.dhas("body"): + body = i.dget(qres, "body") if not body.isString: raiseInvalid("Response body is not a string.") - if qres.dhas("version".newVal): - v = qres.dget("version".newVal) - if qres.dhas("headers".newVal): - rawHeaders = qres.dget("headers".newVal) + if qres.dhas("version"): + v = i.dget(qres, "version").getString + if qres.dhas("headers"): + rawHeaders = i.dget(qres, "headers") if not rawHeaders.isDictionary(): raiseInvalid("Response headers are not in a dictionary.") var headers = newHttpHeaders()
M lib/min_lang.nimlib/min_lang.nim

@@ -247,7 +247,7 @@ def.symbol("raise") do (i: In):

let vals = i.expect("dict") let err = vals[0] if err.dhas("error".newVal) and err.dhas("message".newVal): - raiseRuntime("($1) $2" % [err.dget("error".newVal).getString, err.dget("message".newVal).getString], err.qVal) + raiseRuntime("($1) $2" % [i.dget(err, "error".newVal).getString, i.dget(err, "message").getString], err.qVal) else: raiseInvalid("Invalid error dictionary")

@@ -257,15 +257,15 @@ let err = vals[0]

if err.dhas("error".newVal) and err.dhas("message".newVal): var msg: string var list = newSeq[MinValue]() - list.add err.dget("message".newVal) - if err.qVal.contains("symbol".newVal): - list.add err.dget("symbol".newVal) - if err.qVal.contains("filename".newVal): - list.add err.dget("filename".newVal) - if err.qVal.contains("line".newVal): - list.add err.dget("line".newVal) - if err.qVal.contains("column".newVal): - list.add err.dget("column".newVal) + list.add i.dget(err, "message") + if err.dhas("symbol"): + list.add i.dget(err, "symbol") + if err.dhas("filename"): + list.add i.dget(err, "filename") + if err.dhas("line"): + list.add i.dget(err, "line") + if err.dhas("column"): + list.add i.dget(err, "column") if list.len <= 1: msg = "$1" % $$list[0] else:
M lib/min_net.nimlib/min_net.nim

@@ -24,22 +24,22 @@ protocol = IPPROTO_TCP

sDomain = "ipv4" sSockType = "stream" sProtocol = "tcp" - if q.dhas("domain".newVal): - sDomain = q.dget("domain".newVal).getString + if q.dhas("domain"): + sDomain = i.dget(q, "domain").getString if (sDomain == "unix"): domain = AF_UNIX elif (sDomain == "ipv6"): domain = AF_INET6 - if q.dhas("type".newVal): - sSockType = q.dget("type".newVal).getString + if q.dhas("type"): + sSockType = i.dget(q, "type").getString if (sSockType == "dgram"): sockettype = SOCK_DGRAM elif (sSockType == "raw"): sockettype = SOCK_RAW elif (sSockType == "seqpacket"): sockettype = SOCK_SEQPACKET - if q.dhas("protocol".newVal): - sProtocol = q.dget("protocol".newVal).getstring + if q.dhas("protocol"): + sProtocol = i.dget(q, "protocol").getstring if (sProtocol == "udp"): protocol = IPPROTO_UDP elif (sProtocol == "ipv4"):

@@ -52,9 +52,9 @@ elif (sProtocol == "icmp"):

protocol = IPPROTO_ICMP var socket = newSocket(domain, sockettype, protocol) var skt = newSeq[MinValue](0).newVal(i.scope) - skt = i.dset(skt, "domain".newVal, sDomain.newVal) - skt = i.dset(skt, "type".newVal, sSockType.newVal) - skt = i.dset(skt, "protocol".newVal, sProtocol.newVal) + skt = i.dset(skt, "domain", sDomain.newVal) + skt = i.dset(skt, "type", sSockType.newVal) + skt = i.dset(skt, "protocol", sProtocol.newVal) skt.objType = "socket" skt.obj = socket[].addr i.push skt

@@ -70,13 +70,13 @@ var skt = vals[1]

var socket = skt.toSocket var address = "0.0.0.0" var port: BiggestInt = 80 - if params.dhas("address".newVal): - address = params.dget("address".newVal).getString - if params.dhas("port".newVal): - port = params.dget("port".newVal).intVal + if params.dhas("address"): + address = i.dget(params, "address").getString + if params.dhas("port"): + port = i.dget(params, "port").intVal socket.bindAddr(Port(port), address) - skt = i.dset(skt, "address".newVal, address.newVal) - skt = i.dset(skt, "port".newVal, port.newVal) + skt = i.dset(skt, "address", address.newVal) + skt = i.dset(skt, "port", port.newVal) skt.objType = "socket" skt.obj = socket[].addr socket.listen()

@@ -90,7 +90,7 @@ var address = ""

var serverSocket = server.toSocket var clientSocket = client.toSocket serverSocket.acceptAddr(clientSocket, address) - i.dset(client, "address".newVal, address.newVal) + i.dset(client, "address", address.newVal) client.objType = "socket" client.obj = clientSocket[].addr i.push client

@@ -102,8 +102,8 @@ let address = vals[1]

var skt = vals[2] let socket = skt.toSocket socket.connect(address.getString, Port(port.intVal)) - skt = i.dset(skt, "address".newVal, address) - skt = i.dset(skt, "port".newVal, port) + skt = i.dset(skt, "address", address) + skt = i.dset(skt, "port", port) skt.objType = "socket" skt.obj = socket[].addr i.push skt
M lib/min_time.nimlib/min_time.nim

@@ -28,31 +28,31 @@ time = t.intVal.fromUnix

else: time = t.floatVal.int64.fromUnix let tinfo = time.local - var info = newSeq[MinValue](0).newVal(i.scope) - info.qVal.add @["year".newVal, tinfo.year.newVal].newVal(i.scope) - info.qVal.add @["month".newVal, (tinfo.month.int+1).newVal].newVal(i.scope) - info.qVal.add @["day".newVal, tinfo.monthday.newVal].newVal(i.scope) - info.qVal.add @["weekday".newVal, (tinfo.weekday.int+1).newVal].newVal(i.scope) - info.qVal.add @["yearday".newVal, tinfo.yearday.newVal].newVal(i.scope) - info.qVal.add @["hour".newVal, tinfo.hour.newVal].newVal(i.scope) - info.qVal.add @["minute".newVal, tinfo.minute.newVal].newVal(i.scope) - info.qVal.add @["second".newVal, tinfo.second.newVal].newVal(i.scope) - info.qVal.add @["dst".newVal, tinfo.isDST.newVal].newVal(i.scope) - info.qVal.add @["timezone".newVal, tinfo.utcOffset.newVal].newVal(i.scope) + var info = newDict(i.scope) + i.dset info, "year", tinfo.year.newVal + i.dset info, "month", (tinfo.month.int+1).newVal + i.dset info, "day", tinfo.monthday.newVal + i.dset info, "weekday", (tinfo.weekday.int+1).newVal + i.dset info, "yearday", tinfo.yearday.newVal + i.dset info, "hour", tinfo.hour.newVal + i.dset info, "minute", tinfo.minute.newVal + i.dset info, "second", tinfo.second.newVal + i.dset info, "dst", tinfo.isDST.newVal + i.dset info, "timezone", tinfo.utcOffset.newVal i.push info def.symbol("to-timestamp") do (i: In): let vals = i.expect("dict") let dict = vals[0] try: - let year = dict.dget("year".newVal).intVal.int - let month = dict.dget("month".newVal).intVal.int - 1 - let monthday = dict.dget("day".newVal).intVal.int - let hour = dict.dget("hour".newVal).intVal.int - let minute = dict.dget("minute".newVal).intVal.int - let second = dict.dget("second".newVal).intVal.int - let dst = dict.dget("dst".newVal).boolVal - let timezone = dict.dget("timezone".newVal).intVal.int + let year = i.dget(dict, "year").intVal.int + let month = i.dget(dict, "month").intVal.int - 1 + let monthday = i.dget(dict, "day").intVal.int + let hour = i.dget(dict, "hour").intVal.int + let minute = i.dget(dict, "minute").intVal.int + let second = i.dget(dict, "second").intVal.int + let dst = i.dget(dict, "dst").boolVal + let timezone = i.dget(dict, "timezone").intVal.int let tinfo = Datetime(year: year, month: Month(month), monthday: monthday, hour: hour, minute: minute, second: second, isDST: dst, utcOffset: timezone) i.push tinfo.toTime.toUnix.int.newVal except: