nomsu/lib/things.nom

141 lines
5.3 KiB
Plaintext

#!/usr/bin/env nomsu -V6.15.13.8
#
A library for simple object oriented programming.
test:
an (Empty) is a thing
a (Buffer) is a thing:
$its.is_a_buffer = (yes)
($its, set up) means:
$its.bits or= []
($it, as text) means
$it.bits, joined
[($its, add $bit), ($its, append $bit)] all mean:
$its.bits, add $bit
assume (Buffer).is_a_buffer
$b = (a Buffer)
assume (type of $b) == "Buffer"
assume $b.is_a_buffer
assume "\$b" == ""
assume ($b, as text) == ""
$b = (a Buffer with {.bits = ["x"]})
$b,
add "y"
append "z"
assume "\$b" == "xyz"
assume $b == (a Buffer with {.bits = ["x", "y", "z"]})
assume $b != (a Buffer with {.bits = []})
a (Comma Buffer) is a (Buffer):
($it, as text) means ($it.bits, joined with ",")
($its, number of commas) means ((#$its.bits) - 1)
$csv = (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}:
($its, + $other) means (Vec {.x = ($its.x + $other.x), .y = ($its.y + $other.y)})
assume ((Vec {.x = 1, .y = 2}) + (Vec {.x = 10, .y = 10})) ==
Vec {.x = 11, .y = 12}
assume
((Vec {.x = 1, .y = 2}) + (Vec {.x = 10, .y = 10})) != (Vec {.x = 0, .y = 0})
$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:
[
a $parent class named $classname with $members $(initialize $)
an $parent class named $classname with $members $(initialize $)
] all mean:
$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
if $members:
$class.__members = $members
$class.__newindex =
for ($its $key = $value):
if $members.$key:
rawset $its $key $value
..else:
fail "Cannot set \$key, it's not one of the allowed member fields."
set $class's metatable to {
.__index = $parent
.__tostring = ($class -> $class.__type)
.__call =
for ($class with $initial_values):
if ($initial_values == (nil)): return $class
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 $classname is a $parent with $members $class_body
an $classname is a $parent with $members $class_body
a $classname is an $parent with $members $class_body
an $classname is an $parent with $members $class_body
] all compile to:
$class_id = ($classname.stub, as lua id)
$lua =
Lua ("
\$class_id = a_1_class_named_2_with(\($parent as lua), \(quote $classname.stub), \($members as lua)\(
(
Lua ("
, function(\$class_id)
local it, its = \$class_id, \$class_id;
\($class_body as lua)
end
")
) if $class_body else ""
))
a_\$class_id = function(initial_values) return \$class_id(initial_values or {}) end
an_\$class_id, a_\($class_id)_with, an_\($class_id)_with = a_\$class_id, a_\$class_id, a_\$class_id
")
$lua, add free vars [$class_id, "a_\$class_id", "an_\$class_id"]
return $lua
[
a $classname is a thing with $members $class_body
an $classname is a thing with $members $class_body
a $classname is an thing with $members $class_body
an $classname is an thing with $members $class_body
] all parse as (a $classname is a (nil) with $members $class_body)
[a $classname is a thing $class_body, an $classname is a thing $class_body]
..all parse as (a $classname is a (nil) with (nil) $class_body)
[
a $classname is a $parent $class_body, an $classname is a $parent $class_body
a $classname is an $parent $class_body, an $classname is an $parent $class_body
] all parse as (a $classname is a $parent with (nil) $class_body)