all repos — min @ 7ca23972c8059acc22e6cc139fefb1e36c576ad5

A small but practical concatenative programming language.

lib/min_net.nim

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
import net, nativesockets
import 
  ../core/parser, 
  ../core/value, 
  ../core/interpreter, 
  ../core/utils

# Time

proc toSocket(q: MinValue): Socket =
  return cast[Socket](q.obj)


proc net_module*(i: In)=
  let def = i.define()
  
  def.symbol("socket") do (i: In):
    let vals = i.expect "dict"
    var q = vals[0]
    # ((domain ipv4) (type stream) (protocol tcp))
    var 
      domain = AF_INET
      sockettype = SOCK_STREAM
      protocol = IPPROTO_TCP
      sDomain = "ipv4"
      sSockType = "stream"
      sProtocol = "tcp"
    if q.dhas("domain".newVal):
      sDomain = q.dget("domain".newVal).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 (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 (sProtocol == "udp"):
        protocol = IPPROTO_UDP
      elif (sProtocol == "ipv4"):
        protocol = IPPROTO_IP
      elif (sProtocol == "ipv6"):
        protocol = IPPROTO_IPV6
      elif (sProtocol == "raw"):
        protocol = IPPROTO_RAW
      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.objType = "socket"
    skt.obj = socket[].addr
    i.push skt

  def.symbol("close") do (i: In):
    let vals = i.expect("dict:socket")
    vals[0].toSocket.close()
 
  def.symbol("listen") do (i: In):
    let vals = i.expect("dict", "dict:socket")
    let params = vals[0]
    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
    socket.bindAddr(Port(port), address)
    skt = i.dset(skt, "address".newVal, address.newVal)
    skt = i.dset(skt, "port".newVal, port.newVal)
    skt.objType = "socket"
    skt.obj = socket[].addr
    socket.listen()
    i.push skt

  def.symbol("accept") do (i: In):
    let vals = i.expect("dict:socket", "dict:socket")
    var client = vals[0]
    var server = vals[1]
    var address = ""
    var serverSocket = server.toSocket
    var clientSocket = client.toSocket
    serverSocket.acceptAddr(clientSocket, address)
    i.dset(client, "address".newVal, address.newVal)
    client.objType = "socket"
    client.obj = clientSocket[].addr
    i.push client


  def.finalize("net")