diff --git a/README.md b/README.md index 203bf95b..c0b8076d 100644 --- a/README.md +++ b/README.md @@ -5,26 +5,25 @@ This can be useful if you'd like to test out a new virtual machine's bytecode, or even if you're eager to write programs for the new processor architecture you just implemented in FPGA! Check out the Releases section for pre-built binaries. -Check out the Wiki for usage instructions. + +Check out the documentation for usage instructions: +- [Definition File Format](/doc/def.md) ``` -Usage: - customasm [options] [] - customasm -v | -h - +Usage: customasm [options] [] + Options: - -h, --help Display this information. - -v, --version Display version information. - -q, --quiet Do not print progress to stdout. - -f , --format= The format of the output file. Can be one of: - binary, binstr, hexstr, bindump, hexdump. - [default: hexdump] + -h, --help Display this information. + -v, --version Display version information. + -q, --quiet Suppress progress reports. + -f, --format FORMAT The format of the output file. Possible formats: + binary, binstr, hexstr, bindump, hexdump ``` The idea is that, given this definition file: ``` -.align 8 +#align 8 load r1, {value: _ <= 0xff} -> 8'0x11 value[7:0] load r2, {value: _ <= 0xff} -> 8'0x12 value[7:0] @@ -38,17 +37,17 @@ ret -> 8'0x50 ...the assembler would take this file: ``` -.address 0x8000 +#address 0x8000 multiply3x4: load r1, 0 load r2, 3 load r3, 4 - 'loop: + .loop: add r1, r2 sub r3, 1 - jnz 'loop + jnz .loop ret ``` diff --git a/doc/def.md b/doc/def.md new file mode 100644 index 00000000..23cf10e0 --- /dev/null +++ b/doc/def.md @@ -0,0 +1,160 @@ +# Definition File Format + +## Directives + +The file starts with a list of configuration directives, one per line. +The currently available directives are: + +- ```#align ``` +Sets the number of bits in a byte for the target machine. +For example, ```#align 8``` is the usual configuration for +most modern CPUs. +Memory addresses are counted in bytes, so, with 8-bit bytes, +address 0x01 actually refers to the bits 8 through 15 in +memory, inclusive. +Machine instructions must be aligned to a byte boundary, +hence the directive's name. So, with 8-bit bytes, valid +instruction sizes are 8 bits, 16 bits, 24 bits, and so on. + +## Rules + +The first line not starting with a ```#``` begins the list of rules. +A rule defines a valid mnemonic for the target machine, and its +respective binary representation. +Rules are written as ```pattern -> production```, one per line. + +### Pattern + +The pattern part of a rule defines its mnemonic. It may consist of +text, punctuation, and/or argument expressions (that will be +specified by the programmer when invoking the mnemonic). +The pattern is written as a sequence of tokens separated by spaces. +- For text and punctuation, just write it out verbatim. +- For argument expressions, write it as ```{x}```, with ```x``` +substituted for any other desired name. If there is more than one +argument, give each one a unique name. This name will be used +in the rule's binary representation to refer to its value. +- Arguments can be given a constraint that, if not +satisfied, will produce an error and abort assembly. Specify it +by adding a colon followed by the constraint after the argument +name, like ```{x: constraint}```. Use ```_``` for the argument's +value, and make sure the constraint expression returns a boolean, +like ```{x: _ >= 0 && _ <= 0xff}```. You may use [predefined +variables](#predefined-variables) in the constraint expression. + +### Production + +The production part of a rule defines its binary representation. +It consists of a sequence of expressions separated by spaces. +The binary representation must have a fixed number of bits. +- For literals (like fixed opcodes), use explicitly-sized literals: +the size in bits, followed by a single quote, followed by the value, like ```8'0x05```. +- For user-entered expressions, use a bit slice: +the expression name followed by two numbers inside brackets, like ```abc[y:x]```. +```x``` and ```y``` define the rightmost and the leftmost 0-based bit index +of the value that will be selected, counting from the least significant bit. +For example, if ```abc = 0xbbaa```, then ```abc[7:0] = 0xaa``` and ```abc[15:8] = 0xbb```. +- More complex expressions can also be evaluated; just end it off with an +explicit bit slice, like ```(abc + 0xff)[7:0]```. +- You may use [predefined variables](#predefined-variables) in expressions. + +### Predefined Variables + +The following predefined variables can be used in either argument constraints +or production expressions: +- ```pc``` +The address of the current instruction, or, in other words, the +value of the program counter when it reaches the current instruction. +Use it like ```{x: _ + pc <= 0xff}``` or ```(x - pc + 1)[7:0]```. + +### Rule Cascading + +For the purposes of automatically selecting the best binary +representation for a given mnemonic (e.g. when there are short +forms for commonly used arguments), one can use rule cascading. +Write an exclamation mark after the argument name to indicate +that the rule will only be selected if the argument satisfies +the constraint; otherwise, the next rules will be tried instead. +For example, one can write: + +``` +#align 8 + +mov {value!: _ <= 0xff} -> 8'0x10 value[ 7:0] +mov {value!: _ <= 0xffff} -> 8'0x11 value[15:0] +mov {value : _ <= 0xffffff} -> 8'0x12 value[23:0] +``` + +This will select the best fitting representation according to +the argument value. The last rule has no exclamation mark and +thus it is selected when the previous rules fail, or if the +argument value cannot be determined immediately (e.g. when +a label that will only be defined later is used). +Since it is impossible to force the use of a certain cascading +rule, it is recommended to specify unambiguous rules for all +forms, like: + +``` +#align 8 + +mov.b {value: _ <= 0xff} -> 8'0x10 value[ 7:0] +mov.w {value: _ <= 0xffff} -> 8'0x11 value[15:0] +mov.t {value: _ <= 0xffffff} -> 8'0x12 value[23:0] + +mov {value!: _ <= 0xff} -> 8'0x10 value[ 7:0] +mov {value!: _ <= 0xffff} -> 8'0x11 value[15:0] +mov {value : _ <= 0xffffff} -> 8'0x12 value[23:0] +``` + +### Rule Examples + +With ```#align 8```: + +Rule | Used as | Output +-----|---------|-------- +```load {x} -> 8'0x55 x[7:0]``` | ```load 0xff``` | ```0x55 0xff``` +```load #{x} -> 8'0x55 x[7:0]``` | ```load #0xff``` | ```0x55 0xff``` +```load.b {x} -> 8'0x55 x[7:0]``` | ```load.b 0xff``` | ```0x55 0xff``` +```mov {a} -> 8'0x77 a[7:0]``` | ```mov 0xff``` | ```0x77 0xff``` +```mov {a} -> 8'0x77 a[15:0]``` | ```mov 0xff``` | ```0x77 0x00 0xff``` +```mov {a} -> 8'0x77 a[15:0]``` | ```mov 0x1234``` | ```0x77 0x12 0x34``` +```mov {a} -> 8'0x77 a[15:8]``` | ```mov 0x1234``` | ```0x77 0x12``` +```mov {a} -> 8'0x77 a[15:8] a[7:0]``` | ```mov 0x1234``` | ```0x77 0x12 0x34``` +```mov {a} -> 8'0x77 a[7:0] a[15:8]``` | ```mov 0x1234``` | ```0x77 0x34 0x12``` +```jmp {a} -> 8'0x99 (a + 2)[7:0]``` | ```jmp 0x12``` | ```0x99 0x14``` + +## Full Examples + +``` +#align 8 + +load r1, {value: _ <= 0xff} -> 8'0x11 value[7:0] +load r2, {value: _ <= 0xff} -> 8'0x12 value[7:0] +load r3, {value: _ <= 0xff} -> 8'0x13 value[7:0] +add r1, r2 -> 8'0x21 +sub r3, {value: _ <= 0xff} -> 8'0x33 value[7:0] +jnz {address: _ <= 0xffff} -> 8'0x40 address[15:0] +ret -> 8'0x50 +``` + +``` +#align 8 + +ld r1, {value!: _ <= 0xff} -> 8'0x10 value[ 7:0] +ld r1, {value!: _ <= 0xffff} -> 8'0x11 value[15:0] +ld r1, {value : _ <= 0xffffff} -> 8'0x12 value[23:0] +add r1, {value : _ <= 0xff} -> 8'0x20 value[7:0] +add {address: _ <= 0xffffff}, {value : _ <= 0xff} -> 8'0x21 address[23:0] value[7:0] +inc r1 -> 8'0x30 +jmp {address: _ <= 0xffffff} -> 8'0x40 address[23:0] +``` + +``` +#align 3 + +lda #{value: _ <= 0b111} -> 3'0b001 value[2:0] +ldx #{value: _ <= 0b111} -> 3'0b010 value[2:0] +sta {address: _ <= 0b111111} -> 3'0b011 address[5:0] +nop -> 3'0b110 +halt -> 3'0b111 +``` \ No newline at end of file diff --git a/src/assembler.rs b/src/assembler.rs index 308aa8f7..4e2499a4 100644 --- a/src/assembler.rs +++ b/src/assembler.rs @@ -129,7 +129,7 @@ impl<'def> Assembler<'def> while !parser.is_over() { - if parser.current().is_operator(".") + if parser.current().is_operator("#") { try!(self.parse_directive(&mut parser, filename)); } else if parser.current().is_identifier() && parser.next(1).is_operator("=") @@ -138,7 +138,7 @@ impl<'def> Assembler<'def> else if parser.current().is_identifier() && parser.next(1).is_operator(":") { try!(self.parse_global_label(&mut parser)); } - else if parser.current().is_operator("'") && parser.next(1).is_identifier() && parser.next(2).is_operator(":") + else if parser.current().is_operator(".") && parser.next(1).is_identifier() && parser.next(2).is_operator(":") { try!(self.parse_local_label(&mut parser)); } else @@ -151,7 +151,7 @@ impl<'def> Assembler<'def> fn parse_directive(&mut self, parser: &mut Parser, cur_path: &Path) -> Result<(), Error> { - try!(parser.expect_operator(".")); + try!(parser.expect_operator("#")); let (directive, directive_span) = try!(parser.expect_identifier()); // If the directive starts with a 'd', it might @@ -338,7 +338,7 @@ impl<'def> Assembler<'def> fn parse_local_label(&mut self, parser: &mut Parser) -> Result<(), Error> { - try!(parser.expect_operator("'")); + try!(parser.expect_operator(".")); let (label, label_span) = try!(parser.expect_identifier()); try!(parser.expect_operator(":")); diff --git a/src/definition.rs b/src/definition.rs index fdd5a2fe..f77ed686 100644 --- a/src/definition.rs +++ b/src/definition.rs @@ -47,7 +47,7 @@ impl Definition fn parse_directives(&mut self, parser: &mut Parser) -> Result<(), Error> { - while parser.match_operator(".") + while parser.match_operator("#") { let (directive, directive_span) = try!(parser.expect_identifier()); diff --git a/src/main.rs b/src/main.rs index 92e8c252..9cdf143c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,7 +24,7 @@ fn main() let mut opts = getopts::Options::new(); opts.optflag("h", "help", "Display this information."); opts.optflag("v", "version", "Display version information."); - opts.optflag("q", "quiet", "Suppress diagnostics and progress reports."); + opts.optflag("q", "quiet", "Suppress progress reports."); opts.optopt("f", "format", "The format of the output file. Possible formats: binary, binstr, hexstr, bindump, hexdump", "FORMAT"); let matches = match opts.parse(&args[1..]) diff --git a/src/tests/definition.rs b/src/tests/definition.rs index 84c0e8ac..3074fc67 100644 --- a/src/tests/definition.rs +++ b/src/tests/definition.rs @@ -37,69 +37,69 @@ fn fail(def_str: &str, expected_error_line: usize, expected_error_substr: &str) fn test_simple() { pass(""); - pass(".align 8"); - pass(".align 8 \n halt -> 8'0"); - pass(".align 8 \n halt -> 8'0x3"); - pass(".align 8 \n halt -> 8'0x33"); - pass(".align 8 \n halt -> 4'0xd 4'0xa"); + pass("#align 8"); + pass("#align 8 \n halt -> 8'0"); + pass("#align 8 \n halt -> 8'0x3"); + pass("#align 8 \n halt -> 8'0x33"); + pass("#align 8 \n halt -> 4'0xd 4'0xa"); - pass("\n .align 8 \n halt -> 8'0x3 \n nop -> 8'0x6"); - pass(" .align 8 \n \n halt -> 8'0x3 \n nop -> 8'0x6"); - pass(" .align 8 \n halt -> 8'0x3 \n \n nop -> 8'0x6"); - pass(" .align 8 \n halt -> 8'0x3 \n nop -> 8'0x6 \n"); - pass("\n .align 8 \n \n halt -> 8'0x3 \n \n nop -> 8'0x6 \n"); + pass("\n #align 8 \n halt -> 8'0x3 \n nop -> 8'0x6"); + pass(" #align 8 \n \n halt -> 8'0x3 \n nop -> 8'0x6"); + pass(" #align 8 \n halt -> 8'0x3 \n \n nop -> 8'0x6"); + pass(" #align 8 \n halt -> 8'0x3 \n nop -> 8'0x6 \n"); + pass("\n #align 8 \n \n halt -> 8'0x3 \n \n nop -> 8'0x6 \n"); - pass("; comment \n .align 8 \n halt -> 8'0x3 \n nop -> 8'0x6"); - pass(" .align 8 ; comment \n halt -> 8'0x3 \n nop -> 8'0x6"); - pass(" .align 8 \n halt -> 8'0x3 ; comment \n nop -> 8'0x6"); - pass(" .align 8 \n halt -> 8'0x3 \n nop -> 8'0x6 ; comment"); - pass("; comment \n .align 8 ; comment \n halt -> 8'0x3 ; comment \n nop -> 8'0x6 ; comment"); + pass("; comment \n #align 8 \n halt -> 8'0x3 \n nop -> 8'0x6"); + pass(" #align 8 ; comment \n halt -> 8'0x3 \n nop -> 8'0x6"); + pass(" #align 8 \n halt -> 8'0x3 ; comment \n nop -> 8'0x6"); + pass(" #align 8 \n halt -> 8'0x3 \n nop -> 8'0x6 ; comment"); + pass("; comment \n #align 8 ; comment \n halt -> 8'0x3 ; comment \n nop -> 8'0x6 ; comment"); - pass("; comment \n \n .align 8 \n halt -> 8'0x3 \n nop -> 8'0x6"); - pass(" .align 8 ; comment \n \n halt -> 8'0x3 \n nop -> 8'0x6"); - pass(" .align 8 \n halt -> 8'0x3 ; comment \n \n nop -> 8'0x6"); - pass(" .align 8 \n halt -> 8'0x3 \n nop -> 8'0x6 ; comment \n"); - pass(" .align 8 \n halt -> 8'0x3 \n nop -> 8'0x6 ; comment \n"); - pass("; comment \n \n .align 8 ; comment \n \n halt -> 8'0x3 ; comment \n \n nop -> 8'0x6 ; comment \n"); + pass("; comment \n \n #align 8 \n halt -> 8'0x3 \n nop -> 8'0x6"); + pass(" #align 8 ; comment \n \n halt -> 8'0x3 \n nop -> 8'0x6"); + pass(" #align 8 \n halt -> 8'0x3 ; comment \n \n nop -> 8'0x6"); + pass(" #align 8 \n halt -> 8'0x3 \n nop -> 8'0x6 ; comment \n"); + pass(" #align 8 \n halt -> 8'0x3 \n nop -> 8'0x6 ; comment \n"); + pass("; comment \n \n #align 8 ; comment \n \n halt -> 8'0x3 ; comment \n \n nop -> 8'0x6 ; comment \n"); - pass(".align 8 \n halt -> pc[7:0]"); - pass(".align 8 \n halt {a} -> a[7:0]"); - pass(".align 8 \n halt {a} -> a[15:0]"); - pass(".align 8 \n halt {a} -> (a + 3)[7:0]"); - pass(".align 8 \n halt {a} -> a[3:0] a[3:0]"); - pass(".align 8 \n halt {a} {b} -> a[7:0] b[7:0]"); - pass(".align 8 \n halt {a} {b} -> a[3:0] b[3:0]"); - pass(".align 8 \n halt {a} {b} -> a[7:0] a[7:0]"); - pass(".align 8 \n halt {a} {b} -> b[7:0] a[7:0]"); - pass(".align 8 \n halt {a} {b} -> b[7:0] b[7:0]"); + pass("#align 8 \n halt -> pc[7:0]"); + pass("#align 8 \n halt {a} -> a[7:0]"); + pass("#align 8 \n halt {a} -> a[15:0]"); + pass("#align 8 \n halt {a} -> (a + 3)[7:0]"); + pass("#align 8 \n halt {a} -> a[3:0] a[3:0]"); + pass("#align 8 \n halt {a} {b} -> a[7:0] b[7:0]"); + pass("#align 8 \n halt {a} {b} -> a[3:0] b[3:0]"); + pass("#align 8 \n halt {a} {b} -> a[7:0] a[7:0]"); + pass("#align 8 \n halt {a} {b} -> b[7:0] a[7:0]"); + pass("#align 8 \n halt {a} {b} -> b[7:0] b[7:0]"); - pass(".align 8 \n halt {a} -> 8'0x45 a[7:0]"); - pass(".align 8 \n halt {a} -> 4'0x7 a[7:0] 4'0x7"); + pass("#align 8 \n halt {a} -> 8'0x45 a[7:0]"); + pass("#align 8 \n halt {a} -> 4'0x7 a[7:0] 4'0x7"); - pass(".align 8 \n halt {a: _ <= 0xff} -> 8'0x45 a[7:0]"); - pass(".align 8 \n halt {a!: _ <= 0xff} -> 8'0x45 a[7:0]"); - pass(".align 8 \n halt {a: pc <= 0xff} -> 8'0x45 a[7:0] pc[7:0]"); - pass(".align 8 \n halt {a: pc + _ <= 0xff} -> 8'0x45 a[7:0] pc[7:0]"); + pass("#align 8 \n halt {a: _ <= 0xff} -> 8'0x45 a[7:0]"); + pass("#align 8 \n halt {a!: _ <= 0xff} -> 8'0x45 a[7:0]"); + pass("#align 8 \n halt {a: pc <= 0xff} -> 8'0x45 a[7:0] pc[7:0]"); + pass("#align 8 \n halt {a: pc + _ <= 0xff} -> 8'0x45 a[7:0] pc[7:0]"); - fail(".xyz 8", 1, "directive"); - fail(".align 8 .align 8", 1, "expected line break"); - fail(".align 8 \n -> 8'0", 2, "expected pattern"); - fail(".align 8 \n halt ->", 2, "expected expression"); - fail(".align 8 \n halt -> ; 8'0x3", 2, "expected expression"); - fail(".align 8 \n halt -> 64'0xff00ff00ff00ff00", 2, "invalid"); - fail(".align 8 \n halt -> 0x12", 2, "explicit size"); - fail(".align 8 \n halt -> 8'0xfff", 2, "not fit"); - fail(".align 8 \n halt -> 4'0xd", 2, "aligned"); - fail(".align 8 \n halt {a} -> a", 2, "explicit size"); - fail(".align 8 \n halt {a} -> a[3:0]", 2, "aligned"); - fail(".align 8 \n halt {a} -> a[0:3]", 2, "invalid slice"); - fail(".align 8 \n halt {a} -> a[64:3]", 2, "big slice"); - fail(".align 8 \n halt {a} -> a[65:64]", 2, "big slice"); - fail(".align 8 \n halt {a: a <= 0xff} -> a[7:0]", 2, "invalid variable"); - fail(".align 8 \n halt {a: xyz <= 0xff} -> a[7:0]", 2, "invalid variable"); - fail(".align 8 \n halt {a: 'a <= 0xff} -> a[7:0]", 2, "invalid variable"); - fail(".align 8 \n halt {a: _ <= 0xff} -> 'a[7:0]", 2, "invalid variable"); - fail(".align 8 \n halt -> xyz", 2, "unknown parameter"); - fail(".align 8 \n halt {a: _ <= 0xff} -> _[7:0]", 2, "unknown parameter"); - fail(".align 8 \n halt {a: _ <= 0xff} -> b[7:0]", 2, "unknown parameter"); + fail("#xyz 8", 1, "directive"); + fail("#align 8 #align 8", 1, "expected line break"); + fail("#align 8 \n -> 8'0", 2, "expected pattern"); + fail("#align 8 \n halt ->", 2, "expected expression"); + fail("#align 8 \n halt -> ; 8'0x3", 2, "expected expression"); + fail("#align 8 \n halt -> 64'0xff00ff00ff00ff00", 2, "invalid"); + fail("#align 8 \n halt -> 0x12", 2, "explicit size"); + fail("#align 8 \n halt -> 8'0xfff", 2, "not fit"); + fail("#align 8 \n halt -> 4'0xd", 2, "aligned"); + fail("#align 8 \n halt {a} -> a", 2, "explicit size"); + fail("#align 8 \n halt {a} -> a[3:0]", 2, "aligned"); + fail("#align 8 \n halt {a} -> a[0:3]", 2, "invalid slice"); + fail("#align 8 \n halt {a} -> a[64:3]", 2, "big slice"); + fail("#align 8 \n halt {a} -> a[65:64]", 2, "big slice"); + fail("#align 8 \n halt {a: a <= 0xff} -> a[7:0]", 2, "invalid variable"); + fail("#align 8 \n halt {a: xyz <= 0xff} -> a[7:0]", 2, "invalid variable"); + fail("#align 8 \n halt {a: .a <= 0xff} -> a[7:0]", 2, "invalid variable"); + fail("#align 8 \n halt {a: _ <= 0xff} -> .a[7:0]", 2, "invalid variable"); + fail("#align 8 \n halt -> xyz", 2, "unknown parameter"); + fail("#align 8 \n halt {a: _ <= 0xff} -> _[7:0]", 2, "unknown parameter"); + fail("#align 8 \n halt {a: _ <= 0xff} -> b[7:0]", 2, "unknown parameter"); } \ No newline at end of file diff --git a/src/tests/full.rs b/src/tests/full.rs index 5e679027..98be3656 100644 --- a/src/tests/full.rs +++ b/src/tests/full.rs @@ -85,7 +85,7 @@ fn fail_filehandler( static DEF_SIMPLE: &'static str = " - .align 8 + #align 8 halt -> 8'0x10 add {a} -> 8'0x11 a[7:0] @@ -97,7 +97,7 @@ static DEF_SIMPLE: &'static str = static DEF_WHITESPACE: &'static str = " - .align 8 ; comment + #align 8 ; comment ; comment @@ -115,7 +115,7 @@ static DEF_WHITESPACE: &'static str = static DEF_CONSTRAINT: &'static str = " - .align 8 + #align 8 simple0 {a! : _ <= 0xff} -> 8'0x00 a[ 7:0] simple0 {a! : _ <= 0xffff} -> 8'0x01 a[15:0] @@ -137,7 +137,7 @@ static DEF_CONSTRAINT: &'static str = static DEF_EXPR: &'static str = " - .align 8 + #align 8 slice0 {a} -> 8'0x10 a[15:0] slice1 {a} -> 8'0x11 a[15:8] a[ 7:0] @@ -245,9 +245,9 @@ fn test_rules_constraints() pass(DEF_CONSTRAINT, "range1 0x91", 16, "4191"); pass(DEF_CONSTRAINT, "range1 0xa0", 16, "41a0"); - fail(DEF_CONSTRAINT, "simple0 start \n .address 0x100110011 \n start:", 1, "not satisfied"); - fail(DEF_CONSTRAINT, "multi0 start start \n .address 0x100110011 \n start:", 1, "not satisfied"); - fail(DEF_CONSTRAINT, ".d8 0xdd \n pc0 0xff", 2, "not satisfied"); + fail(DEF_CONSTRAINT, "simple0 start \n #address 0x100110011 \n start:", 1, "not satisfied"); + fail(DEF_CONSTRAINT, "multi0 start start \n #address 0x100110011 \n start:", 1, "not satisfied"); + fail(DEF_CONSTRAINT, "#d8 0xdd \n pc0 0xff", 2, "not satisfied"); fail(DEF_CONSTRAINT, "range0 0x70", 1, "not satisfied"); fail(DEF_CONSTRAINT, "range0 0x7f", 1, "not satisfied"); fail(DEF_CONSTRAINT, "range0 0x91", 1, "not satisfied"); @@ -276,8 +276,8 @@ fn test_rules_with_production_expressions() pass(DEF_EXPR, "pc0", 16, "3000"); pass(DEF_EXPR, "pc1 0x08", 16, "3108"); - pass(DEF_EXPR, ".d8 0xff \n pc0", 16, "ff3001"); - pass(DEF_EXPR, ".d8 0xff \n pc1 0x08", 16, "ff3109"); + pass(DEF_EXPR, "#d8 0xff \n pc0", 16, "ff3001"); + pass(DEF_EXPR, "#d8 0xff \n pc1 0x08", 16, "ff3109"); } @@ -305,126 +305,126 @@ fn test_rules_with_argument_expressions() #[test] fn test_address_directive() { - pass(DEF_SIMPLE, ".address 0x80 \n a: \n jmp a", 16, "1380"); - pass(DEF_SIMPLE, ".address 0x80 \n jmp a \n a:", 16, "1382"); - pass(DEF_SIMPLE, ".address 0x40 + 0x40 \n jmp a \n a:", 16, "1382"); + pass(DEF_SIMPLE, "#address 0x80 \n a: \n jmp a", 16, "1380"); + pass(DEF_SIMPLE, "#address 0x80 \n jmp a \n a:", 16, "1382"); + pass(DEF_SIMPLE, "#address 0x40 + 0x40 \n jmp a \n a:", 16, "1382"); - pass(DEF_SIMPLE, ".address pc \n a: \n jmp a", 16, "1300"); - pass(DEF_SIMPLE, ".address pc + 0x80 \n a: \n jmp a", 16, "1380"); + pass(DEF_SIMPLE, "#address pc \n a: \n jmp a", 16, "1300"); + pass(DEF_SIMPLE, "#address pc + 0x80 \n a: \n jmp a", 16, "1380"); - pass(DEF_SIMPLE, ".address pc + 0x80 \n jmp a \n .address pc + 0x10 \n a:", 16, "1392"); + pass(DEF_SIMPLE, "#address pc + 0x80 \n jmp a \n #address pc + 0x10 \n a:", 16, "1392"); - fail(DEF_SIMPLE, ".address 0 - 0x80 \n a: \n jmp a", 1, "invalid"); - fail(DEF_SIMPLE, ".address pc - 0x80 \n a: \n jmp a", 1, "invalid"); + fail(DEF_SIMPLE, "#address 0 - 0x80 \n a: \n jmp a", 1, "invalid"); + fail(DEF_SIMPLE, "#address pc - 0x80 \n a: \n jmp a", 1, "invalid"); } #[test] fn test_output_directive() { - pass(DEF_SIMPLE, ".output 0x00 \n a: \n jmp a", 16, "1300"); - pass(DEF_SIMPLE, ".output 0x01 \n a: \n jmp a", 16, "001300"); - pass(DEF_SIMPLE, ".output 0x01 + 0x01 \n jmp a \n a:", 16, "00001302"); + pass(DEF_SIMPLE, "#output 0x00 \n a: \n jmp a", 16, "1300"); + pass(DEF_SIMPLE, "#output 0x01 \n a: \n jmp a", 16, "001300"); + pass(DEF_SIMPLE, "#output 0x01 + 0x01 \n jmp a \n a:", 16, "00001302"); - pass(DEF_SIMPLE, ".output pc \n a: \n jmp a", 16, "1300"); - pass(DEF_SIMPLE, ".address 0x02 \n .output pc \n a: \n jmp a", 16, "00001302"); - pass(DEF_SIMPLE, ".address 0x02 \n .output pc \n jmp a \n a:", 16, "00001304"); + pass(DEF_SIMPLE, "#output pc \n a: \n jmp a", 16, "1300"); + pass(DEF_SIMPLE, "#address 0x02 \n #output pc \n a: \n jmp a", 16, "00001302"); + pass(DEF_SIMPLE, "#address 0x02 \n #output pc \n jmp a \n a:", 16, "00001304"); - fail(DEF_SIMPLE, ".output 0 - 0x80 \n a: \n jmp a", 1, "invalid"); - fail(DEF_SIMPLE, ".output pc - 0x80 \n a: \n jmp a", 1, "invalid"); + fail(DEF_SIMPLE, "#output 0 - 0x80 \n a: \n jmp a", 1, "invalid"); + fail(DEF_SIMPLE, "#output pc - 0x80 \n a: \n jmp a", 1, "invalid"); } #[test] fn test_data_directive_simple() { - pass(".align 1", ".d1 1, 0, 1, 0", 2, "1010"); - pass(".align 1", ".d1 1, 0, 1, 0", 16, "a"); - pass(".align 1", ".d1 0, 1, 0, 1, 0, 1, 0, 1", 16, "55"); - pass(".align 2", ".d2 2, 3", 2, "1011"); - pass(".align 2", ".d2 2, 3", 16, "b"); - pass(".align 2", ".d2 2, 3, 1, 0", 16, "b4"); - pass(".align 2", ".d8 0xb4", 16, "b4"); - pass(".align 3", ".d3 0b101", 2, "101"); - pass(".align 3", ".d3 0b101, 0b110", 2, "101110"); - pass(".align 3", ".d3 0b101, 0b110, 0b111, 0b10", 16, "bba"); - pass(".align 4", ".d4 0b1011", 2, "1011"); - pass(".align 5", ".d5 0b10110", 2, "10110"); - pass(".align 6", ".d6 0b101100", 2, "101100"); - pass(".align 7", ".d7 0b1011001", 2, "1011001"); - - pass(".align 8", ".d8 0xab, 0xcd, 0xef", 16, "abcdef"); - pass(".align 8", ".d16 0xabcd, 0xcdef, 0xefab", 16, "abcdcdefefab"); - pass(".align 8", ".d32 0x12345678, 0x1, 0xabcdef", 16, "123456780000000100abcdef"); + pass("#align 1", "#d1 1, 0, 1, 0", 2, "1010"); + pass("#align 1", "#d1 1, 0, 1, 0", 16, "a"); + pass("#align 1", "#d1 0, 1, 0, 1, 0, 1, 0, 1", 16, "55"); + pass("#align 2", "#d2 2, 3", 2, "1011"); + pass("#align 2", "#d2 2, 3", 16, "b"); + pass("#align 2", "#d2 2, 3, 1, 0", 16, "b4"); + pass("#align 2", "#d8 0xb4", 16, "b4"); + pass("#align 3", "#d3 0b101", 2, "101"); + pass("#align 3", "#d3 0b101, 0b110", 2, "101110"); + pass("#align 3", "#d3 0b101, 0b110, 0b111, 0b10", 16, "bba"); + pass("#align 4", "#d4 0b1011", 2, "1011"); + pass("#align 5", "#d5 0b10110", 2, "10110"); + pass("#align 6", "#d6 0b101100", 2, "101100"); + pass("#align 7", "#d7 0b1011001", 2, "1011001"); + + pass("#align 8", "#d8 0xab, 0xcd, 0xef", 16, "abcdef"); + pass("#align 8", "#d16 0xabcd, 0xcdef, 0xefab", 16, "abcdcdefefab"); + pass("#align 8", "#d32 0x12345678, 0x1, 0xabcdef", 16, "123456780000000100abcdef"); // Big integers currently not supported. - //pass(".align 8", ".d64 0x12345678abcdef00, 0x123", 16, "12345678abcdef000000000000000123"); - //pass(".align 8", ".d128 0x12345678abcdef", 16, "00000000000000000012345678abcdef"); - fail(".align 8", ".d64 0x123", 1, "not supported"); - fail(".align 8", ".d128 0x123", 1, "not supported"); - - fail(".align 3", ".d1 0b1", 1, "aligned"); - fail(".align 3", ".d2 0b10", 1, "aligned"); - fail(".align 4", ".d1 0b1", 1, "aligned"); - fail(".align 4", ".d2 0b10", 1, "aligned"); - fail(".align 4", ".d3 0b101", 1, "aligned"); - fail(".align 8", ".d4 0b1010", 1, "aligned"); - fail(".align 8", ".d8 0x79 \n .d4 0b1010", 2, "aligned"); + //pass("#align 8", "#d64 0x12345678abcdef00, 0x123", 16, "12345678abcdef000000000000000123"); + //pass("#align 8", "#d128 0x12345678abcdef", 16, "00000000000000000012345678abcdef"); + fail("#align 8", "#d64 0x123", 1, "not supported"); + fail("#align 8", "#d128 0x123", 1, "not supported"); + + fail("#align 3", "#d1 0b1", 1, "aligned"); + fail("#align 3", "#d2 0b10", 1, "aligned"); + fail("#align 4", "#d1 0b1", 1, "aligned"); + fail("#align 4", "#d2 0b10", 1, "aligned"); + fail("#align 4", "#d3 0b101", 1, "aligned"); + fail("#align 8", "#d4 0b1010", 1, "aligned"); + fail("#align 8", "#d8 0x79 \n #d4 0b1010", 2, "aligned"); } #[test] fn test_data_directive_with_expressions() { - pass(".align 8", ".d8 (1)", 16, "01"); - pass(".align 8", ".d8 1 + 1", 16, "02"); - pass(".align 8", ".d8 1 + 2 + 3", 16, "06"); - pass(".align 8", ".d8 (1 + 1)", 16, "02"); - - pass(".align 8", ".d8 (1), (2)", 16, "0102"); - pass(".align 8", ".d8 1 + 1, 1 + 2", 16, "0203"); - pass(".align 8", ".d8 1 + 2 + 3, 1 + 3 + 6", 16, "060a"); - pass(".align 8", ".d8 (1 + 1), (2 + 3)", 16, "0205"); + pass("#align 8", "#d8 (1)", 16, "01"); + pass("#align 8", "#d8 1 + 1", 16, "02"); + pass("#align 8", "#d8 1 + 2 + 3", 16, "06"); + pass("#align 8", "#d8 (1 + 1)", 16, "02"); + + pass("#align 8", "#d8 (1), (2)", 16, "0102"); + pass("#align 8", "#d8 1 + 1, 1 + 2", 16, "0203"); + pass("#align 8", "#d8 1 + 2 + 3, 1 + 3 + 6", 16, "060a"); + pass("#align 8", "#d8 (1 + 1), (2 + 3)", 16, "0205"); } #[test] fn test_data_directive_with_variables() { - pass(".align 8", ".d8 pc", 16, "00"); - pass(".align 8", ".d8 0x12, pc", 16, "1201"); + pass("#align 8", "#d8 pc", 16, "00"); + pass("#align 8", "#d8 0x12, pc", 16, "1201"); - pass(".align 8", "start: \n .d8 start", 16, "00"); - pass(".align 8", "start: \n .d8 0x12, 0x34, start", 16, "123400"); + pass("#align 8", "start: \n #d8 start", 16, "00"); + pass("#align 8", "start: \n #d8 0x12, 0x34, start", 16, "123400"); - pass(".align 8", ".d8 start \n start:", 16, "01"); - pass(".align 8", ".d8 0x12, 0x34, start \n start:", 16, "123403"); + pass("#align 8", "#d8 start \n start:", 16, "01"); + pass("#align 8", "#d8 0x12, 0x34, start \n start:", 16, "123403"); - pass(".align 8", "start: \n .d8 start, end \n end:", 16, "0002"); - pass(".align 8", "start: \n .d8 end, start \n end:", 16, "0200"); - pass(".align 8", "start: \n .d8 start, 0x45, end \n end:", 16, "004503"); - pass(".align 8", "start: \n .d8 end, 0x45, start \n end:", 16, "034500"); + pass("#align 8", "start: \n #d8 start, end \n end:", 16, "0002"); + pass("#align 8", "start: \n #d8 end, start \n end:", 16, "0200"); + pass("#align 8", "start: \n #d8 start, 0x45, end \n end:", 16, "004503"); + pass("#align 8", "start: \n #d8 end, 0x45, start \n end:", 16, "034500"); - pass(".align 8", ".address 0x1234 \n start: \n .d8 start", 16, "34"); - pass(".align 8", ".address 0x1234 \n start: \n .d16 start", 16, "1234"); - pass(".align 8", ".d8 start \n .address 0x1234 \n start:", 16, "34"); - pass(".align 8", ".d16 start \n .address 0x1234 \n start:", 16, "1234"); + pass("#align 8", "#address 0x1234 \n start: \n #d8 start", 16, "34"); + pass("#align 8", "#address 0x1234 \n start: \n #d16 start", 16, "1234"); + pass("#align 8", "#d8 start \n #address 0x1234 \n start:", 16, "34"); + pass("#align 8", "#d16 start \n #address 0x1234 \n start:", 16, "1234"); - fail(".align 8", ".d8 xyz", 1, "unknown"); - fail(".align 8", ".d8 0x12, xyz", 1, "unknown"); - fail(".align 8", ".d8 0x12 \n .d8 xyz", 2, "unknown"); + fail("#align 8", "#d8 xyz", 1, "unknown"); + fail("#align 8", "#d8 0x12, xyz", 1, "unknown"); + fail("#align 8", "#d8 0x12 \n #d8 xyz", 2, "unknown"); } #[test] fn test_reserve_directive() { - pass(DEF_SIMPLE, ".res 1 \n halt", 16, "0010"); - pass(DEF_SIMPLE, ".res 3 \n halt", 16, "00000010"); - pass(DEF_SIMPLE, ".res 1 + 2 \n halt", 16, "00000010"); + pass(DEF_SIMPLE, "#res 1 \n halt", 16, "0010"); + pass(DEF_SIMPLE, "#res 3 \n halt", 16, "00000010"); + pass(DEF_SIMPLE, "#res 1 + 2 \n halt", 16, "00000010"); - pass(DEF_SIMPLE, "a: \n .res 1 \n b: \n .res 1 \n jmp a", 16, "00001300"); - pass(DEF_SIMPLE, "a: \n .res 1 \n b: \n .res 1 \n jmp b", 16, "00001301"); + pass(DEF_SIMPLE, "a: \n #res 1 \n b: \n #res 1 \n jmp a", 16, "00001300"); + pass(DEF_SIMPLE, "a: \n #res 1 \n b: \n #res 1 \n jmp b", 16, "00001301"); } @@ -452,22 +452,22 @@ fn test_labels_simple() pass(DEF_SIMPLE, "jmp loop \n loop: \n halt", 16, "130210"); pass(DEF_SIMPLE, "jmp loop \n loop: \n jmp loop", 16, "13021302"); - pass(DEF_SIMPLE, "start: \n 'x: \n jmp 'x \n loop: \n 'x: \n jmp 'x", 16, "13001302"); - pass(DEF_SIMPLE, " 'x: \n jmp 'x \n loop: \n 'x: \n jmp 'x", 16, "13001302"); + pass(DEF_SIMPLE, "start: \n .x: \n jmp .x \n loop: \n .x: \n jmp .x", 16, "13001302"); + pass(DEF_SIMPLE, " .x: \n jmp .x \n loop: \n .x: \n jmp .x", 16, "13001302"); fail(DEF_SIMPLE, "start: \n jmp start \n start:", 3, "duplicate"); - fail(DEF_SIMPLE, "'xyz: \n jmp 'xyz \n 'xyz:", 3, "duplicate local"); + fail(DEF_SIMPLE, ".xyz: \n jmp .xyz \n .xyz:", 3, "duplicate local"); fail(DEF_SIMPLE, " jmp xyz", 1, "unknown"); fail(DEF_SIMPLE, "halt \n jmp xyz", 2, "unknown"); - fail(DEF_SIMPLE, " jmp 'xyz", 1, "unknown local"); - fail(DEF_SIMPLE, "halt \n jmp 'xyz", 2, "unknown local"); + fail(DEF_SIMPLE, " jmp .xyz", 1, "unknown local"); + fail(DEF_SIMPLE, "halt \n jmp .xyz", 2, "unknown local"); - fail(DEF_SIMPLE, "jmp 'xyz \n start: \n 'xyz: \n halt", 1, "unknown local"); - fail(DEF_SIMPLE, "jmp 'xyz \n start: \n 'xyz: \n jmp 'xyz", 1, "unknown local"); + fail(DEF_SIMPLE, "jmp .xyz \n start: \n .xyz: \n halt", 1, "unknown local"); + fail(DEF_SIMPLE, "jmp .xyz \n start: \n .xyz: \n jmp .xyz", 1, "unknown local"); - fail(DEF_SIMPLE, "'xyz: \n halt \n start: \n jmp 'xyz", 4, "unknown local"); - fail(DEF_SIMPLE, "'xyz: \n jmp 'xyz \n start: \n jmp 'xyz", 4, "unknown local"); + fail(DEF_SIMPLE, ".xyz: \n halt \n start: \n jmp .xyz", 4, "unknown local"); + fail(DEF_SIMPLE, ".xyz: \n jmp .xyz \n start: \n jmp .xyz", 4, "unknown local"); } @@ -479,26 +479,26 @@ fn test_include_directive() filehandler.add("def_global", "start: \n halt \n add 0x45"); filehandler.add("use_global", "jmp start"); filehandler.add("sub/simple", "halt \n add 0x67"); - filehandler.add("sub/include", "halt \n add 0x89 \n .include \"other\""); + filehandler.add("sub/include", "halt \n add 0x89 \n #include \"other\""); filehandler.add("sub/other", "halt \n add 0xab"); - filehandler.add("pass1", ".include \"simple\""); + filehandler.add("pass1", "#include \"simple\""); pass_filehandler(DEF_SIMPLE, &filehandler, "pass1", 16, "101145"); - filehandler.add("pass2", ".include \"def_global\""); - filehandler.add("pass3", ".include \"def_global\" \n .include \"use_global\""); - filehandler.add("pass4", ".include \"use_global\" \n .include \"def_global\""); + filehandler.add("pass2", "#include \"def_global\""); + filehandler.add("pass3", "#include \"def_global\" \n #include \"use_global\""); + filehandler.add("pass4", "#include \"use_global\" \n #include \"def_global\""); pass_filehandler(DEF_SIMPLE, &filehandler, "pass2", 16, "101145"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass3", 16, "1011451300"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass4", 16, "1302101145"); - filehandler.add("pass5", ".include \"sub/simple\""); - filehandler.add("pass6", ".include \"sub/include\""); + filehandler.add("pass5", "#include \"sub/simple\""); + filehandler.add("pass6", "#include \"sub/include\""); pass_filehandler(DEF_SIMPLE, &filehandler, "pass5", 16, "101167"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass6", 16, "1011891011ab"); - filehandler.add("fail1", ".include \"xyz\""); - filehandler.add("fail2", ".include \"use_global\""); + filehandler.add("fail1", "#include \"xyz\""); + filehandler.add("fail2", "#include \"use_global\""); fail_filehandler(DEF_SIMPLE, &filehandler, "fail1", "fail1", 1, "not exist"); fail_filehandler(DEF_SIMPLE, &filehandler, "fail2", "use_global", 1, "unknown"); } @@ -512,25 +512,25 @@ fn test_includebin_directive() filehandler.add("24bits", vec![0x12, 0x34, 0xe0]); filehandler.add("32bits", vec![0x12, 0x00, 0x56, 0xf0]); - filehandler.add("pass1", ".includebin \"8bits\""); - filehandler.add("pass2", ".includebin \"24bits\""); - filehandler.add("pass3", ".includebin \"32bits\""); + filehandler.add("pass1", "#includebin \"8bits\""); + filehandler.add("pass2", "#includebin \"24bits\""); + filehandler.add("pass3", "#includebin \"32bits\""); pass_filehandler(DEF_SIMPLE, &filehandler, "pass1", 16, "d0"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass2", 16, "1234e0"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass3", 16, "120056f0"); - filehandler.add("pass4", "halt \n .includebin \"8bits\" \n halt"); - filehandler.add("pass5", "halt \n .includebin \"24bits\" \n halt"); - filehandler.add("pass6", "halt \n .includebin \"32bits\" \n halt"); + filehandler.add("pass4", "halt \n #includebin \"8bits\" \n halt"); + filehandler.add("pass5", "halt \n #includebin \"24bits\" \n halt"); + filehandler.add("pass6", "halt \n #includebin \"32bits\" \n halt"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass4", 16, "10d010"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass5", 16, "101234e010"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass6", 16, "10120056f010"); - filehandler.add("fail1", ".includebin \"xyz\""); + filehandler.add("fail1", "#includebin \"xyz\""); fail_filehandler(DEF_SIMPLE, &filehandler, "fail1", "fail1", 1, "not exist"); - filehandler.add("fail2", ".includebin \"24bits\""); - fail_filehandler(".align 16", &filehandler, "fail2", "fail2", 1, "not aligned"); + filehandler.add("fail2", "#includebin \"24bits\""); + fail_filehandler("#align 16", &filehandler, "fail2", "fail2", 1, "not aligned"); } @@ -545,43 +545,43 @@ fn test_includebinstr_directive() filehandler.add("16bits", "1110101010001100"); filehandler.add("invalid", "1110101010021100"); - filehandler.add("pass1", ".includebinstr \"empty\""); - filehandler.add("pass2", ".includebinstr \"1bit\""); - filehandler.add("pass3", ".includebinstr \"2bits\""); - filehandler.add("pass4", ".includebinstr \"8bits\""); - filehandler.add("pass5", ".includebinstr \"16bits\""); - pass_filehandler(".align 1", &filehandler, "pass1", 2, ""); - pass_filehandler(".align 2", &filehandler, "pass1", 2, ""); - pass_filehandler(".align 8", &filehandler, "pass1", 2, ""); - pass_filehandler(".align 16", &filehandler, "pass1", 2, ""); - pass_filehandler(".align 1", &filehandler, "pass2", 2, "1"); - pass_filehandler(".align 1", &filehandler, "pass3", 2, "10"); - pass_filehandler(".align 2", &filehandler, "pass3", 2, "10"); - pass_filehandler(".align 1", &filehandler, "pass4", 2, "11101010"); - pass_filehandler(".align 2", &filehandler, "pass4", 2, "11101010"); - pass_filehandler(".align 4", &filehandler, "pass4", 2, "11101010"); - pass_filehandler(".align 8", &filehandler, "pass4", 2, "11101010"); - pass_filehandler(".align 1", &filehandler, "pass5", 2, "1110101010001100"); - pass_filehandler(".align 8", &filehandler, "pass5", 2, "1110101010001100"); - pass_filehandler(".align 16", &filehandler, "pass5", 2, "1110101010001100"); - - filehandler.add("pass6", "halt \n .includebinstr \"8bits\" \n halt"); - filehandler.add("pass7", "halt \n .includebinstr \"16bits\" \n halt"); + filehandler.add("pass1", "#includebinstr \"empty\""); + filehandler.add("pass2", "#includebinstr \"1bit\""); + filehandler.add("pass3", "#includebinstr \"2bits\""); + filehandler.add("pass4", "#includebinstr \"8bits\""); + filehandler.add("pass5", "#includebinstr \"16bits\""); + pass_filehandler("#align 1", &filehandler, "pass1", 2, ""); + pass_filehandler("#align 2", &filehandler, "pass1", 2, ""); + pass_filehandler("#align 8", &filehandler, "pass1", 2, ""); + pass_filehandler("#align 16", &filehandler, "pass1", 2, ""); + pass_filehandler("#align 1", &filehandler, "pass2", 2, "1"); + pass_filehandler("#align 1", &filehandler, "pass3", 2, "10"); + pass_filehandler("#align 2", &filehandler, "pass3", 2, "10"); + pass_filehandler("#align 1", &filehandler, "pass4", 2, "11101010"); + pass_filehandler("#align 2", &filehandler, "pass4", 2, "11101010"); + pass_filehandler("#align 4", &filehandler, "pass4", 2, "11101010"); + pass_filehandler("#align 8", &filehandler, "pass4", 2, "11101010"); + pass_filehandler("#align 1", &filehandler, "pass5", 2, "1110101010001100"); + pass_filehandler("#align 8", &filehandler, "pass5", 2, "1110101010001100"); + pass_filehandler("#align 16", &filehandler, "pass5", 2, "1110101010001100"); + + filehandler.add("pass6", "halt \n #includebinstr \"8bits\" \n halt"); + filehandler.add("pass7", "halt \n #includebinstr \"16bits\" \n halt"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass6", 2, "000100001110101000010000"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass7", 2, "00010000111010101000110000010000"); - filehandler.add("fail1", ".includebinstr \"xyz\""); + filehandler.add("fail1", "#includebinstr \"xyz\""); fail_filehandler(DEF_SIMPLE, &filehandler, "fail1", "fail1", 1, "not exist"); - filehandler.add("fail2", ".includebinstr \"1bit\""); - filehandler.add("fail3", ".includebinstr \"2bits\""); - filehandler.add("fail4", ".includebinstr \"8bits\""); - fail_filehandler(".align 2", &filehandler, "fail2", "fail2", 1, "not aligned"); - fail_filehandler(".align 3", &filehandler, "fail3", "fail3", 1, "not aligned"); - fail_filehandler(".align 3", &filehandler, "fail4", "fail4", 1, "not aligned"); + filehandler.add("fail2", "#includebinstr \"1bit\""); + filehandler.add("fail3", "#includebinstr \"2bits\""); + filehandler.add("fail4", "#includebinstr \"8bits\""); + fail_filehandler("#align 2", &filehandler, "fail2", "fail2", 1, "not aligned"); + fail_filehandler("#align 3", &filehandler, "fail3", "fail3", 1, "not aligned"); + fail_filehandler("#align 3", &filehandler, "fail4", "fail4", 1, "not aligned"); - filehandler.add("fail5", ".includebinstr \"invalid\""); - fail_filehandler(".align 8", &filehandler, "fail5", "fail5", 1, "invalid"); + filehandler.add("fail5", "#includebinstr \"invalid\""); + fail_filehandler("#align 8", &filehandler, "fail5", "fail5", 1, "invalid"); } @@ -595,38 +595,38 @@ fn test_includehexstr_directive() filehandler.add("16bits", "ca5f"); filehandler.add("invalid", "8z3d"); - filehandler.add("pass1", ".includehexstr \"empty\""); - filehandler.add("pass2", ".includehexstr \"4bits\""); - filehandler.add("pass3", ".includehexstr \"8bits\""); - filehandler.add("pass4", ".includehexstr \"16bits\""); - pass_filehandler(".align 1", &filehandler, "pass1", 16, ""); - pass_filehandler(".align 2", &filehandler, "pass1", 16, ""); - pass_filehandler(".align 8", &filehandler, "pass1", 16, ""); - pass_filehandler(".align 16", &filehandler, "pass1", 16, ""); - pass_filehandler(".align 1", &filehandler, "pass2", 16, "c"); - pass_filehandler(".align 2", &filehandler, "pass2", 16, "c"); - pass_filehandler(".align 4", &filehandler, "pass2", 16, "c"); - pass_filehandler(".align 4", &filehandler, "pass3", 16, "de"); - pass_filehandler(".align 8", &filehandler, "pass3", 16, "de"); - pass_filehandler(".align 4", &filehandler, "pass4", 16, "ca5f"); - pass_filehandler(".align 8", &filehandler, "pass4", 16, "ca5f"); - pass_filehandler(".align 16", &filehandler, "pass4", 16, "ca5f"); - - filehandler.add("pass5", "halt \n .includehexstr \"8bits\" \n halt"); - filehandler.add("pass6", "halt \n .includehexstr \"16bits\" \n halt"); + filehandler.add("pass1", "#includehexstr \"empty\""); + filehandler.add("pass2", "#includehexstr \"4bits\""); + filehandler.add("pass3", "#includehexstr \"8bits\""); + filehandler.add("pass4", "#includehexstr \"16bits\""); + pass_filehandler("#align 1", &filehandler, "pass1", 16, ""); + pass_filehandler("#align 2", &filehandler, "pass1", 16, ""); + pass_filehandler("#align 8", &filehandler, "pass1", 16, ""); + pass_filehandler("#align 16", &filehandler, "pass1", 16, ""); + pass_filehandler("#align 1", &filehandler, "pass2", 16, "c"); + pass_filehandler("#align 2", &filehandler, "pass2", 16, "c"); + pass_filehandler("#align 4", &filehandler, "pass2", 16, "c"); + pass_filehandler("#align 4", &filehandler, "pass3", 16, "de"); + pass_filehandler("#align 8", &filehandler, "pass3", 16, "de"); + pass_filehandler("#align 4", &filehandler, "pass4", 16, "ca5f"); + pass_filehandler("#align 8", &filehandler, "pass4", 16, "ca5f"); + pass_filehandler("#align 16", &filehandler, "pass4", 16, "ca5f"); + + filehandler.add("pass5", "halt \n #includehexstr \"8bits\" \n halt"); + filehandler.add("pass6", "halt \n #includehexstr \"16bits\" \n halt"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass5", 16, "10de10"); pass_filehandler(DEF_SIMPLE, &filehandler, "pass6", 16, "10ca5f10"); - filehandler.add("fail1", ".includehexstr \"xyz\""); + filehandler.add("fail1", "#includehexstr \"xyz\""); fail_filehandler(DEF_SIMPLE, &filehandler, "fail1", "fail1", 1, "not exist"); - filehandler.add("fail2", ".includehexstr \"4bits\""); - filehandler.add("fail3", ".includehexstr \"8bits\""); - filehandler.add("fail4", ".includehexstr \"16bits\""); - fail_filehandler(".align 8", &filehandler, "fail2", "fail2", 1, "not aligned"); - fail_filehandler(".align 3", &filehandler, "fail3", "fail3", 1, "not aligned"); - fail_filehandler(".align 3", &filehandler, "fail4", "fail4", 1, "not aligned"); + filehandler.add("fail2", "#includehexstr \"4bits\""); + filehandler.add("fail3", "#includehexstr \"8bits\""); + filehandler.add("fail4", "#includehexstr \"16bits\""); + fail_filehandler("#align 8", &filehandler, "fail2", "fail2", 1, "not aligned"); + fail_filehandler("#align 3", &filehandler, "fail3", "fail3", 1, "not aligned"); + fail_filehandler("#align 3", &filehandler, "fail4", "fail4", 1, "not aligned"); - filehandler.add("fail5", ".includehexstr \"invalid\""); - fail_filehandler(".align 8", &filehandler, "fail5", "fail5", 1, "invalid"); + filehandler.add("fail5", "#includehexstr \"invalid\""); + fail_filehandler("#align 8", &filehandler, "fail5", "fail5", 1, "invalid"); } \ No newline at end of file diff --git a/src/util/expression.rs b/src/util/expression.rs index 67d66d73..0d3148b6 100644 --- a/src/util/expression.rs +++ b/src/util/expression.rs @@ -397,7 +397,7 @@ impl<'p, 'tok> ExpressionParser<'p, 'tok> }) } - else if self.parser.current().is_operator("'") && self.parser.next(1).is_identifier() + else if self.parser.current().is_operator(".") && self.parser.next(1).is_identifier() { let start_span = self.parser.current().span.clone(); self.parser.advance();