io
about
blog
community
docs
downloads

    2006 11 30         Objective-C Syntax

    For a while we have been considering supporting Objective-C message syntax when using the ObjcBridge addon, but I recently got around to putting something together. It basically works by overriding the squareBrackets method (which Io calls when some code is in []s) to modify its AST and eval itself. The next time around, it just evals the modified version with no overhead:

    Message do(
    end := method(if(next, next end, self))
    
    insertNext := method(m,
    	if(next, m end setNext(next))
    	setNext(m)
    )
    
    makeColonUnary := method(l,
    	if(next) then(
    		if(next name == ":") then(
    			arg := next arguments first
    			if(arg next, next insertNext(arg next); arg setNext(nil))
    		)
    		next makeColonUnary
    	)
    	self
    )
    
    joinColons := method(l,
    	if(next) then(
    		if(next name == ":") then(
    			setName(self name .. ":")
    			setArguments(next arguments)
    			setNext(next next)
    		)
    		next ?joinColons
    	)
    	self
    )
    
    unInfix := method(l,
    	if(name endsWithSeq(":") and next and next name endsWithSeq(":")) then(
    		setName(self name .. next name)
    		setArguments(self arguments appendSeq(next arguments))
    		setNext(next next)
    	)
    	next ?unInfix
    	self
    )
    )
    
    squareBrackets := method(
    	call message argAt(0) makeColonUnary joinColons unInfix
    	call message setName("")
    	call sender doMessage(call message argAt(0), call sender)
    )
    
    Note,: methods like Message end and Message insertNext will probably be made part of io and the other methods will likely be simpler when support for previous pointers on Messages is added.

    And heres some test code that also shows how the AST manipulation works:
    m1 := message(a b:c d:e)
    writeln("                ", m1)
    writeln("makeColonUnary: ", m1 makeColonUnary)
    writeln("joinColons:     ", m1 joinColons)
    writeln("unInfix:        ", m1 unInfix)
    
    writeln("---------")
    
    m1 := message([a b:c d:e])
    m1 println
    try(doMessage(m1))
    m1 println
    
    
    m1 := message([a b:[c foo] d:e])
    try(doMessage(m1))
    m1 println
    
    So now expressions like:
    [a b:[c foo] d:e];
    
    Can be automatically mapped to:
    (a b:d:((c foo), e))