diff options
| author | Andrew Chambers <[email protected]> | 2021-10-05 18:10:36 +1300 |
|---|---|---|
| committer | Andrew Chambers <[email protected]> | 2021-10-05 18:10:36 +1300 |
| commit | 5c0af4055474834542e2813f36f4dd9a16479e53 (patch) | |
| tree | 0132bfdfd56bc995b83f2a6f1791dd4f4b8bc2c1 /asm.peg | |
| parent | dda3e77e5b3c01c52fc38a29cd81d49c52abb26c (diff) | |
Port lexer to leg.
Diffstat (limited to 'asm.peg')
| -rw-r--r-- | asm.peg | 80 |
1 files changed, 80 insertions, 0 deletions
@@ -0,0 +1,80 @@ + +line = s:stmt (eol | !. ) { yy->v = s; } + | eol { yy->v.kind = ASM_BLANK; } + | . { yy->v.kind = ASM_SYNTAX_ERROR; } + +stmt = d:directive {$$ = d;} + | i:instr { $$ = i; } + | l:label { $$ = l; } + +directive = ".glob" "o"? "l" ws i:ident + { $$.globl = (Globl){.kind = ASM_DIR_GLOBL, .name = i.ident.name }; } + | ".data" { $$.kind = ASM_DIR_DATA; } + | ".text" { $$.kind = ASM_DIR_TEXT; } + | ".balign" ws n:number + { $$.balign = (Balign){.kind = ASM_DIR_BALIGN, .align = n.number.v }; } + | ".byte" ws n:number + { $$.byte = (Byte){.kind = ASM_DIR_BYTE, .b = (uint8_t)n.number.v }; } + +label = i:ident ':' + { $$.label = (Label){.kind = ASM_LABEL, .name = i.ident.name}; } + +instr = "nop"{ $$.kind = ASM_NOP; } + | "leave" { $$.kind = ASM_LEAVE; } + | "ret" { $$.kind = ASM_RET; } + | i:jmp { $$ = i; } + | i:add { $$ = i; } + +jmp = "jmp" ws i:ident + { $$.jmp = (Jmp){.kind = ASM_JMP, .target = i.ident.name}; } + +add = "addq" ws s:r-m64 ws? ',' ws? d:r64 + { $$.add = (Add){ .kind = ASM_ADD, .type = 'q', .src = dupv(&s), .dst = dupv(&d) } } + | "addq" ws s:r64 ws? ',' ws? d:r-m64 + { $$.add = (Add){ .kind = ASM_ADD, .type = 'q', .src = dupv(&s), .dst = dupv(&d) } } + | "addq" ws s:imm ws? ',' ws? d:r-m64 + { $$.add = (Add){ .kind = ASM_ADD, .type = 'q', .src = dupv(&s), .dst = dupv(&d) } } + +r-m64 = r:r64 { $$ = r; } + | m:m { $$ = m; } + +m = '(' ws? r:r64 ws? ')' + { $$.memarg = (Memarg){ .kind = ASM_MEMARG, .c = 0, .l = NULL, .reg = r.kind } } + | <'-'?[0-9]+> ws? '(' ws? r:r64 ws? ')' + { $$.memarg = (Memarg){ .kind = ASM_MEMARG, .c = strtoll(yytext, NULL, 10), .l = NULL, .reg = r.kind } } + | i:ident ws? '(' ws? r:r64 ws? ')' + { $$.memarg = (Memarg){ .kind = ASM_MEMARG, .c = 0, .l = i.ident.name, .reg = r.kind } } + +r64 = "%rax" { $$.kind = ASM_RAX } + | "%rcx" { $$.kind = ASM_RCX } + | "%rdx" { $$.kind = ASM_RDX } + | "%rbx" { $$.kind = ASM_RBX } + | "%rsp" { $$.kind = ASM_RSP } + | "%rbp" { $$.kind = ASM_RBP } + | "%rsi" { $$.kind = ASM_RSI } + | "%rdi" { $$.kind = ASM_RDI } + | "%r8" { $$.kind = ASM_R8 } + | "%r9" { $$.kind = ASM_R9 } + | "%r10" { $$.kind = ASM_R10 } + | "%r11" { $$.kind = ASM_R11 } + | "%r12" { $$.kind = ASM_R12 } + | "%r13" { $$.kind = ASM_R13 } + | "%r14" { $$.kind = ASM_R14 } + | "%r15" { $$.kind = ASM_R15 } + + +imm = '$' i:ident + { $$.imm = (Imm){.kind = ASM_IMM, .l = i.ident.name, .c = 0 }; } + | '$' <'-'?[0-9]+> + { $$.imm = (Imm){.kind = ASM_IMM, .l = NULL, .c = strtoll(yytext, NULL, 10) }; } + +ident = <[_a-zA-Z][_a-zA-Z0-9]*> + { $$.ident = (Ident){ .kind = ASM_IDENT, .name = xstrdup(yytext) }; } + +number = <'-'?[0-9]+> + { $$.number = (Number){ .kind = ASM_NUMBER, .v = strtoll(yytext, NULL, 10) }; } + +ws = [ \t]+ + +eol = ws? "\n" + |
