#!/usr/bin/env nomsu -V7.0.0 ### A library for simple object oriented programming. use "core/metaprogramming" use "core/operators" use "core/control_flow" use "core/collections" use "core/errors" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ test: (an Empty) is (a thing) with [] (a Buffer) is (a thing) with [$bits]: $self.is_a_buffer = (yes) ($self, set up) means: $bits or= [] ($self, as text) means ($bits, joined) [($self, add $bit), ($self, append $bit)] all mean: $bits, add $bit assume $(a Buffer).is_a_buffer $b = (a Buffer) assume (type of $b) == "a Buffer" assume ($b is "a Buffer") assume $b.is_a_buffer assume "\$b" == "" assume ($b, as text) == "" $b = (a Buffer {.bits = ["x"]}) $b, add "y" append "z" assume "\$b" == "xyz" assume $b == (a Buffer {.bits = ["x", "y", "z"]}) assume $b != (a Buffer {.bits = []}) (a Comma Buffer) is (a Buffer) with [$bits]: ($self, as text) means ($bits, joined with ",") ($self, number of commas) means (#$bits - 1) $csv = (a Comma Buffer) assume $csv.is_a_buffer assume ($csv is "a Comma Buffer") assume ($csv is "a Buffer") assume "\$csv" == "" $csv, add "x" $csv, add "y" assume "\$csv" == "x,y" assume ($csv, number of commas) == 1 (a Vec) is (a thing) with [$x, $y]: ($self, +$other) means (Vec ($x + $other.x) ($y + $other.y)) ($self, length) means (sqrt ($x * $x + $y * $y)) (Vec $x $y) means (a Vec {.x = $x, .y = $y}) assume ((Vec 1 2) + (Vec 10 10)) == (Vec 11 12) assume (((Vec 1 2) + (Vec 10 10)) != (Vec 0 0)) assume (Vec 3 4, length) == 5 $METAMETHOD_MAP = { ."as text" = "__tostring", ."clean up" = "__gc", ."+" = "__add", ."-" = "__sub" ."*" = "__mul", ."/" = "__div", .negative = "__unm", ."//" = "__idiv" .mod = "__mod", ."^" = "__pow", ."&" = "__band", ."|" = "__bor", ."~" = "__bxor" ."~" = "__bnot", ."<<" = "__bshl", .">>" = "__bshr", ."==" = "__eq" ."<" = "__lt", ."<=" = "__le", ."set 1 =" = "__newindex" .size = "__len", .iterate = "__ipairs", ."iterate all" = "__pairs" } $($ as text like a dict) = ({}'s metatable).__tostring external: ($parent class named $classname $(initialize $)) means: $class = {.__type = $classname} $class.__index = $class $class.class = $class $class.__tostring = ($ -> "\($.__type) \($ as text like a dict)") $class.__eq = ({}'s metatable).__eq $class.__len = ({}'s metatable).__len set $class's metatable to { .__index = $parent, .__tostring = ($class -> $class.__type) .__call = for ($class with $initial_values): $initial_values or= {} set $initial_values's metatable to $class if $initial_values.set_up: $initial_values, set up return $initial_values } if $(initialize $): initialize $class for ($stub = $metamethod) in $METAMETHOD_MAP: if $class.($stub, as lua id): $class.$metamethod = $class.($stub, as lua id) return $class $(a thing) = ((nil) class named "thing") ($classname is $parent with $vars $class_body) compiles to: unless ($vars.type == "List"): at $vars fail "Compile error: This is not a list of variables." $class_id = ($classname.stub, as lua id) $class_body and= $class_body, with $t ->: for $v in $vars: if ($t == $v): return "IndexChain" tree with ("Var" tree with "self") "Index" tree with ("Text" tree with $v.1) if ($parent.type == "Action"): $parent = ("Var" tree with $parent) $lua = Lua (" \$class_id = _1_class_named(\($parent as lua id), \(quote $classname.stub)\( ( Lua (" , function(\$class_id) local self = \$class_id \($class_body as lua) end ") ) if $class_body else "" )) ") $lua, add free vars [$class_id] return $lua