add built in socket lib

This commit is contained in:
2023-06-22 09:27:21 +01:00
parent a8cbfa66e9
commit b8ceafa3c9
3 changed files with 134 additions and 1 deletions

View File

@@ -11,6 +11,7 @@ func makeGlobal() ArObject {
vars["term"] = ArTerm vars["term"] = ArTerm
vars["number"] = builtinFunc{"number", ArgonNumber} vars["number"] = builtinFunc{"number", ArgonNumber}
vars["string"] = builtinFunc{"string", ArgonString} vars["string"] = builtinFunc{"string", ArgonString}
vars["socket"] = builtinFunc{"boolean", ArSocket}
vars["infinity"] = infinity vars["infinity"] = infinity
vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) { vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) {
if len(a) == 0 { if len(a) == 0 {

132
src/socket.go Normal file
View File

@@ -0,0 +1,132 @@
package main
import (
"fmt"
"net"
)
func ArSocket(args ...any) (any, ArErr) {
if len(args) != 2 {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: "Socket takes exactly 2 arguments",
EXISTS: true,
}
} else if typeof(args[0]) != "string" {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: "Socket type must be a string",
EXISTS: true,
}
} else if typeof(args[1]) != "number" {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: "Socket port must be a number",
EXISTS: true,
}
}
networktype := ArValidToAny(args[0]).(string)
port := args[1].(number)
if port.Denom().Int64() != 1 {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: "Socket port must be an integer",
EXISTS: true,
}
}
ln, err := net.Listen(networktype, ":"+fmt.Sprint(port.Num().Int64()))
fmt.Println("Listening on port " + fmt.Sprint(port.Num().Int64()))
if err != nil {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: err.Error(),
EXISTS: true,
}
}
return Map(anymap{
"accept": builtinFunc{
"accept",
func(args ...any) (any, ArErr) {
conn, err := ln.Accept()
if err != nil {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: err.Error(),
EXISTS: true,
}
}
return Map(anymap{
"read": builtinFunc{
"read",
func(args ...any) (any, ArErr) {
if len(args) != 1 {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: "Socket.read() takes exactly 1 argument",
EXISTS: true,
}
} else if typeof(args[0]) != "number" {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: "Socket.read() argument must be a number",
EXISTS: true,
}
}
buf := make([]byte, args[0].(number).Num().Int64())
n, err := conn.Read(buf)
if err != nil {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: err.Error(),
EXISTS: true,
}
}
return ArString(string(buf[:n])), ArErr{}
},
},
"write": builtinFunc{
"write",
func(args ...any) (any, ArErr) {
if len(args) != 1 {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: "Socket.write() takes exactly 1 argument",
EXISTS: true,
}
} else if typeof(args[0]) != "string" {
return ArObject{}, ArErr{
TYPE: "SocketError",
message: "Socket.write() argument must be a string",
EXISTS: true,
}
}
data := ArValidToAny(args[0]).(string)
conn.Write([]byte(data))
return nil, ArErr{}
},
},
"close": builtinFunc{
"close",
func(args ...any) (any, ArErr) {
conn.Close()
return nil, ArErr{}
},
},
"isClosed": builtinFunc{
"isClosed",
func(args ...any) (any, ArErr) {
return conn == nil, ArErr{}
},
},
}), ArErr{}
},
},
"close": builtinFunc{
"close",
func(args ...any) (any, ArErr) {
ln.Close()
return nil, ArErr{}
},
},
}), ArErr{}
}

View File

@@ -1,6 +1,6 @@
f() = do f() = do
let a = [] let a = []
for (i from 0 to 10000000) a.append(i) for (i from 0 to 1000000) a.append(i)
term.log("start") term.log("start")
f() f()