]>
Witch of Git - jade-rose/blob - toolchain/src/inst/parse.rs
1 use super::{AddImm
, AluI
, Data
, Inst
, Op1
, OpI3
, OpR
, Reg
, Special
, Target
, 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("JABS", Inst
::Jump(Target
::Abs
)),
22 fixed("CABS", Inst
::Call(Target
::Abs
)),
23 fixed("JOFF", Inst
::Jump(Target
::Off
)),
24 fixed("COFF", Inst
::Call(Target
::Off
)),
27 with_reg("SWAP", |r
| Inst
::Swap(r
)),
28 with_reg("GETR", |r
| Inst
::GetR(r
)),
29 with_reg("SETR", |r
| Inst
::SetR(r
)),
32 fixed("GET1", Inst
::Get(Special
::Data(Data
::D1
))),
33 fixed("GET2", Inst
::Get(Special
::Data(Data
::D2
))),
34 fixed("GETC", Inst
::Get(Special
::Code
)),
35 fixed("SET1", Inst
::Set(Special
::Data(Data
::D1
))),
36 fixed("SET2", Inst
::Set(Special
::Data(Data
::D2
))),
37 fixed("SETC", Inst
::Set(Special
::Code
)),
38 fixed("ZERO", Inst
::Alu1(Op1
::Zero
)),
39 fixed("LSL1", Inst
::Alu1(Op1
::Lsl1
)),
40 fixed("LSR1", Inst
::Alu1(Op1
::Lsr1
)),
41 fixed("ASR1", Inst
::Alu1(Op1
::Asr1
)),
42 fixed("INCR", Inst
::Alu1(Op1
::Incr
)),
43 fixed("DECR", Inst
::Alu1(Op1
::Decr
)),
44 fixed("COMP", Inst
::Alu1(Op1
::Comp
)),
45 fixed("NEGT", Inst
::Alu1(Op1
::Negt
)),
48 with_reg("ISLT", |r
| Inst
::IsLt(r
)),
49 with_reg("ADDR", |r
| Inst
::AluR(OpR
::Add
, r
)),
50 with_reg("SUBR", |r
| Inst
::AluR(OpR
::Sub
, r
)),
51 with_reg("ANDR", |r
| Inst
::AluR(OpR
::And
, r
)),
52 with_reg("IORR", |r
| Inst
::AluR(OpR
::Ior
, r
)),
53 with_reg("XORR", |r
| Inst
::AluR(OpR
::Xor
, r
)),
54 with_reg("LSLR", |r
| Inst
::AluR(OpR
::Lsl
, r
)),
55 with_reg("LSRR", |r
| Inst
::AluR(OpR
::Lsr
, r
)),
56 with_reg("ASRR", |r
| Inst
::AluR(OpR
::Asr
, r
)),
59 with_reg_bang("LD1U", |r
, b
| Inst
::LdD(Data
::D1
, r
, b
)),
60 with_reg_bang("ST1U", |r
, b
| Inst
::StD(Data
::D1
, r
, b
)),
61 with_reg_bang("LD2U", |r
, b
| Inst
::LdD(Data
::D2
, r
, b
)),
62 with_reg_bang("ST2U", |r
, b
| Inst
::StD(Data
::D2
, r
, b
)),
65 with_imm8("ANDI", |imm
| Inst
::AluI(AluI
::And(imm
))),
66 with_imm8("IORI", |imm
| Inst
::AluI(AluI
::Ior(imm
))),
67 with_imm8("XORI", |imm
| Inst
::AluI(AluI
::Xor(imm
))),
69 with_add_imm("ADDI", |imm
| Inst
::AluI(AluI
::Add(imm
))),
71 with_imm3("ROLI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Rol
, imm
))),
72 with_imm3("LSLI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Lsl
, imm
))),
73 with_imm3("LSRI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Lsr
, imm
))),
74 with_imm3("ASRI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Asr
, imm
))),
75 with_imm3("CLRI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Clr
, imm
))),
76 with_imm3("SETI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Set
, imm
))),
77 with_imm3("TOGI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Tog
, imm
))),
78 with_imm3("EXTI", |imm
| Inst
::AluI(AluI
::Compact(OpI3
::Ext
, imm
))),
81 with_off("BEZI", |off
| Inst
::BEzI(off
)),
82 with_off("JOFI", |off
| Inst
::Jump(Target
::OffImm(off
))),
83 with_off("COFI", |off
| Inst
::Call(Target
::OffImm(off
))),
88 fn fixed
<'s
>(tag
: &'s
str, inst
: Inst
) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
89 value(inst
, tag_no_case(tag
))
92 fn reg(s
: &str) -> IResult
<&str, Reg
> {
93 let raw
= preceded(tag_no_case("r"), digit1
);
94 let num
= map_res(raw
, |x
: &str| x
.parse());
95 map_opt(num
, Reg
::new
)(s
)
98 fn imm_dec(s
: &str) -> IResult
<&str, i16> {
99 let text
= recognize(pair(opt(one_of("+-")), digit1
));
100 let prefix
= alt((tag_no_case("#d"), tag_no_case("#")));
101 map_res(preceded(prefix
, text
), |x
: &str| x
.parse())(s
)
104 fn imm_hex(s
: &str) -> IResult
<&str, i16> {
105 let text
= recognize(hex_digit1
);
106 map_res(preceded(tag_no_case("#x"), text
), |x
| {
107 i16::from_str_radix(x
, 16)
111 fn imm_oct(s
: &str) -> IResult
<&str, i16> {
112 let text
= recognize(oct_digit1
);
113 map_res(preceded(tag_no_case("#o"), text
), |x
| {
114 i16::from_str_radix(x
, 8)
118 fn imm_bin(s
: &str) -> IResult
<&str, i16> {
119 let text
= recognize(many1(one_of("01")));
120 map_res(preceded(tag_no_case("#b"), text
), |x
| {
121 i16::from_str_radix(x
, 2)
125 fn imm(s
: &str) -> IResult
<&str, i16> {
126 alt((imm_hex
, imm_oct
, imm_bin
, imm_dec
))(s
)
129 fn imm8(s
: &str) -> IResult
<&str, u8> {
130 map_res(imm
, TryFrom
::try_from
)(s
)
133 fn add_imm(s
: &str) -> IResult
<&str, AddImm
> {
134 map_opt(map_res(imm
, TryFrom
::try_from
), AddImm
::new
)(s
)
137 fn imm3(s
: &str) -> IResult
<&str, U3
> {
138 map_opt(map_res(imm
, TryFrom
::try_from
), U3
::new
)(s
)
141 fn imm_off(s
: &str) -> IResult
<&str, i8> {
142 map_res(imm
, TryFrom
::try_from
)(s
)
147 make_inst
: impl Fn(Reg
) -> Inst
,
148 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
149 let reg
= preceded(pair(tag_no_case(tag
), space1
), reg
);
153 fn with_reg_bang
<'s
>(
155 make_inst
: impl Fn(Reg
, bool
) -> Inst
,
156 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
158 preceded(pair(tag_no_case(tag
), space1
), reg
),
159 map(opt(char('
!'
)), |x
| x
.is
_some
()),
161 map(reg_bang
, move |(r
, b
)| make_inst(r
, b
))
166 make_inst
: impl Fn(u8) -> Inst
,
167 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
168 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm8
);
174 make_inst
: impl Fn(AddImm
) -> Inst
,
175 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
176 let imm
= preceded(pair(tag_no_case(tag
), space1
), add_imm
);
182 make_inst
: impl Fn(U3
) -> Inst
,
183 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
184 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm3
);
190 make_inst
: impl Fn(i8) -> Inst
,
191 ) -> impl Fn(&'s
str) -> IResult
<&'s
str, Inst
> {
192 let imm
= preceded(pair(tag_no_case(tag
), space1
), imm_off
);