Created
December 19, 2010 00:10
-
-
Save xaviershay/746997 to your computer and use it in GitHub Desktop.
IO code to interpret JS style hashes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Code to interpret javascript style hashes, without having to source them from | |
# a different file (as happens when you use the operator table. The key | |
# does not have to be surrounded in quotes. | |
# | |
# {key: "my value} | |
# Resolver is a proxy object needed to figure out the key of a pair. | |
Resolver := Object clone | |
Resolver resolve := method( | |
# Jiggery-pokery to extract name and value from the message without eval-ing it | |
# Eval the message in the context of the sender just once, since the message | |
# will be a variable pointing at the code we actually want, such as "a | |
# : 1". This resultant Message is not eval'ed yet. | |
name := call sender doMessage(call message arguments at(0)) | |
# This will include the : message as the first thing, but that is skipped | |
# by the definition of : on Resolved | |
value := name next | |
# Just take the first token for name (setNext with no arg sets it to nil) | |
name setNext | |
Map clone atPut( | |
doMessage(name) asString, # Eval the name, unquoted messages will fall through to #forward below | |
doMessage(value) # Eval the value, will fall through to #: below | |
) | |
) | |
# Pass over the : method silently by simply calling the next message in | |
# the chain (the value). | |
Resolver : := method( | |
# Don't execute value in the context of the resolver, we don't want method | |
# missing behaviour. | |
Object (call message next) | |
) | |
# Support string keys without surrounding "" by returning the name of the | |
# method. Defined variables of actual Strings/Numbers will not trigger this | |
# method, and will evaluate to themselves. | |
Resolver forward := method( | |
call message name | |
) | |
curlyBrackets := method( | |
m := Map clone | |
call message arguments foreach(x, | |
m mergeInPlace(Resolver resolve(x)) | |
) | |
m | |
) | |
# Adapted from http://c2.com/~ward/io/IoGame/iogame.io | |
assert := method ( | |
actual := self clone doMessage (call message argAt(0)) | |
expected := call sender doMessage (call message argAt(1)) | |
if (expected != actual, | |
writeln ( | |
self type .. ": ", | |
call message argAt(0) code, | |
" ==> ", actual, " not ", expected | |
) | |
Exception raise ("Assert Failed", self type .. ": " .. call message argAt(0) code) | |
) | |
) | |
assertRaise := method ( | |
if(try( self clone doMessage(call message argAt(0))) not, | |
Exception raise("Assert Failed", self type .. ": " .. call message argAt(0) code) | |
) | |
) | |
d := 4 | |
{a: 1, b: 1+1, "c": "3", "d": d, "e": {a: 6}} do( | |
assert(at("a"), 1) | |
assert(at("b"), 2) | |
assert(at("c"), "3") | |
assert(at("d"), 4) | |
assert(at("e") at("a"), 6) | |
) | |
assertRaise({"a": a}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment