11use crate :: {
22 assembler:: { MaybeUnresolvedInstr , Op , PseudoOp , Token } ,
3- defs:: LC3Word ,
3+ defs:: { LC3Word , RegAddr } ,
44 instruction:: { ADD_OPCODE , AND_OPCODE , ALL_JUMP_OPCODES , BRANCH_OPCODE , JSR_OPCODE , ALL_LOAD_OPCODES , ALL_STORE_OPCODES , TRAP_OPCODE , NOT_OPCODE } ,
55} ;
66use anyhow:: { bail, Result } ;
@@ -26,7 +26,7 @@ pub fn prefix_label_pass(token_chain: &[Token]) -> (Option<&str>, &[Token]) {
2626/// the asm op. If the line consists only of a comment, then an empty Vec is returned
2727#[ inline]
2828pub fn construct_instruction_pass ( token_chain : & [ Token ] ) -> Result < Vec < MaybeUnresolvedInstr > > {
29- let result: Vec < MaybeUnresolvedInstr > = Vec :: new ( ) ;
29+ let mut result: Vec < MaybeUnresolvedInstr > = Vec :: new ( ) ;
3030
3131 let operation = & token_chain[ 0 ] ;
3232
@@ -76,6 +76,7 @@ pub fn construct_instruction_pass(token_chain: &[Token]) -> Result<Vec<MaybeUnre
7676 let max_mask = const { 1 << ( MAX_OFFSET_LEN + 1 ) } ;
7777 if * num < max_mask {
7878 instr. value |= num << SHIFT ;
79+ instr. value |= 1 << MAX_OFFSET_LEN ;
7980 Ok ( ( ) )
8081 } else {
8182 bail ! ( "TOO BIG" )
@@ -100,27 +101,27 @@ pub fn construct_instruction_pass(token_chain: &[Token]) -> Result<Vec<MaybeUnre
100101 [ check_reg :: < 9 > , check_reg :: < 6 > , check_reg_or_offset :: < 0 , 5 > ] . as_slice ( ) ) ,
101102 Op :: LD => (
102103 ALL_LOAD_OPCODES [ 0 ] ,
103- [ check_reg :: < 9 > , check_offset :: < 0 , 0 > ] . as_slice ( )
104+ [ check_reg :: < 9 > , check_offset :: < 0 , 9 > ] . as_slice ( )
104105 ) ,
105106 Op :: LDI => (
106107 ALL_LOAD_OPCODES [ 1 ] ,
107- [ check_reg :: < 9 > , check_offset :: < 0 , 0 > ] . as_slice ( )
108+ [ check_reg :: < 9 > , check_offset :: < 0 , 9 > ] . as_slice ( )
108109 ) ,
109110 Op :: LDR => (
110111 ALL_LOAD_OPCODES [ 2 ] ,
111112 [ check_reg :: < 9 > , check_reg :: < 6 > , check_offset :: < 0 , 6 > ] . as_slice ( )
112113 ) ,
113114 Op :: LEA => (
114115 ALL_LOAD_OPCODES [ 3 ] ,
115- [ check_reg :: < 9 > , check_offset :: < 0 , 0 > ] . as_slice ( )
116+ [ check_reg :: < 9 > , check_offset :: < 0 , 9 > ] . as_slice ( )
116117 ) ,
117118 Op :: ST => (
118119 ALL_STORE_OPCODES [ 0 ] ,
119- [ check_reg :: < 9 > , check_offset :: < 0 , 0 > ] . as_slice ( )
120+ [ check_reg :: < 9 > , check_offset :: < 0 , 9 > ] . as_slice ( )
120121 ) ,
121122 Op :: STI => (
122123 ALL_STORE_OPCODES [ 1 ] ,
123- [ check_reg :: < 9 > , check_offset :: < 0 , 0 > ] . as_slice ( )
124+ [ check_reg :: < 9 > , check_offset :: < 0 , 9 > ] . as_slice ( )
124125 ) ,
125126 Op :: STR => (
126127 ALL_STORE_OPCODES [ 2 ] ,
@@ -142,6 +143,8 @@ pub fn construct_instruction_pass(token_chain: &[Token]) -> Result<Vec<MaybeUnre
142143 for ( process, token) in sequence. iter ( ) . zip ( & token_chain[ 1 ..] ) {
143144 process ( token, & mut instr) ?;
144145 }
146+
147+ result. push ( instr) ;
145148 } else if operation. is_meta ( ) {
146149 todo ! ( )
147150 } else if !operation. is_comment ( ) {
@@ -176,4 +179,149 @@ mod test {
176179 assert_eq ! ( label. unwrap( ) , "LABEL1" ) ;
177180 assert_eq ! ( instr[ 0 ] , Token :: INSTR ( Op :: ILLEGAL ) ) ;
178181 }
182+
183+ #[ test]
184+ fn lex_and_instr ( ) {
185+ let test_vec = vec ! [
186+ Token :: STRING ( "LABEL1" . to_string( ) ) ,
187+ Token :: INSTR ( Op :: AND ) ,
188+ Token :: REGISTER ( RegAddr :: Zero ) ,
189+ Token :: REGISTER ( RegAddr :: One ) ,
190+ Token :: REGISTER ( RegAddr :: Zero )
191+ ] ;
192+ let ( label, instr) = lexer ( & test_vec) ;
193+
194+ assert_eq ! ( label. unwrap( ) , "LABEL1" ) ;
195+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b0101000001000000 ) ;
196+
197+ let test_vec = vec ! [
198+ Token :: INSTR ( Op :: AND ) ,
199+ Token :: REGISTER ( RegAddr :: Three ) ,
200+ Token :: REGISTER ( RegAddr :: One ) ,
201+ Token :: NUM ( 0b10011 )
202+ ] ;
203+ let ( label, instr) = lexer ( & test_vec) ;
204+
205+ assert_eq ! ( label, None ) ;
206+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b0101011001110011 ) ;
207+ }
208+
209+ #[ test]
210+ fn lex_add_instr ( ) {
211+ let test_vec = vec ! [
212+ Token :: STRING ( "LABEL1" . to_string( ) ) ,
213+ Token :: INSTR ( Op :: ADD ) ,
214+ Token :: REGISTER ( RegAddr :: Zero ) ,
215+ Token :: REGISTER ( RegAddr :: One ) ,
216+ Token :: REGISTER ( RegAddr :: Zero )
217+ ] ;
218+ let ( label, instr) = lexer ( & test_vec) ;
219+
220+ assert_eq ! ( label. unwrap( ) , "LABEL1" ) ;
221+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b0001000001000000 ) ;
222+
223+ let test_vec = vec ! [
224+ Token :: INSTR ( Op :: ADD ) ,
225+ Token :: REGISTER ( RegAddr :: Three ) ,
226+ Token :: REGISTER ( RegAddr :: One ) ,
227+ Token :: NUM ( 0b10011 )
228+ ] ;
229+ let ( label, instr) = lexer ( & test_vec) ;
230+
231+ assert_eq ! ( label, None ) ;
232+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b0001011001110011 ) ;
233+ }
234+
235+ #[ test]
236+ fn lex_load_instrs ( ) {
237+ let test_vec = vec ! [
238+ Token :: INSTR ( Op :: LD ) ,
239+ Token :: REGISTER ( RegAddr :: Five ) ,
240+ Token :: NUM ( 0b000111000 )
241+ ] ;
242+ let ( label, instr) = lexer ( & test_vec) ;
243+
244+ assert_eq ! ( label, None ) ;
245+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b0010101000111000 ) ;
246+
247+ let test_vec = vec ! [
248+ Token :: INSTR ( Op :: LDI ) ,
249+ Token :: REGISTER ( RegAddr :: Five ) ,
250+ Token :: NUM ( 0b000111000 )
251+ ] ;
252+ let ( label, instr) = lexer ( & test_vec) ;
253+
254+ assert_eq ! ( label, None ) ;
255+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b1010101000111000 ) ;
256+
257+ let test_vec = vec ! [
258+ Token :: INSTR ( Op :: LDR ) ,
259+ Token :: REGISTER ( RegAddr :: Five ) ,
260+ Token :: REGISTER ( RegAddr :: Two ) ,
261+ Token :: NUM ( 0b111000 )
262+ ] ;
263+ let ( label, instr) = lexer ( & test_vec) ;
264+
265+ assert_eq ! ( label, None ) ;
266+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b0110101010111000 ) ;
267+
268+ let test_vec = vec ! [
269+ Token :: INSTR ( Op :: LEA ) ,
270+ Token :: REGISTER ( RegAddr :: Five ) ,
271+ Token :: NUM ( 0b000111000 )
272+ ] ;
273+ let ( label, instr) = lexer ( & test_vec) ;
274+
275+ assert_eq ! ( label, None ) ;
276+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b1110101000111000 ) ;
277+ }
278+
279+ #[ test]
280+ fn lex_store_instrs ( ) {
281+ let test_vec = vec ! [
282+ Token :: INSTR ( Op :: ST ) ,
283+ Token :: REGISTER ( RegAddr :: Five ) ,
284+ Token :: NUM ( 0b000111000 )
285+ ] ;
286+ let ( label, instr) = lexer ( & test_vec) ;
287+
288+ assert_eq ! ( label, None ) ;
289+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b0011101000111000 ) ;
290+
291+ let test_vec = vec ! [
292+ Token :: INSTR ( Op :: STI ) ,
293+ Token :: REGISTER ( RegAddr :: Five ) ,
294+ Token :: NUM ( 0b000111000 )
295+ ] ;
296+ let ( label, instr) = lexer ( & test_vec) ;
297+
298+ assert_eq ! ( label, None ) ;
299+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b1011101000111000 ) ;
300+
301+ let test_vec = vec ! [
302+ Token :: INSTR ( Op :: STR ) ,
303+ Token :: REGISTER ( RegAddr :: Five ) ,
304+ Token :: REGISTER ( RegAddr :: Two ) ,
305+ Token :: NUM ( 0b111000 )
306+ ] ;
307+ let ( label, instr) = lexer ( & test_vec) ;
308+
309+ assert_eq ! ( label, None ) ;
310+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b0111101010111000 ) ;
311+ }
312+
313+ #[ test]
314+ fn lex_not_instr ( ) {
315+ let test_vec = vec ! [
316+ Token :: INSTR ( Op :: NOT ) ,
317+ Token :: REGISTER ( RegAddr :: Five ) ,
318+ Token :: REGISTER ( RegAddr :: Zero ) ,
319+ ] ;
320+ let ( label, instr) = lexer ( & test_vec) ;
321+
322+ assert_eq ! ( label, None ) ;
323+ // This is the value that should be produced. Currently this fails, as there is no way to
324+ // insert arbitrary bits into instructions when forming them.
325+ assert_eq ! ( instr. unwrap( ) . first( ) . unwrap( ) . value, 0b1001101000111111 ) ;
326+ }
179327}
0 commit comments