diff --git a/Makefile b/Makefile index 967700f..2b02375 100644 --- a/Makefile +++ b/Makefile @@ -7,3 +7,6 @@ global: compile: bin/moonc moon/ moonscript/ + +watch: + moonc -w moon/ moonscript/ diff --git a/docs/reference.md b/docs/reference.md index 3a1e21c..b19f3a5 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -774,6 +774,29 @@ object to retrieve class methods and properties. print BackPack.size -- prints 10 ``` +Where as `@` can be put in front of a name to access it within self, `@@` can +be used to access a value that is stored in the `__class` of `self`. Thus, +`@@hello` is shorthand for `self.__class.hello`. + + ```moon + class Counter + count: 0 + new: => + @@count += 1 + + Counter! + Counter! + + print Counter.count -- prints 2 + ``` + +The calling semantics of `@@` are similar to `@`. Calling a `@@` name will pass +the class in as the first argument using Lua's colon syntax. + + ```moon + @@hello 1,2,3,4 + ``` + ## Export Statement Because, by default, all assignments to variables that are not lexically visible will diff --git a/moonscript/compile/value.lua b/moonscript/compile/value.lua index 677f958..a3401fc 100644 --- a/moonscript/compile/value.lua +++ b/moonscript/compile/value.lua @@ -118,8 +118,9 @@ value_compile = { return error("Unknown chain action: " .. t) end end - if ntype(callee) == "self" and node[3] and ntype(node[3]) == "call" then - callee[1] = "self_colon" + local t = ntype(callee) + if (t == "self" or t == "self_class") and node[3] and ntype(node[3]) == "call" then + callee[1] = t .. "_colon" end local callee_value = self:value(callee) if ntype(callee) == "exp" then @@ -151,7 +152,7 @@ value_compile = { if type(name) == "string" then name = name else - if name[1] == "self" then + if name[1] == "self" or name[1] == "self_class" then insert(self_args, name) end name = name[2] @@ -305,9 +306,15 @@ value_compile = { self = function(self, node) return "self." .. self:value(node[2]) end, + self_class = function(self, node) + return "self.__class." .. self:value(node[2]) + end, self_colon = function(self, node) return "self:" .. self:value(node[2]) end, + self_class_colon = function(self, node) + return "self.__class:" .. self:value(node[2]) + end, raw_value = function(self, value) local sup = self:get("super") if value == "super" and sup then diff --git a/moonscript/compile/value.moon b/moonscript/compile/value.moon index 67166a7..c298b2e 100644 --- a/moonscript/compile/value.moon +++ b/moonscript/compile/value.moon @@ -74,8 +74,9 @@ value_compile = else error "Unknown chain action: "..t - if ntype(callee) == "self" and node[3] and ntype(node[3]) == "call" - callee[1] = "self_colon" + t = ntype(callee) + if (t == "self" or t == "self_class") and node[3] and ntype(node[3]) == "call" + callee[1] = t.."_colon" callee_value = @value callee callee_value = @line "(", callee_value, ")" if ntype(callee) == "exp" @@ -95,7 +96,7 @@ value_compile = name = if type(name) == "string" name else - if name[1] == "self" + if name[1] == "self" or name[1] == "self_class" insert self_args, name name[2] insert default_args, arg if default_value @@ -176,9 +177,15 @@ value_compile = self: (node) => "self."..@value node[2] + self_class: (node) => + "self.__class."..@value node[2] + self_colon: (node) => "self:"..@value node[2] + self_class_colon: (node) => + "self.__class:"..@value node[2] + -- catch all pure string values raw_value: (value) => sup = @get"super" diff --git a/moonscript/parse.lua b/moonscript/parse.lua index 093f366..f383e4e 100644 --- a/moonscript/parse.lua +++ b/moonscript/parse.lua @@ -268,7 +268,9 @@ local build_grammar = wrap_env(function() return true end) / trim - local Name = sym"@" * Name / mark"self" + Name + Space * "..." / trim + local SelfName = Space * "@" * ("@" * _Name / mark"self_class" + _Name / mark"self") + + local Name = SelfName + Name + Space * "..." / trim local g = lpeg.P{ File, diff --git a/tests/inputs/class.moon b/tests/inputs/class.moon index 629a63f..7e63add 100644 --- a/tests/inputs/class.moon +++ b/tests/inputs/class.moon @@ -80,4 +80,14 @@ class CoolSuper nil +-- selfing +x = @hello +x = @@hello + +@hello "world" +@@hello "world" + +@@one @@two(4,5) @three, @four + +xx = (@hello, @@world, cool) ->