| 
									
										
										
										
											2014-10-18 13:31:20 +02:00
										 |  |  | package vm | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"math/big" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | func newStack() *stack { | 
					
						
							|  |  |  | 	return &stack{} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | type stack struct { | 
					
						
							|  |  |  | 	data []*big.Int | 
					
						
							|  |  |  | 	ptr  int | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | func (st *stack) push(d *big.Int) { | 
					
						
							| 
									
										
										
										
											2015-03-27 16:09:57 +01:00
										 |  |  | 	// NOTE push limit (1024) is checked in baseCheck | 
					
						
							| 
									
										
										
										
											2015-03-12 01:12:28 +01:00
										 |  |  | 	stackItem := new(big.Int).Set(d) | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | 	if len(st.data) > st.ptr { | 
					
						
							| 
									
										
										
										
											2015-03-12 01:12:28 +01:00
										 |  |  | 		st.data[st.ptr] = stackItem | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2015-03-12 01:12:28 +01:00
										 |  |  | 		st.data = append(st.data, stackItem) | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	st.ptr++ | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | func (st *stack) pop() (ret *big.Int) { | 
					
						
							|  |  |  | 	st.ptr-- | 
					
						
							|  |  |  | 	ret = st.data[st.ptr] | 
					
						
							|  |  |  | 	return | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | func (st *stack) len() int { | 
					
						
							|  |  |  | 	return st.ptr | 
					
						
							| 
									
										
										
										
											2014-08-21 18:15:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | func (st *stack) swap(n int) { | 
					
						
							|  |  |  | 	st.data[st.len()-n], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-n] | 
					
						
							| 
									
										
										
										
											2014-08-21 18:15:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | func (st *stack) dup(n int) { | 
					
						
							|  |  |  | 	st.push(st.data[st.len()-n]) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | func (st *stack) peek() *big.Int { | 
					
						
							|  |  |  | 	return st.data[st.len()-1] | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-27 16:09:57 +01:00
										 |  |  | func (st *stack) require(n int) error { | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | 	if st.len() < n { | 
					
						
							| 
									
										
										
										
											2015-03-27 16:09:57 +01:00
										 |  |  | 		return fmt.Errorf("stack underflow (%d <=> %d)", len(st.data), n) | 
					
						
							| 
									
										
										
										
											2014-12-31 11:12:40 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-27 16:09:57 +01:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2014-12-31 11:12:40 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | func (st *stack) Print() { | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	fmt.Println("### stack ###") | 
					
						
							|  |  |  | 	if len(st.data) > 0 { | 
					
						
							|  |  |  | 		for i, val := range st.data { | 
					
						
							|  |  |  | 			fmt.Printf("%-3d  %v\n", i, val) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		fmt.Println("-- empty --") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fmt.Println("#############") | 
					
						
							|  |  |  | } |