Fixes comment lexing, adds tls to net-conn, adds timeout to net-conn, adds read-all-lines
This commit is contained in:
parent
cb561e0b8d
commit
940624fa6a
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
slope
|
||||
*.slo
|
||||
|
@ -111,11 +111,6 @@ Implemented:
|
||||
|
||||
`net-conn`
|
||||
|
||||
Not implemented, but on my radar:
|
||||
|
||||
`net-conn-tls`
|
||||
|
||||
|
||||
|
||||
\*the general write, read, and close operations in the IO section apply to net objects as well as files and string buffers
|
||||
|
||||
|
9
lexer.go
9
lexer.go
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
@ -148,8 +149,14 @@ func Tokenize(s string) []string {
|
||||
case '"':
|
||||
currentString = eatString(reader)
|
||||
tokens = append(tokens, currentString)
|
||||
case '#':
|
||||
case ';':
|
||||
eatSingleLineComment(reader)
|
||||
case '#':
|
||||
c, _, err := reader.ReadRune()
|
||||
if err != nil {
|
||||
break TokenizationLoop
|
||||
}
|
||||
tokens = append(tokens, fmt.Sprintf("#%c", c))
|
||||
default:
|
||||
reader.UnreadRune()
|
||||
currentString = eatSymbol(reader)
|
||||
|
182
lib.go
182
lib.go
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -11,6 +12,7 @@ import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var stdLibrary = vars{
|
||||
@ -513,6 +515,9 @@ var stdLibrary = vars{
|
||||
case *net.Conn:
|
||||
(*ft).Write([]byte(stringOut))
|
||||
return a[1].(*IOHandle)
|
||||
case *tls.Conn:
|
||||
ft.Write([]byte(stringOut))
|
||||
return a[1].(*IOHandle)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@ -536,6 +541,9 @@ var stdLibrary = vars{
|
||||
case *net.Conn:
|
||||
(*ft).Write([]byte(String(a[0])))
|
||||
return a[1].(*IOHandle)
|
||||
case *tls.Conn:
|
||||
ft.Write([]byte([]byte(String(a[0]))))
|
||||
return a[1].(*IOHandle)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@ -571,8 +579,54 @@ var stdLibrary = vars{
|
||||
return false
|
||||
}
|
||||
return string(b)
|
||||
case *tls.Conn:
|
||||
b, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return string(b)
|
||||
default:
|
||||
panic("'read-line' has not been implemented for this object type")
|
||||
panic("'read-all' has not been implemented for this object type")
|
||||
}
|
||||
}
|
||||
},
|
||||
"read-all-lines": func(a ...expression) expression {
|
||||
if len(a) == 0 {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
text, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return strings.SplitN(text[:len(text)-1], "\n", -1)
|
||||
} else {
|
||||
obj, ok := a[0].(*IOHandle)
|
||||
if !ok {
|
||||
panic("'read-all-lines' expected an IO handle as its argument, but was not given an IO handle")
|
||||
}
|
||||
if !obj.Open {
|
||||
panic("'read-all-lines' was given an IO handle that is already closed")
|
||||
}
|
||||
switch f := obj.Obj.(type) {
|
||||
case *os.File:
|
||||
b, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return strings.SplitN(string(b), "\n", -1)
|
||||
case *net.Conn:
|
||||
b, err := ioutil.ReadAll(*f)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return strings.SplitN(string(b), "\n", -1)
|
||||
case *tls.Conn:
|
||||
b, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return strings.SplitN(string(b), "\n", -1)
|
||||
default:
|
||||
panic("'read-all' has not been implemented for this object type")
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -633,6 +687,26 @@ var stdLibrary = vars{
|
||||
}
|
||||
}
|
||||
return o.String()
|
||||
case *tls.Conn:
|
||||
var o strings.Builder
|
||||
for {
|
||||
b := make([]byte, 1)
|
||||
n, err := (*f).Read(b)
|
||||
if n > 0 {
|
||||
if b[0] == '\n' {
|
||||
break
|
||||
}
|
||||
o.Write(b)
|
||||
}
|
||||
if err != nil && err != io.EOF && o.Len() == 0 {
|
||||
return false
|
||||
} else if err != nil && err == io.EOF {
|
||||
return symbol("EOF")
|
||||
} else if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return o.String()
|
||||
default:
|
||||
panic("'read-line' has not been implemented for this object type")
|
||||
}
|
||||
@ -814,6 +888,8 @@ var stdLibrary = vars{
|
||||
o.Close()
|
||||
case *net.Conn:
|
||||
(*o).Close()
|
||||
case *tls.Conn:
|
||||
o.Close()
|
||||
default:
|
||||
panic("'close' encountered an unsupported IO handle type")
|
||||
}
|
||||
@ -851,15 +927,77 @@ var stdLibrary = vars{
|
||||
if !ok {
|
||||
panic("'net-conn' expects a host as a string, a non-string value was given")
|
||||
}
|
||||
port, ok := a[1].(string)
|
||||
if !ok {
|
||||
var port string
|
||||
switch p := a[1].(type) {
|
||||
case string:
|
||||
port = p
|
||||
case number:
|
||||
port = strconv.Itoa(int(p))
|
||||
default:
|
||||
panic("'net-conn' expects a port as a string, a non-string value was given")
|
||||
}
|
||||
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%s", host, port))
|
||||
if err != nil {
|
||||
return false
|
||||
|
||||
usetls := false
|
||||
if len(a) >= 3 {
|
||||
t, ok := a[2].(bool)
|
||||
if !ok {
|
||||
panic("'net-conn' expects a boolean value as the third argument (use-tls), a non-bool value was given")
|
||||
}
|
||||
usetls = t
|
||||
}
|
||||
|
||||
timeout := -1
|
||||
if len(a) >= 4 {
|
||||
switch to := a[3].(type) {
|
||||
case number:
|
||||
timeout = int(to)
|
||||
case string:
|
||||
t, err := strconv.Atoi(to)
|
||||
if err != nil {
|
||||
panic("'net-conn' was given a timeout string that does not cast to an integer")
|
||||
}
|
||||
timeout = t
|
||||
default:
|
||||
panic("'net-conn' expects a string or number value representing a timeout, in seconds; a non-string non-number value was given ")
|
||||
}
|
||||
}
|
||||
var conn net.Conn
|
||||
var tlsconn *tls.Conn
|
||||
var err error
|
||||
addr := fmt.Sprintf("%s:%s", host, port)
|
||||
if usetls {
|
||||
conf := &tls.Config{InsecureSkipVerify: true}
|
||||
if timeout > 0 {
|
||||
tlsconn, err = tls.DialWithDialer(&net.Dialer{Timeout: time.Duration(timeout)*time.Second}, "tcp", addr, conf)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
tlsconn, err = tls.Dial("tcp", addr, conf)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if timeout > 0 {
|
||||
conn, err = net.DialTimeout("tcp", addr, time.Duration(timeout) * time.Second)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
conn, err = net.Dial("tcp", addr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
// based on the tls value use tls or not, same with the timeout value for adding a timeout
|
||||
var handle *IOHandle
|
||||
if usetls {
|
||||
handle = &IOHandle{tlsconn, true}
|
||||
} else {
|
||||
handle = &IOHandle{&conn, true}
|
||||
}
|
||||
handle := &IOHandle{&conn, true}
|
||||
openFiles = append(openFiles, handle)
|
||||
return handle
|
||||
},
|
||||
@ -944,9 +1082,9 @@ IO Based:
|
||||
[x] write (should do stdout by default, or accept a file, buf, or conn)
|
||||
[x] write-raw (same as write, but does not unescape strings)
|
||||
[x] read-line (defaults to stdin, or takes a file or conn)
|
||||
[ ] read-all (takes a file or conn as argument)
|
||||
[x] read-all (takes a file or conn as argument)
|
||||
[ ] read-bytes (takes a file or conn)
|
||||
[ ] read-all-lines (takes a file or conn)
|
||||
[x] read-all-lines (takes a file or conn)
|
||||
[x] file-create (overwrites existing, returns *File || bool)
|
||||
[x] file-open-read (returns *file || bool, file is set to read only)
|
||||
[x] file-open-write (returns *file || bool, file is set to read only)
|
||||
@ -956,23 +1094,21 @@ IO Based:
|
||||
|
||||
Net Based:
|
||||
[x] net-conn
|
||||
- url-host
|
||||
- url-port
|
||||
- url-scheme
|
||||
- url-path
|
||||
- url-query
|
||||
- url-set-host
|
||||
- url-set-port
|
||||
- url-set-query
|
||||
- url-set-path
|
||||
|
||||
|
||||
[ ] http-get
|
||||
[ ] http-post
|
||||
[ ] url-host
|
||||
[ ] url-port
|
||||
[ ] url-scheme
|
||||
[ ] url-path
|
||||
[ ] url-query
|
||||
[ ] url-set-host
|
||||
[ ] url-set-port
|
||||
[ ] url-set-query
|
||||
[ ] url-set-path
|
||||
|
||||
System Based:
|
||||
[x] exit
|
||||
[ ] env-get
|
||||
[ ] env-set
|
||||
[ ] env-chdir
|
||||
[ ] environ (can be used to list, get, or set)
|
||||
[ ] subprocess (may require multiple funcs)
|
||||
[ ] load (loads a scheme file)
|
||||
[x] equal? (compares any two things)
|
||||
|
4
main.go
4
main.go
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -26,6 +27,9 @@ func SafeExit(code int) {
|
||||
case *net.Conn:
|
||||
(*o).Close()
|
||||
openFiles[i].Open = false
|
||||
case *tls.Conn:
|
||||
o.Close()
|
||||
openFiles[i].Open = false
|
||||
}
|
||||
}
|
||||
os.Exit(code)
|
||||
|
Loading…
Reference in New Issue
Block a user