Skip to content

Commit

Permalink
Fix semantic routines being associated with the wrong production
Browse files Browse the repository at this point in the history
Write NES ROM example with limited uLisp synthetic power
  • Loading branch information
andriybyelikov committed Sep 15, 2021
1 parent 7d95380 commit c3036f9
Show file tree
Hide file tree
Showing 7 changed files with 2,190 additions and 69 deletions.
136 changes: 116 additions & 20 deletions spec/sample/6502_to_bin
Original file line number Diff line number Diff line change
@@ -1,34 +1,130 @@
t_gobble__blank -> [ \t\r\n]+;
t_gobble__blank -> [ \t\r\n]+;
t_gobble__linecomment -> ";".*"\n";
t_mnemonic -> [A-Z]+;
t_directive -> "."[a-z]*; -- buggy kleene plus, use kleene star
t_symbol -> [a-z][a-z0-9_]*;
t_colon -> ":";
t_immediate -> "#";
t_hex -> "$"[0-9A-Fa-f]*;
t_with_x_reg -> ",X";
t_numbersign -> "#";
t_hexadecimal -> "0x"[0-9A-Fa-f]*;
t_decimal -> [1-9][0-9]*;
t_comma -> ",";
t_reg -> [axy];

start -> expressions;
expressions -> expression expressions | expression;
expression -> instruction | directive | label;
expression -> instruction;

instruction ->
t_mnemonic operand
<
(emit_byte 0x42)
>| t_mnemonic
instruction -> t_mnemonic
<
(if (strequ (lexeme "t_mnemonic") "BRK")
(emit_byte 0)
(if (strequ (lexeme "t_mnemonic") "PHP")
(emit_byte 0x8)
(if (strequ (lexeme "t_mnemonic") "CLC")
(emit_byte 0x18)
(if (strequ (lexeme "t_mnemonic") "PLP")
(emit_byte 0x28)
(if (strequ (lexeme "t_mnemonic") "SEC")
(emit_byte 0x38)
(if (strequ (lexeme "t_mnemonic") "RTI")
(emit_byte 0x40)
(if (strequ (lexeme "t_mnemonic") "PHA")
(emit_byte 0x48)
(if (strequ (lexeme "t_mnemonic") "CLI")
(emit_byte 0x58)
(if (strequ (lexeme "t_mnemonic") "RTS")
(emit_byte 0x60)
(if (strequ (lexeme "t_mnemonic") "PLA")
(emit_byte 0x68)
(if (strequ (lexeme "t_mnemonic") "SEI")
(emit_byte 0x78)
(if (strequ (lexeme "t_mnemonic") "DEY")
(emit_byte 0x88)
(if (strequ (lexeme "t_mnemonic") "TXA")
(emit_byte 0x8A)
(if (strequ (lexeme "t_mnemonic") "TYA")
(emit_byte 0x98)
(if (strequ (lexeme "t_mnemonic") "TXS")
(emit_byte 0x9A)
(if (strequ (lexeme "t_mnemonic") "TAY")
(emit_byte 0xA8)
(if (strequ (lexeme "t_mnemonic") "TAX")
(emit_byte 0xAA)
(if (strequ (lexeme "t_mnemonic") "CLV")
(emit_byte 0xB8)
(if (strequ (lexeme "t_mnemonic") "TSX")
(emit_byte 0xBA)
(if (strequ (lexeme "t_mnemonic") "INY")
(emit_byte 0xC8)
(if (strequ (lexeme "t_mnemonic") "DEX")
(emit_byte 0xCA)
(if (strequ (lexeme "t_mnemonic") "CLD")
(emit_byte 0xD8)
(if (strequ (lexeme "t_mnemonic") "INX")
(emit_byte 0xE8)
(if (strequ (lexeme "t_mnemonic") "NOP")
(emit_byte 0xEA)
(if (strequ (lexeme "t_mnemonic") "SED")
(emit_byte 0xF8)
(nil)
)))))))))))))))))))))))))
> | t_mnemonic t_numbersign t_hexadecimal -- immediate
<
(if (strequ (lexeme "t_mnemonic") "LDX")
(emit_byte 0xA2)
(if (strequ (lexeme "t_mnemonic") "LDA")
(emit_byte 0xA9)
(nil)
))
>;
(emit_byte (strtol (lexeme "t_hexadecimal")))
> | t_mnemonic t_decimal t_hexadecimal -- absolute

-- trickery: t_decimal is page number while t_hexadecimal is offset

operand -> t_immediate t_hex | t_hex t_with_x_reg | t_hex | t_symbol;

directive -> t_directive darg | t_directive;
darg -> t_hex | t_symbol;

