ref: 422bc7217a71af4a1485202bb1870d40fd504870
parent: 0777dce112452cb95d09037ef49a5f35b48ed6e3
parent: 5b2e3e6495320fa7ce29823d72c27de3194befd4
author: Ori Bernstein <[email protected]>
date: Mon Aug 26 16:20:01 EDT 2013
Merge branch 'master' of git+ssh://git.eigenstate.org/git/ori/mc
--- a/doc/lang.txt
+++ b/doc/lang.txt
@@ -331,16 +331,21 @@
const Val234 = `Val 234 /* set up a constant value */
var v = `Val 123 /* set up variable to match */
match v
- /* pattern clauses */
- `Val 123: std.put("Matched literal union pat\n");;
-
- Val234: std.put("Matched const value pat\n");;
-
- `Val a: std.put("Matched pattern with capture\n")
- std.put("Captured value: a = %i\n", a)
- ;;
- a std.put("A top level bind matches anything.");;
- `Val 111 std.put("Unreachable block");;
+ /* pattern clauses */
+ `Val 123:
+ std.put("Matched literal union pat\n");;
+ Val234:
+ std.put("Matched const value pat\n")
+ ;;
+ `Val a:
+ std.put("Matched pattern with capture\n")
+ std.put("Captured value: a = %i\n", a)
+ ;;
+ a
+ std.put("A top level bind matches anything.");;
+ `Val 111
+ std.put("Unreachable block.")
+ ;;
;;
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -4,10 +4,12 @@
blat.myr \
chartype.myr \
die.myr \
+ env.myr \
error.myr \
extremum.myr \
fmt.myr \
intparse.myr \
+ now.myr \
option.myr \
optparse.myr \
rand.myr \
--- /dev/null
+++ b/libstd/now.myr
@@ -1,0 +1,18 @@
+use "sys.use"
+use "types.use"
+use "fmt.use"
+
+pkg std =
+
+ const now : (-> time)
+;;
+
+const now = {
+ var tm
+
+ if clock_gettime(`Clockrealtime, &tm) == 0
+ -> (tm.sec*1000 + tm.nsec / (1000*1000)) castto(time)
+ else
+ -> -1
+ ;;
+}
--- a/libstd/start-linux.s
+++ b/libstd/start-linux.s
@@ -1,6 +1,17 @@
+.data
+/* std._environment : byte[:][:] */
+.globl std$_environment
+std$_environment:
+.envbase:
+.quad 0 /* env size */
+.envlen:
+.quad 0 /* env ptr */
+
+.text
/*
* counts the length of the string pointed to
- * by %rbx, returning len in %r9
+ * by %r8, returning len in %r9. Does not modify
+ * any registers outside of %r9
*/
cstrlen:
xorq %r9,%r9
@@ -13,36 +24,74 @@
jne .lenloop
ret
+
+/*
+ * Counts the size of the null terminated string vector
+ * pointed to by %rbx. Clobbers %r10,%r11
+ */
+count:
+ xorq %r9,%r9
+ movq %rbx,%r11
+.countloop:
+ movq (%r11),%r10
+ testq %r10,%r10
+ jz .countdone
+ addq $1,%r9
+ addq $8,%r11
+ jmp .countloop
+.countdone:
+ ret
+
+/*
+ * iterate over the strings for argc, and put
+ * them into the args array.
+ *
+ * argc in %rax, argv in %rbx, dest vector in %rcx
+ */
+cvt:
+ jmp .cvttest
+.cvtloop:
+ subq $1,%rax
+ movq (%rbx),%r8
+ call cstrlen
+ movq %r8, (%rcx)
+ movq %r9, 8(%rcx)
+ addq $8, %rbx
+ addq $16, %rcx
+.cvttest:
+ testq %rax,%rax
+ jnz .cvtloop
+.cvtdone:
+ ret
+
.globl _start
_start:
/* turn args into a slice */
movq %rsp,%rbp
- /* stack allocate sizeof(byte[:])*argc */
+ /* stack allocate sizeof(byte[:])*(argc + len(envp)) */
movq (%rbp),%rax
+ leaq 16(%rbp,%rax,8), %rbx /* envp = argv + 8*argc + 8 */
+ call count
+ addq %r9,%rax
imulq $16,%rax
subq %rax,%rsp
movq %rsp, %rdx /* saved args[:] */
- /* iterate over the strings for argc, and put
- * them into the args array. */
+ /* convert envp to byte[:][:] for std._environment */
+ movq (%rbp),%rax
+ leaq 16(%rbp,%rax,8), %rbx /* envp = argv + 8*argc + 8 */
+ movq %r9,%rax
+ movq %rsp, %rcx
+ movq %r9,.envlen
+ movq %rdx,.envbase
+ call cvt
+ movq %rcx,%rdx
+
+ /* convert argc, argv to byte[:][:] for args. */
movq (%rbp), %rax /* argc */
leaq 8(%rbp), %rbx /* argv */
- movq %rsp, %rcx
movq (%rbp), %rsi /* saved argc */
-
- testq %rax,%rax
- jz .cvtdone
- .cvtloop:
- subq $1,%rax
- movq (%rbx),%r8
- call cstrlen
- movq %r8, (%rcx)
- movq %r9, 8(%rcx)
- addq $8, %rbx
- addq $16, %rcx
- testq %rax,%rax
- jnz .cvtloop
- .cvtdone:
+ call cvt
pushq %rsi
pushq %rdx
--- a/libstd/sys-linux.myr
+++ b/libstd/sys-linux.myr
@@ -7,6 +7,24 @@
type mopt = int64
type fd = int64
+ type clock = union
+ `Clockrealtime
+ `Clockmonotonic
+ `Clockproccpu
+ `Clockthreadcpu
+ `Clockmonotonicraw
+ `Clockrealtimecoarse
+ `Clockmonotoniccoarse
+ `Clockboottime
+ `Clockrealtimealarm
+ `Clockboottimealarm
+ ;;
+
+ type timespec = struct
+ secs : uint64
+ nsecs : uint64
+ ;;
+
type statbuf = struct
dev : uint
ino : uint
@@ -370,9 +388,11 @@
const Sysprocess_vm_readv : scno = 310
const Sysprocess_vm_writev : scno = 311
+ /* getting to the os */
extern const syscall : (sc:scno, args:... -> int64)
extern const cstring : (str : byte[:] -> byte#)
+ /* process management */
const exit : (status:int -> void)
const getpid : ( -> int64)
const kill : (pid:int64, sig:int64 -> int64)
@@ -386,13 +406,22 @@
const lseek : (fd:fd, off:uint64, whence:int64 -> int64)
const fstat : (fd:fd, sb:statbuf# -> int64)
+ /* memory mapping */
const munmap : (addr:byte#, len:size -> int64)
const mmap : (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#)
+
+ /* time */
+ const clock_getres : (clk : clock, ts : timespec# -> int32)
+ const clock_gettime : (clk : clock, ts : timespec# -> int32)
+ const clock_settime : (clk : clock, ts : timespec# -> int32)
;;
+/* process management */
const exit = {status; syscall(Sysexit, status castto(int64))}
const getpid = {; -> syscall(Sysgetpid, 1)}
const kill = {pid, sig; -> syscall(Syskill, pid, sig)}
+
+/* fd manipulation */
const open = {path, opts, mode; -> syscall(Sysopen, cstring(path), opts, mode) castto(fd)}
const close = {fd; -> syscall(Sysclose, fd)}
const creat = {path, mode; -> syscall(Syscreat, cstring(path), mode) castto(fd)}
@@ -400,5 +429,28 @@
const write = {fd, buf; -> syscall(Syswrite, fd, buf castto(byte#), buf.len castto(size)) castto(size)}
const lseek = {fd, off, whence; -> syscall(Syslseek, fd, off, whence)}
const fstat = {fd, sb; -> syscall(Sysfstat, fd, sb)}
+
+/* memory mapping */
const munmap = {addr, len; -> syscall(Sysmunmap, addr, len)}
const mmap = {addr, len, prot, flags, fd, off; -> syscall(Sysmmap, addr, len, prot, flags, fd, off) castto(byte#)}
+
+/* time */
+const clock_getres = {clk, ts; -> syscall(Sysclock_getres, clockid(clk), ts) castto(int32)}
+const clock_gettime = {clk, ts; -> syscall(Sysclock_gettime, clockid(clk), ts) castto(int32)}
+const clock_settime = {clk, ts; -> syscall(Sysclock_settime, clockid(clk), ts) castto(int32)}
+
+const clockid = {clk
+ match clk
+ `Clockrealtime: -> 0;;
+ `Clockmonotonic: -> 1;;
+ `Clockproccpu: -> 2;;
+ `Clockthreadcpu: -> 3;;
+ `Clockmonotonicraw: -> 4;;
+ `Clockrealtimecoarse: -> 5;;
+ `Clockmonotoniccoarse: -> 6;;
+ `Clockboottime: -> 7;;
+ `Clockrealtimealarm: -> 8;;
+ `Clockboottimealarm: -> 9;;
+ ;;
+ -> -1
+}
--- a/libstd/test.myr
+++ b/libstd/test.myr
@@ -8,6 +8,7 @@
var o
var a
+ std.put("The time is %l seconds past the epoch\n", std.now()/1000);
ctx = std.optinit("asdf:g?h", args)
std.put("arglen = %i\n", ctx.args.len)
while !std.optdone(ctx)
@@ -18,6 +19,10 @@
std.put("option %c, arg = %s\n", o, a)
;;
+ std.put("env.len = %i\n", std._environment.len)
+ for i = 0; i < std._environment.len; i++
+ std.put("env[%i] = %s\n", i, std._environment[i])
+ ;;
std.put("args.len = %i\n", args.len)
for i = 0; i < args.len; i++
std.put("args[%i] = %s\n", i, args[i])
--- a/libstd/types.myr
+++ b/libstd/types.myr
@@ -2,4 +2,5 @@
type size = uint64 /* spans entire address space */
type off = uint64 /* file offsets */
type intptr = uint64 /* can hold any pointer losslessly */
+ type time = uint64 /* milliseconds since epoch */
;;