summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/getc.c131
-rw-r--r--tests/new_arrays.c31
-rw-r--r--tests/printf.c164
-rw-r--r--tests/syscalls.c30
4 files changed, 356 insertions, 0 deletions
diff --git a/tests/getc.c b/tests/getc.c
new file mode 100644
index 0000000..ef3b860
--- /dev/null
+++ b/tests/getc.c
@@ -0,0 +1,131 @@
+int g_passed = 0;
+int g_failed = 0;
+
+int getc() {
+ char c;
+ int n = syscall(0, 0, &c, 1);
+ if (n <= 0) return -1;
+ return (int)c;
+}
+
+int write_char(int c) {
+ char b;
+ b = (char)c;
+ syscall(1, 1, &b, 1);
+ return 1;
+}
+
+int write_str(char *s) {
+ int n = 0;
+ while (s[n] != 0) n++;
+ syscall(1, 1, s, n);
+ return n;
+}
+
+int write_int(int n) {
+ char tmp[24];
+ int len = 0;
+ int neg = n < 0;
+ if (neg) { write_char('-'); n = -n; }
+ if (n == 0) { write_char('0'); return 1; }
+ while (n > 0) { tmp[len] = (char)('0' + n % 10); n = n / 10; len++; }
+ int i = len - 1;
+ while (i >= 0) { write_char(tmp[i]); i--; }
+ return neg + len;
+}
+
+int check(char *name, int got, int want) {
+ if (got == want) {
+ write_str("PASS "); write_str(name); write_char('\n');
+ g_passed++;
+ return 1;
+ }
+ write_str("FAIL "); write_str(name);
+ write_str(": got "); write_int(got);
+ write_str(" want "); write_int(want);
+ write_char('\n');
+ g_failed++;
+ return 0;
+}
+
+int read_line(char *buf, int cap) {
+ int i = 0;
+ int c;
+ while (i < cap - 1) {
+ c = getc();
+ if (c == -1 || c == '\n') break;
+ buf[i] = (char)c;
+ i++;
+ }
+ buf[i] = 0;
+ return i;
+}
+
+int test1() {
+ int c = getc();
+ int result = c;
+ while (c != '\n' && c != -1) c = getc();
+ return check("single_char_is_65", result, 65);
+}
+
+int test2() {
+ char buf[64];
+ int n = read_line(buf, 64);
+ write_str(buf); write_char('\n');
+ return check("readline_length", n, 5);
+}
+
+int test3() {
+ int newlines = 0;
+ int c;
+ while (newlines < 2) {
+ c = getc();
+ if (c == -1) break;
+ if (c == '\n') newlines++;
+ }
+ return check("count_lines", newlines, 2);
+}
+
+int test4() {
+ int value = 0;
+ int c;
+ while (1) {
+ c = getc();
+ if (c < '0' || c > '9') break;
+ value = value * 10 + (c - '0');
+ }
+ return check("parse_int", value, 42);
+}
+
+int test5() {
+ char buf[64];
+ int n = read_line(buf, 64);
+ int i = 0;
+ while (i < n) {
+ char ch = buf[i];
+ if (ch >= 'a' && ch <= 'z') buf[i] = ch - 'a' + 'A';
+ i++;
+ }
+ write_str(buf); write_char('\n');
+ return check("toupper_length", n, 5);
+}
+
+int test6() {
+ int c = getc();
+ return check("eof_is_minus1", c, -1);
+}
+
+int main() {
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ test6();
+
+ write_char('\n');
+ write_int(g_passed); write_str(" passed, ");
+ write_int(g_failed); write_str(" failed\n");
+
+ return g_failed == 0 ? 0 : 1;
+}
diff --git a/tests/new_arrays.c b/tests/new_arrays.c
new file mode 100644
index 0000000..5b7b59b
--- /dev/null
+++ b/tests/new_arrays.c
@@ -0,0 +1,31 @@
+int strlen_p(char *s) {
+ int n = 0;
+ while (s[n] != 0) { n = n + 1; }
+ return n;
+}
+
+int sum(int *arr, int n) {
+ int s = 0;
+ int i = 0;
+ while (i < n) { s += arr[i]; i++; }
+ return s;
+}
+
+int main() {
+ int nums[5] = {10, 20, 30, 40, 50};
+ int total = sum(nums, 5);
+
+ char msg[4] = {'O', 'K', '\n', 0};
+ syscall(1, 1, msg, 3);
+
+ int *p = nums;
+ p += 2;
+ int mid = *p;
+
+ int n = sizeof(nums);
+ int c = sizeof(char);
+ int ip = sizeof(int);
+
+ int score = (total == 150) + (mid == 30) + (n == 20) + (c == 1) + (ip == 4);
+ return score;
+}
diff --git a/tests/printf.c b/tests/printf.c
new file mode 100644
index 0000000..fc0d68d
--- /dev/null
+++ b/tests/printf.c
@@ -0,0 +1,164 @@
+char out_buf[4096];
+int out_pos = 0;
+
+int buf_putc(char c) {
+ out_buf[out_pos] = c;
+ out_pos++;
+ if (out_pos >= 4096) {
+ syscall(1, 1, out_buf, out_pos);
+ out_pos = 0;
+ }
+ return 1;
+}
+
+int buf_flush() {
+ if (out_pos > 0) {
+ syscall(1, 1, out_buf, out_pos);
+ out_pos = 0;
+ }
+ return 0;
+}
+
+
+int my_strlen(char *s) {
+ int n = 0;
+ while (s[n] != 0) { n++; }
+ return n;
+}
+
+int print_str(char *s) {
+ int i = 0;
+ while (s[i] != 0) { buf_putc(s[i]); i++; }
+ return i;
+}
+
+
+int print_int(int n) {
+ char tmp[24];
+ int len = 0;
+ int neg = n < 0;
+ if (neg) { buf_putc('-'); n = -n; }
+ if (n == 0) { buf_putc('0'); return neg + 1; }
+ while (n > 0) {
+ tmp[len] = (char)('0' + n % 10);
+ n = n / 10;
+ len++;
+ }
+
+ int i = len - 1;
+ while (i >= 0) { buf_putc(tmp[i]); i--; }
+ return neg + len;
+}
+
+
+int print_hex(int n) {
+ char hex[16] = {'0','1','2','3','4','5','6','7',
+ '8','9','a','b','c','d','e','f'};
+ if (n == 0) { buf_putc('0'); return 1; }
+ char tmp[18];
+ int len = 0;
+ int u = n;
+ while (u != 0) {
+ tmp[len] = hex[u & 15];
+ u = u / 16;
+ len++;
+ }
+ int i = len - 1;
+ while (i >= 0) { buf_putc(tmp[i]); i--; }
+ return len;
+}
+
+
+int my_printf(char *fmt, int a, int b, int c) {
+ int arg_idx = 0;
+ int i = 0;
+ int total = 0;
+ while (fmt[i] != 0) {
+ if (fmt[i] != '%') {
+ buf_putc(fmt[i]);
+ total++;
+ i++;
+ continue;
+ }
+ i++; /* skip '%' */
+ int arg = arg_idx == 0 ? a : (arg_idx == 1 ? b : c);
+ arg_idx++;
+ if (fmt[i] == 'd') {
+ total += print_int(arg);
+ } else if (fmt[i] == 's') {
+ total += print_str((char*)arg);
+ } else if (fmt[i] == 'c') {
+ buf_putc((char)arg);
+ total++;
+ } else if (fmt[i] == 'x') {
+ total += print_hex(arg);
+ } else if (fmt[i] == '%') {
+ buf_putc('%');
+ total++;
+ arg_idx--; /* %% doesn't consume an arg */
+ } else {
+ buf_putc('%'); buf_putc(fmt[i]);
+ total += 2;
+ }
+ i++;
+ }
+ return total;
+}
+
+
+int fact(int n) {
+ return n <= 1 ? 1 : n * fact(n - 1);
+}
+
+int fib(int n) {
+ if (n <= 1) return n;
+ return fib(n - 1) + fib(n - 2);
+}
+
+int main() {
+ my_printf("=== JIT printf demo ===\n", 0, 0, 0);
+
+ my_printf("Hello, %s!\n", "world", 0, 0);
+ my_printf("int: %d neg: %d\n", 42, -7, 0);
+ my_printf("hex: 0x%x\n", 255, 0, 0);
+ my_printf("char: %c\n", 'A', 0, 0);
+ my_printf("percent: 100%%\n", 0, 0, 0);
+
+ my_printf("\nFactorials:\n", 0, 0, 0);
+ int i = 1;
+ while (i <= 8) {
+ my_printf(" %d! = %d\n", i, fact(i), 0);
+ i++;
+ }
+
+ my_printf("\nFibonacci:\n ", 0, 0, 0);
+ i = 0;
+ while (i < 10) {
+ my_printf("%d ", fib(i), 0, 0);
+ i++;
+ }
+ my_printf("\n", 0, 0, 0);
+
+
+ my_printf("\nCountdown: ", 0, 0, 0);
+ int n = 5;
+ do {
+ my_printf("%d ", n, 0, 0);
+ n--;
+ } while (n > 0);
+ my_printf("\n", 0, 0, 0);
+
+
+ my_printf("Odd 1-9: ", 0, 0, 0);
+ i = 0;
+ while (i < 10) {
+ i++;
+ if (i % 2 == 0) continue;
+ my_printf("%d ", i, 0, 0);
+ if (i == 9) break;
+ }
+ my_printf("\n", 0, 0, 0);
+
+ buf_flush();
+ return 0;
+}
diff --git a/tests/syscalls.c b/tests/syscalls.c
new file mode 100644
index 0000000..285e539
--- /dev/null
+++ b/tests/syscalls.c
@@ -0,0 +1,30 @@
+int strlen(char *s) {
+ int n = 0;
+ while (s[n] != 0) { n = n + 1; }
+ return n;
+}
+
+int puts_fd(int fd, char *s) {
+ return syscall(1, fd, s, strlen(s));
+}
+
+int main() {
+ puts_fd(1, "Hello from JIT syscall!\n");
+
+ int pid = syscall(39);
+ int pid_ok = pid > 0;
+
+ char msg[32];
+ msg[0] = 'P'; msg[1] = 'I'; msg[2] = 'D'; msg[3] = ' ';
+ msg[4] = 'o'; msg[5] = 'k'; msg[6] = ':'; msg[7] = ' ';
+ msg[8] = '0' + pid_ok;
+ msg[9] = '\n';
+ syscall(1, 1, msg, 10);
+
+ int n1 = syscall(1, 1, "write test 1\n", 13);
+ int n2 = syscall(1, 1, "write test 2\n", 13);
+
+ int result = pid_ok + (n1 == 13) + (n2 == 13);
+
+ return result;
+}