Skip to content

Commit

Permalink
Support global variable initialization
Browse files Browse the repository at this point in the history
Close #12

Change test bench
  • Loading branch information
eecheng87 committed Oct 15, 2020
1 parent cd72dd4 commit b3c302c
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 14 deletions.
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,19 +165,18 @@ int fib(int n) fib: Reserve stack frame for function

1. Any non-zero value is NOT treated as logical truth by all ops.
That is, the expression `0 == strcmp(ptr, "hello")` is not equivalent to `!strcmp(ptr, "hello")`.
2. Global variable initialization is not supported.
Therefore, you can not initialize a global such as `int i = [expr]`.
3. Dereference is incomplete. Consider `int x = 5; int *ptr = &x;` and it is forbidden to use `*ptr`.
2. Dereference is incomplete. Consider `int x = 5; int *ptr = &x;` and it is forbidden to use `*ptr`.
However, it is valid to use `ptr[0]`, which behaves the same of `*ptr`.
4. The support of varying number of function arguments is incomplete. No `<stdarg.h>` can be used.
3. The support of varying number of function arguments is incomplete. No `<stdarg.h>` can be used.
Alternatively, check the implementation `printf` in source `lib/c.c` for `var_arg`.
5. The memory region allocated by `malloc` can not be released. In fact, there is no `free` function.
4. The memory region allocated by `malloc` can not be released. In fact, there is no `free` function.
Memory allocator should be introduced in embedded libc implementation.
6. If you attempt to return values in `main` function, the value will not be reserved after the
5. If you attempt to return values in `main` function, the value will not be reserved after the
program exited. You have to modify the `return` statement to `exit` call. Check the test items in
file `tests/driver.sh` for details.
7. The C front-end is a bit dirty because there is no effective AST.
8. No function pointer is supported.
6. The C front-end is a bit dirty because there is no effective AST.
7. No function pointer is supported.
8. ELF lacks of .bss and .rodata section

## License

Expand Down
Binary file added bench
Binary file not shown.
37 changes: 33 additions & 4 deletions src/cfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ int read_numeric_constant(char buffer[])

void read_inner_var_decl(var_t *vd)
{
vd->init_val = 0;
if (lex_accept(T_asterisk))
vd->is_ptr = 1;
else
Expand Down Expand Up @@ -1308,6 +1309,30 @@ int read_body_assignment(char *token, block_t *parent)
return 0;
}

int read_global_assignment(char *token)
{
var_t *var = find_global_var(token);
if (var) {
char buffer[10];
int isneg = 0;
/* global initialization must be constant */
/* TODO: support rvalue as expression e.g. int a = 3 + 2; */
if (lex_accept(T_minus))
isneg = 1;
if (lex_peek(T_numeric, buffer))
var->init_val = read_numeric_constant(buffer);
else
error("Invalid value after assignment");
if (isneg)
var->init_val = -1 * var->init_val;
lex_expect(T_numeric);
lex_expect(T_semicolon);

return 1;
}
return 0;
}

int break_exit_ir_index[MAX_NESTING];

void read_code_block(func_t *func, block_t *parent);
Expand Down Expand Up @@ -1696,10 +1721,14 @@ void read_global_decl(block_t *block)
/* is a variable */
memcpy(&block->locals[block->next_local++], &_temp_var, sizeof(var_t));

if (lex_accept(T_assign))
/* global variable initialization is not supported at the moment. */
error("Global initialization not supported");
else if (lex_accept(T_comma))
if (lex_accept(T_assign)) {
if (_temp_var.is_ptr == 0 && _temp_var.array_size == 0) {
read_global_assignment(_temp_var.var_name);
return;
}
/* TODO: support global initialization for array and pointer */
error("Global initialization for array and pointer not supported");
} else if (lex_accept(T_comma))
/* TODO: continuation */
error("Global continuation not supported");
else if (lex_accept(T_semicolon))
Expand Down
7 changes: 6 additions & 1 deletion src/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,12 @@ void size_funcs(int data_start)
blk->locals[i].offset = elf_data_idx; /* set offset in data section */
elf_add_symbol(blk->locals[i].var_name, strlen(blk->locals[i].var_name),
data_start + elf_data_idx);
elf_data_idx += size_var(&blk->locals[i]);
/* TODO: add .bss section */
if (strcmp(blk->locals[i].type_name, "int") == 0 &&
blk->locals[i].init_val != 0)
elf_write_data_int(blk->locals[i].init_val);
else
elf_data_idx += size_var(&blk->locals[i]);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ typedef struct {
char var_name[MAX_VAR_LEN];
int is_ptr;
int array_size;
int offset; /* offset from stack or frame */
int offset; /* offset from stack or frame */
int init_val; /* for global initialization */
} var_t;

/* function definition */
Expand Down
8 changes: 8 additions & 0 deletions src/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ void elf_write_data_str(char *vals, int len)
elf_data[elf_data_idx++] = vals[i];
}

void elf_write_data_int(int val)
{
elf_data[elf_data_idx++] = (val & 0x000000FF);
elf_data[elf_data_idx++] = (val & 0x0000FF00) >> 8;
elf_data[elf_data_idx++] = (val & 0x00FF0000) >> 16;
elf_data[elf_data_idx++] = (val & 0xFF000000) >> 24;
}

void elf_write_header_byte(int val)
{
elf_header[elf_header_idx++] = val;
Expand Down
10 changes: 10 additions & 0 deletions tests/driver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,16 @@ int main() {
}
EOF

# global initialization
try_ 41 << EOF
int a = 44;
int b = -3;
int main()
{
exit(a + b);
}
EOF

# conditional operator
# expr 10 "1 ? 10 : 5"
# expr 25 "0 ? 10 : 25"
Expand Down

0 comments on commit b3c302c

Please sign in to comment.