From f09280141f18fbe8cef0ed576cf932e12e315666 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 17 Sep 2018 22:57:10 -0700 Subject: 4548: start of a compiler for a new experimental low-level language --- subx/apps/factorial.k2 | 21 +++++++++++++++++++++ subx/examples/ex3.k2 | 20 ++++++++++++++++++++ subx/examples/ex4.k2 | 17 +++++++++++++++++ subx/examples/ex5.k2 | 12 ++++++++++++ subx/examples/ex6.k2 | 13 +++++++++++++ subx/examples/ex7.k2 | 24 ++++++++++++++++++++++++ subx/examples/ex8.k2 | 41 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 148 insertions(+) create mode 100644 subx/apps/factorial.k2 create mode 100644 subx/examples/ex3.k2 create mode 100644 subx/examples/ex4.k2 create mode 100644 subx/examples/ex5.k2 create mode 100644 subx/examples/ex6.k2 create mode 100644 subx/examples/ex7.k2 create mode 100644 subx/examples/ex8.k2 (limited to 'subx') 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 +] -- cgit 1.4.1-2-gfad0