Implementing the require_tree was fairly trivial since everything else was basically in place. I was able to make use of filepath.Walk to just walk the files and then run the Javascript processor over the files, one by one.

There are still a few issues with the implementation. For instance, using a require_tree .. is likely going to crash. The easy solution would be to disallow going up directories. A perhaps better solution would be to checksum the files, store that in a hash, and only process files that don't match a processed checksum. This is going to be slower, but should provide a better experience when using it.

Other things that still need to be done are:

  • caching
  • custom processors (think, Coffeescript, SASS, minification, etc)
  • command line tools for pre-processing assets (for caching.)

Other things that might be interesting. Getting the baseline application layout from ember-rails, getting the uncompressed jQuery, HTMLBars, & Ember.js, and then loading them from application.js with appropriate requires; everything seems to work as expected. It'll be faster, to include these normally, but it's a slightly interesting point of reference that it processed 2020288 bytes in about 20ms. Honestly, this was the end goal I was really hoping to accomplish with this project. I was really wanting to play with Ember from a non-Rails application (specifically in Go) that had Sprockets-like autoloading of Javascript files for quick iterations. The project will likely be going on Github in the next few days after I write some documentation & tests for it.

More submissions by Harley for Code @Home

Back at it

A submission by Harley for Code @Home 225

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.)

GCC

A submission by Harley for Code @Home 33

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.

mul.S187 bytes
2 downloads

Go

A submission by Harley for Code @Home 31

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

Quick

A submission by Harley for Code @Home 30

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.

Ember.js

A submission by Harley for Code @Home 28

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.

MSP430

A submission by Harley for Code @Home 27

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.

Code @Home

Work on a Home Project each day

daily from 2015-01-26 to 2015-12-31