all repos — min @ 8185d611d250b1df53ea756430c5f70ae1cd96d2

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
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
import net, nativesockets, strutils
import 
  ../core/parser, 
  ../core/value, 
  ../core/interpreter, 
  ../core/utils

# Net

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]
    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.symbol("connect") do (i: In):
    let vals = i.expect("int", "string", "dict:socket")
    let port = vals[0]
    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.objType = "socket"
    skt.obj = socket[].addr
    i.push skt

  def.symbol("send") do (i: In):
    let vals = i.expect("string", "dict:socket")
    let msg = vals[0]
    let skt = vals[1]
    skt.toSocket.send msg.getString

  def.symbol("recv") do (i: In):
    let vals = i.expect("int", "dict:socket")
    let size = vals[0]
    let skt = vals[1]
    var s = ""
    discard skt.toSocket.recv(s, size.intVal.int)
    i.push s.newVal

  def.symbol("recv-line") do (i: In):
    let vals = i.expect("dict:socket")
    let skt = vals[0]
    var s = skt.toSocket.recvLine()
    i.push s.newVal

  def.finalize("net")