Saturday, May 26, 2007

Ruby Fun

I've been looking into Ruby lately. For the halibut, I decided to create a rotor-based encryption program in the spirit of Enigma. Easy peas, once I quit thinking I knew how things worked and started modeling the actual machine.

Here's a snippet that shows rotor #3.


class Rotor3 < BaseRotor
def initialize()
super
@rot =
[
[22,2,0,14,25,21,24,3,17,4,19,8,11,18,10,5,9,12,6,15,16,20,23,13,1,7],
[2,24,1,7,9,15,18,25,11,16,14,12,17,23,3,19,20,8,13,10,21,5,0,22,6,4]
]
@notches = [3,5,16,19,22]
end
end


The @rot array-of-arrays shows how a pin on one side of the rotor is wired to a pin on the other side. The @notches array is analogous to a "notch" in the rotor where a pawl would be able to engage a ratchet, spinning the rotor adjacent to this rotor. In this example, when rotor three rotates from position 3 to position 4, the next rotor should also be rotated.


EJEXCBTZHHSSPGEESJEWVNJKRGKDMDUSLPIIFUUBDDYZLAOZKK
OFAUCVITGJMNFPJFNRFZZXUPUQUSZHMZPFKPBLWURBTYCHTNOR
DVSQEGXCJIHZCHRIEQOHJLLSQJFMOKQMTRGWMFIEWQHTKCAFIV
QUALZTNCRLTMFRJROXTKQVIPPIRTVHZIRIQRSBIBSBOZFRSLKV
YEIHSVHYSJHFPAKEZMTEGURWJOKGZNBVDFZKKKHIRRMHYVUEFC
XHMEPXFABFCGCZCMYABPWTVZXBVGEDRNEKUYGXCN

Saturday, May 19, 2007

SPAMalot!

I was fortunate enough to win tickets to see SPAMalot, the stage adaptation of "Monty Python and the Holy Grail."

Parts of it were so funny it made my head hurt.

No spoilers, just go see it if you can. It is as irreverant as the original but in different ways.

Thursday, May 17, 2007

Ruby on Rails

Taking a break from the TAS project - I need to rethink my code generation strategy as it pertains to the operator precedence parser.

I installed Ruby on Rails last night. Install itself was easy. I found this excellent tutorial and created a st00pid recipe book application. Then I modified it a little, not really knowing Ruby. I monkey-see-monkey-do'd part of my changes, and guessed otherwise. This was possible due to the 'convention not configuration' midset of the Rails designers.

Rails is very much a code generator. With all such 'rapid development' tools, the first app they show you is a Rolodex. How my eyes roll. With many such tools, when you have to write a real application, the work-level goes up and suddenly you're doing all the same work anyway.

I find the "no XML config" philosophy behind rails to be refreshing and in total contrast to Hibernate. I'm getting pretty tired of XML. I'll fiddle around with RoR for a while and se what it can really do.

Now, if I only needed a database-enabled web app...

Friday, May 11, 2007

TAS Must Die, Chapter 24

Again not a lot has happened. I need to hit the lottery and become a professional hobbiest.

Most of my work lately has been improving the operator precedence parser (OPP) as I implement more of Iscript's command set. Not surprisingly, most of the mojo is in the expressions, not the rest of the syntax.

I don't like the feature of OPPs is that they provide no mechanism for robust syntax checking. Or at least the 'student' version I started with doesn't. The problem is that I implemented a stack for operators and a stack for IDs. Easy to use but it allows the following:

( 3 2 + )

When the ) is scanned, it will cause the + to be reduced. It works but isn't syntactically correct. In reality, '2' never should have been able to follow '3'. This could probably be solved by using a single stack for IDs and operators at some loss of elegance. You'd have to implement a "can this follow that" sort of routine. The stack itself would handle matching parentheses. The action table would handle "is this token valid at all" checking.

The other thing that I believe will come back to haunt me is that I push Tokens onto the ID stack. This isn't wrong in itself, but a Token is what comes back from a lexer. By the time I'm parsing it, I suspect I need something more high-powered than a Token which isn't a lot more than a name and a general data type. This became evident when I started dealing with associative arrays. Since all I have to work with in a Token is a textual name, I end up representing v1[v2] as a variable called "v1@v2". This will cause me to have to dismantle this in the Executable which is ridiculous. I can use "v1@v2" as the variable name, but under the hood I should keep track of the discreet parts (v1, v2, and their relationship) so I don't have to re-parse them later. Basically, instead of pushing Tokens onto the ID stack, I should probably be pushing Pcodes! I'll have to investigate this.

