]>
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
, terminated
},
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("STOP", Inst
::Stop
),
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 sign(s
: &str) -> IResult
<&str, i16> {
105 value(-1, char('
-'
)),
106 value(1, tag_no_case("")),
110 fn imm_dec(s
: &str) -> IResult
<&str, i16> {
111 let prefix
= terminated(sign
, opt(tag_no_case("0d")));
112 map_res(pair(prefix
, digit1
), |p
: (i16, &str)| {
113 p
.1.parse
::<i16>().map(|x
| x
* p
.0)
117 fn imm_hex(s
: &str) -> IResult
<&str, i16> {
118 let text
= recognize(hex_digit1
);
119 map_res(preceded(tag_no_case("0x"), text
), |x
| {
120 i16::from_str_radix(x
, 16)
124 fn imm_oct(s
: &str) -> IResult
<&str, i16> {
125 let text
= recognize(oct_digit1
);
126 map_res(preceded(tag_no_case("0o"), text
), |x
| {
127 i16::from_str_radix(x
, 8)
131 fn imm_bin(s
: &str) -> IResult
<&str, i16> {
132 let text
= recognize(many1(one_of("01")));
133 map_res(preceded(tag_no_case("0b"), text
), |x
| {
134 i16::from_str_radix(x
, 2)
138 fn imm(s
: &str) -> IResult
<&str, i16> {
139 alt((imm_hex
, imm_oct
, imm_bin
, imm_dec
))(s
)
142 fn imm8(s
: &str) -> IResult
<&str, u8> {
143 map_res(imm
, TryFrom
::try_from
)(s
)
146 fn simm8(s
: &str) -> IResult
<&str, i8> {
147 map_res(imm
, TryFrom
::try_from
)(s
)
150 fn fimm8(s
: &str) -> IResult
<&str, u8> {
151 alt((imm8
, map(simm8
, |x
| x
as u8)))(s
)
154 fn add_imm(s
: &str) -> IResult
<&str, AddImm
> {
155 map_opt(map_res(imm
, TryFrom
::try_from
), AddImm
::new
)(s
)
158 fn imm3(s
: &str) -> IResult
<&str, U3
> {
159 map_opt(map_res(imm
, TryFrom
::try_from
), U3
::new
)(s
)
162 fn imm_off(s
: &str) -> IResult
<&str, i8> {
163 map_res(imm
, TryFrom
::try_from
)(s
)
168 make_inst
: impl Fn(Reg
) -> Inst
,
169 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
170 let reg
= preceded(pair(tag_no_case(tag
), space1
), reg
);
174 fn with_reg_bang
<'s
>(
176 make_inst
: impl Fn(Reg
, bool
) -> Inst
,
177 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
179 preceded(pair(tag_no_case(tag
), space1
), reg
),
180 map(opt(char('
!'
)), |x
| x
.is
_some
()),
182 map(reg_bang
, move |(r
, b
)| make_inst(r
, b
))
187 make_inst
: impl Fn(u8) -> Inst
,
188 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
189 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm8
);
195 make_inst
: impl Fn(AddImm
) -> Inst
,
196 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
197 let imm
= preceded(pair(tag_no_case(tag
), space1
), add_imm
);
203 make_inst
: impl Fn(U3
) -> Inst
,
204 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
205 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm3
);
211 make_inst
: impl Fn(i8) -> Inst
,
212 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
213 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm_off
);
219 make_inst
: impl Fn(u8) -> Inst
,
220 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
221 let imm
= preceded(pair(tag_no_case(tag
), space1
), fimm8
);