feat(net) Implemented net module (basic socket communication).
h3rald h3rald@h3rald.com
Sun, 12 Jun 2016 19:55:07 +0200
4 files changed,
80 insertions(+),
15 deletions(-)
M
core/utils.nim
→
core/utils.nim
@@ -40,6 +40,9 @@
proc newVal*(s: bool): MinValue = return MinValue(kind: minBool, boolVal: s) +proc newSym*(s: string): MinValue = + return MinValue(kind: minSymbol, symVal: s) + proc isStringLike*(s: MinValue): bool = return s.isSymbol or s.isString@@ -88,6 +91,9 @@
template alias*[T](varname: untyped, value: var T) = var varname {.inject.}: type(value) shallowCopy varname, value + +proc to*(q: MinValue, T: typedesc): T = + return cast[T](q.obj) # Error Helpers@@ -210,3 +216,8 @@ a = i.pop
b = i.pop if not ((a.kind == a.kind or (a.isNumber and a.isNumber)) and not a.isSymbol): raiseInvalid("Two non-symbol values of similar type are required on the stack") + +proc reqObject*(i: var MinInterpreter, t: string, a: var MinValue) = + a = i.pop + if not a.isQuotation or a.objType.isNil or a.objType != t: + raiseInvalid("A $1 object is required" % [t])
M
lib/min_net.nim
→
lib/min_net.nim
@@ -1,4 +1,4 @@
-import net, nativesockets +import net, nativesockets, strutils import ../core/types, ../core/parser,@@ -9,8 +9,7 @@ # Network
define("net") - .symbol("open") do (i: In): - echo "all good" + .symbol("open-socket") do (i: In): var q: MinValue i.reqQuotation q # (ipv4 stream tcp)@@ -41,31 +40,85 @@ protocol = IPPROTO_TCP
else: protocol = IPPROTO_UDP var socket = newSocket(domain, sockettype, protocol) - echo "all good" q.objType = "socket" - q.obj = socket.addr + q.obj = socket[].addr i.push @[q] + + .symbol("tcp-socket") do (i: In): + i.eval("(ipv4 stream tcp) net %open-socket") + .symbol("udp-socket") do (i: In): + i.eval("(ipv4 dgram udp) net %open-socket") - .symbol("close") do (i: In): - discard + .symbol("tcp6-socket") do (i: In): + i.eval("(ipv6 stream tcp) net %open-socket") + + .symbol("udp6-socket") do (i: In): + i.eval("(ipv6 dgram udp) net %open-socket") + + .symbol("close-socket") do (i: In): + var q: MinValue + i.reqObject "socket", q + q.to(Socket).close() .symbol("listen") do (i: In): - discard + var port, q: MinValue + i.reqInt port + i.reqObject "socket", q + var socket = q.to(Socket) + socket.bindAddr(Port(port.intVal)) + q.qVal.add "0.0.0.0".newSym + q.qVal.add port + socket.listen() + i.push @[q] .symbol("accept") do (i: In): - discard + var server: MinValue + i.reqObject "socket", server + # Open same socket type as server + echo $server + i.eval "$1 net %open-socket" % [$server.qVal[0..2].newVal] + var clientVal: MinValue + i.reqObject "socket", clientVal + var client = clientVal.to(Socket) + var address = "" + server.to(Socket).acceptAddr(client, address) + clientVal.qVal.add address.newSym + i.push @[clientVal] .symbol("connect") do (i: In): - discard + var q, address, port: MinValue + i.reqInt port + i.reqString address + i.reqObject "socket", q + q.to(Socket).connect(address.strVal, Port(port.intVal)) + q.qVal.add address.strVal.newSym + q.qVal.add port + i.push @[q] .symbol("send") do (i: In): - discard + var q, s: MinValue + i.reqString s + i.reqObject "socket", q + q.to(Socket).send s.strVal + i.push @[q] + .symbol("recv") do (i: In): - discard + var size, q: MinValue + i.reqInt size + i.reqObject "socket", q + var s = "" + discard q.to(Socket).recv(s, size.intVal) + i.push @[q] + i.push s.newVal - .symbol("bind") do (i: In): - discard + .symbol("recv-line") do (i: In): + var q: MinValue + i.reqObject "socket", q + var s = "" + q.to(Socket).readLine(s) + i.push @[q] + i.push s.newVal .finalize()
M
lib/prelude.min
→
lib/prelude.min
@@ -8,6 +8,7 @@ #num
#stack #sys #time +#net ; Common sigils (bind) (.) sigil
M
tests/lang.min
→
tests/lang.min
@@ -3,7 +3,7 @@ #test
"lang" describe - (symbols size 165 ==) assert + (symbols size put 178 ==) assert (sigils size 10 ==) assert