commit 23e36ee7be6254d01bee13a7d23db5ebe574e73a
parent 07cb2d7cd9b825c87aec47207073f793be320883
Author: thing1 <l.standen@posteo.com>
Date: Sun, 5 Oct 2025 13:17:58 +0100
added full support for standard unix functions!
Diffstat:
9 files changed, 147 insertions(+), 9 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -2,3 +2,5 @@ lli
lliasm
*.rom
*.so
+*.tar
+*.txt
diff --git a/Makefile b/Makefile
@@ -8,6 +8,8 @@ lliasm: lliasm.c
cc lliasm.c -o lliasm ${CFLAGS}
cores: cores/*
cd cores && make
+tarball:
+ tar -cf lli.tar *
install: all
cp lli lliasm /usr/local/bin
diff --git a/cores/unix_core.c b/cores/unix_core.c
@@ -1,14 +1,64 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
/* table of memory
- * | function | size |
- * ------------------
- * | stdin | 1 |
- * | stdout | 1 |
- * | stderr | 1 |
+ * | function | size | loc |
+ * +----------+------+-----+
+ * | stdin | 1 | 0 |
+ * | stdout | 1 | 1 |
+ * | stderr | 1 | 2 |
+ * | syscall | 1 | 3 |
+ * | arg1 | 4 | 4 |
+ * | arg2 | 4 | 8 |
+ * | arg3 | 4 | 12 |
+ * | arg4 | 4 | 16 |
+ * | result | 4 | 20 |
+ * | fd | 4 | 24 |
+ * | read | 1 | 28 |
+ * | write | 1 | 29 |
*/
+enum syscalls {
+ NOP = 0, // no args
+ OPEN = 1, // path, 0 | 1 | 2 (read | write | append) -> id
+ CLOSE = 2, // id
+ EXIT = 3, // status
+ FORK = 4, // no args -> pid
+};
+
+static void
+dosyscall(uint8_t num, int args[4], char *mem) {
+ int fd, pid;
+ switch (num) {
+ case NOP: return;
+ case OPEN:
+ if (args[1] == 0)
+ fd = open(&mem[args[0]], O_RDONLY);
+ else if (args[1] == 1)
+ fd = open(&mem[args[0]], O_RDWR | O_TRUNC | O_CREAT, 0666);
+ else if (args[1] == 2)
+ fd = open(&mem[args[0]], O_RDWR | O_APPEND | O_CREAT, 0666);
+ if (fd == -1)
+ perror("failed to open file");
+ memcpy(&mem[20], &fd, sizeof(int));
+ break;
+ case CLOSE:
+ close(args[0]);
+ break;
+ case EXIT:
+ exit(args[0]);
+ break;
+ case FORK:
+ pid = fork();
+ memcpy(&mem[20], &pid, sizeof(int));
+ break;
+ }
+}
+
void
onwrite(char *addr) {
if (*(addr + 1)) {
@@ -19,6 +69,25 @@ onwrite(char *addr) {
putc(*(addr + 2), stderr);
*(addr + 2) = 0;
}
+ if (*(addr + 3)) {
+ int args[] = {
+ *(int *)(addr + 4),
+ *(int *)(addr + 8),
+ *(int *)(addr + 12),
+ *(int *)(addr + 16),
+ };
+ dosyscall(*(uint8_t *)(addr + 3), args, addr);
+ *(addr + 3) = 0;
+ *(int *)(addr + 4) = 0;
+ *(int *)(addr + 8) = 0;
+ *(int *)(addr + 12) = 0;
+ *(int *)(addr + 16) = 0;
+ }
+ if (*(addr + 29)) {
+ char c = *(addr + 29);
+ write(*(int *)&addr[24], &c, 1);
+ *(addr + 29) = 0;
+ }
}
void
@@ -26,4 +95,8 @@ onread(char *addr, char *ptr) {
if (ptr == addr) {
*ptr = getc(stdin);
}
+ if (ptr == (addr + 28)) {
+ read(*(int *)&addr[24], (addr + 28), 1);
+ *(addr + 28) = 0;
+ }
}
diff --git a/examples/Makefile b/examples/Makefile
@@ -1,4 +1,4 @@
-all: cat loadprog callstack print conditional
+all: cat loadprog callstack print conditional fs fork
cat: cat.ll
lliasm -o cat.rom cat.ll
@@ -10,6 +10,10 @@ print: print.ll
lliasm -o print.rom print.ll
conditional: conditional.ll
lliasm -o conditional.rom conditional.ll
+fs: fs.ll
+ lliasm -o fs.rom fs.ll
+fork: fork.ll
+ lliasm -o fork.rom fork.ll
clean:
rm -rf *.rom
diff --git a/examples/callstack.ll b/examples/callstack.ll
@@ -1,5 +1,5 @@
|0x0 @stdin |0x1 @stdout |0x2 @stderr
-|0x20 @str "hello b0
+|0x50 @str "hello b0
|0x100 @tester
&str loadb &stdout storeb
diff --git a/examples/fork.ll b/examples/fork.ll
@@ -0,0 +1,38 @@
+(unix core) |0x0 @stdin |0x1 @stdout |0x2 @stderr |0x3 @syscall |0x4 @arg1 |0x8 @arg2 |0xc @arg3 |0x10 @arg4 |0x14 @result |0x18 @fd |0x1c @read |0x1d @write
+
+|0x100 @file "test.txt b0
+
+@parent (writes the letter A to the file marked at @file)
+&file &arg1 storei (opens the file)
+#1 &arg2 storei
+#1 i2b &syscall storeb
+
+&result loadi (gets the fd)
+&fd storei
+
+#65 i2b &write storeb (write the letter)
+
+&fd loadi &arg1 storei (close the file)
+#2 i2b &syscall storeb
+ret
+
+@child (writes the letter B to stdout)
+#66 i2b &stdout storeb (writes to stdout)
+ret
+
+(main) |0x1000
+#4 i2b &syscall storeb
+
+&result loadi
+#0 neq (if fork != 0)
+&true jnz
+&false jmp
+@true (fork != 0)
+ &parent call
+ &end jmp
+@false (fork == 0)
+ &child call
+ &end jmp
+@end
+
+halt
diff --git a/examples/fs.ll b/examples/fs.ll
@@ -0,0 +1,19 @@
+(unix core) |0x0 @stdin |0x1 @stdout |0x2 @stderr |0x3 @syscall |0x4 @arg1 |0x8 @arg2 |0xc @arg3 |0x10 @arg4 |0x14 @result |0x18 @fd |0x1c @read |0x1d @write
+
+|0x100 @file "test.txt b0
+
+(main) |0x1000
+&file &arg1 storei (load the address of file name)
+#1 &arg2 storei (load the open mode)
+#1 i2b &syscall storeb (open the file)
+
+&result loadi (move the fd to the fd register)
+&fd storei
+
+#65 i2b &write storeb
+
+&fd loadi
+&arg1 storei
+#2 i2b &syscall storeb
+
+halt
diff --git a/examples/print.ll b/examples/print.ll
@@ -1,5 +1,5 @@
|0x0 @stdin |0x1 @stdout |0x2 @stderr (define stdin, stdout and error)
-|0x10 @str "hello b32 "world b10 b0 (define the string to print, the b32, b10, and b0 are ascii for ' ', '\n' and '\0')
+|0x50 @str "hello b32 "world b10 b0 (define the string to print, the b32, b10, and b0 are ascii for ' ', '\n' and '\0')
|0x100 @print (define a print function)
dupi (duplicate the input address, so it stays on the stack for the next call)
diff --git a/lliasm.c b/lliasm.c
@@ -64,7 +64,7 @@ readword(char *in) {
if (!in) input = NULL;
else input = in;
- char *tok = strtok(input, " \n\0");
+ char *tok = strtok(input, " \t\n\0");
while (tok && *tok && isblank(*tok)) tok++;
return tok;
}