]>
Witch of Git - jade-rose/blob - toolchain/src/inst/parse.rs
1 use super::{AddImm
, AluI
, Data
, Inst
, LdSt
, Op1
, OpI3
, OpR
, Reg
, Special
, U3
};
4 bytes
::complete
::tag_no_case
,
5 character
::complete
::{char, digit1
, hex_digit1
, oct_digit1
, one_of
, space1
},
6 combinator
::{complete
, map
, map_opt
, map_res
, opt
, recognize
, value
},
8 sequence
::{pair
, preceded
},
11 use std
::convert
::TryFrom
;
13 pub fn parse_inst(s
: &str) -> Option
<Inst
> {
14 complete(inst
)(s
).ok().map(|x
| x
.1)
17 pub fn inst(s
: &str) -> IResult
<&str, Inst
> {
20 fixed("TRAP", Inst
::Trap
),
21 fixed("NOPE", Inst
::Nope
),
22 fixed("PRNT", Inst
::Prnt
),
23 fixed("CABA", Inst
::CAbA
),
24 fixed("COFA", Inst
::COfA
),
27 fixed("ZERO", Inst
::Alu1(Op1
::Zero
)),
28 fixed("LSL1", Inst
::Alu1(Op1
::Lsl1
)),
29 fixed("LSR1", Inst
::Alu1(Op1
::Lsr1
)),
30 fixed("ASR1", Inst
::Alu1(Op1
::Asr1
)),
31 fixed("INCR", Inst
::Alu1(Op1
::Incr
)),
32 fixed("DECR", Inst
::Alu1(Op1
::Decr
)),
33 fixed("COMP", Inst
::Alu1(Op1
::Comp
)),
34 fixed("NEGT", Inst
::Alu1(Op1
::Negt
)),
37 fixed("GET1", Inst
::Get(Special
::Data(Data
::D1
))),
38 fixed("GET2", Inst
::Get(Special
::Data(Data
::D2
))),
39 fixed("GETC", Inst
::Get(Special
::Code
)),
40 fixed("SET1", Inst
::Set(Special
::Data(Data
::D1
))),
41 fixed("SET2", Inst
::Set(Special
::Data(Data
::D2
))),
42 fixed("SETC", Inst
::Set(Special
::Code
)),
45 with_reg("GETR", |r
| Inst
::GetR(r
)),
46 with_reg("SETR", |r
| Inst
::SetR(r
)),
47 with_reg("SWAP", |r
| Inst
::Swap(r
)),
48 with_reg("ISLT", |r
| Inst
::IsLt(r
)),
51 with_reg("ADDR", |r
| Inst
::AluR(OpR
::Add
, r
)),
52 with_reg("SUBR", |r
| Inst
::AluR(OpR
::Sub
, r
)),
53 with_reg("ANDR", |r
| Inst
::AluR(OpR
::And
, r
)),
54 with_reg("IORR", |r
| Inst
::AluR(OpR
::Ior
, r
)),
55 with_reg("XORR", |r
| Inst
::AluR(OpR
::Xor
, r
)),
56 with_reg("LSLR", |r
| Inst
::AluR(OpR
::Lsl
, r
)),
57 with_reg("LSRR", |r
| Inst
::AluR(OpR
::Lsr
, r
)),
58 with_reg("ASRR", |r
| Inst
::AluR(OpR
::Asr
, r
)),
61 with_reg_bang("LD1U", |r
, b
| Inst
::Mem(LdSt
::Ld
, Data
::D1
, r
, b
)),
62 with_reg_bang("ST1U", |r
, b
| Inst
::Mem(LdSt
::St
, Data
::D1
, r
, b
)),
63 with_reg_bang("LD2U", |r
, b
| Inst
::Mem(LdSt
::Ld
, Data
::D2
, r
, b
)),
64 with_reg_bang("ST2U", |r
, b
| Inst
::Mem(LdSt
::St
, Data
::D2
, r
, b
)),
67 with_imm8("ANDI", |imm
| Inst
::AluI(AluI
::And(imm
))),
68 with_imm8("IORI", |imm
| Inst
::AluI(AluI
::Ior(imm
))),
69 with_imm8("XORI", |imm
| Inst
::AluI(AluI
::Xor(imm
))),
71 with_add_imm("ADDI", |imm
| Inst
::AluI(AluI
::Add(imm
))),
73 with_imm3("ROLI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Rol
, imm
))),
74 with_imm3("LSLI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Lsl
, imm
))),
75 with_imm3("LSRI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Lsr
, imm
))),
76 with_imm3("ASRI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Asr
, imm
))),
77 with_imm3("CLRI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Clr
, imm
))),
78 with_imm3("INSI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Ins
, imm
))),
79 with_imm3("TOGI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Tog
, imm
))),
80 with_imm3("EXTI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Ext
, imm
))),
83 with_off("BEZI", |off
| Inst
::BEzI(off
)),
84 with_off("JOFI", |off
| Inst
::JOfI(off
)),
85 with_imm8("CABI", |imm
| Inst
::CAbI(imm
)),
86 with_off("COFI", |off
| Inst
::COfI(off
)),
87 with_fimm8("GETI", |imm
| Inst
::GetI(imm
)),
92 fn fixed
<'s
>(tag
: &'s
str, inst
: Inst
) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
93 value(inst
, tag_no_case(tag
))
96 fn reg(s
: &str) -> IResult
<&str, Reg
> {
97 let raw
= preceded(tag_no_case("r"), digit1
);
98 let num
= map_res(raw
, |x
: &str| x
.parse());
99 map_opt(num
, Reg
::new
)(s
)
102 fn imm_dec(s
: &str) -> IResult
<&str, i16> {
103 let text
= recognize(pair(opt(one_of("+-")), digit1
));
104 let prefix
= alt((tag_no_case("#d"), tag_no_case("#")));
105 map_res(preceded(prefix
, text
), |x
: &str| x
.parse())(s
)
108 fn imm_hex(s
: &str) -> IResult
<&str, i16> {
109 let text
= recognize(hex_digit1
);
110 map_res(preceded(tag_no_case("#x"), text
), |x
| {
111 i16::from_str_radix(x
, 16)
115 fn imm_oct(s
: &str) -> IResult
<&str, i16> {
116 let text
= recognize(oct_digit1
);
117 map_res(preceded(tag_no_case("#o"), text
), |x
| {
118 i16::from_str_radix(x
, 8)
122 fn imm_bin(s
: &str) -> IResult
<&str, i16> {
123 let text
= recognize(many1(one_of("01")));
124 map_res(preceded(tag_no_case("#b"), text
), |x
| {
125 i16::from_str_radix(x
, 2)
129 fn imm(s
: &str) -> IResult
<&str, i16> {
130 alt((imm_hex
, imm_oct
, imm_bin
, imm_dec
))(s
)
133 fn imm8(s
: &str) -> IResult
<&str, u8> {
134 map_res(imm
, TryFrom
::try_from
)(s
)
137 fn simm8(s
: &str) -> IResult
<&str, i8> {
138 map_res(imm
, TryFrom
::try_from
)(s
)
141 fn fimm8(s
: &str) -> IResult
<&str, u8> {
142 alt((imm8
, map(simm8
, |x
| x
as u8)))(s
)
145 fn add_imm(s
: &str) -> IResult
<&str, AddImm
> {
146 map_opt(map_res(imm
, TryFrom
::try_from
), AddImm
::new
)(s
)
149 fn imm3(s
: &str) -> IResult
<&str, U3
> {
150 map_opt(map_res(imm
, TryFrom
::try_from
), U3
::new
)(s
)
153 fn imm_off(s
: &str) -> IResult
<&str, i8> {
154 map_res(imm
, TryFrom
::try_from
)(s
)
159 make_inst
: impl Fn(Reg
) -> Inst
,
160 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
161 let reg
= preceded(pair(tag_no_case(tag
), space1
), reg
);
165 fn with_reg_bang
<'s
>(
167 make_inst
: impl Fn(Reg
, bool
) -> Inst
,
168 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
170 preceded(pair(tag_no_case(tag
), space1
), reg
),
171 map(opt(char('
!'
)), |x
| x
.is
_some
()),
173 map(reg_bang
, move |(r
, b
)| make_inst(r
, b
))
178 make_inst
: impl Fn(u8) -> Inst
,
179 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
180 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm8
);
186 make_inst
: impl Fn(AddImm
) -> Inst
,
187 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
188 let imm
= preceded(pair(tag_no_case(tag
), space1
), add_imm
);
194 make_inst
: impl Fn(U3
) -> Inst
,
195 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
196 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm3
);
202 make_inst
: impl Fn(i8) -> Inst
,
203 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
204 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm_off
);
210 make_inst
: impl Fn(u8) -> Inst
,
211 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
212 let imm
= preceded(pair(tag_no_case(tag
), space1
), fimm8
);