mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 00:46:07 +00:00
add client, seek, and size
This commit is contained in:
2
go.mod
2
go.mod
@@ -8,7 +8,7 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
)
|
||||
|
||||
|
||||
@@ -9,9 +9,13 @@ func makeGlobal() ArObject {
|
||||
var vars = anymap{}
|
||||
vars["global"] = vars
|
||||
vars["term"] = ArTerm
|
||||
vars["ArgonVersion"] = ArString(VERSION)
|
||||
vars["number"] = builtinFunc{"number", ArgonNumber}
|
||||
vars["string"] = builtinFunc{"string", ArgonString}
|
||||
vars["socket"] = builtinFunc{"boolean", ArSocket}
|
||||
vars["socket"] = Map(anymap{
|
||||
"server": builtinFunc{"server", ArSocketServer},
|
||||
"client": builtinFunc{"client", ArSocketClient},
|
||||
})
|
||||
vars["infinity"] = infinity
|
||||
vars["map"] = builtinFunc{"map", func(a ...any) (any, ArErr) {
|
||||
if len(a) == 0 {
|
||||
@@ -277,5 +281,59 @@ func makeGlobal() ArObject {
|
||||
}
|
||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot convert '" + typeof(a[0]) + "' to string", EXISTS: true}
|
||||
}}
|
||||
vars["max"] = builtinFunc{"max", func(a ...any) (any, ArErr) {
|
||||
if len(a) != 1 {
|
||||
return nil, ArErr{TYPE: "runtime Error", message: "max takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
|
||||
}
|
||||
a[0] = ArValidToAny(a[0])
|
||||
switch x := a[0].(type) {
|
||||
case []any:
|
||||
if len(x) == 0 {
|
||||
return nil, ArErr{TYPE: "runtime Error", message: "max takes a non-empty array", EXISTS: true}
|
||||
}
|
||||
var max number
|
||||
for i, v := range x {
|
||||
switch m := v.(type) {
|
||||
case number:
|
||||
if i == 0 {
|
||||
max = m
|
||||
} else {
|
||||
if m.Cmp(max) == 1 {
|
||||
max = m
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return max, ArErr{}
|
||||
}
|
||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot get max of type '" + typeof(a[0]) + "'", EXISTS: true}
|
||||
}}
|
||||
vars["min"] = builtinFunc{"min", func(a ...any) (any, ArErr) {
|
||||
if len(a) != 1 {
|
||||
return nil, ArErr{TYPE: "runtime Error", message: "max takes 1 argument, got " + fmt.Sprint(len(a)), EXISTS: true}
|
||||
}
|
||||
a[0] = ArValidToAny(a[0])
|
||||
switch x := a[0].(type) {
|
||||
case []any:
|
||||
if len(x) == 0 {
|
||||
return nil, ArErr{TYPE: "runtime Error", message: "max takes a non-empty array", EXISTS: true}
|
||||
}
|
||||
var max number
|
||||
for i, v := range x {
|
||||
switch m := v.(type) {
|
||||
case number:
|
||||
if i == 0 {
|
||||
max = m
|
||||
} else {
|
||||
if m.Cmp(max) == -1 {
|
||||
max = m
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return max, ArErr{}
|
||||
}
|
||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot get max of type '" + typeof(a[0]) + "'", EXISTS: true}
|
||||
}}
|
||||
return Map(vars)
|
||||
}
|
||||
|
||||
24
src/file.go
24
src/file.go
@@ -92,6 +92,30 @@ func ArRead(args ...any) (any, ArErr) {
|
||||
}
|
||||
return ArBuffer(bytes), ArErr{}
|
||||
}},
|
||||
"seek": builtinFunc{"seek", func(args ...any) (any, ArErr) {
|
||||
if len(args) != 1 {
|
||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "seek takes 1 argument, got " + fmt.Sprint(len(args)), EXISTS: true}
|
||||
}
|
||||
if typeof(args[0]) != "number" {
|
||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "seek takes a number not type '" + typeof(args[0]) + "'", EXISTS: true}
|
||||
}
|
||||
offset := args[0].(number)
|
||||
if offset.Denom().Int64() != 1 {
|
||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: "seek takes an integer not type '" + typeof(args[0]) + "'", EXISTS: true}
|
||||
}
|
||||
_, err := file.Seek(offset.Num().Int64(), io.SeekStart)
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
||||
}
|
||||
return nil, ArErr{}
|
||||
}},
|
||||
"size": builtinFunc{"size", func(...any) (any, ArErr) {
|
||||
info, err := file.Stat()
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{TYPE: "Runtime Error", message: err.Error(), EXISTS: true}
|
||||
}
|
||||
return newNumber().SetInt64(info.Size()), ArErr{}
|
||||
}},
|
||||
}), ArErr{}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ var Args = os.Args[1:]
|
||||
|
||||
type stack = []ArObject
|
||||
|
||||
const VERSION = "3.0.0"
|
||||
|
||||
func newscope() ArObject {
|
||||
return Map(anymap{})
|
||||
}
|
||||
|
||||
@@ -114,8 +114,9 @@ func parseMap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
|
||||
}, true, ArErr{}, countIndex
|
||||
}
|
||||
|
||||
var mutex = sync.RWMutex{}
|
||||
|
||||
func Map(m anymap) ArObject {
|
||||
var mutex = sync.RWMutex{}
|
||||
obj := ArObject{
|
||||
obj: anymap{
|
||||
"__value__": m,
|
||||
|
||||
147
src/socket.go
147
src/socket.go
@@ -6,7 +6,152 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func ArSocket(args ...any) (any, ArErr) {
|
||||
func ArSocketClient(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]) != "string" {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "SocketError",
|
||||
message: "Socket address must be a string",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
networktype := ArValidToAny(args[0]).(string)
|
||||
address := ArValidToAny(args[1]).(string)
|
||||
conn, err := net.Dial(networktype, address)
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "SocketError",
|
||||
message: fmt.Sprintf("Socket connection failed: %s", err.Error()),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
return ArObject{
|
||||
obj: anymap{
|
||||
"read": builtinFunc{
|
||||
"read",
|
||||
func(args ...any) (any, ArErr) {
|
||||
if len(args) != 1 {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "SocketError",
|
||||
message: "Socket.readData() takes exactly 1 argument",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
if conn == nil {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "SocketError",
|
||||
message: "Connection is closed",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
buf := make([]byte, args[0].(number).Num().Int64())
|
||||
n, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "SocketError",
|
||||
message: fmt.Sprintf("Socket read failed: %s", err.Error()),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
return ArBuffer(buf[:n]), ArErr{}
|
||||
}},
|
||||
"write": builtinFunc{
|
||||
"write",
|
||||
func(args ...any) (any, ArErr) {
|
||||
if len(args) != 1 {
|
||||
return nil, ArErr{
|
||||
TYPE: "TypeError",
|
||||
message: fmt.Sprintf("write() takes exactly 1 argument (%d given)", len(args)),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
if typeof(args[0]) != "buffer" {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "TypeError",
|
||||
message: fmt.Sprintf("write() argument must be a buffer, not %s", typeof(args[0])),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
if conn == nil {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "SocketError",
|
||||
message: "Connection is closed",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
args[0] = ArValidToAny(args[0])
|
||||
if typeof(args[0]) != "buffer" {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "TypeError",
|
||||
message: fmt.Sprintf("write() argument must be a buffer, not %s", typeof(args[0])),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
_, err := conn.Write(args[0].([]byte))
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "SocketError",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
return nil, ArErr{}
|
||||
}},
|
||||
"close": builtinFunc{
|
||||
"close",
|
||||
func(args ...any) (any, ArErr) {
|
||||
if conn == nil {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "SocketError",
|
||||
message: "Connection is already closed",
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
err := conn.Close()
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "SocketError",
|
||||
message: err.Error(),
|
||||
EXISTS: true,
|
||||
}
|
||||
}
|
||||
conn = nil
|
||||
return nil, ArErr{}
|
||||
},
|
||||
},
|
||||
"isClosed": builtinFunc{
|
||||
"isClosed",
|
||||
func(args ...any) (any, ArErr) {
|
||||
if conn == nil {
|
||||
return true, ArErr{}
|
||||
}
|
||||
conn.SetWriteDeadline(time.Now().Add(1 * time.Millisecond))
|
||||
_, err := conn.Write([]byte{})
|
||||
conn.SetWriteDeadline(time.Time{})
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
conn = nil
|
||||
return true, ArErr{}
|
||||
}
|
||||
return false, ArErr{}
|
||||
|
||||
},
|
||||
},
|
||||
}}, ArErr{}
|
||||
}
|
||||
|
||||
func ArSocketServer(args ...any) (any, ArErr) {
|
||||
if len(args) != 2 {
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "SocketError",
|
||||
|
||||
@@ -71,9 +71,6 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
||||
return resp, worked, err, i
|
||||
}
|
||||
}
|
||||
if isnot(code) {
|
||||
return parseNot(code, index, codelines, isLine)
|
||||
}
|
||||
if isSetVariable(code) {
|
||||
resp, worked, err, i = parseSetVariable(code, index, codelines, isLine)
|
||||
if worked {
|
||||
@@ -121,6 +118,12 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
||||
return nil, worked, err, step
|
||||
}
|
||||
}
|
||||
if isnot(code) {
|
||||
resp, worked, err, i = parseNot(code, index, codelines, isLine)
|
||||
if worked {
|
||||
return resp, worked, err, i
|
||||
}
|
||||
}
|
||||
if isCall(code) {
|
||||
resp, worked, err, i = parseCall(code, index, codelines)
|
||||
if worked {
|
||||
|
||||
@@ -18,6 +18,10 @@ func typeof(val any) string {
|
||||
return "function"
|
||||
case builtinFunc:
|
||||
return "function"
|
||||
case byte:
|
||||
return "byte"
|
||||
case []byte:
|
||||
return "buffer"
|
||||
case ArObject:
|
||||
if val, ok := x.obj["__name__"]; ok {
|
||||
val := ArValidToAny(val)
|
||||
|
||||
Reference in New Issue
Block a user