emul8 0.1.2

A simple rust-based toolchain to interoperate and emulate the CHIP-8 architecture
Documentation
/*register = @{ "V" ~ ASCII_HEX_DIGIT }
special_register = @{"K" | "DT" | "F" | "B" | "I"}
address = @{("0x")? ~ ASCII_HEX_DIGIT{1, 3}} // actually this can be both: an address or a constant
ident_char = _{ 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" }
identifier =  @{('a'..'z' | 'A'..'Z') ~ ident_char* | "_" ~ ident_char+ }
math_operator = { "SUB" | "ADD"}
conditionals = { "SE" | "SNE" }
ldi_operator = { "LDI" } // this is done so strangely so in opcode we have an "operator"
ld_operator = { "LD" }
jmp_operator = { "JMP" }
drw_operator = { "DRW" }
call_operator = { "CALL" }
label_definition = { identifier ~ ":" }
opcode = { "CLS" | "RET" |
  math_operator ~ register ~ "," ~ register |
  call_operator ~ (address | identifier) |
  ldi_operator ~ address |
  jmp_operator ~ (address | identifier) |
  math_operator ~ register ~ "," ~ address |
  drw_operator ~ register ~ "," ~ register ~ "," ~ address |
  conditionals ~ register ~ "," ~ address |
  ld_operator ~ register ~ "," ~ (special_register | address) | 
  ld_operator ~ special_register ~ "," ~ register |
  label_definition
}*/

ident_char = _{ 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" }
identifier =  @{('a'..'z' | 'A'..'Z') ~ ident_char* | "_" ~ ident_char+ }

path_char = _{ 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" | "/" | "." }
path = @{path_char+}
preprocessor_identifier = {identifier | "<" ~ path ~ ">"}

// @TODO: No identifier here
string_literal = { "\"" ~ identifier ~ "\"" }
numeric_literal = { "-"? ~ ASCII_DIGIT+}

preprocessor_directive = { "#" ~ (preprocessor_identifier ~ (preprocessor_identifier)*)}

function_parameter = { identifier | string_literal | numeric_literal }
function_parameters = { (function_parameter ~ ",")* ~ function_parameter }
function_call = { identifier ~ "(" ~ function_parameters ~ ")" }
statement = { function_call ~ ";" | preprocessor_directive }

COMMENT = _{"//" ~ (!NEWLINE ~ ANY)*} // COMMENT is special so we don't need to use it with expressions

file = {
    SOI ~
    ((statement)? ~ NEWLINE)* ~
    statement? ~ // The upper rule only works with a trailing new line.
    EOI
}

WHITESPACE = _{ " " | "\t" }