about summary refs log tree commit diff stats
path: root/subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-09-17 22:57:10 -0700
committerKartik Agaram <vc@akkartik.com>2018-09-17 22:57:58 -0700
commitf09280141f18fbe8cef0ed576cf932e12e315666 (patch)
treed00962b07cb013f89d4fdb2fcf19c392afb62b5c /subx
parent0a7b03727a736f73c16d37b22afef8496c60d657 (diff)
downloadmu-f09280141f18fbe8cef0ed576cf932e12e315666.tar.gz
4548: start of a compiler for a new experimental low-level language
Diffstat (limited to 'subx')
-rw-r--r--subx/apps/factorial.k221
-rw-r--r--subx/examples/ex3.k220
-rw-r--r--subx/examples/ex4.k217
-rw-r--r--subx/examples/ex5.k212
-rw-r--r--subx/examples/ex6.k213
-rw-r--r--subx/examples/ex7.k224
-rw-r--r--subx/examples/ex8.k241
7 files changed, 148 insertions, 0 deletions
diff --git a/subx/apps/factorial.k2 b/subx/apps/factorial.k2
new file mode 100644
index 00000000..82c44352
--- /dev/null
+++ b/subx/apps/factorial.k2
@@ -0,0 +1,21 @@
+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
+]
+
+data structures:
+
+add entry for "factorial" into the Types table, with value (fn int -> int)
+add entry for "factorial" into the address table, with value next available address
+add entry for "factorial" into the size table, with value size of "0b 0a bb ..."
+increase next available address by size of "factorial"
diff --git a/subx/examples/ex3.k2 b/subx/examples/ex3.k2
new file mode 100644
index 00000000..aa17ac7b
--- /dev/null
+++ b/subx/examples/ex3.k2
@@ -0,0 +1,20 @@
+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/subx/examples/ex4.k2 b/subx/examples/ex4.k2
new file mode 100644
index 00000000..ad968eaf
--- /dev/null
+++ b/subx/examples/ex4.k2
@@ -0,0 +1,17 @@
+# 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  # watch out; reading a global may not be possible in all instructions
+                                # but the address is more easily obtained
+  result/EAX <- call write 1/stdout, x, 1/size
+  call exit, result/EAX
+]
+
+fn exit x : int [
+  code/EBX <- copy x
+  code/EAX <- copy 1/exit
+  syscall
+]
diff --git a/subx/examples/ex5.k2 b/subx/examples/ex5.k2
new file mode 100644
index 00000000..79920614
--- /dev/null
+++ b/subx/examples/ex5.k2
@@ -0,0 +1,12 @@
+fn main [
+  var x : char
+  call read 0/stdin, x, 1/size
+  result/EBX <- call write 1/stdout, x, 1/size
+  call exit-EBX
+]
+
+# like exit, but assumes the code is already in EBX
+fn exit-EBX [
+  code/EAX <- copy 1/exit
+  syscall
+]
diff --git a/subx/examples/ex6.k2 b/subx/examples/ex6.k2
new file mode 100644
index 00000000..d9b54dd4
--- /dev/null
+++ b/subx/examples/ex6.k2
@@ -0,0 +1,13 @@
+var size : int = 14
+var x : (array character) = "hello, world!"
+
+fn main [
+  call write 1/stdout, x, size
+  call exit, 0
+]
+
+fn exit x : int [
+  code/EBX <- copy x
+  code/EAX <- copy 1/exit
+  syscall
+]
diff --git a/subx/examples/ex7.k2 b/subx/examples/ex7.k2
new file mode 100644
index 00000000..515c5c12
--- /dev/null
+++ b/subx/examples/ex7.k2
@@ -0,0 +1,24 @@
+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
+]
+
+# like exit, but assumes the code is already in EBX
+fn exit-EBX [
+  code/EAX <- copy 1/exit
+  syscall
+]
diff --git a/subx/examples/ex8.k2 b/subx/examples/ex8.k2
new file mode 100644
index 00000000..f6c359f7
--- /dev/null
+++ b/subx/examples/ex8.k2
@@ -0,0 +1,41 @@
+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
+]
+
+# must 
+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
+      => compare (ESP+4), *(ESP+8)  ; '*' from compiler2
+         jump-unless-equal panic
+         EDX <- add ESP, 8
+         EDX <- copy *EDX
+         EDX <- add EDX, 4
+         EDX <- 8d/lea EDX + result
+    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
+]