aboutsummaryrefslogtreecommitdiff
path: root/lib/core/things.nom
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2019-01-16 16:38:15 -0800
committerBruce Hill <bruce@bruce-hill.com>2019-01-16 16:38:15 -0800
commit1cbf9f3e07de9303283c747f7dbad61b77278819 (patch)
treec925f9a3c08d7a6eaceac33b585e52416628103d /lib/core/things.nom
parent2daebbff27b72c3cbae02a7cb12a4df141425784 (diff)
Moved things into core/
Diffstat (limited to 'lib/core/things.nom')
-rw-r--r--lib/core/things.nom141
1 files changed, 141 insertions, 0 deletions
diff --git a/lib/core/things.nom b/lib/core/things.nom
new file mode 100644
index 0000000..c52eb5d
--- /dev/null
+++ b/lib/core/things.nom
@@ -0,0 +1,141 @@
+#!/usr/bin/env nomsu -V6.15.13.8
+#
+ 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
+ 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)