about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-09-23 09:23:21 -0700
committerKartik Agaram <vc@akkartik.com>2018-09-23 09:23:21 -0700
commitaa00959024643a33f766ef3f060a934006fe7725 (patch)
treef73a6ade8937c70a4df6b480ac8602e21ae1d7d3
parent7d4e351a0d1e3c4e71b58d3218b4e6b833f542f2 (diff)
downloadmu-aa00959024643a33f766ef3f060a934006fe7725.tar.gz
4504
-rw-r--r--transect/ex3.k222
-rw-r--r--transect/ex4.k234
-rw-r--r--transect/ex5.k230
-rw-r--r--transect/ex6.k223
-rw-r--r--transect/ex7.k264
-rw-r--r--transect/ex8.k236
-rw-r--r--transect/factorial.k216
7 files changed, 225 insertions, 0 deletions
diff --git a/transect/ex3.k2 b/transect/ex3.k2
new file mode 100644
index 00000000..63151396
--- /dev/null
+++ b/transect/ex3.k2
@@ -0,0 +1,22 @@
+# add the first 10 numbers, and return the result in the exit code
+
+fn main [
+  var result/EBX : int
+  result/EBX <- copy 0
+  var counter/ECX : int
+  counter/ECX <- copy 1
+  {
+    compare counter/ECX, 10
+    break-if >
+    result/EBX <- add counter/ECX
+    counter/ECX <- add 1
+    loop
+  }
+  call exit, 1
+]
+
+fn exit x : int [
+  code/EBX <- copy x
+  code/EAX <- copy 1/exit
+  syscall
+]
diff --git a/transect/ex4.k2 b/transect/ex4.k2
new file mode 100644
index 00000000..9a7ddee7
--- /dev/null
+++ b/transect/ex4.k2
@@ -0,0 +1,34 @@
+## read a character from stdin, save it to a global, write it to stdout
+
+# variables are always references
+#   read their address with their names: x (can't write to their address)
+#   read/write their contents with a lookup: *x
+var x : char
+
+fn main [
+  call read 0/stdin, x, 1/size
+  result/EAX <- call write 1/stdout, x, 1/size
+  call exit, result/EAX
+]
+
+fn read fd : int, x : (address array byte), size : int [
+  EBX <- copy fd
+  ECX <- copy x
+  EDX <- copy size
+  EAX <- copy 3/read
+  syscall
+]
+
+fn write fd : int, x : (address array byte), size : int [
+  EBX <- copy fd
+  ECX <- copy x
+  EDX <- copy size
+  EAX <- copy 4/write
+  syscall
+]
+
+fn exit x : int [
+  code/EBX <- copy x
+  code/EAX <- copy 1/exit
+  syscall
+]
diff --git a/transect/ex5.k2 b/transect/ex5.k2
new file mode 100644
index 00000000..0d7148fe
--- /dev/null
+++ b/transect/ex5.k2
@@ -0,0 +1,30 @@
+# read a character from stdin, save it to a local on the stack, write it to stdout
+
+fn main [
+  var x : char
+  call read 0/stdin, x, 1/size
+  result/EBX <- call write 1/stdout, x, 1/size
+  call exit-EBX
+]
+
+fn read fd : int, x : (address array byte), size : int [
+  EBX <- copy fd
+  ECX <- copy x
+  EDX <- copy size
+  EAX <- copy 3/read
+  syscall
+]
+
+fn write fd : int, x : (address array byte), size : int [
+  EBX <- copy fd
+  ECX <- copy x
+  EDX <- copy size
+  EAX <- copy 4/write
+  syscall
+]
+
+# like exit, but assumes the code is already in EBX
+fn exit-EBX [
+  code/EAX <- copy 1/exit
+  syscall
+]
diff --git a/transect/ex6.k2 b/transect/ex6.k2
new file mode 100644
index 00000000..cd68f861
--- /dev/null
+++ b/transect/ex6.k2
@@ -0,0 +1,23 @@
+## print out a (global variable) string to stdout
+
+var size : int = 14
+var x : (array character) = "hello, world!"
+
+fn main [
+  call write 1/stdout, x, size
+  call exit, 0
+]
+
+fn write fd : int, x : (address array byte), size : int [
+  EBX <- copy fd
+  ECX <- copy x
+  EDX <- copy size
+  EAX <- copy 4/write
+  syscall
+]
+
+fn exit x : int [
+  code/EBX <- copy x
+  code/EAX <- copy 1/exit
+  syscall
+]
diff --git a/transect/ex7.k2 b/transect/ex7.k2
new file mode 100644
index 00000000..3ede2c5e
--- /dev/null
+++ b/transect/ex7.k2
@@ -0,0 +1,64 @@
+# example showing file syscalls
+#
+# Create a file, open it for writing, write a character to it, close it, open
+# it for reading, read a character from it, close it, delete it, and return
+# the character read.
+
+var stream : int = 0
+var a : char = 97
+var b : char = 0
+var filename : (array char) = ".foo"
+
+fn main [
+  call create, filename
+  *stream <- call open, filename, 1/wronly
+  call write, *stream, a, 1
+  call close, *stream
+  stream <- call open, filename, 0/rdonly
+  call read, *stream, b, 1
+  call close, *stream
+  call unlink, filename
+  var result/EBX : char
+  result/EBX <- copy b  # TODO: copy char to int?
+  call exit-EBX
+]
+
+fn read fd : int, x : (address array byte), size : int [
+  EBX <- copy fd
+  ECX <- copy x
+  EDX <- copy size
+  EAX <- copy 3/read
+  syscall
+]
+
+fn write fd : int, x : (address array byte), size : int [
+  EBX <- copy fd
+  ECX <- copy x
+  EDX <- copy size
+  EAX <- copy 4/write
+  syscall
+]
+
+fn open name : (address array byte) [
+  EBX <- copy name
+  EAX <- copy 5/open
+  syscall
+]
+
+fn close name : (address array byte) [
+  EBX <- copy name
+  EAX <- copy 6/close
+  syscall
+]
+
+fn unlink name : (address array byte) [
+  EBX <- copy name
+  EAX <- copy 10/unlink
+  syscall
+]
+
+# like exit, but assumes the code is already in EBX
+fn exit-EBX [
+  code/EAX <- copy 1/exit
+  syscall
+]
diff --git a/transect/ex8.k2 b/transect/ex8.k2
new file mode 100644
index 00000000..dfef03b0
--- /dev/null
+++ b/transect/ex8.k2
@@ -0,0 +1,36 @@
+# Example reading commandline arguments: compute length of first arg.
+
+fn main argc : int, argv : (array (ref array char)) -> [
+  var tmp : (index char)
+  tmp <- index 1, %size(ref array char)
+  var tmp2 : (address (ref array char))
+  tmp2 <- advance argv, tmp
+  var s/EBX : (ref array char)
+  s/EBX <- copy *tmp2
+  var result/EAX : int
+  result/EAX <- ascii_length s/EBX
+  call exit, result/EAX
+]
+
+fn ascii_length s : (ref array char) -> result : int [
+  var result/EBX : int
+  result/EBX <- copy 0
+  {
+    var tmp0/EDI : (offset char)
+    tmp0/EDI <- index result/EBX, %size(char)
+    var tmp/EDX : (address char)
+    tmp/EDX <- advance *s, tmp0/EDI
+    var c/ECX : char
+    c/ECX <- copy *tmp
+    compare c/ECX, 0
+    break-if-equal
+    loop
+  }
+  return result/EBX
+]
+
+fn exit x : int [
+  code/EBX <- copy x
+  code/EAX <- copy 1/exit
+  syscall
+]
diff --git a/transect/factorial.k2 b/transect/factorial.k2
new file mode 100644
index 00000000..79269773
--- /dev/null
+++ b/transect/factorial.k2
@@ -0,0 +1,16 @@
+# compute the factorial of 5, and return the result in the exit code
+
+fn factorial n : int -> result/EAX : int [
+  result/EAX <- copy 1
+  {
+    compare n, 1
+    break-if <=
+    var tmp/EBX : int
+    tmp/EBX <- copy n
+    tmp/EBX <- subtract 1
+    var tmp2/EAX : int
+    tmp2/EAX <- call factorial, tmp/EBX
+    result/EAX <- multiply tmp2/EAX, n
+  }
+  return result/EAX
+]