break/continue N works

This commit is contained in:
anon
2024-07-28 21:50:42 +02:00
parent c90d0e1807
commit a9f77e5b8e
7 changed files with 112 additions and 15 deletions

@ -35,8 +35,11 @@ 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;
/* 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 +57,62 @@ 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(NOP, NOP, NOP, NOP, NOP);
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--]);
append_instructions(NOP, NOP, NOP, NOP, NOP);
--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 %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 %d level(s) of nesting",
i,
repeat_stack_empty_top
);
return;
}
append_instructions(NOP, NOP, NOP, NOP, NOP);
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,12 @@ instruction_like: exit
| break
;
continue: CONTINUE { add_continue(); }
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); }

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

@ -0,0 +1,5 @@
program end_jmp
begin
jmp my_label
my_label:
end program

@ -1,5 +1,5 @@
program heyo_world
s8 <12> message "Heyo world!\n" // AVAR D8 12 ...
s8 <12> message = "Heyo world!\n" // AVAR D8 12 ...
begin // DECL 0XFFFFFFFFU
mov eax 1 // MOV D32 REG R0 IMM 1

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