# 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