Merge branch 'master' of https://codeberg.org/eaxcc/eaxcc
This commit is contained in:
@ -88,6 +88,20 @@ void debug_token_dump(void) {
|
||||
fclose(o);
|
||||
}
|
||||
|
||||
__attribute__((unused))
|
||||
static
|
||||
void debug_dump_tail(void) {
|
||||
debug_dump_symbols();
|
||||
debug_token_dump();
|
||||
|
||||
if (has_encountered_error) {
|
||||
puts("###############################\n"
|
||||
"### ERRORS WERE ENCOUNTERED ###\n"
|
||||
"###############################"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# define debug_puts(msg)
|
||||
@ -96,6 +110,7 @@ void debug_token_dump(void) {
|
||||
# define debug_dump_functions() do {} while (0)
|
||||
# define debug_dump_symbols() do {} while (0)
|
||||
# define debug_token_dump() do {} while (0)
|
||||
# define debug_dump_tail() do {} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -24,6 +24,9 @@ int is_program_found = 0;
|
||||
|
||||
char * yyfilename = "";
|
||||
|
||||
/* Used for ensuring that `get_*` calls recieve a valid symbol,
|
||||
* not segfaulting the parser in the process
|
||||
*/
|
||||
static symbol_t * undeclared_symbol;
|
||||
|
||||
/* Used for naming variables constructed from literals
|
||||
@ -35,8 +38,12 @@ static size_t anon_variable_counter = 0;
|
||||
*/
|
||||
static size_t unresolved_label_counter = 0;
|
||||
|
||||
static int control_block_stack[12];
|
||||
static size_t control_block_stack_top = 0;
|
||||
/* Used for storing `repeat` implicit label information
|
||||
* For each loop we allocate 2 ids. 1 for the start and 1 for the end,
|
||||
* the second is implicitly ((the value stored in the stack) + 1)
|
||||
*/
|
||||
static int repeat_stack[MAX_REPEAT_NESTING];
|
||||
static size_t repeat_stack_empty_top = 0;
|
||||
|
||||
static unsigned symbol_id = 1;
|
||||
tommy_hashtable symbol_table;
|
||||
@ -54,20 +61,59 @@ void add_logic_equals(cpuregister_t * c1, cpuregister_t * c2) {
|
||||
append_instructions(CMP, c1->size, REG, c1->number, REG, c2->number);
|
||||
append_instructions(JNE, D32, REL, control_block_stack[control_block_stack_top]);
|
||||
}
|
||||
void add_break(void) {
|
||||
append_instructions(JMP, D32)
|
||||
}
|
||||
*/
|
||||
|
||||
void add_repeat(void) {
|
||||
control_block_stack[control_block_stack_top++] = symbol_id++;
|
||||
append_instructions(ASMDIRMEM, control_block_stack[control_block_stack_top]);
|
||||
if (repeat_stack_empty_top == MAX_REPEAT_NESTING) {
|
||||
issue_error("this implementation only support a maximum"
|
||||
" number of %d levels of repeat nesting",
|
||||
MAX_REPEAT_NESTING
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
append_instructions(ASMDIRMEM, symbol_id);
|
||||
repeat_stack[repeat_stack_empty_top] = symbol_id;
|
||||
++repeat_stack_empty_top;
|
||||
symbol_id += 2;
|
||||
}
|
||||
|
||||
void fin_repeat(void) {
|
||||
append_instructions(JMP, D32, REL, control_block_stack[control_block_stack_top--]);
|
||||
--repeat_stack_empty_top;
|
||||
append_instructions(JMP, D32, REL, repeat_stack[repeat_stack_empty_top]);
|
||||
append_instructions(ASMDIRMEM, repeat_stack[repeat_stack_empty_top]+1);
|
||||
}
|
||||
void add_continue(void) {
|
||||
append_instructions(JMP, D32, REL, control_block_stack[control_block_stack_top]);
|
||||
|
||||
void add_continue(unsigned i) {
|
||||
if (!repeat_stack_empty_top) {
|
||||
issue_error("'continue' is only valid inside 'repeat'");
|
||||
return;
|
||||
}
|
||||
if (((int)repeat_stack_empty_top - (int)i) < 0) {
|
||||
issue_error("'continue %u' is too deep inside just %d level(s) of nesting",
|
||||
i,
|
||||
repeat_stack_empty_top
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
append_instructions(JMP, D32, REL, repeat_stack[repeat_stack_empty_top-i]);
|
||||
}
|
||||
|
||||
void add_break(unsigned i) {
|
||||
if (!repeat_stack_empty_top) {
|
||||
issue_error("'break' is only valid inside 'repeat'");
|
||||
return;
|
||||
}
|
||||
if (((int)repeat_stack_empty_top - (int)i) < 0) {
|
||||
issue_error("'break %u' is too deep inside just %d level(s) of nesting",
|
||||
i,
|
||||
repeat_stack_empty_top
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
append_instructions(JMP, D32, REL, repeat_stack[repeat_stack_empty_top-i]+1);
|
||||
}
|
||||
|
||||
static char * scope = NULL;
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#define WORD_SIZE_IN_BYTES (64/8)
|
||||
|
||||
#define MAX_REPEAT_NESTING 12
|
||||
|
||||
// XXX these should be private
|
||||
typedef enum {
|
||||
VARIABLE_SYMBOL,
|
||||
@ -78,9 +80,9 @@ extern void fin_hla(void);
|
||||
// testing
|
||||
extern void add_repeat(void);
|
||||
extern void fin_repeat(void);
|
||||
extern void add_continue(void);
|
||||
extern void add_continue(unsigned i);
|
||||
extern void add_break(unsigned i);
|
||||
/* Not implemented
|
||||
extern void add_break(void);
|
||||
|
||||
extern symbol_t * add_function(symbol_t function);
|
||||
extern symbol_t * get_function(const char * const name);
|
||||
|
@ -440,10 +440,17 @@ instruction_like: exit
|
||||
| break
|
||||
;
|
||||
|
||||
continue: CONTINUE { add_continue(); }
|
||||
/* XXX: currently passing a negative is gramatically legal
|
||||
we could either define a more abstract token
|
||||
and only accept positives here or make eaxhla.c check.
|
||||
as of now however, i do not care
|
||||
*/
|
||||
continue: CONTINUE { add_continue(1); }
|
||||
| CONTINUE LITERAL { add_continue($2); }
|
||||
;
|
||||
|
||||
break: BREAK { ; }
|
||||
break: BREAK { add_break(1); }
|
||||
| BREAK LITERAL { add_break($2); }
|
||||
;
|
||||
|
||||
exit: EXIT value { append_exit($2); }
|
||||
|
@ -44,8 +44,7 @@ signed main(int argc, char * argv[]) {
|
||||
|
||||
yyparse();
|
||||
|
||||
debug_dump_symbols();
|
||||
debug_token_dump();
|
||||
debug_dump_tail();
|
||||
|
||||
if (!has_encountered_error) {
|
||||
compile();
|
||||
|
21
test/break.eax
Normal file
21
test/break.eax
Normal file
@ -0,0 +1,21 @@
|
||||
program my_break
|
||||
u8 <> yeah = "yeah"
|
||||
u8 <> nope = "nope"
|
||||
begin
|
||||
repeat
|
||||
mov eax 1
|
||||
mov edi 1
|
||||
mov esi yeah
|
||||
mov edx 4
|
||||
syscall
|
||||
|
||||
break
|
||||
|
||||
mov eax 1
|
||||
mov edi 1
|
||||
mov esi nope
|
||||
mov edx 4
|
||||
syscall
|
||||
end repeat
|
||||
exit 0
|
||||
end program
|
5
test/end_jmp.eax
Normal file
5
test/end_jmp.eax
Normal file
@ -0,0 +1,5 @@
|
||||
program end_jmp
|
||||
begin
|
||||
jmp my_label
|
||||
my_label:
|
||||
end program
|
22
test/nested_repeat.eax
Normal file
22
test/nested_repeat.eax
Normal file
@ -0,0 +1,22 @@
|
||||
program nested_repeat
|
||||
u8 <> yeah = "yeah"
|
||||
u8 <> nope = "nope"
|
||||
begin
|
||||
repeat
|
||||
mov eax 1
|
||||
mov edi 1
|
||||
mov esi yeah
|
||||
mov edx 4
|
||||
syscall
|
||||
|
||||
repeat
|
||||
continue 2
|
||||
|
||||
mov eax 1
|
||||
mov edi 1
|
||||
mov esi nope
|
||||
mov edx 4
|
||||
syscall
|
||||
end repeat
|
||||
end repeat
|
||||
end program
|
Reference in New Issue
Block a user