|
October 2007
[
bamboo
]
09:50, Wednesday, 31 October 2007
Oren talks about a simple but interesting macro to aid with mocking. I decided to see if and how the latest meta programming facilities I've been working on are actually useful. Here's the complete application, what do you think? namespace Adapter
import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.Ast.Visitors
import Boo.Lang.Compiler.TypeSystem
import Boo.Lang.Compiler.MetaProgramming
class AdapterMacro(AbstractAstMacro):
def Expand(macro as MacroStatement):
if macro.Arguments.Count != 1 or not macro.Arguments[0] isa ReferenceExpression:
raise "adapter must be called with a single argument"
entity = NameResolutionService.Resolve(macro.Arguments[0].ToString())
raise "adapter only accept types" unless entity.EntityType == EntityType.Type
BuildType(macro, entity)
def GetModule(node as Node) as Boo.Lang.Compiler.Ast.Module:
return node.GetAncestor(NodeType.Module)
def BuildType(macro as MacroStatement, type as IType):
adapterInterface = [|
interface $("I" + type.Name):
pass
|]
adapter = [|
class $(type.Name + "Adapter")($adapterInterface):
theTarget as $(type.FullName)
def constructor(target as $(type.FullName)):
theTarget = target
|]
GetModule(macro).Members.Add(adapter)
GetModule(macro).Members.Add(adapterInterface)
for member in type.GetMembers():
AddMethod(adapter, adapterInterface, member) if member isa IMethod
BooPrinterVisitor(System.Console.Out).Visit(adapterInterface)
BooPrinterVisitor(System.Console.Out).Visit(adapter)
def AddMethod(adapter as ClassDefinition,
adapterInterface as InterfaceDefinition,
method as IMethod):
if not method.IsPublic: return
if method.IsStatic: return
if method.ReturnType.IsByRef: return
if method.ReturnType.IsArray: return
interfaceMethod = [|
def $(method.Name)() as $(method.ReturnType.FullName):
pass
|]
forwarder = interfaceMethod.CloneNode()
forwardInvocation = [| theTarget.$(method.Name)() |]
for param in method.GetParameters():
if param.IsByRef or param.Type.IsArray:
return
forwarder.Parameters.Add(
ParameterDeclaration(
Name: param.Name,
Type: SimpleTypeReference(param.Type.FullName)))
interfaceMethod.Parameters.Add(
ParameterDeclaration(
Name: param.Name,
Type: SimpleTypeReference(param.Type.FullName)))
forwardInvocation.Arguments.Add(ReferenceExpression(param.Name))
adapterInterface.Members.Add(interfaceMethod)
adapter.Members.Add(forwarder)
if method.ReturnType == TypeSystemServices.VoidType:
forwarder.Body.Add(forwardInvocation)
else:
forwarder.Body.Add([| return $forwardInvocation |])
code = [|
import Adapter
adapter int
print Int32Adapter(42) isa IInt32
|]
try:
module = compile(code, typeof(AdapterMacro).Assembly)
module.EntryPoint.Invoke(null, (null,))
except x as CompilationErrorsException:
print x.Errors.ToString(true)
[
bamboo
]
00:33, Saturday, 27 October 2007
"""
Hello World eclipse plugin.
A direct translation of
http://www.eclipse.org/articles/Article-Your%20First%20Plug-in/YourFirstPlugin.html
to boo.
"""
namespace HelloWorldPlugin
import org.eclipse.ui
import org.eclipse.jface.action
import org.eclipse.jface.dialogs
import org.eclipse.jface.viewers
class HelloWorldAction(IWorkbenchWindowActionDelegate):
activeWindow as IWorkbenchWindow
def run(proxyAction as IAction):
shell = activeWindow.getShell()
MessageDialog.openInformation(shell, "Hello from boojay!", "Hello World!")
def init(window as IWorkbenchWindow):
activeWindow = window
def dispose():
pass
def selectionChanged(proxyAction as IAction, selection as ISelection):
pass
[
bamboo
]
22:08, Thursday, 25 October 2007
If you think it makes sense to have a JVM backend for the boo programming language, join us.
[
bamboo
]
14:08, Thursday, 25 October 2007
This release includes bug fixes, performance improvements and better meta-programming capabilities [1].
[
bamboo
]
11:56, Wednesday, 24 October 2007
Yeah, I won't be playing Halo 3 unless I get one for free (hint, hint).
[
bamboo
]
20:21, Tuesday, 23 October 2007
Consider the following simple application for a moment: import org.eclipse.swt
import org.eclipse.swt.widgets
display = Display()
shell = Shell(display)
shell.setText("Hello!")
shell.setSize(200, 200)
shell.open()
while not shell.isDisposed():
if not display.readAndDispatch():
display.sleep()
display.dispose()
A boo application using the SWT java GUI library. Thanks to IKVM that's not only possible but very simple as well. So what's the news? Well, Friday morning I was chatting with Klaus and he said to me "if you get boo to emit java bytecodes I'll do all my stuff in boo". How's that for a challenge? :) Thanks again to IKVM, ObjectWeb ASM and the extensible boo pipeline architecture after a weekend of relaxed hacking boojay was born. UPDATE: Just in case it's not clear, the generated class files DO NOT require IKVM in any way and can be executed in any compliant JVM.
[
bamboo
]
18:22, Tuesday, 16 October 2007
I've finally took some time off this weekend to implement a simple object pattern matching facility as part of the newly created boo-extensions project. import Boo.PatternMatching
import Boo.Adt
def eval(e as Expression) as int:
match e:
case Const(value):
return value
case Add(left, right):
return eval(left) + eval(right)
def simplify(e as Expression) as Expression:
match e:
case Add(left: Const(value: 0), right):
return simplify(right)
case Add(left, right: Const(value: 0)):
return simplify(left)
case Add(left, right):
return Add(simplify(left), simplify(right))
case _:
return _
data Expression = Const(value as int) | Add(left as Expression, right as Expression)
e = Add(Add(Const(19), Const(0)), Add(Const(0), Const(23)))
print simplify(e)
print eval(e)
print eval(simplify(e))
'match' coupled with our recently acquired quasiquoting capabilities makes writing macros for boo a pleasant endeavour actually. |