aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2013-09-02 11:27:01 +0200
committerDrahflow <drahflow@gmx.de>2013-09-02 11:27:01 +0200
commit92b6155a1c3a209936dddebb8bf3372ebee78f94 (patch)
tree8680757163dc8dbbea513b60f27945ec9c021af9
parentdd98844bd4968664f9dd7be996df596873733ecd (diff)
I CAN HAZ TCP/IP CONNECTION!
Very crappy HTTP client: "drahflow.name:80" net .tcp .connect "+" via "GET / HTTP/1.0\n\n" +writeall 4096 +read dump
-rw-r--r--compiler/standard.ey6
-rw-r--r--compiler/standardClient.ey4
-rw-r--r--elymas/lib/bin.ey62
-rw-r--r--elymas/lib/net.ey6
-rw-r--r--elymas/lib/net/dns.ey138
-rw-r--r--elymas/lib/net/tcp.ey37
-rw-r--r--elymas/lib/net/udp.ey36
-rw-r--r--elymas/lib/sys/linux.ey668
-rw-r--r--elymas/lib/txt.ey12
-rw-r--r--elymas/loaded.ey14
-rw-r--r--examples/working-compiler/deffd.test8
-rw-r--r--examples/working-compiler/defvs.test33
-rw-r--r--examples/working-compiler/lookup-constant.ey7
-rw-r--r--examples/working-compiler/lookup-dynamic.ey7
-rw-r--r--examples/working-compiler/lookup-static.ey7
-rw-r--r--examples/working/unscoped-function.ey3
-rw-r--r--interpreter/ElymasGlobal.pm45
17 files changed, 784 insertions, 309 deletions
diff --git a/compiler/standard.ey b/compiler/standard.ey
index caf9b0e..f440fb0 100644
--- a/compiler/standard.ey
+++ b/compiler/standard.ey
@@ -11,11 +11,9 @@
} quoted { } { * } ? *
} "}_" defq
-{ deffst }' " globalDeff" deffd # this is not for public usage
{
- { -01 < ==o { o -01 . } > -12 } quoted { } { * } ? *
- quoted { |deffst } " globalDeff" | ? *
-} /via defq
+ { -01 < ==o { o -01 . } > -12 deffst }" quoted { }" { * }" ? *
+}" /via defq
{ -1110 ; ==f =*a len _
{
diff --git a/compiler/standardClient.ey b/compiler/standardClient.ey
index 940b974..3d93aa5 100644
--- a/compiler/standardClient.ey
+++ b/compiler/standardClient.ey
@@ -455,7 +455,9 @@
} /eachLine deff
> > -- } /makefile deff
- |makefile /fdToFile sys .deff
+ {
+ RDWR 511 makefile
+ } /fdToFile sys .deff
{ # 0777 = 511
1 neg RDONLY 511 makefile
diff --git a/elymas/lib/bin.ey b/elymas/lib/bin.ey
index 74caa04..9216d69 100644
--- a/elymas/lib/bin.ey
+++ b/elymas/lib/bin.ey
@@ -2,21 +2,63 @@
# as binary data structures
<
+ {
+ { 8 uw } /u64 deffd
+ { 4 uw } /u32 deffd
+ { 2 uw } /u16 deffd
+ { 1 uw } /u8 deffd
+ { 8 unw } /un64 deffd
+ { 4 unw } /un32 deffd
+ { 2 unw } /un16 deffd
+ { 1 unw } /un8 deffd
+ }" /defBitVariants deffd
+
<
# 0 -> number of bytes to combine into unsigned int
# 1 -> string
- # 0 <- string from (w+1)th byte onwards
- # 1 <- first w bytes of string interpreted as unsigned int
+ # 0 <- first w bytes of string interpreted as unsigned int
+ # 1 <- string from (w+1)th byte onwards
{ ==w ==s
w s str .postfix
[ 0 w range s each ] 256 math .unbase
- } /uw deff
-
- { 8 uw } /u64 deff
- { 4 uw } /u32 deff
- { 2 uw } /u16 deff
- { 1 uw } /u8 deff
- > /scan defv
-> /bin defv
+ } /uw deffst
+
+ # network byte order (i.e. big endian)
+ { ==w ==s
+ w s str .postfix
+ [ 0 w range reverse s each ] 256 math .unbase
+ } /unw deffst
+
+ defBitVariants
+ > /scan defvd
+
+ <
+ # 0 -> number of bytes to produce
+ # 1 -> int to convert to bytes
+ # 0 <- string enlengthened by binary encoded integer
+ { ==w ==i
+ w str .alloc ==s
+ 0 w range { 0 -01 s =[] }" each
+ i 256 math .base _ dom { -101*0 s =[] }" each --
+ s
+ } /uw deffst
+
+ # network byte order (i.e. big endian)
+ { ==w ==i
+ w str .alloc ==s
+ 0 w range { 0 -01 s =[] }" each
+ i 256 math .base _ dom { -101*0 w 1 sub -01 sub s =[] }" each --
+ s
+ } /unw deffst
+
+ defBitVariants
+ > /produce defvd
+
+ <
+ { produce .uw cat } /uw deffst
+ { produce .unw cat } /unw deffst
+ defBitVariants
+ > /print defvd
+> /bin defvd
# vim: syn=elymas
diff --git a/elymas/lib/net.ey b/elymas/lib/net.ey
new file mode 100644
index 0000000..4e782ac
--- /dev/null
+++ b/elymas/lib/net.ey
@@ -0,0 +1,6 @@
+<
+ { =*? }' /deff deffd
+ { ==? }' /defv deffd
+> /net defv
+
+# vim: syn=elymas
diff --git a/elymas/lib/net/dns.ey b/elymas/lib/net/dns.ey
new file mode 100644
index 0000000..b4a5dbe
--- /dev/null
+++ b/elymas/lib/net/dns.ey
@@ -0,0 +1,138 @@
+# Provide nice ways to do DNS resolution
+# Spec: http://www.faqs.org/rfcs/rfc1035.html
+
+<
+# Uncomment to enable function ("deffd") tracing for this scope
+# {
+# -010 { " executing" cat dump }_ -01 ; -01 =*:
+# }" /deffd deffd
+
+ bin .scan "->" via
+ bin .print "<-" via
+ bin .produce "<=" via
+ sys .linux "+" via
+
+ # 0 -> ascii ip address
+ # 0 <- ipv4 address as un32
+ { [ -01 "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$" regex not { "not an IPv4 address" die } rep ]
+ [ -01 txt .consume .|u each ] # FIXME employ typed functions and auto-map
+ reverse str .fromArray
+ } /parseIpv4 deffd
+
+ # 0 -> hostname
+ # 0 <- ipv4 address as un32
+ { ==host
+ ensureResolvConf
+ resolvConf .nameserver parseIpv4 53 net .udp .sockaddrIpv4
+ +AFINET +SOCKDGRAM +IPPROTOUDP +socket _ ==s # TODO: error handling
+ -01 +connect -- # TODO: error handling
+
+ s
+ host buildDnsQueryMessage
+ _ len
+ +write -- # TODO: error handling
+
+ 1024 str .alloc ==buf
+
+ s
+ buf
+ _ len
+ +read # TODO: error handling
+ buf str .inplacePrefix =buf
+
+ buf
+ ->un16 ==id # expected to be zero
+ ->u16 2 math .base ==bitfields
+ ->un16 ==qdCount
+ ->un16 ==anCount
+ ->un16 ==nsCount # expected to be zero
+ ->un16 ==arCount # expected to be zero
+
+ qdCount {
+ ->u8 ==labelLength
+ { labelLength } {
+ labelLength 64 ge {
+ "unexpected compression pointer in DNS reply" die
+ } {
+ labelLength -01 str .postfix
+ ->u8 =labelLength
+ } ? *
+ } loop
+ ->un16 ==qType
+ ->un16 ==qClass
+ } rep
+
+ # _ |dump each
+
+ anCount {
+ ->u8 ==labelLength
+ { labelLength } {
+ labelLength 64 ge {
+ ->u8 labelLength 63 band 256 mul add ==pointerTarget # TODO actually care for pointer target
+ 0 =labelLength
+ } {
+ labelLength -01 str .postfix
+ ->u8 =labelLength
+ } ? *
+ } loop
+
+ ->un16 1 eq not { "Answer type field was not 'A'" die } rep
+ ->un16 1 eq not { "Answer class field was not 'INET'" die } rep
+ ->un32 -- # _ ==ttl "TTL: " dump dump
+ ->un16 4 eq not { "Answer data length was not 4" die } rep
+ 4 -01 str .inplacePrefix # 4 byte IP data to be returned
+ } {
+ "Answer did not contain any answer data" die
+ } ? *
+ } /resolveIpv4 deffd
+
+ # 0 -> hostname
+ # 0 <- dns query message
+ { ==host
+ 0 <=un16 # id
+ [ 1 0 0 0 0 0 0 0 ] 2 math .unbase <-u8 # QR Opcode*4 AA TC RD
+ [ 0 0 0 0 0 0 0 0 ] 2 math .unbase <-u8 # RA Z*3 RCODE*4
+ 1 <-un16 # qdcount
+ 0 <-un16 # ancount
+ 0 <-un16 # nscount
+ 0 <-un16 # arcount
+ ==query
+
+ host { "^([^.]+)\\.?(.*)" regex } {
+ makeLabel query -01 cat =query
+ } loop
+
+ query
+ "\0" cat
+
+ 1 <-un16 # "A" query
+ 1 <-un16 # "Internet" QCLASS
+ } /buildDnsQueryMessage deffd
+
+ # 0 -> string
+ # 0 <- string with u8 length prepended
+ { _ len <=u8 -01 cat } /makeLabel deffd
+
+ # 0 -> dns message
+ # 0 <- dns message with tcp transport header prepended
+ { _ len <=u16 -01 cat } /prepareTcpMessage deffd
+
+ <
+ 0 ==?loaded
+ { defv }' /put deffd
+ > /resolvConf defvd
+
+ # ensure resolv.conf is parsed
+ {
+ resolvConf .loaded not {
+ { [
+ { _ "^[ ]*nameserver[ ]+(.*)" regex } { /nameserver resolvConf .put }
+ ] conds -- }
+ "/etc/resolv.conf" sys .file ":" via :open :eachLine :close
+
+ 1 /loaded resolvConf .put
+ } rep
+ } /ensureResolvConf deffd
+> /dns net .defv
+
+# vim: syn=elymas
diff --git a/elymas/lib/net/tcp.ey b/elymas/lib/net/tcp.ey
new file mode 100644
index 0000000..dc77515
--- /dev/null
+++ b/elymas/lib/net/tcp.ey
@@ -0,0 +1,37 @@
+# Provide nice ways to do TCP/IP networking
+
+<
+ bin .scan "->" via
+ bin .print "<-" via
+ bin .produce "<=" via
+ sys .linux "+" via
+
+ # 0 -> port
+ # 1 -> host (as network byte ordered string)
+ # 0 <- string representing the sockaddr_in
+ { ==port ==host
+ +AFINET <=u16
+ port <-un16
+ host cat
+ 0 <-un64
+ } /sockaddrIpv4 deffd
+
+ # 0 -> "host:port"
+ # 0 <- connected socket fd
+ { "^([^:]+):(\\d+)$" regex not { "host:port expected" die } rep
+ net .dns .resolveIpv4
+ -01 txt .consume .u
+ sockaddrIpv4
+ +AFINET +SOCKSTREAM +IPPROTOTCP +socket _ ==s # TODO: error handling
+ -01 +connect -- # TODO: error handling
+ s
+ } /connectFd deffd
+
+ # 0 -> "host:port"
+ # 0 <- connected socket as file
+ {
+ connectFd sys .fdToFile
+ } /connect deffd
+> /tcp net .defv
+
+# vim: syn=elymas
diff --git a/elymas/lib/net/udp.ey b/elymas/lib/net/udp.ey
new file mode 100644
index 0000000..5260d5c
--- /dev/null
+++ b/elymas/lib/net/udp.ey
@@ -0,0 +1,36 @@
+# Provide nice ways to do TCP/IP networking
+
+<
+ bin .scan "->" via
+ bin .print "<-" via
+ bin .produce "<=" via
+ sys .linux "+" via
+
+ # 0 -> port
+ # 1 -> host (as network byte ordered string)
+ # 0 <- string representing the sockaddr_in
+ { ==port ==host
+ +AFINET <=u16
+ port <-un16
+ host cat
+ 0 <-un64
+ } /sockaddrIpv4 deffd
+
+ # 0 -> "host:port"
+ # 0 <- connected socket fd
+ { "^([^:]+):(\\d+)$" regex not { "host:port expected" die } rep
+ net .dns .resolveIpv4
+ -01 txt .consume .u16
+ sockaddrIpv4
+ +socket _ ==s
+ -01 +connect -- # TODO: error handling
+ } /connectFd deffd
+
+ # 0 -> "host:port"
+ # 0 <- connected socket as file
+ {
+ connectFd sys .RDWR 0 sys .fdToFile
+ } /connect deffd
+> /udp net .defv
+
+# vim: syn=elymas
diff --git a/elymas/lib/sys/linux.ey b/elymas/lib/sys/linux.ey
index b607bc3..8f3abfb 100644
--- a/elymas/lib/sys/linux.ey
+++ b/elymas/lib/sys/linux.ey
@@ -3,313 +3,314 @@
# argument order tends to follow kernel API
<
- 43 ==:ACCEPT
- 288 ==:ACCEPT64
- 21 ==:ACCESS
- 163 ==:ACCT
- 248 ==:ADD_KEY
- 159 ==:ADJTIMEX
- 183 ==:AFS_SYSCALL
- 37 ==:ALARM
- 158 ==:ARCH_PRCTL
- 49 ==:BIND
- 12 ==:BRK
- 125 ==:CAPGET
- 126 ==:CAPSET
- 80 ==:CHDIR
- 90 ==:CHMOD
- 92 ==:CHOWN
- 161 ==:CHROOT
- 229 ==:CLOCK_GETRES
- 228 ==:CLOCK_GETTIME
- 230 ==:CLOCK_NANOSLEEP
- 227 ==:CLOCK_SETTIME
- 56 ==:CLONE
+ # 43 ==:ACCEPT
+ # 288 ==:ACCEPT64
+ # 21 ==:ACCESS
+ # 163 ==:ACCT
+ # 248 ==:ADDKEY
+ # 159 ==:ADJTIMEX
+ # 183 ==:AFSSYSCALL
+ # 37 ==:ALARM
+ # 158 ==:ARCHPRCTL
+ # 49 ==:BIND
+ # 12 ==:BRK
+ # 125 ==:CAPGET
+ # 126 ==:CAPSET
+ # 80 ==:CHDIR
+ # 90 ==:CHMOD
+ # 92 ==:CHOWN
+ # 161 ==:CHROOT
+ # 229 ==:CLOCKGETRES
+ # 228 ==:CLOCKGETTIME
+ # 230 ==:CLOCKNANOSLEEP
+ # 227 ==:CLOCKSETTIME
+ # 56 ==:CLONE
3 ==:CLOSE
42 ==:CONNECT
- 85 ==:CREAT
- 174 ==:CREATE_MODULE
- 176 ==:DELETE_MODULE
- 32 ==:DUP
- 33 ==:DUP2
- 292 ==:DUP3
- 213 ==:EPOLL_CREATE
- 291 ==:EPOLL_CREATE1
- 233 ==:EPOLL_CTL
- 214 ==:EPOLL_CTL_OLD
- 281 ==:EPOLL_PWAIT
- 232 ==:EPOLL_WAIT
- 215 ==:EPOLL_WAIT_OLD
- 284 ==:EVENTFD
- 290 ==:EVENTFD2
- 59 ==:EXECVE
- 60 ==:EXIT
- 231 ==:EXIT_GROUP
- 269 ==:FACCESSAT
- 221 ==:FADVISE64
- 285 ==:FALLOCATE
- 300 ==:FANOTIFY_INIT
- 301 ==:FANOTIFY_MARK
- 81 ==:FCHDIR
- 91 ==:FCHMOD
- 268 ==:FCHMODAT
- 93 ==:FCHOWN
- 260 ==:FCHOWNAT
- 72 ==:FCNTL
- 75 ==:FDATASYNC
- 193 ==:FGETXATTR
- 196 ==:FLISTXATTR
- 73 ==:FLOCK
- 57 ==:FORK
- 199 ==:FREMOVEXATTR
- 190 ==:FSETXATTR
- 5 ==:FSTAT
- 138 ==:FSTATFS
- 74 ==:FSYNC
- 77 ==:FTRUNCATE
- 202 ==:FUTEX
- 261 ==:FUTIMESAT
- 177 ==:GET_KERNEL_SYMS
- 239 ==:GET_MEMPOLICY
- 274 ==:GET_ROBUST_LIST
- 211 ==:GET_THREAD_AREA
- 79 ==:GETCWD
- 78 ==:GETDENTS
- 217 ==:GETDENTS64
- 108 ==:GETEGID
- 107 ==:GETEUID
- 104 ==:GETGID
- 115 ==:GETGROUPS
- 36 ==:GETITIMER
- 52 ==:GETPEERNAME
- 121 ==:GETPGID
- 111 ==:GETPGRP
- 39 ==:GETPID
- 181 ==:GETPMSG
- 110 ==:GETPPID
- 140 ==:GETPRIORITY
- 120 ==:GETRESGID
- 118 ==:GETRESUID
- 97 ==:GETRLIMIT
- 98 ==:GETRUSAGE
- 124 ==:GETSID
- 51 ==:GETSOCKNAME
- 55 ==:GETSOCKOPT
- 186 ==:GETTID
+ # 85 ==:CREAT
+ # 174 ==:CREATEMODULE
+ # 176 ==:DELETEMODULE
+ # 32 ==:DUP
+ # 33 ==:DUP2
+ # 292 ==:DUP3
+ 213 ==:EPOLLCREATE
+ # 291 ==:EPOLLCREATE1
+ 233 ==:EPOLLCTL
+ # 214 ==:EPOLLCTLOLD
+ # 281 ==:EPOLLPWAIT
+ 232 ==:EPOLLWAIT
+ # 215 ==:EPOLLWAITOLD
+ # 284 ==:EVENTFD
+ # 290 ==:EVENTFD2
+ # 59 ==:EXECVE
+ # 60 ==:EXIT
+ # 231 ==:EXITGROUP
+ # 269 ==:FACCESSAT
+ # 221 ==:FADVISE64
+ # 285 ==:FALLOCATE
+ # 300 ==:FANOTIFYINIT
+ # 301 ==:FANOTIFYMARK
+ # 81 ==:FCHDIR
+ # 91 ==:FCHMOD
+ # 268 ==:FCHMODAT
+ # 93 ==:FCHOWN
+ # 260 ==:FCHOWNAT
+ # 72 ==:FCNTL
+ # 75 ==:FDATASYNC
+ # 193 ==:FGETXATTR
+ # 196 ==:FLISTXATTR
+ # 73 ==:FLOCK
+ # 57 ==:FORK
+ # 199 ==:FREMOVEXATTR
+ # 190 ==:FSETXATTR
+ # 5 ==:FSTAT
+ # 138 ==:FSTATFS
+ # 74 ==:FSYNC
+ # 77 ==:FTRUNCATE
+ # 202 ==:FUTEX
+ # 261 ==:FUTIMESAT
+ # 177 ==:GETKERNELSYMS
+ # 239 ==:GETMEMPOLICY
+ # 274 ==:GETROBUSTLIST
+ # 211 ==:GETTHREADAREA
+ # 79 ==:GETCWD
+ # 78 ==:GETDENTS
+ # 217 ==:GETDENTS64
+ # 108 ==:GETEGID
+ # 107 ==:GETEUID
+ # 104 ==:GETGID
+ # 115 ==:GETGROUPS
+ # 36 ==:GETITIMER
+ # 52 ==:GETPEERNAME
+ # 121 ==:GETPGID
+ # 111 ==:GETPGRP
+ # 39 ==:GETPID
+ # 181 ==:GETPMSG
+ # 110 ==:GETPPID
+ # 140 ==:GETPRIORITY
+ # 120 ==:GETRESGID
+ # 118 ==:GETRESUID
+ # 97 ==:GETRLIMIT
+ # 98 ==:GETRUSAGE
+ # 124 ==:GETSID
+ # 51 ==:GETSOCKNAME
+ # 55 ==:GETSOCKOPT
+ # 186 ==:GETTID
96 ==:GETTIMEOFDAY
- 102 ==:GETUID
- 191 ==:GETXATTR
- 175 ==:INIT_MODULE
- 254 ==:INOTIFY_ADD_WATCH
- 253 ==:INOTIFY_INIT
- 294 ==:INOTIFY_INIT1
- 255 ==:INOTIFY_RM_WATCH
- 210 ==:IO_CANCEL
- 207 ==:IO_DESTROY
- 208 ==:IO_GETEVENTS
- 206 ==:IO_SETUP
- 209 ==:IO_SUBMIT
- 16 ==:IOCTL
- 173 ==:IOPERM
- 172 ==:IOPL
- 252 ==:IOPRIO_GET
- 251 ==:IOPRIO_SET
- 246 ==:KEXEC_LOAD
- 250 ==:KEYCTL
- 62 ==:KILL
- 94 ==:LCHOWN
- 192 ==:LGETXATTR
- 86 ==:LINK
- 265 ==:LINKAT
- 50 ==:LISTEN
- 194 ==:LISTXATTR
- 195 ==:LLISTXATTR
- 212 ==:LOOKUP_DCOOKIE
- 198 ==:LREMOVEXATTR
- 8 ==:LSEEK
- 189 ==:LSETXATTR
- 6 ==:LSTAT
- 28 ==:MADVISE
- 237 ==:MBIND
- 256 ==:MIGRATE_PAGES
- 27 ==:MINCORE
- 83 ==:MKDIR
- 258 ==:MKDIRAT
- 133 ==:MKNOD
- 259 ==:MKNODAT
- 149 ==:MLOCK
- 151 ==:MLOCKALL
- 9 ==:MMAP
- 154 ==:MODIFY_LDT
- 165 ==:MOUNT
- 279 ==:MOVE_PAGES
- 10 ==:MPROTECT
- 245 ==:MQ_GETSETATTR
- 244 ==:MQ_NOTIFY
- 240 ==:MQ_OPEN
- 243 ==:MQ_TIMEDRECEIVE
- 242 ==:MQ_TIMEDSEND
- 241 ==:MQ_UNLINK
- 25 ==:MREMAP
- 71 ==:MSGCTL
- 68 ==:MSGGET
- 70 ==:MSGRCV
- 69 ==:MSGSND
- 26 ==:MSYNC
- 150 ==:MUNLOCK
- 152 ==:MUNLOCKALL
- 11 ==:MUNMAP
- 35 ==:NANOSLEEP
- 262 ==:NEWFSTATAT
- 180 ==:NFSSERVCTL
+ # 102 ==:GETUID
+ # 191 ==:GETXATTR
+ # 175 ==:INITMODULE
+ # 254 ==:INOTIFYADDWATCH
+ # 253 ==:INOTIFYINIT
+ # 294 ==:INOTIFYINIT1
+ # 255 ==:INOTIFYRMWATCH
+ # 210 ==:IOCANCEL
+ # 207 ==:IODESTROY
+ # 208 ==:IOGETEVENTS
+ # 206 ==:IOSETUP
+ # 209 ==:IOSUBMIT
+ # 16 ==:IOCTL
+ # 173 ==:IOPERM
+ # 172 ==:IOPL
+ # 252 ==:IOPRIOGET
+ # 251 ==:IOPRIOSET
+ # 246 ==:KEXECLOAD
+ # 250 ==:KEYCTL
+ # 62 ==:KILL
+ # 94 ==:LCHOWN
+ # 192 ==:LGETXATTR
+ # 86 ==:LINK
+ # 265 ==:LINKAT
+ # 50 ==:LISTEN
+ # 194 ==:LISTXATTR
+ # 195 ==:LLISTXATTR
+ # 212 ==:LOOKUPDCOOKIE
+ # 198 ==:LREMOVEXATTR
+ # 8 ==:LSEEK
+ # 189 ==:LSETXATTR
+ # 6 ==:LSTAT
+ # 28 ==:MADVISE
+ # 237 ==:MBIND
+ # 256 ==:MIGRATEPAGES
+ # 27 ==:MINCORE
+ # 83 ==:MKDIR
+ # 258 ==:MKDIRAT
+ # 133 ==:MKNOD
+ # 259 ==:MKNODAT
+ # 149 ==:MLOCK
+ # 151 ==:MLOCKALL
+ # 9 ==:MMAP
+ # 154 ==:MODIFYLDT
+ # 165 ==:MOUNT
+ # 279 ==:MOVEPAGES
+ # 10 ==:MPROTECT
+ # 245 ==:MQGETSETATTR
+ # 244 ==:MQNOTIFY
+ # 240 ==:MQOPEN
+ # 243 ==:MQTIMEDRECEIVE
+ # 242 ==:MQTIMEDSEND
+ # 241 ==:MQUNLINK
+ # 25 ==:MREMAP
+ # 71 ==:MSGCTL
+ # 68 ==:MSGGET
+ # 70 ==:MSGRCV
+ # 69 ==:MSGSND
+ # 26 ==:MSYNC
+ # 150 ==:MUNLOCK
+ # 152 ==:MUNLOCKALL
+ # 11 ==:MUNMAP
+ # 35 ==:NANOSLEEP
+ # 262 ==:NEWFSTATAT
+ # 180 ==:NFSSERVCTL
2 ==:OPEN
- 257 ==:OPENAT
- 34 ==:PAUSE
- 298 ==:PERF_EVENT_OPEN
- 135 ==:PERSONALITY
- 22 ==:PIPE
- 293 ==:PIPE2
- 155 ==:PIVOT_ROOT
- 7 ==:POLL
- 271 ==:PPOLL
- 157 ==:PRCTL
- 17 ==:PREAD64
- 295 ==:PREADV
- 302 ==:PRLIMIT64
- 270 ==:PSELECT6
+ # 257 ==:OPENAT
+ # 34 ==:PAUSE
+ # 298 ==:PERFEVENTOPEN
+ # 135 ==:PERSONALITY
+ # 22 ==:PIPE
+ # 293 ==:PIPE2
+ # 155 ==:PIVOTROOT
+ # 7 ==:POLL
+ # 271 ==:PPOLL
+ # 157 ==:PRCTL
+ # 17 ==:PREAD64
+ # 295 ==:PREADV
+ # 302 ==:PRLIMIT64
+ # 270 ==:PSELECT6
101 ==:PTRACE
- 182 ==:PUTPMSG
- 18 ==:PWRITE64
- 296 ==:PWRITEV
- 178 ==:QUERY_MODULE
- 179 ==:QUOTACTL
+ # 182 ==:PUTPMSG
+ # 18 ==:PWRITE64
+ # 296 ==:PWRITEV
+ # 178 ==:QUERYMODULE
+ # 179 ==:QUOTACTL
0 ==:READ
- 187 ==:READAHEAD
- 89 ==:READLINK
- 267 ==:READLINKAT
- 19 ==:READV
- 169 ==:REBOOT
- 45 ==:RECVFROM
- 299 ==:RECVMMSG
- 47 ==:RECVMSG
- 216 ==:REMAP_FILE_PAGES
- 197 ==:REMOVEXATTR
- 82 ==:RENAME
- 264 ==:RENAMEAT
- 249 ==:REQUEST_KEY
- 219 ==:RESTART_SYSCALL
- 84 ==:RMDIR
- 13 ==:RT_SIGACTION
- 127 ==:RT_SIGPENDING
- 14 ==:RT_SIGPROCMASK
- 129 ==:RT_SIGQUEUEINFO
- 15 ==:RT_SIGRETURN
- 130 ==:RT_SIGSUSPEND
- 128 ==:RT_SIGTIMEDWAIT
- 297 ==:RT_TGSIGQUEUEINFO
- 146 ==:SCHED_GET_PRIORITY_MAX
- 147 ==:SCHED_GET_PRIORITY_MIN
- 204 ==:SCHED_GETAFFINITY
- 143 ==:SCHED_GETPARAM
- 145 ==:SCHED_GETSCHEDULER
- 148 ==:SCHED_RR_GET_INTERVAL
- 203 ==:SCHED_SETAFFINITY
- 142 ==:SCHED_SETPARAM
- 144 ==:SCHED_SETSCHEDULER
- 24 ==:SCHED_YIELD
- 185 ==:SECURITY
- 23 ==:SELECT
- 66 ==:SEMCTL
- 64 ==:SEMGET
- 65 ==:SEMOP
- 220 ==:SEMTIMEDOP
- 40 ==:SENDFILE
- 46 ==:SENDMSG
- 44 ==:SENDTO
- 238 ==:SET_MEMPOLICY
- 273 ==:SET_ROBUST_LIST
- 205 ==:SET_THREAD_AREA
- 218 ==:SET_TID_ADDRESS
- 171 ==:SETDOMAINNAME
- 123 ==:SETFSGID
- 122 ==:SETFSUID
- 106 ==:SETGID
- 116 ==:SETGROUPS
- 170 ==:SETHOSTNAME
- 38 ==:SETITIMER
- 109 ==:SETPGID
- 141 ==:SETPRIORITY
- 114 ==:SETREGID
- 119 ==:SETRESGID
- 117 ==:SETRESUID
- 113 ==:SETREUID
- 160 ==:SETRLIMIT
- 112 ==:SETSID
- 54 ==:SETSOCKOPT
- 164 ==:SETTIMEOFDAY
- 105 ==:SETUID
- 188 ==:SETXATTR
- 30 ==:SHMAT
- 31 ==:SHMCTL
- 67 ==:SHMDT
- 29 ==:SHMGET
- 48 ==:SHUTDOWN
- 131 ==:SIGALTSTACK
- 282 ==:SIGNALFD
- 289 ==:SIGNALFD4
+ # 187 ==:READAHEAD
+ # 89 ==:READLINK
+ # 267 ==:READLINKAT
+ # 19 ==:READV
+ # 169 ==:REBOOT
+ # 45 ==:RECVFROM
+ # 299 ==:RECVMMSG
+ # 47 ==:RECVMSG
+ # 216 ==:REMAPFILEPAGES
+ # 197 ==:REMOVEXATTR
+ # 82 ==:RENAME
+ # 264 ==:RENAMEAT
+ # 249 ==:REQUESTKEY
+ # 219 ==:RESTARTSYSCALL
+ # 84 ==:RMDIR
+ # 13 ==:RTSIGACTION
+ # 127 ==:RTSIGPENDING
+ # 14 ==:RTSIGPROCMASK
+ # 129 ==:RTSIGQUEUEINFO
+ # 15 ==:RTSIGRETURN
+ # 130 ==:RTSIGSUSPEND
+ # 128 ==:RTSIGTIMEDWAIT
+ # 297 ==:RTTGSIGQUEUEINFO
+ # 146 ==:SCHEDGETPRIORITYMAX
+ # 147 ==:SCHEDGETPRIORITYMIN
+ # 204 ==:SCHEDGETAFFINITY
+ # 143 ==:SCHEDGETPARAM
+ # 145 ==:SCHEDGETSCHEDULER
+ # 148 ==:SCHEDRRGETINTERVAL
+ # 203 ==:SCHEDSETAFFINITY
+ # 142 ==:SCHEDSETPARAM
+ # 144 ==:SCHEDSETSCHEDULER
+ # 24 ==:SCHEDYIELD
+ # 185 ==:SECURITY
+ # 23 ==:SELECT
+ # 66 ==:SEMCTL
+ # 64 ==:SEMGET
+ # 65 ==:SEMOP
+ # 220 ==:SEMTIMEDOP
+ # 40 ==:SENDFILE
+ # 46 ==:SENDMSG
+ # 44 ==:SENDTO
+ # 238 ==:SETMEMPOLICY
+ # 273 ==:SETROBUSTLIST
+ # 205 ==:SETTHREADAREA
+ # 218 ==:SETTIDADDRESS
+ # 171 ==:SETDOMAINNAME
+ # 123 ==:SETFSGID
+ # 122 ==:SETFSUID
+ # 106 ==:SETGID
+ # 116 ==:SETGROUPS
+ # 170 ==:SETHOSTNAME
+ # 38 ==:SETITIMER
+ # 109 ==:SETPGID
+ # 141 ==:SETPRIORITY
+ # 114 ==:SETREGID
+ # 119 ==:SETRESGID
+ # 117 ==:SETRESUID
+ # 113 ==:SETREUID
+ # 160 ==:SETRLIMIT
+ # 112 ==:SETSID
+ # 54 ==:SETSOCKOPT
+ # 164 ==:SETTIMEOFDAY
+ # 105 ==:SETUID
+ # 188 ==:SETXATTR
+ # 30 ==:SHMAT
+ # 31 ==:SHMCTL
+ # 67 ==:SHMDT
+ # 29 ==:SHMGET
+ # 48 ==:SHUTDOWN
+ # 131 ==:SIGALTSTACK
+ # 282 ==:SIGNALFD
+ # 289 ==:SIGNALFD4
41 ==:SOCKET
- 53 ==:SOCKETPAIR
- 275 ==:SPLICE
+ # 53 ==:SOCKETPAIR
+ # 275 ==:SPLICE
4 ==:STAT
- 137 ==:STATFS
- 168 ==:SWAPOFF
- 167 ==:SWAPON
- 88 ==:SYMLINK
- 266 ==:SYMLINKAT
- 162 ==:SYNC
- 277 ==:SYNC_FILE_RANGE
- 156 ==:SYSCTL
- 139 ==:SYSFS
- 99 ==:SYSINFO
- 103 ==:SYSLOG
- 276 ==:TEE
- 234 ==:TGKILL
- 201 ==:TIME
- 222 ==:TIMER_CREATE
- 226 ==:TIMER_DELETE
- 225 ==:TIMER_GETOVERRUN
- 224 ==:TIMER_GETTIME
- 223 ==:TIMER_SETTIME
- 283 ==:TIMERFD_CREATE
- 287 ==:TIMERFD_GETTIME
- 286 ==:TIMERFD_SETTIME
- 100 ==:TIMES
- 200 ==:TKILL
- 76 ==:TRUNCATE
- 184 ==:TUXCALL
- 95 ==:UMASK
- 166 ==:UMOUNT2
- 63 ==:UNAME
- 87 ==:UNLINK
- 263 ==:UNLINKAT
- 272 ==:UNSHARE
- 134 ==:USELIB
- 136 ==:USTAT
- 132 ==:UTIME
- 280 ==:UTIMENSAT
- 235 ==:UTIMES
- 58 ==:VFORK
- 153 ==:VHANGUP
- 278 ==:VMSPLICE
- 236 ==:VSERVER
+ # 137 ==:STATFS
+ # 168 ==:SWAPOFF
+ # 167 ==:SWAPON
+ # 88 ==:SYMLINK
+ # 266 ==:SYMLINKAT
+ # 162 ==:SYNC
+ # 277 ==:SYNCFILERANGE
+ # 156 ==:SYSCTL
+ # 139 ==:SYSFS
+ # 99 ==:SYSINFO
+ # 103 ==:SYSLOG
+ # 276 ==:TEE
+ # 234 ==:TGKILL
+ # 201 ==:TIME
+ # 222 ==:TIMERCREATE
+ # 226 ==:TIMERDELETE
+ # 225 ==:TIMERGETOVERRUN
+ # 224 ==:TIMERGETTIME
+ # 223 ==:TIMERSETTIME
+ # 283 ==:TIMERFDCREATE
+ # 287 ==:TIMERFDGETTIME
+ # 286 ==:TIMERFDSETTIME
+ # 100 ==:TIMES
+ # 200 ==:TKILL
+ # 76 ==:TRUNCATE
+ # 184 ==:TUXCALL
+ # 95 ==:UMASK
+ # 166 ==:UMOUNT2
+ # 63 ==:UNAME
+ # 87 ==:UNLINK
+ # 263 ==:UNLINKAT
+ # 272 ==:UNSHARE
+ # 134 ==:USELIB
+ # 136 ==:USTAT
+ # 132 ==:UTIME
+ # 280 ==:UTIMENSAT
+ # 235 ==:UTIMES
+ # 58 ==:VFORK
+ # 153 ==:VHANGUP
+ # 278 ==:VMSPLICE
+ # 236 ==:VSERVER
61 ==:WAIT4
- 247 ==:WAITID
+ # 247 ==:WAITID
1 ==:WRITE
- 20 ==:WRITEV
+ # 20 ==:WRITEV
0 ==errno
- bin .scan "->" via
+ bin .scan "->" via
+ bin .print "<-" via
# defines a syscall which has identical argument order
# to kernel API and returns the raw return value
@@ -322,6 +323,8 @@
{ 0 0 0 0 0 CLOSE } /close defStdSyscall
+ { _ len 0 0 0 CONNECT } /connect defStdSyscall
+
# 0 <- raw return value
# 1 <- seconds since 1970
# 2 <- microseconds since 1970
@@ -333,6 +336,83 @@
-023
} /gettimeofday deffd
+ <
+ 1 ==:EPOLLCTLADD
+ 3 ==:EPOLLCTLMOD
+ 2 ==:EPOLLCTLDEL
+
+ 1 ==:EPOLLIN
+ 4 ==:EPOLLOUT
+ 8192 ==:EPOLLRDHUP
+ 2 ==:EPOLLPRI
+ 8 ==:EPOLLERR
+ 16 ==:EPOLLHUP
+ 2147483648 ==:EPOLLLET
+ 1073741824 ==:EPOLLONESHOT
+
+ # 0 <- raw return value, i.e. epoll file descriptor
+ { 1 0 0 0 0 0 EPOLLCREATE sys .asm .syscall =errno } /create deffd
+
+ # 0 -> callback data
+ # 1 -> event mask
+ # 2 -> fd to add
+ # 3 -> epoll fd
+ # 0 <- raw return value
+ { ==callbackData ==eventMask ==fd ==action ==epollFd
+ # struct epoll_event takes 16 bytes on a x86
+ ""
+ eventMask <-u64
+ callbackData <-u64
+ ==buf
+
+ epollFd action fd buf 0 0 EPOLLCTL sys .asm .syscall =errno
+ } /ctl deffd
+
+ # 0 -> timeout
+ # 1 -> maxevents
+ # 2 -> epollfd
+ # 0 <- raw return value, i.e. number of file descriptors returned
+ # 1 <- [ < ==events ==data > ... ] (possibly empty if no file descriptors were returned)
+ # (not existing if raw return value -1)
+ { ==timeout ==maxevents ==epollFd
+ maxevents 16 mul str .alloc ==buf
+ epollFd buf maxevents timeout 0 0 EPOLLWAIT sys .asm .syscall =errno ==ret
+ [ buf ret { <
+ ->u64 ==events
+ ->u64 ==data
+ > } rep -- ]
+ ret
+ } /wait deffd
+ > /epoll defvd
+
+ 1 ==:AFUNIX
+ 1 ==:AFLOCAL
+ 2 ==:AFINET
+ 10 ==:AFINET6
+ 4 ==:AFIPX
+ 16 ==:AFNETLINK
+ 9 ==:AFX25
+ 3 ==:AFAX25
+ 8 ==:AFATMPVC
+ 5 ==:AFAPPLETALK
+ 17 ==:AFPACKET
+
+ 1 ==:SOCKSTREAM
+ 2 ==:SOCKDGRAM
+ 3 ==:SOCKRAW
+ 4 ==:SOCKRDM
+ 5 ==:SOCKSEQPACKET
+ 524288 ==:SOCKCLOEXEC
+ 2048 ==:SOCKNONBLOCK
+
+ 6 ==:IPPROTOTCP
+ 17 ==:IPPROTOUDP
+
+ # 0 -> domain
+ # 1 -> type
+ # 2 -> protocol (or use zero if the protocol is already determined by domain and type)
+ { 0 0 0 SOCKET } /socket defStdSyscall
+
# 0 -> path to stat
# 0 <- raw return value
# 1 <- (struct stat)-like scope
diff --git a/elymas/lib/txt.ey b/elymas/lib/txt.ey
new file mode 100644
index 0000000..b3bc361
--- /dev/null
+++ b/elymas/lib/txt.ey
@@ -0,0 +1,12 @@
+<
+ <
+ # 0 -> string
+ # 0 <- leading digits converted to int (0, if none)
+ # 1 <- rest of string
+ { "^(\\d*)" regex -- ==n
+ [ n { 48 sub } each ] reverse 10 math .unbase
+ } /u deffd
+ > /consume defvd
+> /txt defvd
+
+# vim: syn=elymas
diff --git a/elymas/loaded.ey b/elymas/loaded.ey
new file mode 100644
index 0000000..ffe59bc
--- /dev/null
+++ b/elymas/loaded.ey
@@ -0,0 +1,14 @@
+#!/usr/bin/env elymas
+
+[
+ "lib/bin.ey"
+ "lib/txt.ey"
+ "lib/math.ey"
+ "lib/sys/linux.ey"
+ "lib/net.ey"
+ "lib/net/tcp.ey"
+ "lib/net/udp.ey"
+ "lib/net/dns.ey"
+] { _ dump include }' each
+
+{ "/proc/self/fd/0" include }' "loaded" sys .freeze
diff --git a/examples/working-compiler/deffd.test b/examples/working-compiler/deffd.test
new file mode 100644
index 0000000..e1877e7
--- /dev/null
+++ b/examples/working-compiler/deffd.test
@@ -0,0 +1,8 @@
+1 --
+{ "here" } /foo deffd
+{ foo } /bar deffd
+{ bar } /quux deffd
+quux
+--
+quux
+die
diff --git a/examples/working-compiler/defvs.test b/examples/working-compiler/defvs.test
new file mode 100644
index 0000000..31f10cd
--- /dev/null
+++ b/examples/working-compiler/defvs.test
@@ -0,0 +1,33 @@
+{
+ "herea" /fooa defvs
+ "hereb" /foob defvs
+ "herec" /fooc defvs
+ "hered" /food defvs
+ "heree" /fooe defvs
+ "heref" /foof defvs
+ "hereg" /foog defvs
+ "hereg" /fooga defvs
+ "hereg" /foogb defvs
+ "hereg" /foogc defvs
+ "hereg" /foogd defvs
+ "hereg" /fooge defvs
+ "hereg" /foogf defvs
+ "hereg" /foogg defvs
+ "hereg" /foogh defvs
+ "hereg" /foogi defvs
+ "hereg" /foogj defvs
+ "hereh" /fooh defvs
+ "herei" /fooi defvs
+ "herej" /fooj defvs
+ "herek" /fook defvs
+ "herel" /fool defvs
+ "herem" /foom defvs
+ "heren" /foon defvs
+ "hereo" /fooo defvs
+ { { foon } } * /bar deffd
+ { bar } /quux deffd
+ quux
+ quux
+} *
+--
+die
diff --git a/examples/working-compiler/lookup-constant.ey b/examples/working-compiler/lookup-constant.ey
new file mode 100644
index 0000000..b7802c8
--- /dev/null
+++ b/examples/working-compiler/lookup-constant.ey
@@ -0,0 +1,7 @@
+0 ==:someName
+
+{ { {
+ 5000000 { someName -- } rep
+} } } * * *
+
+"done" dump
diff --git a/examples/working-compiler/lookup-dynamic.ey b/examples/working-compiler/lookup-dynamic.ey
new file mode 100644
index 0000000..30a1f39
--- /dev/null
+++ b/examples/working-compiler/lookup-dynamic.ey
@@ -0,0 +1,7 @@
+0 ==?someName
+
+{ { {
+ 5000000 { someName -- } rep
+} } } * * *
+
+"done" dump
diff --git a/examples/working-compiler/lookup-static.ey b/examples/working-compiler/lookup-static.ey
new file mode 100644
index 0000000..1a45e9a
--- /dev/null
+++ b/examples/working-compiler/lookup-static.ey
@@ -0,0 +1,7 @@
+0 ==someName
+
+{ { {
+ 5000000 { someName -- } rep
+} } } * * *
+
+"done" dump
diff --git a/examples/working/unscoped-function.ey b/examples/working/unscoped-function.ey
new file mode 100644
index 0000000..6464793
--- /dev/null
+++ b/examples/working/unscoped-function.ey
@@ -0,0 +1,3 @@
+< { deff }" > -- /abc deff
+
+{ 1 /foo abc foo dump } *
diff --git a/interpreter/ElymasGlobal.pm b/interpreter/ElymasGlobal.pm
index 321a10d..1d1770d 100644
--- a/interpreter/ElymasGlobal.pm
+++ b/interpreter/ElymasGlobal.pm
@@ -174,6 +174,51 @@ EOPERL
weaken($sub);
}
}, ['func', "}'"], 'quote'],
+ "}\"" => [sub {
+ my ($data) = @_;
+
+ --$quoted;
+
+ my @code;
+
+ while(1) {
+ my $t = pop @$data or die "Stack underflow";
+ last if($t->[1] eq 'tok' and $t->[0] eq '{');
+
+ unshift @code, $t;
+ };
+
+ die "unexpanded token in quoted code" if grep { $_->[1] eq 'tok' } @code;
+
+ if($quoted) {
+ my $sub = <<'EOPERL' .
+ sub {
+ my ($data) = @_;
+ my $s = sub {
+ my ($data, $lscope) = @_;
+EOPERL
+ compileCode(\@code) . <<'EOPERL';
+ };
+ push @$data, [$s, ['func', 'compiled sub (1)']];
+ weaken($s);
+ }
+EOPERL
+ $sub = eval($sub);
+ push @$data, [$sub, ['func', 'func-quoted'], \@code];
+ weaken($sub);
+ } else {
+ my $sub = <<'EOPERL' .
+ sub {
+ my ($data, $lscope) = @_;
+EOPERL
+ compileCode(\@code) . <<'EOPERL';
+ };
+EOPERL
+ $sub = eval($sub);
+ push @$data, [$sub, ['func', 'compiled sub (2)']];
+ weaken($sub);
+ }
+ }, ['func', "}'"], 'quote'],
'quoted' => [sub {
my ($data, $scope) = @_;
push @$data, [$quoted? 1: 0, 'int'];