Streak Club is a place for hosting and participating in creative streaks.
I enjoy programming languages, game engines, games, music, and old school homebrew.
I'm not going to attempt every day, but I'll try to post here a bit again. I've more-or-less been lazy about submitting here. In any case, maybe this will motivate others to remember to submit again.
Mostly I've worked on GoForth the last couple of months. It's been pretty fun hitting 100% test coverage and benchmarking most implemented words. As an example:
BenchmarkCoreWordsStackSwapCodeWord-2 2000000 638 ns/op BenchmarkCoreWordsStackSwapFastCodeWord-2 5000000 339 ns/op BenchmarkCoreWordsStackRotCodeWord-2 2000000 837 ns/op BenchmarkCoreWordsStackRotFastCodeWord-2 5000000 270 ns/op
This shows a stack swap time performing 1.8x as fast and a stack rotation performing 3.1x as fast. This one speedup was taken across any operation that was popping from the stack and then pushing a result. In most cases, an item is popped if needed, and then the top item is changed in place (or in the case of unary operators, changed in place without any push/pop.)
I also now have a basic REPL. It was surprisingly short:
package main import ( "fmt" "forth" ) func main() { reader := make(chan rune) quit := make(chan bool) f := forth.NewForth() f.SetStdInOut() f.Reader(reader, quit) fmt.Println("Welcome to an example REPL.\nType die and press enter to exit") var s string for { fmt.Scan(&s) // Just a simple break out of the repl if s == "die" { break } for _, v := range s { reader <- v } reader <- ' ' } }
This will read from input, execute any words in the dictionary, and exit when you type " die" (without quotes and the leading space) and press enter.
Next up will likely be things like branching words and figuring out a good method for doing that.
Took another break mostly out of lack of time, other obligations, etc. I got back into it a bit tonight when I realized I hadn't updated Docker in a very long time (as in, I was on version 0.4.6 circa June 22, 2013) on my desktop at home. Upon updating that, also built the docker client for the BeagleBone Black.Unfortunately (and rather expectedly), the daemon wouldn't build.
After playing around with that a bit, I started prototyping a Forth implementation in Go. I got as far as defining a couple structures implementing a common word header (name & flags mostly.) They also satisfy a common interface which includes a codeword function. The linked version iterates through the functions executing them, while the func struct runs a single function defined in the structure. This seems like a pretty straight forward way to implement this, but I'll likely play around with other methods out of curiosity.
Needed to take a bit of a break after the 33 day streak. Spent a bit of time looking at the Forth word structure. Figured out .int was giving a 32 bit int instead of 16 bit. Think the alignment issues should be worked out now. Did some other testing with MSP430 Forth. Simplified the test case a bit by about 10-20 lines.
Cleaned up things some more. Removed utility functions that the library function basically did the same thing.Overall, the code is shaping up to be in fairly good shape to submit. I'll likely spend a bit more time on it before submitting, but I don't think I'll be able to get to the more cowbell piece that's not judged anyways.
I got the tests passing. Though, I may reevaluate how I'm readingthe binary. I also went through and fixed go vet and go lint issues. I the better commented the code.
Started reading data today and modifying things as needed. Moved some things into smaller functions.I think I know what all but two bytes of the datafile is now. Right now they're read and labeled with a /* ??? */ comment. I also have the first part converting from the raw file structure into the higher level structure.
It's not great having only a few minutes at a time to work on this, but I have the Stringer methods for most of the data structure working and a best guess data structure for the binary file.
Did a bit more on my lunch break for this. Nothing to really show yet.
I make take a break form MSP430 Forth and Pipeln to try out Go Challenge. I didn't spend much time coding, as most of my time was evaluating the binary files.
Played around with the minimal Forth I pulled out and think I've figure out why IP was going to 0. So I pulled in more words to have a closer to realistic test (QUIT, RZ, RSPSTORE, & BRANCH.)
Spent my time tonight ripping out everything but what was needed to test some things. Specifically it still had NEXT, DOCOL, main, a word, and an assembly code word. I believe I've tracked the problems I've been having to the way the instruction pointer is handled in the inner interpreter. I'll probably spend tomorrow diagramming out the memory & program flow. It's nice to have the problem narrowed down more. It's much less nice not knowing exactly how to solve said issue.
I spent a fair amount of time moving code out of the main (only) source file into smaller files. I first pulled the macros into a header, then I pulled groups of word definitions into separate files, and finally fixed compilation errors. I ended up needing to declare more labels as global. In addition to that, I also implemented the rest of the comparison operations, fixed some potential problems, and finished finished the implementation for another word. I think I'm down to the last 9 words to implement (and some have partial implementations.)
Didn't get much actually done today. I mostly fought with GCC and Binutils. Specifically, the linker and linker scripts and trying to compile with -nostdlib. I may skip this bit for now and come back to it as the stdlib works for now.
Went through and added TODO markers for all incomplete words. Made stubs for several subroutines. Implemented MUL & DIVMOD as well as untested >CFA & INTERPRET.
I think I mentioned this before, but the one thing I dislike about MSP430 assembly is the lack of multiplication & division mnenomics. That said, the naive multiply function is trivial:
/* Arguments are passed in r12 & r13, r15 is used to store the result */ clr r15 1: add r12, r15 /* ignores overflow */ dec r13 jnz 1b /* To comply with the MSP430 GCC calling convension, the result would be put back into r12 */
Division is a bit more complicated, but still didn't seem too bad. I'm not posting that because I haven't done any verification of it yet. This one at least had minimal testing in isolation.
Wrote a little bit of Go code and developed a better understood a simple checksumming algorithm. Also read through most of the Elm syntax at http://elm-lang.org/learn/Syntax.elm
Keeping it short since it's really late. Did a bit of Ember.js with Go and finally understand how Ember templates have to be included since there isn't an asset pipeline that embeds the Handlebars templates into the file. I could add that to pipeln, but that means I'll need to get more into filters to allow it to be extensible.
I then spent a fair amount of time with MSP430 Forth running it on an MSP430G2553 setting breakpoints and single stepping. Things seem to work up to a point, and I figured out where it's failing. However, I'm not 100% sure what needs to happen to fix it. Need to sleep on it.
I should have realized this, but using something newly written is a great way to get distracted by finding bugs in it. I spent most of my time fixing issues that cropped up in pipeln. On the plus side, it makes that project better. On the flip-side, I didn't really get that much done with Ember.js tonight. I did get a little done, but it felt like there was a fair amount of time getting my tmux session and VIM ctrlspace workspace(s) setup.
Most of the time was working on an Ember.js application and really getting everything ready to go to fully start learning the framework. During this process I fixed a couple issues with pipeln's javascript loading via requires. One issue was it wasn't processing a file that was included with a require. However, require_tree seemed to be working as expected. Looking at the code, it ended up being pretty obvious that the processing wasn't being called there, but it was being called from the require tree function.
Once that was fixed, things started loading, but the javascript was then breaking on the client side. Turns out, another thing I sort of arbitrarily decided when writing the initial implementation of the asset loader was to collect all require statements, then go though each processing as required, and finally prepending them to the file.This can pretty easily cause errors with undefined variables after it's loaded into the browser. My solution was to include the files processed from require/require_tree statements at the site they're declared at. This way, if the require is at the bottom of the file, it loads the file at the bottom.
I also played around a little with Bourbon, Neat, & Bitters in so far as to give up on them for now since the Sass processing isn't built into pipeln yet. I briefly looked at options for building them outside of that. Manually compiling the Sass also only yielded about 200 lines of CSS with the imports for the three libraries. As that seemed like a mistake, I decided to table that for now and go with Bootstrap.
Earlier today I spent some time with MSP430 Forth cleaning up some things and committing some code that's been hanging out uncommitted for several days now.
Didn't get much done tonight. Found the msp430-elf-run command. Fixed some things when running it.
Keeping it short tonight since I've been terrible about sleeping a proper amount at night.
Shortly after posting last night, I remembered that I should be looking at the linker script for hints as to what it's expecting. Sure enough, up by the top there's something like:
__interrupt_vector_9 : { KEEP (*(__interrupt_vector_9 )) KEEP (*(__interrupt_vector_timer0_a1)) } > VECT9
So, of course I tested the human readable version
.macro SECTION_VECTOR vector .section __interrupt_vector_\vector,"ax",@progbits .endm .global test_int SECTION_VECTOR timer0_a1 .word test_int .text test_int: push r9 mov #9, r9 pop r9 reti
Compiled it and did an objdump -S:
Disassembly of section __interrupt_vector_9: 0000fff0 <__interrupt_vector_9>: fff0: 2e c1 interrupt service routine at 0xc12e 0000c12e <test_int>: c12e: 09 12 push r9 ; c130: 39 40 09 00 mov #9, r9 ; c134: 39 41 pop r9 ; c136: 00 13 reti
So there you have it. Mystery solved (or at least, was a mystery to me.) They were nice enough to allow a tolower version of the vector name appended to __interrupt_vector_ be used to lookup the expected name. This was much easier than the weird preprocessor macro expansion I was trying to get working last night.
I seem to be unable to find the documentation regarding interrupts (especially with regard to the generated assembly.) I decided to write a quick C test to figure out what it's expecting. It's interesting, but not surprising, the old toolchain and new toolchain produce interrupts differently.
#include <msp430.h> #define t_int(i) void __interrupt(i) test_##i() {} t_int(TRAPINT_VECTOR) t_int(PORT1_VECTOR) t_int(PORT2_VECTOR) t_int(ADC10_VECTOR) t_int(USCIAB0TX_VECTOR) t_int(USCIAB0RX_VECTOR) t_int(TIMER0_A1_VECTOR) t_int(TIMER0_A0_VECTOR) t_int(WDT_VECTOR) t_int(COMPARATORA_VECTOR) t_int(TIMER1_A1_VECTOR) t_int(TIMER1_A0_VECTOR) t_int(NMI_VECTOR) t_int(RESET_VECTOR)
compiled with:
msp430-elf-gcc -I$MSPGCC/include -mmcu=msp430g2553 -S test_inter.c
It results in (just a snippet):
.balign 2 .global test_TIMER0_A0_VECTOR .section __interrupt_vector_10,"ax",@progbits .word test_TIMER0_A0_VECTOR .text test_TIMER0_A0_VECTOR: ; start of function ; attributes: interrupt ; framesize_regs: 0 ; framesize_locals: 0 ; framesize_outgoing: 0 ; framesize: 0 ; elim ap -> fp 2 ; elim fp -> sp 0 ; saved regs:(none) ; start of prologue ; end of prologue ; start of epilogue RETI .size test_TIMER0_A0_VECTOR, .-test_TIMER0_A0_VECTOR
A similar macro
#define t_int(i) void __attribute__((interrupt(i))) test_##i() {}
for the old toolchain produced:
.p2align 1,0 .global test_TIMER0_A0_VECTOR .type test_TIMER0_A0_VECTOR,@function /*********************** * Interrupt Vector 9 Service Routine `test_TIMER0_A0_VECTOR' ***********************/ test_TIMER0_A0_VECTOR: .global __isr_9 __isr_9: push r4 mov r1, r4 add #2, r4 pop r4 reti .Lfe7: .size test_TIMER0_A0_VECTOR,.Lfe7-test_TIMER0_A0_VECTOR ;; End of function
It's interesting that the new toolchain puts the interrupt in a different section, while the old toolchain has a predefined global that, I'm assuming, the linker knows to look for. Not sure which one I like, but both feel relatively under documented.
Today is my 15th day in a row. I think I'm more proud of that than what I was able to accomplish today.
I didn't get nearly as much as I would have liked to done. I started reading the documentation for USCI UART in the User's Guide, I started to look at how MSPGCC generates interrupts in assembly. At about that time, I realized I'm not yet using the upstream Ti MSP430 GCC. I ended up downloading that, and fixing my code to compile with that toolchain, which was trivially adding a couple ampersands in front of some constants. It was actually more work to edit the Makefile to work out the MSP430 GCC toolchain directory. I find it slightly inconvenient to need to tell msp430-elf-gcc where to include standard headers from. Overall, I think the new toolchain is the right switch going forward.
Only had about 15 minutes today. Spent it looking at msp430-forth and started implementing KEY when I ran out of time. Maybe I'll have more time tomorrow.
It's not the most fun part of writing software, but html/template is now at 100% coverage. Almost exactly ⅓ of the code resides in html/template, so I still have a fair few more tests to write. Sadly, I think the easiest tests are written. I don't really think the middleware piece is too hard, but really requires the assets piece to be tested. The assets piece does file access & manipulation. I can't help but think that's going to be a bit more challenging to test properly.
I also decided to say screw it and threw the code on Github: https://github.com/losinggeneration/pipeln
Spent a fair amount of time benchmarking the Go code against Sprockets (I was curious.) The Go Javascript serving isn't as fast as the Sprockets implementation currently. One thing that I can think of that could get it closer to that speed would be last modified checks and serving the preprocessed version. Overall though, as far as on my desktop, I wasn't too disappointed with the results. 20ms to serve the Ember.js app (including the debug ember.js & jquery.js files.) compared to 8ms from Rails with Unicorn. Somewhat interesting was the BeagleBone Black took roughly 1400ms to serve the same files from Go. I wasn't able to run the Rails test on BeagleBone Black hardware because...
A good portion of my time was spend trying to figure out why ember-rails on the BeagleBone Black was throwing an "undefined method 'ember'" error when trying to run rails generate ember:bootstrap.
I finished the night off writing unit tests for the template code. I got to about 60% code coverage (of ~150 lines.) Overall, I was pretty happy with how well the code behaved when I started writing tests. A few things that I expected to throw errors or junk output, ended up being handled gracefully. It's likely because I did a fair amount of iterative testing before this point.
daily from
Best streak: 33, Completion: 12%