label -> t_symbol t_colon | t_symbol;
<
(if (strequ (lexeme "t_mnemonic") "STX")
(emit_byte 0x8E)
(if (strequ (lexeme "t_mnemonic") "BIT")
(emit_byte 0x2C)
(if (strequ (lexeme "t_mnemonic") "STA")
(emit_byte 0x8D)
(if (strequ (lexeme "t_mnemonic") "JMP")
(emit_byte 0x4C)
(nil)
))))
-- emit in little endian
(emit_byte (strtol (lexeme "t_hexadecimal")))
(emit_byte (strtol (lexeme "t_decimal")))
> | t_mnemonic t_hexadecimal -- relative
<
(if (strequ (lexeme "t_mnemonic") "BPL")
(emit_byte 0x10)
(if (strequ (lexeme "t_mnemonic") "BNE")
(emit_byte 0xD0)
(if (strequ (lexeme "t_mnemonic") "BEQ")
(emit_byte 0xF0)
(nil)
)))
(emit_byte (strtol (lexeme "t_hexadecimal")))
> | t_mnemonic t_hexadecimal t_comma t_reg -- zeropage x
<
(if (strequ (lexeme "t_reg") "x")
(if (strequ (lexeme "t_mnemonic") "STA")
(emit_byte 0x85)
(nil)
)
(nil)
)
(emit_byte (strtol (lexeme "t_hexadecimal")))
> | t_mnemonic t_decimal t_hexadecimal t_comma t_reg -- absolute x
<
(if (strequ (lexeme "t_reg") "x")
(if (strequ (lexeme "t_mnemonic") "STA")
(emit_byte 0x9D)
(if (strequ (lexeme "t_mnemonic") "LDA")
(emit_byte 0xBD)
(nil)
))
(nil)
)
-- emit in little endian
(emit_byte (strtol (lexeme "t_hexadecimal")))
(emit_byte (strtol (lexeme "t_decimal")))
>;
9 changes: 9 additions & 0 deletions spec/sample/uppercase_text_to_bin
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
t_gobble__blank -> [\n]+;
t_text -> [A-Z ]+;
t_end -> "\\0";

start -> text;
text -> t_text t_end
<
(emit_line (lexeme "t_text"))
>;
6 changes: 5 additions & 1 deletion src/meta/parser_pre_shift_action1.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ void push_terminal_to_parse_tree_stack(terminal_t terminal,

void meta__pre_shift_action1(void *user_ptr, terminal_t terminal)
{
struct data_common *user = user_ptr;
struct data_meta *user = user_ptr;
push_terminal_to_parse_tree_stack(terminal, &user->parse_tree_stack);

if (!strcmp(terminal__lexeme(terminal), "start")) {
user->in_terminals_section = 0;
}
}
25 changes: 16 additions & 9 deletions src/meta/parser_production_attributed_actions2.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,6 @@ void meta__production_attibuted_actions2(void *user_ptr, int pid)
production_t p = new_production(int_id +
int_trie__length(&user->terminals), &body);
production_queue__insert(&user->productions, p);
user->cnt_prod++;

body = NULL;
expr = parse_tree__get_child_by_string(&expr, "expr");
Expand Down Expand Up @@ -370,22 +369,30 @@ void meta__production_attibuted_actions2(void *user_ptr, int pid)
buf_trimmed), &data_ulisp);
free(buf);

// debug
/*fprintf(stderr, "%d\n", user->cnt_prod);
node_t t = parse_tree_stack__access(&data_ulisp.parse_tree_stack);
parse_tree__dump_dot(stdout, &t);*/

int key =
ulisp_parse_tree_avl__length(&user->ulisp_parse_trees);

int key = user->cnt_prod == user->last_prod ?
user->cnt_prod + 1: user->cnt_prod;
user->last_prod = key;
ulisp_parse_tree_avl__insert(&user->ulisp_parse_trees,
(pidxpt_t) { key,
(pidxpt_t) {
key,
parse_tree_stack__access(&data_ulisp.parse_tree_stack)
}, ulisp_parse_tree_avl__cmp_predicate);
}
}
break;
case 7: // expr_a -> expr_0;
{
if ((user->options[OPTION_DUMP_ULISP_PARSE_TREES]
|| user->composition_mode)
&& !user->in_terminals_section) {
int key =
ulisp_parse_tree_avl__length(&user->ulisp_parse_trees);
ulisp_parse_tree_avl__insert(&user->ulisp_parse_trees,
(pidxpt_t) { key, NULL },
ulisp_parse_tree_avl__cmp_predicate);
}
}
break;
case 8: // expr_0 -> expr_1 expr_0;
{
Expand Down
Binary file removed test/6502/game.nes
Binary file not shown.
Loading

0 comments on commit c3036f9

Please sign in to comment.