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 (
|
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
|
golang.org/x/net v0.8.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,13 @@ func makeGlobal() ArObject {
|
|||||||
var vars = anymap{}
|
var vars = anymap{}
|
||||||
vars["global"] = vars
|
vars["global"] = vars
|
||||||
vars["term"] = ArTerm
|
vars["term"] = ArTerm
|
||||||
|
vars["ArgonVersion"] = ArString(VERSION)
|
||||||
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["socket"] = Map(anymap{
|
||||||
|
"server": builtinFunc{"server", ArSocketServer},
|
||||||
|
"client": builtinFunc{"client", ArSocketClient},
|
||||||
|
})
|
||||||
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 {
|
||||||
@@ -277,5 +281,59 @@ func makeGlobal() ArObject {
|
|||||||
}
|
}
|
||||||
return nil, ArErr{TYPE: "TypeError", message: "Cannot convert '" + typeof(a[0]) + "' to string", EXISTS: true}
|
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)
|
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{}
|
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{}
|
}), ArErr{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ var Args = os.Args[1:]
|
|||||||
|
|
||||||
type stack = []ArObject
|
type stack = []ArObject
|
||||||
|
|
||||||
|
const VERSION = "3.0.0"
|
||||||
|
|
||||||
func newscope() ArObject {
|
func newscope() ArObject {
|
||||||
return Map(anymap{})
|
return Map(anymap{})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,8 +114,9 @@ func parseMap(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
|
|||||||
}, true, ArErr{}, countIndex
|
}, true, ArErr{}, countIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mutex = sync.RWMutex{}
|
||||||
|
|
||||||
func Map(m anymap) ArObject {
|
func Map(m anymap) ArObject {
|
||||||
var mutex = sync.RWMutex{}
|
|
||||||
obj := ArObject{
|
obj := ArObject{
|
||||||
obj: anymap{
|
obj: anymap{
|
||||||
"__value__": m,
|
"__value__": m,
|
||||||
|
|||||||
147
src/socket.go
147
src/socket.go
@@ -6,7 +6,152 @@ import (
|
|||||||
"time"
|
"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 {
|
if len(args) != 2 {
|
||||||
return ArObject{}, ArErr{
|
return ArObject{}, ArErr{
|
||||||
TYPE: "SocketError",
|
TYPE: "SocketError",
|
||||||
|
|||||||
@@ -71,9 +71,6 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
|||||||
return resp, worked, err, i
|
return resp, worked, err, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isnot(code) {
|
|
||||||
return parseNot(code, index, codelines, isLine)
|
|
||||||
}
|
|
||||||
if isSetVariable(code) {
|
if isSetVariable(code) {
|
||||||
resp, worked, err, i = parseSetVariable(code, index, codelines, isLine)
|
resp, worked, err, i = parseSetVariable(code, index, codelines, isLine)
|
||||||
if worked {
|
if worked {
|
||||||
@@ -121,6 +118,12 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
|||||||
return nil, worked, err, step
|
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) {
|
if isCall(code) {
|
||||||
resp, worked, err, i = parseCall(code, index, codelines)
|
resp, worked, err, i = parseCall(code, index, codelines)
|
||||||
if worked {
|
if worked {
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ func typeof(val any) string {
|
|||||||
return "function"
|
return "function"
|
||||||
case builtinFunc:
|
case builtinFunc:
|
||||||
return "function"
|
return "function"
|
||||||
|
case byte:
|
||||||
|
return "byte"
|
||||||
|
case []byte:
|
||||||
|
return "buffer"
|
||||||
case ArObject:
|
case ArObject:
|
||||||
if val, ok := x.obj["__name__"]; ok {
|
if val, ok := x.obj["__name__"]; ok {
|
||||||
val := ArValidToAny(val)
|
val := ArValidToAny(val)
|
||||||
|
|||||||
Reference in New Issue
Block a user