diff options
| author | Drahflow <drahflow@gmx.de> | 2013-09-02 11:27:01 +0200 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2013-09-02 11:27:01 +0200 |
| commit | 92b6155a1c3a209936dddebb8bf3372ebee78f94 (patch) | |
| tree | 8680757163dc8dbbea513b60f27945ec9c021af9 | |
| parent | dd98844bd4968664f9dd7be996df596873733ecd (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.ey | 6 | ||||
| -rw-r--r-- | compiler/standardClient.ey | 4 | ||||
| -rw-r--r-- | elymas/lib/bin.ey | 62 | ||||
| -rw-r--r-- | elymas/lib/net.ey | 6 | ||||
| -rw-r--r-- | elymas/lib/net/dns.ey | 138 | ||||
| -rw-r--r-- | elymas/lib/net/tcp.ey | 37 | ||||
| -rw-r--r-- | elymas/lib/net/udp.ey | 36 | ||||
| -rw-r--r-- | elymas/lib/sys/linux.ey | 668 | ||||
| -rw-r--r-- | elymas/lib/txt.ey | 12 | ||||
| -rw-r--r-- | elymas/loaded.ey | 14 | ||||
| -rw-r--r-- | examples/working-compiler/deffd.test | 8 | ||||
| -rw-r--r-- | examples/working-compiler/defvs.test | 33 | ||||
| -rw-r--r-- | examples/working-compiler/lookup-constant.ey | 7 | ||||
| -rw-r--r-- | examples/working-compiler/lookup-dynamic.ey | 7 | ||||
| -rw-r--r-- | examples/working-compiler/lookup-static.ey | 7 | ||||
| -rw-r--r-- | examples/working/unscoped-function.ey | 3 | ||||
| -rw-r--r-- | interpreter/ElymasGlobal.pm | 45 |
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']; |
