Up to Main Index Up to Journal for November, 2013 JOURNAL FOR THURSDAY 28TH NOVEMBER, 2013 ______________________________________________________________________________ SUBJECT: Parsing state and method values DATE: Thu 28 Nov 22:03:51 GMT 2013 This week has been an incredibly stressful one and I thought I wasn't going to get any time to work on WolfMUD. Exactly because it had been so stressful I made sure to make the time and I'm glad I did as it proved to be particularly productive. When Go 1.1 was released it introduced method values. These are methods that are bound to specific receiver values. For the parsers this allow the code to be considerably simplified. Below I've tried to come up with a simple yet relevant example. The example is driven by the count in the state struct. In reality we would be driven by an input source such as from the user or maybe scripted. 1 package main 2 3 type state struct { 4 count int 5 next func() 6 } 7 8 func Init() *state { 9 s := &state{} 10 s.next = s.welcome 11 return s 12 } 13 14 func main() { 15 for s := Init(); s.next != nil; s.next() { 16 } 17 } 18 19 func (s *state) welcome() { 20 println("Welcome!") 21 s.next = s.greet 22 } 23 24 func (s *state) greet() { 25 if s.count++; s.count < 4 { 26 println("Hello...") 27 } else { 28 s.next = s.bye 29 } 30 } 31 32 func (s *state) bye() { 33 println("Bye Bye :(") 34 s.next = nil 35 } If you run it, the following output is produced: Welcome! Hello... Hello... Hello... Bye Bye :( So what is going on here? We have a state struct which is used to pass around our current data values. In this case count which is an int and next which is a function that takes no parameters and returns nothing - actually it will refer to a method receiver bound to the state struct instance called s. The expression s.next = s.func where func is one of welcome, greet or bye will create the method value and store it in s.next. We can then call whichever method is stored in s.next by doing s.next(). So lines 15 and 16 become a very simple driver. We initialise our state struct s and keep calling whatever method value is stored in s.next until s.next is nil. So in the example the processing is: Initially s.next is s.welcome s.welcome sets s.next to s.greet s.greet increments the count if count is less than 4 we don't change s.next so s.greet is called again when count is 4 or more we set s.next to s.bye s.bye sets s.next to nil terminating our driving for loop Obviously for the actual parsers there is a lot more too it but that's basically how they now work. As soon as I finish the coding off and do a lot a cleanup I'll push the changes out for people to play with. Incidentally by doing things this way I have a lot of cleanup to do as I'm actually ripping out a lot of existing code that is no longer needed... -- Diddymus Up to Main Index Up to Journal for November, 2013