diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/getc.c | 131 | ||||
| -rw-r--r-- | tests/new_arrays.c | 31 | ||||
| -rw-r--r-- | tests/printf.c | 164 | ||||
| -rw-r--r-- | tests/syscalls.c | 30 |
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; +} |