Tuesday, May 8, 2007

TAS Must Die, Chapter 23

In order to address the issue with "[...]" having three different meanings, I implemented a TokenStream decorator that determines the context of the "[" token and changes it to something with more meaning. No problems doing it except for a constant stream of wetware failures.

I then modified the operator precedence parser to injest one the new "this open bracket signals an array" meaning. Works fine.

I'll add the other two [-tokens tonight perhaps. The big-O-n^2 operator precedence parser configuration is starting to require a lot ot typing. I suppose I have "made my bed" at this point, perhaps if there is a rev 2 I'll slim it down.

Friday, May 4, 2007

TAS Must Die, Chapter 22

Work is sucking the life out of me. Not much progress on this project.

I shifted gears a bit and installed jboss. Then I wrote a totally crappy servlet that compiles some test iscript file, executes it, and displays it to a browser. In short, I now have a stem-to-stern proof of concept.

I took a gander at some of our other iscript. I need to implement while loops and such. No big deal. The gotcha right now is part of the expression parsing.

In iscript, you can have some very similar looking stuff actually meaning very different things:

<!-- #set name=fred value="zoot" -->
<!-- #set name=bob value=x[fred] -->

Yes, iscript can't support a subroutine but by God it supports associate arrays. /rolleyes
This snippet would assign the value of x["zoot"] to bob.

Now, check this.

<!-- #set name=zoot value="zappa" -->
<!-- #set name=fred value="zoot" -->
<!-- #set name=bob value=[fred] -->

This assigns "zappa" to bob. Swell, huh? The syntax on that last line means, "get the value of fred ("zoot" in this case), and treat it like a variable name, and use its value (zappa)." So the presence of the variable to the left of the open bracket changes drastically the meaning of the construct. Nice.

This gets tricky for my operator precedence parser. The operator stack is of no help if I need to know if the previous token read was a variable. I may be reduced to checking the token stream and replacing open brackets that follow variables with a different, synthetic token. That is, if the token stream is

variable [ variable2 ]

then what the parser is given is

variable ndx variable2 ]

where ndx is an operator that gives the parser enough information to reduce correctly. Now '[ variable2 ]' looks nothing like 'ndx variable2 ]'

Another option which is especially nice is if iscript doesn't support anything fancier than 'variable [' for associative arrays, is for me to tokenize variable as an indexVariable. The it would probably be possible to reduce [ variable2 ] to an index if the topmost item on the variable stack is an indexVariable.

It's also possible to have indexes on the "name" portion of SET

<!-- #set name=x[bob] value=x[eddie] -->

Where if bob is 7, x[7] will receibe a new value. The brackets function differently yet again, however, in this case:

<!-- #set name=[x+7] value=3 -->

If x had the value of "pie" a new variable called 'pie7' would be created. Without the brackets the statement fails. I need to look into this more, however.

Also note that the expressions are pretty free-form. I am pretty sure this is valid:

<!-- #set name=[[x]+[y]] value=4 -->

so append the value of the value of y to the value of the value of x, and create a new variable with that result, and assign 4 to it.

I think this is likely the most dificult part of the syntax.

On deck:

1) Solve the bracket issues
2) Implement about a zillion test cases that show said work is reasonably correct
3) Implement the "include" executable. This is fundamental to any real test of our iscript. This will probably also make me reimplement my servlet in a more reasonable way.

Several hours of work there, easy.

Tuesday, May 1, 2007

TAS Must Die, Chapter 21

Work's been a killer lately. I haven't done much on my project. I decided, since I was pretty tired, to concentrate on getting all my junit tests to work. The biggest problem I had was that I was playing fast and loose with white space. Basically when passing HTML from the input stream to the output stream, I was losing all leading and trailing spaces. This is ok until we get some iscript embedded variables in there:

(*v1*) hello

is not the same as

(*v1*)hello

It was actually pretty tricky to get this to work properly. The parser assumes correctly that all whitespace in the iscript and embedded variable sections is removed as we read from the InputStream. Otherwise we'd have to load the parser up with explicit code to devour the spaces that appear between tokens. I had to use a modal flag so I could tell when to ignore whitespace and when not to. Most unfortunate but a more practical answer doesn't present itself.

If I were using a parser generator, inserting code to devour whitespace would be easy. Adding such code to a hand-coded parser would make the code hard to read.

At this point I need to gather more iscript sample files and continue improving the parser.