diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ad646dc --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 nae.ikari + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lex.c b/lex.c index b0be8e9..1ba732f 100644 --- a/lex.c +++ b/lex.c @@ -101,7 +101,7 @@ int lex_next() { if(c >= 0) { if(c == '/') { /* "//" comment */ - while((c = lex_getc()) != '\n') lex_getc(); + while((c = lex_getc()) != '\n'); lex_getc(); } else if(c == '*') { /* "/*" comment */ diff --git a/test/add1.c b/test/add1.c new file mode 100644 index 0000000..591f5bc --- /dev/null +++ b/test/add1.c @@ -0,0 +1,3 @@ +int add(int a, int b) { + return a + b; +} \ No newline at end of file diff --git a/test/demo/demo.s b/test/demo/demo.s new file mode 100644 index 0000000..ba2df41 --- /dev/null +++ b/test/demo/demo.s @@ -0,0 +1,458 @@ + .section .rodata +.S0: + .string "==== Nested Test ====\n" +.S1: + .string "scope1[a=%d]\n" +.S2: + .string "scope2[a=%d]\n" +.S3: + .string "scope3[a=%d]\n" +.S4: + .string "\n" +.S5: + .string "=== Expr Test ===\n" +.S6: + .string "1 * 2 + 3 - (2 * (1 + 2)) = %d. (should be -1)\n\n" +.S7: + .string "=== Loop Test ===\n" +.S8: + .string "4 * 5: \n" +.S9: + .string " mul_for(4, 5) = %d\n" +.S10: + .string " mul_while(4, 5) = %d\n" +.S11: + .string " 4 * 5 = %d\n" +.S12: + .string "\n" +.S13: + .string "=== Recursive Test ===\n" +.S14: + .string "10! = %d. (should be %d)\n\n" + .text + .globl nested + .type nested, @function +nested: + pushq %rbp + movq %rsp, %rbp + subq $80, %rsp + + mov $1, %edi + mov %edi, -16(%rbp) + + mov $.S0, %rdi + mov $0, %rax + call printf + mov %eax, -24(%rbp) + + mov $.S1, %rdi + mov -16(%rbp), %ebx + mov %rbx, %rsi + mov $0, %rax + call printf + mov %eax, -32(%rbp) + + jmp .L0 + +.L0: + + mov $2, %edi + mov %edi, -40(%rbp) + + mov $.S2, %rdi + mov -40(%rbp), %ebx + mov %rbx, %rsi + mov $0, %rax + call printf + mov %eax, -48(%rbp) + + jmp .L1 + +.L1: + + mov $3, %edi + mov %edi, -56(%rbp) + + mov $.S3, %rdi + mov -56(%rbp), %ebx + mov %rbx, %rsi + mov $0, %rax + call printf + mov %eax, -64(%rbp) + + jmp .L2 + +.L2: + + jmp .L3 + +.L3: + + mov $.S4, %rdi + mov $0, %rax + call printf + mov %eax, -72(%rbp) + + mov $0, %edi + mov %edi, -8(%rbp) + + mov -8(%rbp), %eax + leave + ret + + .globl expr + .type expr, @function +expr: + pushq %rbp + movq %rsp, %rbp + subq $56, %rsp + + mov $.S5, %rdi + mov $0, %rax + call printf + mov %eax, -16(%rbp) + + mov $1, %edi + imull $2, %edi + mov %edi, -24(%rbp) + + mov -24(%rbp), %edi + add $3, %edi + mov %edi, -24(%rbp) + + mov $1, %edi + add $2, %edi + mov %edi, -32(%rbp) + + mov $2, %edi + imull -32(%rbp), %edi + mov %edi, -40(%rbp) + + mov -24(%rbp), %edi + sub -40(%rbp), %edi + mov %edi, -24(%rbp) + + mov $.S6, %rdi + mov -24(%rbp), %ebx + mov %rbx, %rsi + mov $0, %rax + call printf + mov %eax, -48(%rbp) + + mov $0, %edi + mov %edi, -8(%rbp) + + mov -8(%rbp), %eax + leave + ret + + .globl mul_for + .type mul_for, @function +mul_for: + pushq %rbp + movq %rsp, %rbp + subq $64, %rsp + mov %rdi, -16(%rbp) + mov %rsi, -24(%rbp) + + mov $0, %edi + mov %edi, -40(%rbp) + + mov $0, %edi + mov %edi, -32(%rbp) + +.L4: + + mov -32(%rbp), %edi + cmp -24(%rbp), %edi + setl %al + movzx %al, %eax + mov %eax, -48(%rbp) + + cmpl $1, -48(%rbp) + je .L5 + + jmp .L6 + +.L7: + + mov -32(%rbp), %edi + mov %edi, -56(%rbp) + + incl -32(%rbp) + + jmp .L4 + +.L5: + + mov -40(%rbp), %edi + add -16(%rbp), %edi + mov %edi, -48(%rbp) + + mov -48(%rbp), %edi + mov %edi, -40(%rbp) + + jmp .L7 + +.L6: + + mov -40(%rbp), %edi + mov %edi, -8(%rbp) + + mov -8(%rbp), %eax + leave + ret + + .globl mul_while + .type mul_while, @function +mul_while: + pushq %rbp + movq %rsp, %rbp + subq $56, %rsp + mov %rdi, -16(%rbp) + mov %rsi, -24(%rbp) + + mov $0, %edi + mov %edi, -32(%rbp) + + mov $0, %edi + mov %edi, -40(%rbp) + +.L8: + + jmp .L9 + +.L9: + + mov -32(%rbp), %edi + cmp -24(%rbp), %edi + setge %al + movzx %al, %eax + mov %eax, -48(%rbp) + + cmpl $1, -48(%rbp) + je .L10 + + jmp .L11 + +.L10: + + jmp .L12 + + jmp .L11 + +.L11: + + mov -40(%rbp), %edi + add -16(%rbp), %edi + mov %edi, -48(%rbp) + + mov -48(%rbp), %edi + mov %edi, -40(%rbp) + + mov -32(%rbp), %edi + mov %edi, -48(%rbp) + + incl -32(%rbp) + + jmp .L8 + + mov $1234, %edi + mov %edi, -40(%rbp) + +.L12: + + mov -40(%rbp), %edi + mov %edi, -8(%rbp) + + mov -8(%rbp), %eax + leave + ret + + .globl loop + .type loop, @function +loop: + pushq %rbp + movq %rsp, %rbp + subq $88, %rsp + + mov $.S7, %rdi + mov $0, %rax + call printf + mov %eax, -16(%rbp) + + mov $.S8, %rdi + mov $0, %rax + call printf + mov %eax, -24(%rbp) + + mov $4, %rdi + mov $5, %rsi + mov $0, %rax + call mul_for + mov %eax, -32(%rbp) + + mov $.S9, %rdi + mov -32(%rbp), %ebx + mov %rbx, %rsi + mov $0, %rax + call printf + mov %eax, -40(%rbp) + + mov $4, %rdi + mov $5, %rsi + mov $0, %rax + call mul_while + mov %eax, -48(%rbp) + + mov $.S10, %rdi + mov -48(%rbp), %ebx + mov %rbx, %rsi + mov $0, %rax + call printf + mov %eax, -56(%rbp) + + mov $4, %edi + imull $5, %edi + mov %edi, -64(%rbp) + + mov $.S11, %rdi + mov -64(%rbp), %ebx + mov %rbx, %rsi + mov $0, %rax + call printf + mov %eax, -72(%rbp) + + mov $.S12, %rdi + mov $0, %rax + call printf + mov %eax, -80(%rbp) + + mov $0, %edi + mov %edi, -8(%rbp) + + mov -8(%rbp), %eax + leave + ret + + .globl fac + .type fac, @function +fac: + pushq %rbp + movq %rsp, %rbp + subq $48, %rsp + mov %rdi, -16(%rbp) + + mov -16(%rbp), %edi + cmp $1, %edi + sete %al + movzx %al, %eax + mov %eax, -24(%rbp) + + cmpl $1, -24(%rbp) + je .L13 + + jmp .L14 + +.L13: + + mov $1, %edi + mov %edi, -8(%rbp) + + mov -8(%rbp), %eax + leave + ret + + jmp .L15 + +.L14: + + mov -16(%rbp), %edi + sub $1, %edi + mov %edi, -24(%rbp) + + mov -24(%rbp), %ebx + mov %rbx, %rdi + mov $0, %rax + call fac + mov %eax, -32(%rbp) + + mov -32(%rbp), %ebx + mov %rbx, %rdi + mov -16(%rbp), %ebx + mov %rbx, %rsi + mov $0, %rax + call mul_for + mov %eax, -40(%rbp) + + mov -40(%rbp), %edi + mov %edi, -8(%rbp) + + mov -8(%rbp), %eax + leave + ret + +.L15: + + .globl recursive + .type recursive, @function +recursive: + pushq %rbp + movq %rsp, %rbp + subq $40, %rsp + + mov $.S13, %rdi + mov $0, %rax + call printf + mov %eax, -16(%rbp) + + mov $10, %rdi + mov $0, %rax + call fac + mov %eax, -24(%rbp) + + mov $.S14, %rdi + mov -24(%rbp), %ebx + mov %rbx, %rsi + mov $3628800, %rdx + mov $0, %rax + call printf + mov %eax, -32(%rbp) + + mov $0, %edi + mov %edi, -8(%rbp) + + mov -8(%rbp), %eax + leave + ret + + .globl main + .type main, @function +main: + pushq %rbp + movq %rsp, %rbp + subq $48, %rsp + + mov $0, %rax + call nested + mov %eax, -16(%rbp) + + mov $0, %rax + call expr + mov %eax, -24(%rbp) + + mov $0, %rax + call loop + mov %eax, -32(%rbp) + + mov $0, %rax + call recursive + mov %eax, -40(%rbp) + + mov $0, %edi + mov %edi, -8(%rbp) + + mov -8(%rbp), %eax + leave + ret + diff --git a/test/demo/redefine.c b/test/demo/redefine.c new file mode 100644 index 0000000..428173c --- /dev/null +++ b/test/demo/redefine.c @@ -0,0 +1,5 @@ +int main() { + int a = 0; + int a = 2; + return a; +} \ No newline at end of file diff --git a/zcc.h b/zcc.h index 4f97225..9e21644 100644 --- a/zcc.h +++ b/zcc.h @@ -7,7 +7,9 @@ struct type_st; struct context_st; struct func_st; struct var_st; -union value_un; +union value_un; +struct token_st; +enum ir_op_en typedef struct type_st { int bytes; @@ -99,18 +101,11 @@ enum lex_ecode_en { }; typedef enum tk_class_en { - TK_PLACEHOLDER = 1, + TK_NO_CLASS = 0, // keywords #define xx(tk_class, u) tk_class, #include "keywords.h" #undef xx - /* - TK_INT = 1, - TK_CHAR, - TK_VOID, - TK_RETURN, - TK_CONST, - */ // constant TK_CONST_INT, TK_CONST_CHAR, @@ -152,7 +147,7 @@ extern func_st *wrap_func; /* =-- forward declaration --= */ -/* lex */ +/* == lex == */ int lex_load_file(const char *); void lex_print_token(token_st *); void lex_init(); @@ -163,7 +158,7 @@ int lex_isunaryop(token_st*); int lex_isassignop(token_st*); int lex_valid(); -/* parse */ +/* == parse == */ void prs_init(); int prs_expect_char(char); int prs_expect_class(tk_class_en); @@ -192,7 +187,7 @@ int prs_decls(); int prs_decl(); type_st* prs_decl_spec(); -/* sym */ +/* == sym == */ int sym_init(); int sym_hasid(token_st*); int sym_hastype(token_st*); @@ -216,7 +211,7 @@ void sym_add_type(type_st*); label_st* sym_make_label(); type_st* pointer_of(type_st*); -/* gen */ +/* == gen == */ void gen_emit0(ir_op_en); void gen_emit1(ir_op_en, void*); void gen_emit2(ir_op_en, void*, void*); @@ -224,7 +219,9 @@ void gen_emit3(ir_op_en, void*, void*, void*); void gen_emit_call(ir_op_en, func_st*, var_st*, list_st*); void gen_print_func_ir(func_st*); -/* target-specific gen */ +/* target-specific gen + * link gen-x.c to support different target + */ void gen_assembly(FILE*); /* util */