From c8e5a5b5ebe61bbab1adb61ea1f12b5096fdc3b9 Mon Sep 17 00:00:00 2001 From: Keyvan Kambakhsh Date: Sat, 30 Nov 2024 01:59:18 +0330 Subject: [PATCH] test: Add test for varargs --- examples/inp_vararg.c | 45 ++++++ tests/output/inp_vararg.c_asm_output.asm | 136 +++++++++++++++++ tests/output/inp_vararg.c_lex_output.txt | 170 ++++++++++++++++++++++ tests/output/inp_vararg.c_prep_output.txt | 128 ++++++++++++++++ tests/output/inp_vararg.c_tree_output.txt | 110 ++++++++++++++ 5 files changed, 589 insertions(+) create mode 100644 examples/inp_vararg.c create mode 100644 tests/output/inp_vararg.c_asm_output.asm create mode 100644 tests/output/inp_vararg.c_lex_output.txt create mode 100644 tests/output/inp_vararg.c_prep_output.txt create mode 100644 tests/output/inp_vararg.c_tree_output.txt diff --git a/examples/inp_vararg.c b/examples/inp_vararg.c new file mode 100644 index 0000000..819afa2 --- /dev/null +++ b/examples/inp_vararg.c @@ -0,0 +1,45 @@ +void *malloc(int); +void printf(char *, ...); +void sprintf(char *, char *, ...); + +#define PUSHARGS() __asm__("push rdi" \ + "push rsi" \ + "push rdx" \ + "push rcx" \ + "push r8" \ + "push r9") +#define SLARGS() __asm__("mov rdi, rsi" \ + "mov rsi, rdx" \ + "mov rdx, rcx" \ + "mov rcx, r8" \ + "mov r8, r9" \ + "mov r9, 0") +#define SRARGS() __asm__("mov r9, r8" \ + "mov r8, rcx" \ + "mov rcx, rdx" \ + "mov rdx, rsi" \ + "mov rsi, rdi" \ + "mov rdi, 0") +#define POPARGS() __asm__("pop r9" \ + "pop r8" \ + "pop rcx" \ + "pop rdx" \ + "pop rsi" \ + "pop rdi") + +char *cc_asprintf(char *inp, ...) +{ + SRARGS(); + PUSHARGS(); + char *ret = (char *)malloc(128); + POPARGS(); + sprintf(ret, inp); + return ret; +} + +int main() +{ + char *ret = cc_asprintf("salam %s %u%c", "donya", 123, '!'); + printf("%s %s\n", "haha", ret); + return 0; +} \ No newline at end of file diff --git a/tests/output/inp_vararg.c_asm_output.asm b/tests/output/inp_vararg.c_asm_output.asm new file mode 100644 index 0000000..7faf1d6 --- /dev/null +++ b/tests/output/inp_vararg.c_asm_output.asm @@ -0,0 +1,136 @@ +section .data +__cc_asprintf_size: equ 112 +__temp_str_1 db `salam %s %u%c`, 0 +__temp_str_2 db `donya`, 0 +__temp_str_3 db `%s %s\n`, 0 +__temp_str_4 db `haha`, 0 +__main_size: equ 96 +section .text +extern malloc +extern printf +extern sprintf +global cc_asprintf +cc_asprintf: +push rbp +mov rbp, rsp +sub rsp, __cc_asprintf_size +mov [rbp-8], rdi +mov r9, r8 +mov r8, rcx +mov rcx, rdx +mov rdx, rsi +mov rsi, rdi +mov rdi, 0 +push rdi +push rsi +push rdx +push rcx +push r8 +push r9 +mov rax, 128 +mov [rbp-24], rax +mov rdi, [rbp-24] +mov rax, rbp +sub rax, 8 +mov [rbp-32], rax +call malloc +mov [rbp-40], rax +xor rax, rax +mov [rbp-48], rax +mov rax, [rbp-40] +mov [rbp-48], rax +;define variable ret +mov rax, [rbp-48] +mov [rbp-16], rax +;end define variable ret +pop r9 +pop r8 +pop rcx +pop rdx +pop rsi +pop rdi +mov rax, rbp +sub rax, 16 +mov [rbp-56], rax +mov rax, [rbp-16] +mov [rbp-64], rax +mov rax, rbp +sub rax, 8 +mov [rbp-72], rax +mov rax, [rbp-8] +mov [rbp-80], rax +mov rdi, [rbp-64] +mov rsi, [rbp-80] +mov rax, rbp +sub rax, 8 +mov [rbp-88], rax +call sprintf +mov rax, rbp +sub rax, 16 +mov [rbp-96], rax +mov rax, [rbp-16] +mov rsp, rbp +pop rbp +ret +mov rsp, rbp +pop rbp +ret +global main +main: +push rbp +mov rbp, rsp +sub rsp, __main_size +mov rax, __temp_str_1 +mov [rbp-16], rax +mov rax, __temp_str_2 +mov [rbp-24], rax +mov rax, 123 +mov [rbp-32], rax +mov al, 33 +mov [rbp-33], al +mov rdi, [rbp-16] +mov rsi, [rbp-24] +mov rdx, [rbp-32] +mov rcx, [rbp-33] +mov rax, rbp +sub rax, 8 +mov [rbp-41], rax +call cc_asprintf +mov [rbp-49], rax +;define variable ret +mov rax, [rbp-49] +mov [rbp-8], rax +;end define variable ret +mov rax, __temp_str_3 +mov [rbp-57], rax +mov rax, __temp_str_4 +mov [rbp-65], rax +mov rax, rbp +sub rax, 8 +mov [rbp-73], rax +mov rax, [rbp-8] +mov [rbp-81], rax +mov rdi, [rbp-57] +mov rsi, [rbp-65] +mov rdx, [rbp-81] +mov rax, rbp +sub rax, 8 +mov [rbp-89], rax +call printf +mov rax, 0 +mov rsp, rbp +pop rbp +ret +mov rsp, rbp +pop rbp +ret +extern exit +global _start +_start: +; Pass argc and argv +mov rdi, [rsp] +mov rsi, rsp +add rsi, 8 +call main +mov rdi, rax +call exit diff --git a/tests/output/inp_vararg.c_lex_output.txt b/tests/output/inp_vararg.c_lex_output.txt new file mode 100644 index 0000000..8f4b549 --- /dev/null +++ b/tests/output/inp_vararg.c_lex_output.txt @@ -0,0 +1,170 @@ +TKN_VOID +TKN_STAR +TKN_ID(malloc) +TKN_L_PAREN +TKN_INT +TKN_R_PAREN +TKN_SEMICOLON +TKN_VOID +TKN_ID(printf) +TKN_L_PAREN +TKN_CHAR +TKN_STAR +TKN_COMMA +TKN_DOTS +TKN_R_PAREN +TKN_SEMICOLON +TKN_VOID +TKN_ID(sprintf) +TKN_L_PAREN +TKN_CHAR +TKN_STAR +TKN_COMMA +TKN_CHAR +TKN_STAR +TKN_COMMA +TKN_DOTS +TKN_R_PAREN +TKN_SEMICOLON +TKN_DIRECTIVE: + TKN_ID(define) + TKN_ID(PUSHARGS) + TKN_L_PAREN + TKN_R_PAREN + TKN_ASM + TKN_L_PAREN + TKN_LIT_STR(push rdi) + TKN_LIT_STR(push rsi) + TKN_LIT_STR(push rdx) + TKN_LIT_STR(push rcx) + TKN_LIT_STR(push r8) + TKN_LIT_STR(push r9) + TKN_R_PAREN + TKN_EOF +TKN_DIRECTIVE: + TKN_ID(define) + TKN_ID(SLARGS) + TKN_L_PAREN + TKN_R_PAREN + TKN_ASM + TKN_L_PAREN + TKN_LIT_STR(mov rdi, rsi) + TKN_LIT_STR(mov rsi, rdx) + TKN_LIT_STR(mov rdx, rcx) + TKN_LIT_STR(mov rcx, r8) + TKN_LIT_STR(mov r8, r9) + TKN_LIT_STR(mov r9, 0) + TKN_R_PAREN + TKN_EOF +TKN_DIRECTIVE: + TKN_ID(define) + TKN_ID(SRARGS) + TKN_L_PAREN + TKN_R_PAREN + TKN_ASM + TKN_L_PAREN + TKN_LIT_STR(mov r9, r8) + TKN_LIT_STR(mov r8, rcx) + TKN_LIT_STR(mov rcx, rdx) + TKN_LIT_STR(mov rdx, rsi) + TKN_LIT_STR(mov rsi, rdi) + TKN_LIT_STR(mov rdi, 0) + TKN_R_PAREN + TKN_EOF +TKN_DIRECTIVE: + TKN_ID(define) + TKN_ID(POPARGS) + TKN_L_PAREN + TKN_R_PAREN + TKN_ASM + TKN_L_PAREN + TKN_LIT_STR(pop r9) + TKN_LIT_STR(pop r8) + TKN_LIT_STR(pop rcx) + TKN_LIT_STR(pop rdx) + TKN_LIT_STR(pop rsi) + TKN_LIT_STR(pop rdi) + TKN_R_PAREN + TKN_EOF +TKN_CHAR +TKN_STAR +TKN_ID(cc_asprintf) +TKN_L_PAREN +TKN_CHAR +TKN_STAR +TKN_ID(inp) +TKN_COMMA +TKN_DOTS +TKN_R_PAREN +TKN_L_BRACE +TKN_ID(SRARGS) +TKN_L_PAREN +TKN_R_PAREN +TKN_SEMICOLON +TKN_ID(PUSHARGS) +TKN_L_PAREN +TKN_R_PAREN +TKN_SEMICOLON +TKN_CHAR +TKN_STAR +TKN_ID(ret) +TKN_ASSIGN +TKN_L_PAREN +TKN_CHAR +TKN_STAR +TKN_R_PAREN +TKN_ID(malloc) +TKN_L_PAREN +TKN_LIT_INT(128) +TKN_R_PAREN +TKN_SEMICOLON +TKN_ID(POPARGS) +TKN_L_PAREN +TKN_R_PAREN +TKN_SEMICOLON +TKN_ID(sprintf) +TKN_L_PAREN +TKN_ID(ret) +TKN_COMMA +TKN_ID(inp) +TKN_R_PAREN +TKN_SEMICOLON +TKN_RETURN +TKN_ID(ret) +TKN_SEMICOLON +TKN_R_BRACE +TKN_INT +TKN_ID(main) +TKN_L_PAREN +TKN_R_PAREN +TKN_L_BRACE +TKN_CHAR +TKN_STAR +TKN_ID(ret) +TKN_ASSIGN +TKN_ID(cc_asprintf) +TKN_L_PAREN +TKN_LIT_STR(salam %s %u%c) +TKN_COMMA +TKN_LIT_STR(donya) +TKN_COMMA +TKN_LIT_INT(123) +TKN_COMMA +TKN_LIT_CHAR(!) +TKN_R_PAREN +TKN_SEMICOLON +TKN_ID(printf) +TKN_L_PAREN +TKN_LIT_STR(%s %s +) +TKN_COMMA +TKN_LIT_STR(haha) +TKN_COMMA +TKN_ID(ret) +TKN_R_PAREN +TKN_SEMICOLON +TKN_RETURN +TKN_LIT_INT(0) +TKN_SEMICOLON +TKN_R_BRACE +TKN_EOF diff --git a/tests/output/inp_vararg.c_prep_output.txt b/tests/output/inp_vararg.c_prep_output.txt new file mode 100644 index 0000000..c455d04 --- /dev/null +++ b/tests/output/inp_vararg.c_prep_output.txt @@ -0,0 +1,128 @@ +TKN_VOID +TKN_STAR +TKN_ID(malloc) +TKN_L_PAREN +TKN_INT +TKN_R_PAREN +TKN_SEMICOLON +TKN_VOID +TKN_ID(printf) +TKN_L_PAREN +TKN_CHAR +TKN_STAR +TKN_COMMA +TKN_DOTS +TKN_R_PAREN +TKN_SEMICOLON +TKN_VOID +TKN_ID(sprintf) +TKN_L_PAREN +TKN_CHAR +TKN_STAR +TKN_COMMA +TKN_CHAR +TKN_STAR +TKN_COMMA +TKN_DOTS +TKN_R_PAREN +TKN_SEMICOLON +TKN_CHAR +TKN_STAR +TKN_ID(cc_asprintf) +TKN_L_PAREN +TKN_CHAR +TKN_STAR +TKN_ID(inp) +TKN_COMMA +TKN_DOTS +TKN_R_PAREN +TKN_L_BRACE +TKN_ASM +TKN_L_PAREN +TKN_LIT_STR(mov r9, r8) +TKN_LIT_STR(mov r8, rcx) +TKN_LIT_STR(mov rcx, rdx) +TKN_LIT_STR(mov rdx, rsi) +TKN_LIT_STR(mov rsi, rdi) +TKN_LIT_STR(mov rdi, 0) +TKN_R_PAREN +TKN_SEMICOLON +TKN_ASM +TKN_L_PAREN +TKN_LIT_STR(push rdi) +TKN_LIT_STR(push rsi) +TKN_LIT_STR(push rdx) +TKN_LIT_STR(push rcx) +TKN_LIT_STR(push r8) +TKN_LIT_STR(push r9) +TKN_R_PAREN +TKN_SEMICOLON +TKN_CHAR +TKN_STAR +TKN_ID(ret) +TKN_ASSIGN +TKN_L_PAREN +TKN_CHAR +TKN_STAR +TKN_R_PAREN +TKN_ID(malloc) +TKN_L_PAREN +TKN_LIT_INT(128) +TKN_R_PAREN +TKN_SEMICOLON +TKN_ASM +TKN_L_PAREN +TKN_LIT_STR(pop r9) +TKN_LIT_STR(pop r8) +TKN_LIT_STR(pop rcx) +TKN_LIT_STR(pop rdx) +TKN_LIT_STR(pop rsi) +TKN_LIT_STR(pop rdi) +TKN_R_PAREN +TKN_SEMICOLON +TKN_ID(sprintf) +TKN_L_PAREN +TKN_ID(ret) +TKN_COMMA +TKN_ID(inp) +TKN_R_PAREN +TKN_SEMICOLON +TKN_RETURN +TKN_ID(ret) +TKN_SEMICOLON +TKN_R_BRACE +TKN_INT +TKN_ID(main) +TKN_L_PAREN +TKN_R_PAREN +TKN_L_BRACE +TKN_CHAR +TKN_STAR +TKN_ID(ret) +TKN_ASSIGN +TKN_ID(cc_asprintf) +TKN_L_PAREN +TKN_LIT_STR(salam %s %u%c) +TKN_COMMA +TKN_LIT_STR(donya) +TKN_COMMA +TKN_LIT_INT(123) +TKN_COMMA +TKN_LIT_CHAR(!) +TKN_R_PAREN +TKN_SEMICOLON +TKN_ID(printf) +TKN_L_PAREN +TKN_LIT_STR(%s %s +) +TKN_COMMA +TKN_LIT_STR(haha) +TKN_COMMA +TKN_ID(ret) +TKN_R_PAREN +TKN_SEMICOLON +TKN_RETURN +TKN_LIT_INT(0) +TKN_SEMICOLON +TKN_R_BRACE +TKN_EOF diff --git a/tests/output/inp_vararg.c_tree_output.txt b/tests/output/inp_vararg.c_tree_output.txt new file mode 100644 index 0000000..6ad9c35 --- /dev/null +++ b/tests/output/inp_vararg.c_tree_output.txt @@ -0,0 +1,110 @@ +Program( + FunctionDecl( + Name: + malloc + Returns: + Type(Name: (null)): + Pointer of: + TKN_VOID + Params: + Type(Name: (null)): + TKN_INT + ) + FunctionDecl( + Name: + printf + Returns: + Type(Name: (null)): + TKN_VOID + Params: + Type(Name: (null)): + Pointer of: + TKN_CHAR + ) + FunctionDecl( + Name: + sprintf + Returns: + Type(Name: (null)): + TKN_VOID + Params: + Type(Name: (null)): + Pointer of: + TKN_CHAR + Type(Name: (null)): + Pointer of: + TKN_CHAR + ) + Function( + Name: + cc_asprintf + Returns: + Type(Name: (null)): + Pointer of: + TKN_CHAR + Params: + Type(Name: inp): + Pointer of: + TKN_CHAR + Statements: + Asm: + "mov r9, r8" "mov r8, rcx" "mov rcx, rdx" "mov rdx, rsi" "mov rsi, rdi" "mov rdi, 0" Asm: + "push rdi" "push rsi" "push rdx" "push rcx" "push r8" "push r9" VarDecl(ret): + Type(Name: ret): + Pointer of: + TKN_CHAR + Value: + Cast: + Val: + FunctionCall: + Function: + Variable(malloc) + Args: + Literal(Type: 34, Value: 128) + Type: + Type(Name: (null)): + Pointer of: + TKN_CHAR + Asm: + "pop r9" "pop r8" "pop rcx" "pop rdx" "pop rsi" "pop rdi" FunctionCall: + Function: + Variable(sprintf) + Args: + Variable(ret) + Variable(inp) + Return: + Variable(ret) + ) + Function( + Name: + main + Returns: + Type(Name: (null)): + TKN_INT + Params: + Statements: + VarDecl(ret): + Type(Name: ret): + Pointer of: + TKN_CHAR + Value: + FunctionCall: + Function: + Variable(cc_asprintf) + Args: + Literal(Type: 33, Value: salam %s %u%c) + Literal(Type: 33, Value: donya) + Literal(Type: 34, Value: 123) + Literal(Type: 35) + FunctionCall: + Function: + Variable(printf) + Args: + Literal(Type: 33, Value: %s %s +) + Literal(Type: 33, Value: haha) + Variable(ret) + Return: + Literal(Type: 34, Value: 0) + ) +)