#!/usr/bin/env nomsu -V2.5.5.4 # This file contains the implementation of an Object-Oriented programming system. test: object "Dog": (class Dog).genus = "Canus" method [initialize %] (%.barks or= 0) method [bark, woof]: %barks = ("Bark!" for % in 1 to (me).barks) return (%barks joined with " ") method [get pissed off] ((me).barks += 1) %d = (new Dog {barks:2}) as %d: assume ((me) == %d) assume ((me).barks == 2) assume ((bark) == "Bark! Bark!") assume ((woof) == "Bark! Bark!") get pissed off assume ((me).barks == 3) assume ((bark) == "Bark! Bark! Bark!") assume ((me).genus == "Canus") assume ("\(%d.class)" == "Dog") assume (%d.genus == "Canus") assume (%d.barks == 3) as (new Dog) (assume ((me).barks == 0) or barf "Default initializer failed") as (new Dog {barks:1}) (assume ((bark) == "Bark!")) action [foo] (as (new Dog {barks:23}) (return (me).barks)) assume ((foo) == 23) or barf "Oops, \(foo) != 23" as (new Dog {barks:101}): try (as (new Dog {barks:8}) (barf)) and if it succeeds (barf) assume ((me).barks == 101) or barf ".." Error in nested 'as % %' failed to properly reset 'self' object "Corgi" extends (class Dog) (method [sploot] "splooted") %corg = (new Corgi) assume (%corg.barks == 0) as (new Corgi {barks:1}): assume ((sploot) == "splooted") or barf "subclass method failed" assume ((bark) == "Bark!") or barf "inheritance failed" assume ((woof) == "Bark!") compile [@, me] to (Lua value "self") compile [method %actions %body] to: %lua = (compile as (local action %actions %body)) for % in %actions: to %lua write "\nclass.\(% as lua id) = \(% as lua id)" return (..) Lua ".." do -- Method: \(%actions.(1).stub) \%lua end ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ parse [as %instance %body] as (..) result of: %old_self = (me) (me) = %instance try %body and if it barfs %msg: (me) = %old_self barf %msg ..or if it succeeds: (me) = %old_self compile [object %classname extends %parent %class_body] to (..) Lua ".." do local class = {name=\(%classname as lua expr)} setmetatable(class, { __index=\(%parent as lua expr), __tostring=function(cls) return cls.name end, __call=function(cls, inst) inst = setmetatable(inst or {}, cls) if cls.A_initialize_1 then cls.A_initialize_1(inst) end return inst end, }) _ENV["A"..string.as_lua_id("new "..class.name)] = class _ENV["A"..string.as_lua_id("new "..class.name.." 1")] = class _ENV["A"..string.as_lua_id("class "..class.name)] = function() return class end class.__index = class class.class = class \(%class_body as lua statements) class.__tostring = class["A"..string.as_lua_id("as text")] or function(inst) return inst.name..getmetatable(dict{}).__tostring(inst) end end ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ parse [object %classname %class_body] as (..) object %classname extends (nil) %class_body