mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
add readUntil
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
func anyToBool(x any) bool {
|
func anyToBool(x any) bool {
|
||||||
switch x := x.(type) {
|
switch x := x.(type) {
|
||||||
@@ -16,8 +18,8 @@ func anyToBool(x any) bool {
|
|||||||
if y, ok := x.obj["__Boolean__"]; ok {
|
if y, ok := x.obj["__Boolean__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
callable: y,
|
Callable: y,
|
||||||
args: []any{},
|
Args: []any{},
|
||||||
}, stack{}, 0)
|
}, stack{}, 0)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
func ArByte(Byte byte) ArObject {
|
func ArByte(Byte byte) ArObject {
|
||||||
obj := ArObject{
|
obj := ArObject{
|
||||||
|
|||||||
@@ -192,8 +192,8 @@ func makeGlobal() ArObject {
|
|||||||
if callable, ok := x.obj["__fraction__"]; ok {
|
if callable, ok := x.obj["__fraction__"]; ok {
|
||||||
resp, err := runCall(
|
resp, err := runCall(
|
||||||
call{
|
call{
|
||||||
callable: callable,
|
Callable: callable,
|
||||||
args: []any{},
|
Args: []any{},
|
||||||
},
|
},
|
||||||
stack{},
|
stack{},
|
||||||
0,
|
0,
|
||||||
|
|||||||
36
src/call.go
36
src/call.go
@@ -8,11 +8,11 @@ import (
|
|||||||
var callCompile = makeRegex("( *)(.|\n)+\\((.|\n)*\\)( *)")
|
var callCompile = makeRegex("( *)(.|\n)+\\((.|\n)*\\)( *)")
|
||||||
|
|
||||||
type call struct {
|
type call struct {
|
||||||
callable any
|
Callable any
|
||||||
args []any
|
Args []any
|
||||||
code string
|
Code string
|
||||||
line int
|
Line int
|
||||||
path string
|
Path string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Callable struct {
|
type Callable struct {
|
||||||
@@ -61,18 +61,18 @@ func parseCall(code UNPARSEcode, index int, codelines []UNPARSEcode) (any, bool,
|
|||||||
if !works {
|
if !works {
|
||||||
return nil, false, ArErr{"Syntax Error", "invalid call", code.line, code.path, code.realcode, true}, 1
|
return nil, false, ArErr{"Syntax Error", "invalid call", code.line, code.path, code.realcode, true}, 1
|
||||||
}
|
}
|
||||||
return call{callable: callable, args: arguments, line: code.line, code: code.realcode, path: code.path}, true, ArErr{}, 1
|
return call{Callable: callable, Args: arguments, Line: code.line, Code: code.realcode, Path: code.path}, true, ArErr{}, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
||||||
var callable any = c.callable
|
var callable any = c.Callable
|
||||||
switch x := c.callable.(type) {
|
switch x := c.Callable.(type) {
|
||||||
case builtinFunc:
|
case builtinFunc:
|
||||||
callable = x
|
callable = x
|
||||||
case Callable:
|
case Callable:
|
||||||
callable = x
|
callable = x
|
||||||
default:
|
default:
|
||||||
callable_, err := runVal(c.callable, stack, stacklevel+1)
|
callable_, err := runVal(c.Callable, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -82,9 +82,9 @@ func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
x,
|
x,
|
||||||
[]any{"__call__"},
|
[]any{"__call__"},
|
||||||
true,
|
true,
|
||||||
c.line,
|
c.Line,
|
||||||
c.code,
|
c.Code,
|
||||||
c.path,
|
c.Path,
|
||||||
}, stack, stacklevel+1)
|
}, stack, stacklevel+1)
|
||||||
if !err.EXISTS {
|
if !err.EXISTS {
|
||||||
callable = callable_
|
callable = callable_
|
||||||
@@ -95,7 +95,7 @@ func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
args := []any{}
|
args := []any{}
|
||||||
level := append(stack, newscope())
|
level := append(stack, newscope())
|
||||||
for _, arg := range c.args {
|
for _, arg := range c.Args {
|
||||||
resp, err := runVal(arg, level, stacklevel+1)
|
resp, err := runVal(arg, level, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -109,20 +109,20 @@ func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
resp = AnyToArValid(resp)
|
resp = AnyToArValid(resp)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
if err.line == 0 {
|
if err.line == 0 {
|
||||||
err.line = c.line
|
err.line = c.Line
|
||||||
}
|
}
|
||||||
if err.path == "" {
|
if err.path == "" {
|
||||||
err.path = c.path
|
err.path = c.Path
|
||||||
}
|
}
|
||||||
if err.code == "" {
|
if err.code == "" {
|
||||||
err.code = c.code
|
err.code = c.Code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resp, err
|
return resp, err
|
||||||
case Callable:
|
case Callable:
|
||||||
debugPrintln(x.name, args)
|
debugPrintln(x.name, args)
|
||||||
if len(x.params) != len(args) {
|
if len(x.params) != len(args) {
|
||||||
return nil, ArErr{"Runtime Error", "expected " + fmt.Sprint(len(x.params)) + " arguments, got " + fmt.Sprint(len(args)), c.line, c.path, c.code, true}
|
return nil, ArErr{"Runtime Error", "expected " + fmt.Sprint(len(x.params)) + " arguments, got " + fmt.Sprint(len(args)), c.Line, c.Path, c.Code, true}
|
||||||
}
|
}
|
||||||
l := anymap{}
|
l := anymap{}
|
||||||
for i, param := range x.params {
|
for i, param := range x.params {
|
||||||
@@ -131,7 +131,7 @@ func runCall(c call, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
resp, err := runVal(x.run, append(x.stack, Map(l)), stacklevel+1)
|
resp, err := runVal(x.run, append(x.stack, Map(l)), stacklevel+1)
|
||||||
return ThrowOnNonLoop(openReturn(resp), err)
|
return ThrowOnNonLoop(openReturn(resp), err)
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.line, c.path, c.code, true}
|
return nil, ArErr{"Runtime Error", "type '" + typeof(callable) + "' is not callable", c.Line, c.Path, c.Code, true}
|
||||||
}
|
}
|
||||||
|
|
||||||
func builtinCall(callable any, args []any) (any, ArErr) {
|
func builtinCall(callable any, args []any) (any, ArErr) {
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ var indexGetCompile = makeRegex(`(.|\n)+\[(.|\n)+\]( *)`)
|
|||||||
|
|
||||||
type ArMapGet struct {
|
type ArMapGet struct {
|
||||||
VAL any
|
VAL any
|
||||||
args []any
|
Args []any
|
||||||
includeConstuctors bool
|
IncludeConstuctors bool
|
||||||
line int
|
Line int
|
||||||
code string
|
Code string
|
||||||
path string
|
Path string
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
||||||
@@ -29,33 +29,33 @@ func mapGet(r ArMapGet, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
switch m := resp.(type) {
|
switch m := resp.(type) {
|
||||||
case ArObject:
|
case ArObject:
|
||||||
if r.includeConstuctors {
|
if r.IncludeConstuctors {
|
||||||
if obj, ok := m.obj[r.args[0]]; ok {
|
if obj, ok := m.obj[r.Args[0]]; ok {
|
||||||
return obj, ArErr{}
|
return obj, ArErr{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if callable, ok := m.obj["__getindex__"]; ok {
|
if callable, ok := m.obj["__getindex__"]; ok {
|
||||||
resp, err := runCall(call{
|
resp, err := runCall(call{
|
||||||
callable: callable,
|
Callable: callable,
|
||||||
args: r.args,
|
Args: r.Args,
|
||||||
line: r.line,
|
Line: r.Line,
|
||||||
path: r.path,
|
Path: r.Path,
|
||||||
code: r.code,
|
Code: r.Code,
|
||||||
}, stack, stacklevel+1)
|
}, stack, stacklevel+1)
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
key, err := runVal(r.args[0], stack, stacklevel+1)
|
key, err := runVal(r.Args[0], stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
"TypeError",
|
"TypeError",
|
||||||
"cannot read " + anyToArgon(key, true, true, 3, 0, false, 0) + " from type '" + typeof(resp) + "'",
|
"cannot read " + anyToArgon(key, true, true, 3, 0, false, 0) + " from type '" + typeof(resp) + "'",
|
||||||
r.line,
|
r.Line,
|
||||||
r.path,
|
r.Path,
|
||||||
r.code,
|
r.Code,
|
||||||
true,
|
true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
var imported = make(map[string]ArObject)
|
var imported = make(map[string]ArObject)
|
||||||
var importing = make(map[string]bool)
|
var importing = make(map[string]bool)
|
||||||
|
|
||||||
var modules_folder = "argon_modules"
|
const modules_folder = "argon_modules"
|
||||||
|
|
||||||
func FileExists(filename string) bool {
|
func FileExists(filename string) bool {
|
||||||
if _, err := os.Stat(filename); err == nil {
|
if _, err := os.Stat(filename); err == nil {
|
||||||
@@ -36,8 +36,10 @@ func readFile(path string) []UNPARSEcode {
|
|||||||
// optionally, resize scanner's capacity for lines over 64K, see next example
|
// optionally, resize scanner's capacity for lines over 64K, see next example
|
||||||
output := []UNPARSEcode{}
|
output := []UNPARSEcode{}
|
||||||
line := 1
|
line := 1
|
||||||
|
textOutput := []string{}
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
text := scanner.Text()
|
text := scanner.Text()
|
||||||
|
textOutput = append(textOutput, text)
|
||||||
output = append(output, UNPARSEcode{text, text, line, path})
|
output = append(output, UNPARSEcode{text, text, line, path})
|
||||||
line++
|
line++
|
||||||
}
|
}
|
||||||
@@ -102,8 +104,8 @@ func importMod(realpath string, origin string, main bool, global ArObject) (ArOb
|
|||||||
}
|
}
|
||||||
importing[p] = true
|
importing[p] = true
|
||||||
codelines := readFile(p)
|
codelines := readFile(p)
|
||||||
|
|
||||||
translated, translationerr := translate(codelines)
|
translated, translationerr := translate(codelines)
|
||||||
|
|
||||||
if translationerr.EXISTS {
|
if translationerr.EXISTS {
|
||||||
return ArObject{}, translationerr
|
return ArObject{}, translationerr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ type stack = []ArObject
|
|||||||
|
|
||||||
const VERSION = "3.0.0"
|
const VERSION = "3.0.0"
|
||||||
|
|
||||||
|
// Example struct
|
||||||
|
type Person struct {
|
||||||
|
Name string
|
||||||
|
Age int
|
||||||
|
}
|
||||||
|
|
||||||
func newscope() ArObject {
|
func newscope() ArObject {
|
||||||
return Map(anymap{})
|
return Map(anymap{})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ var octalCompile = makeRegex("( *)(-)?(0o[0-7]+(\\.[0-7]+)?(e((\\-|\\+)?([0-9]+(
|
|||||||
type number = *big.Rat
|
type number = *big.Rat
|
||||||
|
|
||||||
// create a new number type
|
// create a new number type
|
||||||
func newNumber() *big.Rat {
|
func newNumber() number {
|
||||||
return new(big.Rat)
|
return new(big.Rat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import (
|
|||||||
var genericImportCompiled = makeRegex(`import( )+(.|\n)+(( )+as( )+([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*)?( *)`)
|
var genericImportCompiled = makeRegex(`import( )+(.|\n)+(( )+as( )+([a-zA-Z_]|(\p{L}\p{M}*))([a-zA-Z0-9_]|(\p{L}\p{M}*))*)?( *)`)
|
||||||
|
|
||||||
type ArImport struct {
|
type ArImport struct {
|
||||||
filePath any
|
FilePath any
|
||||||
values any
|
Values any
|
||||||
code string
|
Code string
|
||||||
line int
|
Line int
|
||||||
path string
|
Path string
|
||||||
}
|
}
|
||||||
|
|
||||||
func isGenericImport(code UNPARSEcode) bool {
|
func isGenericImport(code UNPARSEcode) bool {
|
||||||
@@ -75,26 +75,26 @@ func parseGenericImport(code UNPARSEcode, index int, codeline []UNPARSEcode) (Ar
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) {
|
func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) {
|
||||||
val, err := runVal(importOBJ.filePath, stack, stacklevel+1)
|
val, err := runVal(importOBJ.FilePath, stack, stacklevel+1)
|
||||||
val = ArValidToAny(val)
|
val = ArValidToAny(val)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if typeof(val) != "string" {
|
if typeof(val) != "string" {
|
||||||
return nil, ArErr{"Type Error", "import requires a string, got type '" + typeof(val) + "'", importOBJ.line, importOBJ.path, importOBJ.code, true}
|
return nil, ArErr{"Type Error", "import requires a string, got type '" + typeof(val) + "'", importOBJ.Line, importOBJ.Path, importOBJ.Code, true}
|
||||||
}
|
}
|
||||||
path := val.(string)
|
path := val.(string)
|
||||||
parent := filepath.Dir(importOBJ.path)
|
parent := filepath.Dir(importOBJ.Path)
|
||||||
stackMap, err := importMod(path, parent, false, stack[0])
|
stackMap, err := importMod(path, parent, false, stack[0])
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
if err.line == 0 {
|
if err.line == 0 {
|
||||||
err.line = importOBJ.line
|
err.line = importOBJ.Line
|
||||||
}
|
}
|
||||||
if err.path == "" {
|
if err.path == "" {
|
||||||
err.path = importOBJ.path
|
err.path = importOBJ.Path
|
||||||
}
|
}
|
||||||
if err.code == "" {
|
if err.code == "" {
|
||||||
err.code = importOBJ.code
|
err.code = importOBJ.Code
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -103,18 +103,18 @@ func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return nil, ArErr{
|
return nil, ArErr{
|
||||||
"Import Error",
|
"Import Error",
|
||||||
"could not find __setindex__ in module scope",
|
"could not find __setindex__ in module scope",
|
||||||
importOBJ.line,
|
importOBJ.Line,
|
||||||
importOBJ.path,
|
importOBJ.Path,
|
||||||
importOBJ.code,
|
importOBJ.Code,
|
||||||
true,
|
true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch x := importOBJ.values.(type) {
|
switch x := importOBJ.Values.(type) {
|
||||||
case []string:
|
case []string:
|
||||||
for _, v := range x {
|
for _, v := range x {
|
||||||
val, ok := stackMap.obj[v]
|
val, ok := stackMap.obj[v]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ArErr{"Import Error", "could not find value " + anyToArgon(v, true, false, 3, 0, false, 0) + " in module " + anyToArgon(path, true, false, 3, 0, false, 0), importOBJ.line, importOBJ.path, importOBJ.code, true}
|
return nil, ArErr{"Import Error", "could not find value " + anyToArgon(v, true, false, 3, 0, false, 0) + " in module " + anyToArgon(path, true, false, 3, 0, false, 0), importOBJ.Line, importOBJ.Path, importOBJ.Code, true}
|
||||||
}
|
}
|
||||||
builtinCall(setindex, []any{v, val})
|
builtinCall(setindex, []any{v, val})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/wadey/go-rounding"
|
import (
|
||||||
|
"github.com/wadey/go-rounding"
|
||||||
|
)
|
||||||
|
|
||||||
func floor(x number) number {
|
func floor(x number) number {
|
||||||
|
|
||||||
|
|||||||
24
src/run.go
24
src/run.go
@@ -18,9 +18,9 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return ArString(x), ArErr{}
|
return ArString(x), ArErr{}
|
||||||
case call:
|
case call:
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
linenum = x.line
|
linenum = x.Line
|
||||||
path = x.path
|
path = x.Path
|
||||||
code = x.code
|
code = x.Code
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return runCall(x, stack, stacklevel+1)
|
return runCall(x, stack, stacklevel+1)
|
||||||
@@ -34,17 +34,17 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return runFactorial(x, stack, stacklevel+1)
|
return runFactorial(x, stack, stacklevel+1)
|
||||||
case accessVariable:
|
case accessVariable:
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
linenum = x.line
|
linenum = x.Line
|
||||||
path = x.path
|
path = x.Path
|
||||||
code = x.code
|
code = x.Code
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return readVariable(x, stack)
|
return readVariable(x, stack)
|
||||||
case ArMapGet:
|
case ArMapGet:
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
linenum = x.line
|
linenum = x.Line
|
||||||
path = x.path
|
path = x.Path
|
||||||
code = x.code
|
code = x.Code
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return mapGet(x, stack, stacklevel+1)
|
return mapGet(x, stack, stacklevel+1)
|
||||||
@@ -194,9 +194,9 @@ func runVal(line any, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
return runCreateMap(x, stack, stacklevel+1)
|
return runCreateMap(x, stack, stacklevel+1)
|
||||||
case ArImport:
|
case ArImport:
|
||||||
if stackoverflow {
|
if stackoverflow {
|
||||||
linenum = x.line
|
linenum = x.Line
|
||||||
path = x.path
|
path = x.Path
|
||||||
code = x.code
|
code = x.Code
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return runImport(x, stack, stacklevel+1)
|
return runImport(x, stack, stacklevel+1)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
func ArSequence(a ...any) (any, ArErr) {
|
func ArSequence(a ...any) (any, ArErr) {
|
||||||
if len(a) < 1 || len(a) > 2 {
|
if len(a) < 1 || len(a) > 2 {
|
||||||
|
|||||||
13
src/sha256.go
Normal file
13
src/sha256.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func sha256Hash(s string) string {
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write([]byte(s))
|
||||||
|
bs := h.Sum(nil)
|
||||||
|
return fmt.Sprintf("%x", bs)
|
||||||
|
}
|
||||||
168
src/socket.go
168
src/socket.go
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -66,6 +67,59 @@ func ArSocketClient(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
return ArBuffer(buf[:n]), ArErr{}
|
return ArBuffer(buf[:n]), ArErr{}
|
||||||
}},
|
}},
|
||||||
|
"readUntil": builtinFunc{
|
||||||
|
"readUntil",
|
||||||
|
func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: "Socket.readUntil() takes exactly 1 argument",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if conn == nil {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: "Connection is closed",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value := ArValidToAny(args[0])
|
||||||
|
if typeof(value) != "buffer" {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "TypeError",
|
||||||
|
message: fmt.Sprintf("Socket.readUntil() argument must be a buffer, not %s", typeof(value)),
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endBuf := value.([]byte)
|
||||||
|
reader := io.Reader(conn)
|
||||||
|
buf := make([]byte, len(endBuf))
|
||||||
|
var data []byte
|
||||||
|
for {
|
||||||
|
_, err := reader.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: fmt.Sprintf("Socket read failed: %s", err.Error()),
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = append(data, buf[0])
|
||||||
|
if len(data) >= len(endBuf) {
|
||||||
|
dataSlice := data[len(data)-len(endBuf):]
|
||||||
|
for i := 0; i < len(endBuf); i++ {
|
||||||
|
if dataSlice[i] != endBuf[i] {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if i == len(endBuf)-1 {
|
||||||
|
return ArBuffer(data), ArErr{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}},
|
||||||
"write": builtinFunc{
|
"write": builtinFunc{
|
||||||
"write",
|
"write",
|
||||||
func(args ...any) (any, ArErr) {
|
func(args ...any) (any, ArErr) {
|
||||||
@@ -237,6 +291,120 @@ func ArSocketServer(args ...any) (any, ArErr) {
|
|||||||
return ArBuffer(buf[:n]), ArErr{}
|
return ArBuffer(buf[:n]), ArErr{}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"readUntil": builtinFunc{
|
||||||
|
"readUntil",
|
||||||
|
func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: "Socket.readUntil() takes exactly 1 argument",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if conn == nil {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: "Connection is closed",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value := ArValidToAny(args[0])
|
||||||
|
if typeof(value) != "buffer" {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "TypeError",
|
||||||
|
message: fmt.Sprintf("Socket.readUntil() argument must be a buffer, not %s", typeof(value)),
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endBuf := value.([]byte)
|
||||||
|
var data []byte
|
||||||
|
buf := make([]byte, 1)
|
||||||
|
lookingAt := 0
|
||||||
|
for {
|
||||||
|
n, err := io.ReadFull(conn, buf)
|
||||||
|
if err != nil {
|
||||||
|
return ArBuffer(data), ArErr{}
|
||||||
|
}
|
||||||
|
chunk := buf[:n]
|
||||||
|
data = append(data, chunk...)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
if chunk[i] == endBuf[lookingAt] {
|
||||||
|
lookingAt++
|
||||||
|
if lookingAt == len(endBuf) {
|
||||||
|
data = append(data, chunk...)
|
||||||
|
return ArBuffer(data), ArErr{}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lookingAt = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
"clearTimeout": builtinFunc{
|
||||||
|
"clearTimeout",
|
||||||
|
func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) != 0 {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: "Socket.clearTimeout() takes exactly 0 arguments",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if conn == nil {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: "Connection is closed",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conn.SetDeadline(time.Time{})
|
||||||
|
return ArObject{}, ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"setTimeout": builtinFunc{
|
||||||
|
"setTimeout",
|
||||||
|
func(args ...any) (any, ArErr) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: "Socket.setTimeout() takes exactly 1 argument",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if typeof(args[0]) != "number" {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: "Socket timeout must be a number",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if conn == nil {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: "Connection is closed",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timeout := args[0].(number)
|
||||||
|
if timeout.Denom().Int64() != 1 {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: "Socket timeout must be an integer",
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err := conn.SetDeadline(time.Now().Add(time.Duration(timeout.Num().Int64()) * time.Millisecond))
|
||||||
|
if err != nil {
|
||||||
|
return ArObject{}, ArErr{
|
||||||
|
TYPE: "SocketError",
|
||||||
|
message: err.Error(),
|
||||||
|
EXISTS: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ArObject{}, ArErr{}
|
||||||
|
},
|
||||||
|
},
|
||||||
"write": builtinFunc{
|
"write": builtinFunc{
|
||||||
"write",
|
"write",
|
||||||
func(args ...any) (any, ArErr) {
|
func(args ...any) (any, ArErr) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
type keyCache map[any]any
|
type keyCache map[any]any
|
||||||
|
|
||||||
@@ -71,8 +73,8 @@ func compare(a, b any) (bool, error) {
|
|||||||
if y, ok := x.obj["__LessThan__"]; ok {
|
if y, ok := x.obj["__LessThan__"]; ok {
|
||||||
resp, err := runCall(
|
resp, err := runCall(
|
||||||
call{
|
call{
|
||||||
callable: y,
|
Callable: y,
|
||||||
args: []any{b},
|
Args: []any{b},
|
||||||
}, stack{}, 0)
|
}, stack{}, 0)
|
||||||
if !err.EXISTS {
|
if !err.EXISTS {
|
||||||
return anyToBool(resp), nil
|
return anyToBool(resp), nil
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func ArThread(args ...any) (any, ArErr) {
|
|||||||
}
|
}
|
||||||
hasrun = true
|
hasrun = true
|
||||||
go func() {
|
go func() {
|
||||||
resp, err = runCall(call{callable: tocall, args: []any{}}, nil, 0)
|
resp, err = runCall(call{Callable: tocall, Args: []any{}}, nil, 0)
|
||||||
wg <- true
|
wg <- true
|
||||||
}()
|
}()
|
||||||
return nil, ArErr{}
|
return nil, ArErr{}
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
|
|||||||
if callable, ok := x.obj["__string__"]; ok && !quote {
|
if callable, ok := x.obj["__string__"]; ok && !quote {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
callable: callable,
|
Callable: callable,
|
||||||
args: []any{},
|
Args: []any{},
|
||||||
},
|
},
|
||||||
stack{},
|
stack{},
|
||||||
0,
|
0,
|
||||||
@@ -90,8 +90,8 @@ func anyToArgon(x any, quote bool, simplify bool, depth int, indent int, colored
|
|||||||
} else if callable, ok := x.obj["__repr__"]; ok {
|
} else if callable, ok := x.obj["__repr__"]; ok {
|
||||||
val, err := runCall(
|
val, err := runCall(
|
||||||
call{
|
call{
|
||||||
callable: callable,
|
Callable: callable,
|
||||||
args: []any{},
|
Args: []any{},
|
||||||
},
|
},
|
||||||
stack{},
|
stack{},
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ var blockedVariableNames = map[string]bool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
type accessVariable struct {
|
type accessVariable struct {
|
||||||
name string
|
Name string
|
||||||
line int
|
Line int
|
||||||
code string
|
Code string
|
||||||
path string
|
Path string
|
||||||
}
|
}
|
||||||
|
|
||||||
type setVariable struct {
|
type setVariable struct {
|
||||||
@@ -72,7 +72,7 @@ func isVariable(code UNPARSEcode) bool {
|
|||||||
|
|
||||||
func parseVariable(code UNPARSEcode) (accessVariable, bool, ArErr, int) {
|
func parseVariable(code UNPARSEcode) (accessVariable, bool, ArErr, int) {
|
||||||
name := strings.TrimSpace(code.code)
|
name := strings.TrimSpace(code.code)
|
||||||
return accessVariable{name: name, code: code.realcode, line: code.line, path: code.path}, true, ArErr{}, 1
|
return accessVariable{Name: name, Code: code.realcode, Line: code.line, Path: code.path}, true, ArErr{}, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
||||||
@@ -81,7 +81,7 @@ func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
contains, err := builtinCall(callable, []any{v.name})
|
contains, err := builtinCall(callable, []any{v.Name})
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -90,10 +90,10 @@ func readVariable(v accessVariable, stack stack) (any, ArErr) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return builtinCall(callable, []any{v.name})
|
return builtinCall(callable, []any{v.Name})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Name Error", "variable \"" + v.name + "\" does not exist", v.line, v.path, v.code, true}
|
return nil, ArErr{"Name Error", "variable \"" + v.Name + "\" does not exist", v.Line, v.Path, v.Code, true}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSetVariable(code UNPARSEcode) bool {
|
func isSetVariable(code UNPARSEcode) bool {
|
||||||
@@ -220,14 +220,14 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, ArErr{"Type Error", "stack doesn't have __setindex__", v.line, v.path, v.code, true}
|
return nil, ArErr{"Type Error", "stack doesn't have __setindex__", v.line, v.path, v.code, true}
|
||||||
}
|
}
|
||||||
_, err := builtinCall(stackcallable, []any{v.toset.(accessVariable).name, resp})
|
_, err := builtinCall(stackcallable, []any{v.toset.(accessVariable).Name, resp})
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch x := v.toset.(type) {
|
switch x := v.toset.(type) {
|
||||||
case accessVariable:
|
case accessVariable:
|
||||||
name := x.name
|
name := x.Name
|
||||||
hasSet := false
|
hasSet := false
|
||||||
if v.function {
|
if v.function {
|
||||||
resp = Callable{name, v.params, v.value, v.code, stack, v.line}
|
resp = Callable{name, v.params, v.value, v.code, stack, v.line}
|
||||||
@@ -263,10 +263,10 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(x.args) != 1 {
|
if len(x.Args) != 1 {
|
||||||
return nil, ArErr{"Runtime Error", "cannot set by slice", v.line, v.path, v.code, true}
|
return nil, ArErr{"Runtime Error", "cannot set by slice", v.line, v.path, v.code, true}
|
||||||
}
|
}
|
||||||
key, err := runVal(x.args[0], stack, stacklevel+1)
|
key, err := runVal(x.Args[0], stack, stacklevel+1)
|
||||||
key = ArValidToAny(key)
|
key = ArValidToAny(key)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -276,11 +276,11 @@ func setVariableValue(v setVariable, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if _, ok := y.obj["__setindex__"]; ok {
|
if _, ok := y.obj["__setindex__"]; ok {
|
||||||
callable := y.obj["__setindex__"]
|
callable := y.obj["__setindex__"]
|
||||||
_, err := runCall(call{
|
_, err := runCall(call{
|
||||||
callable: callable,
|
Callable: callable,
|
||||||
args: []any{key, resp},
|
Args: []any{key, resp},
|
||||||
line: v.line,
|
Line: v.line,
|
||||||
path: v.path,
|
Path: v.path,
|
||||||
code: v.code,
|
Code: v.code,
|
||||||
}, stack, stacklevel+1)
|
}, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -322,7 +322,7 @@ func runDelete(d ArDelete, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
contains, err := builtinCall(callable, []any{x.name})
|
contains, err := builtinCall(callable, []any{x.Name})
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -331,19 +331,19 @@ func runDelete(d ArDelete, stack stack, stacklevel int) (any, ArErr) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return builtinCall(callable, []any{x.name})
|
return builtinCall(callable, []any{x.Name})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, ArErr{"Name Error", "variable \"" + x.name + "\" does not exist", d.line, d.path, d.code, true}
|
return nil, ArErr{"Name Error", "variable \"" + x.Name + "\" does not exist", d.line, d.path, d.code, true}
|
||||||
case ArMapGet:
|
case ArMapGet:
|
||||||
respp, err := runVal(x.VAL, stack, stacklevel+1)
|
respp, err := runVal(x.VAL, stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(x.args) != 1 {
|
if len(x.Args) != 1 {
|
||||||
return nil, ArErr{"Runtime Error", "can't delete by slice", d.line, d.path, d.code, true}
|
return nil, ArErr{"Runtime Error", "can't delete by slice", d.line, d.path, d.code, true}
|
||||||
}
|
}
|
||||||
key, err := runVal(x.args[0], stack, stacklevel+1)
|
key, err := runVal(x.Args[0], stack, stacklevel+1)
|
||||||
if err.EXISTS {
|
if err.EXISTS {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user