]>
Witch of Git - jade-rose/blob - toolchain/src/inst/parse.rs
1 use super::{AddImm
, AluI
, Data
, Inst
, Op1
, OpI3
, OpR
, Reg
, Special
, U3
};
4 bytes
::complete
::tag_no_case
,
5 character
::complete
::{char, digit1
, one_of
, space1
},
6 combinator
::{complete
, map
, map_opt
, map_res
, opt
, recognize
, value
},
7 sequence
::{pair
, preceded
},
10 use std
::convert
::TryFrom
;
12 pub fn parse_inst(s
: &str) -> Option
<Inst
> {
13 complete(inst())(s
).ok().map(|x
| x
.1)
20 E
: nom
::error
::ParseError
<I
> + 'a
,
21 List
: nom
::branch
::Alt
<I
, O
, E
> + 'a
,
24 ) -> Box
<dyn
Fn(I
) -> IResult
<I
, O
, E
> + 'a
> {
28 fn inst
<'s
>() -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
31 fixed("trap", Inst
::Trap
),
32 fixed("JABS", Inst
::JAbs
),
33 fixed("CABS", Inst
::CAbs
),
34 fixed("JOFF", Inst
::JOff
),
35 fixed("COFF", Inst
::COff
),
38 with_reg("SWAP", |r
| Inst
::Swap(r
)),
39 with_reg("GETR", |r
| Inst
::GetR(r
)),
40 with_reg("SETR", |r
| Inst
::SetR(r
)),
43 fixed("GET1", Inst
::Get(Special
::Data(Data
::D1
))),
44 fixed("GET2", Inst
::Get(Special
::Data(Data
::D2
))),
45 fixed("GETC", Inst
::Get(Special
::Code
)),
46 fixed("SET1", Inst
::Set(Special
::Data(Data
::D1
))),
47 fixed("SET2", Inst
::Set(Special
::Data(Data
::D2
))),
48 fixed("SETC", Inst
::Set(Special
::Code
)),
49 fixed("ZERO", Inst
::Alu1(Op1
::Zero
)),
50 fixed("LSL1", Inst
::Alu1(Op1
::Lsl1
)),
51 fixed("LSR1", Inst
::Alu1(Op1
::Lsr1
)),
52 fixed("ASR1", Inst
::Alu1(Op1
::Asr1
)),
53 fixed("INCR", Inst
::Alu1(Op1
::Incr
)),
54 fixed("DECR", Inst
::Alu1(Op1
::Decr
)),
55 fixed("COMP", Inst
::Alu1(Op1
::Comp
)),
56 fixed("NEGT", Inst
::Alu1(Op1
::Negt
)),
59 with_reg("ISLT", |r
| Inst
::IsLt(r
)),
60 with_reg("ADDR", |r
| Inst
::AluR(OpR
::Add
, r
)),
61 with_reg("SUBR", |r
| Inst
::AluR(OpR
::Sub
, r
)),
62 with_reg("ANDR", |r
| Inst
::AluR(OpR
::And
, r
)),
63 with_reg("IORR", |r
| Inst
::AluR(OpR
::Ior
, r
)),
64 with_reg("XORR", |r
| Inst
::AluR(OpR
::Xor
, r
)),
65 with_reg("LSLR", |r
| Inst
::AluR(OpR
::Lsl
, r
)),
66 with_reg("LSRR", |r
| Inst
::AluR(OpR
::Lsr
, r
)),
67 with_reg("ASRR", |r
| Inst
::AluR(OpR
::Asr
, r
)),
70 with_reg_bang("LD1U", |r
, b
| Inst
::LdD(Data
::D1
, r
, b
)),
71 with_reg_bang("ST1U", |r
, b
| Inst
::StD(Data
::D1
, r
, b
)),
72 with_reg_bang("LD2U", |r
, b
| Inst
::LdD(Data
::D2
, r
, b
)),
73 with_reg_bang("ST2U", |r
, b
| Inst
::StD(Data
::D2
, r
, b
)),
76 with_imm8("ANDI", |imm
| Inst
::AluI(AluI
::And(imm
))),
77 with_imm8("IORI", |imm
| Inst
::AluI(AluI
::Ior(imm
))),
78 with_imm8("XORI", |imm
| Inst
::AluI(AluI
::Xor(imm
))),
80 with_add_imm("ADDI", |imm
| Inst
::AluI(AluI
::Add(imm
))),
82 with_imm3("ROLI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Rol
, imm
))),
83 with_imm3("LSLI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Lsl
, imm
))),
84 with_imm3("LSRI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Lsr
, imm
))),
85 with_imm3("ASRI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Asr
, imm
))),
86 with_imm3("CLRI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Clr
, imm
))),
87 with_imm3("SETI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Set
, imm
))),
88 with_imm3("TOGI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Tog
, imm
))),
89 with_imm3("EXTI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Ext
, imm
))),
92 with_off("BEZI", |off
| Inst
::BEzI(off
)),
93 with_off("JOFI", |off
| Inst
::JOfI(off
)),
94 with_off("COFI", |off
| Inst
::COfI(off
)),
99 fn fixed
<'s
>(tag
: &'s
str, inst
: Inst
) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
100 value(inst
, tag_no_case(tag
))
103 fn reg
<'s
>() -> impl Fn(&'s
str) -> IResult
<&'s
str, Reg
> {
104 let raw
= preceded(tag_no_case("r"), digit1
);
105 let num
= map_res(raw
, |x
: &str| x
.parse());
106 map_opt(num
, Reg
::new
)
109 fn imm
<'s
>() -> impl Fn(&'s
str) -> IResult
<&'s
str, i16> {
110 let text
= recognize(pair(opt(one_of("+-")), digit1
));
111 map_res(preceded(char('
#'), text), |x: &str| x.parse())
114 fn imm8
<'s
>() -> impl Fn(&'s
str) -> IResult
<&'s
str, u8> {
115 map_res(imm(), TryFrom
::try_from
)
118 fn add_imm
<'s
>() -> impl Fn(&'s
str) -> IResult
<&'s
str, AddImm
> {
119 map_opt(map_res(imm(), TryFrom
::try_from
), AddImm
::new
)
122 fn imm3
<'s
>() -> impl Fn(&'s
str) -> IResult
<&'s
str, U3
> {
123 map_opt(map_res(imm(), TryFrom
::try_from
), U3
::new
)
126 fn imm_off
<'s
>() -> impl Fn(&'s
str) -> IResult
<&'s
str, i8> {
127 map_res(imm(), TryFrom
::try_from
)
132 make_inst
: impl Fn(Reg
) -> Inst
,
133 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
134 let reg
= preceded(pair(tag_no_case(tag
), space1
), reg());
138 fn with_reg_bang
<'s
>(
140 make_inst
: impl Fn(Reg
, bool
) -> Inst
,
141 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
143 preceded(pair(tag_no_case(tag
), space1
), reg()),
144 map(opt(char('
!'
)), |x
| x
.is
_some
()),
146 map(reg_bang
, move |(r
, b
)| make_inst(r
, b
))
151 make_inst
: impl Fn(u8) -> Inst
,
152 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
153 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm8());
159 make_inst
: impl Fn(AddImm
) -> Inst
,
160 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
161 let imm
= preceded(pair(tag_no_case(tag
), space1
), add_imm());
167 make_inst
: impl Fn(U3
) -> Inst
,
168 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
169 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm3());
175 make_inst
: impl Fn(i8) -> Inst
,
176 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
177 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm_off());