From 2fef6981954df735f1f364e96c365c6f000a638b Mon Sep 17 00:00:00 2001 From: pommicket Date: Sun, 13 Feb 2022 15:07:26 -0500 Subject: first C hello world! --- 05/codegen.b | 4 +-- 05/constants.b | 3 ++ 05/main.c | 85 +++++++++++++++++++++++++++++---------------------------- 05/parse.b | 4 ++- 05/preprocess.b | 6 ++++ 05/stdarg.h | 4 +++ 6 files changed, 61 insertions(+), 45 deletions(-) create mode 100644 05/stdarg.h (limited to '05') diff --git a/05/codegen.b b/05/codegen.b index d33eb3e..d42d097 100644 --- a/05/codegen.b +++ b/05/codegen.b @@ -762,7 +762,6 @@ function generate_cast_top_of_stack if *1to == TYPE_VOID goto gen_cast_to_void if *1from == TYPE_VOID goto bad_gen_cast ; cast from void to something - that's bad - if *1from == TYPE_ARRAY goto bad_gen_cast ; cast array (this probably won't ever happen because of decaying) if *1to == TYPE_ARRAY goto bad_gen_cast ; cast to array if *1from == TYPE_FUNCTION goto bad_gen_cast ; shouldn't happen if *1to == TYPE_FUNCTION goto bad_gen_cast ; shouldn't happen @@ -793,6 +792,7 @@ function generate_cast_top_of_stack emit_add_rsp_imm32(c) return :gen_cast_to_integer + if *1from == TYPE_ARRAY goto return_0 ; e.g. (void *)"hello" if *1from == *1to goto return_0 ; casting from type to same type if *1from == TYPE_POINTER goto return_0 ; no need to do anything ; cast float/double to integer @@ -3001,7 +3001,7 @@ function generate_code ; program header 3 (rwdata) emit_dword(1) ; loadable segment - emit_dword(6) ; read/write + emit_dword(7) ; read/write/execute (this needs to be executable for `syscall` to be implementable) emit_qword(RWDATA_ADDR) ; offset in file emit_qword(RWDATA_ADDR) ; virtual address emit_qword(0) ; physical address diff --git a/05/constants.b b/05/constants.b index 7bcc2aa..c4c4676 100644 --- a/05/constants.b +++ b/05/constants.b @@ -536,6 +536,9 @@ :str_comment_end string */ byte 0 +:str_one_line_comment + string // + byte 0 :str_lshift_eq string <<= byte 0 diff --git a/05/main.c b/05/main.c index 6c19317..fc4b036 100644 --- a/05/main.c +++ b/05/main.c @@ -1,49 +1,50 @@ -typedef unsigned long va_list; -#define va_start(list, arg) ((list) = (unsigned long)&arg) -#define va_arg(list, type) (*((type *)(list += ((sizeof(type) + 7) & 0xfffffffffffffff8)))) -#define va_end(list) +static unsigned char __syscall_data[] = { + // mov rax, [rsp+24] + 0x48, 0x8b, 0x84, 0x24, 24, 0, 0, 0, + // mov rdi, rax + 0x48, 0x89, 0xc7, + // mov rax, [rsp+32] + 0x48, 0x8b, 0x84, 0x24, 32, 0, 0, 0, + // mov rsi, rax + 0x48, 0x89, 0xc6, + // mov rax, [rsp+40] + 0x48, 0x8b, 0x84, 0x24, 40, 0, 0, 0, + // mov rdx, rax + 0x48, 0x89, 0xc2, + // mov rax, [rsp+48] + 0x48, 0x8b, 0x84, 0x24, 48, 0, 0, 0, + // mov r10, rax + 0x49, 0x89, 0xc2, + // mov rax, [rsp+56] + 0x48, 0x8b, 0x84, 0x24, 56, 0, 0, 0, + // mov r8, rax + 0x49, 0x89, 0xc0, + // mov rax, [rsp+64] + 0x48, 0x8b, 0x84, 0x24, 64, 0, 0, 0, + // mov r9, rax + 0x49, 0x89, 0xc1, + // mov rax, [rsp+16] + 0x48, 0x8b, 0x84, 0x24, 16, 0, 0, 0, + // syscall + 0x0f, 0x05, + // mov [rsp+8], rax + 0x48, 0x89, 0x84, 0x24, 8, 0, 0, 0, + // ret + 0xc3 +}; -int sum(int n, ...) { - va_list args; - int i; - int total = 0; - va_start(args, n); - for (i = 0; i < n; ++i) { - total += va_arg(args, int); - } - return total; -} - -long factorial(long x) { - if (x == 0) { - return 1; - } else { - return x * factorial(x-1); - } -} +#define __syscall(no, arg1, arg2, arg3, arg4, arg5, arg6)\ + (((unsigned long (*)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long))__syscall_data)\ + (no, arg1, arg2, arg3, arg4, arg5, arg6)) -long fibonacci(long x) { - return x > 0 ? - x > 1 ? - fibonacci(x-1) + fibonacci(x-2) - : 1 - : 0; -} - -long gcd(long a, long b) { - while (a != 0) { - long temp = a; - a = b % a; - b = temp; - } - return b; -} +typedef unsigned long size_t; -int f() { - lb: goto lb; +long write(int fd, void *buf, size_t count) { + __syscall(1, fd, buf, count, 0, 0, 0); } -int main(int argc, char **argv) { - return sum(3, -100, 200, -300); +int main(int argc, char **argv) { + write(1, "Hello, world!\n", 14); + return 0; } diff --git a/05/parse.b b/05/parse.b index 52c8d4a..4373680 100644 --- a/05/parse.b +++ b/05/parse.b @@ -323,7 +323,9 @@ function parse_toplevel_declaration ident_list_add(functions_required_stack_space, f_name, curr_function_stack_space) - ;print_statement(out0) + ; ENABLE/DISABLE PARSING DEBUG OUTPUT: + print_statement(out0) + goto parse_tld_ret :function_no_param_name diff --git a/05/preprocess.b b/05/preprocess.b index 9a7dd5c..2a94119 100644 --- a/05/preprocess.b +++ b/05/preprocess.b @@ -88,6 +88,8 @@ function split_into_preprocessing_tokens if b != 0 goto pptoken_number b = isalpha_or_underscore(c) if b != 0 goto pptoken_identifier + b = str_startswith(in, .str_one_line_comment) + if b != 0 goto pptoken_one_line_comment b = str_startswith(in, .str_comment_start) if b != 0 goto pptoken_comment ; now we check for all the various operators and symbols in C @@ -169,6 +171,10 @@ function split_into_preprocessing_tokens ; " each non-white-space character that cannot be one of the above" goto pptoken_single_character + :pptoken_one_line_comment + ; skip over comment + in = memchr(in, 10) + goto pptokens_loop :pptoken_comment ; emit a space ("Each comment is replaced by one space character.") *1out = 32 diff --git a/05/stdarg.h b/05/stdarg.h new file mode 100644 index 0000000..68fcd8e --- /dev/null +++ b/05/stdarg.h @@ -0,0 +1,4 @@ +typedef unsigned long va_list; +#define va_start(list, arg) ((list) = (unsigned long)&arg) +#define va_arg(list, type) (*((type *)(list += ((sizeof(type) + 7) & 0xfffffffffffffff8)))) +#define va_end(list) -- cgit v1.2.3