aboutsummaryrefslogtreecommitdiff
path: root/nomnom/code_obj.nom
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2018-11-02 15:17:48 -0700
committerBruce Hill <bruce@bruce-hill.com>2018-11-02 15:17:49 -0700
commit0f17c5eb9ac4660f2f969bd1e67af42713e45eac (patch)
tree279ca7da2de0efe2f363684f3c84a540635f11a8 /nomnom/code_obj.nom
parentacd9c2acd4688f2301b091daad910c04e402bd6a (diff)
parentdc41f30c73c9686685e3a4183c1213fb4ba55c90 (diff)
Merge branch 'master' into working
Diffstat (limited to 'nomnom/code_obj.nom')
-rw-r--r--nomnom/code_obj.nom210
1 files changed, 210 insertions, 0 deletions
diff --git a/nomnom/code_obj.nom b/nomnom/code_obj.nom
new file mode 100644
index 0000000..c8d2784
--- /dev/null
+++ b/nomnom/code_obj.nom
@@ -0,0 +1,210 @@
+#!/usr/bin/env nomsu -V4.8.10
+# This file contains objects that are used to track code positions and incrementally
+ build up generated code, while keeping track of where it came from, and managing
+ indentation levels.
+use "lib/things.nom"
+
+a (Code Buffer) is a thing:
+ that can (set up) by:
+ assume %its.source
+ %old_bits = (%its.bits if (%its.bits is a "List") else [%its.bits])
+ %its.bits = []
+ if (type of %its.source) is:
+ "Text":
+ %its.source = (Source from text %its.source)
+ "Syntax Tree":
+ %its.source = %its.source.source
+
+ for % in %old_bits: %its::add %
+
+ whose (text) means:
+ if (%its._text == (nil)):
+ %buff = []
+ %indent = 0
+ for %bit in %its.bits:
+ if (%bit is text):
+ %spaces = (%bit::matching "\n([ ]*)[^\n]*$")
+ if %spaces: %indent = (size of %spaces.1)
+ ..else:
+ %bit = (%bit::text)
+ if (%indent > 0):
+ %bit = (%bit::with "\n" -> "\n\(" "::* %indent)")
+ %buff::add %bit
+ %its._text = (%buff::joined)
+ return %its._text
+
+ whose (lua code) means "\
+ ..a_\(%its.class.name::as lua id)_with{source=\(..)
+ (%its.source::as lua) if %its.source else "nil"
+ .., \(%its.bits::as lua)}"
+
+ whose (nomsu code) means "\
+ ..(a \(%its.class.name) with {source: \((%its.source::as nomsu) if %its.source else "(nil)"), bits: \(..)
+ %its.bits::as nomsu
+ ..})"
+
+ whose (size) means (size of (%its::text))
+
+ that can (mark as dirty) by:
+ %its._text = (nil)
+ %its._trailing_line_len = (nil)
+ %its._num_lines = (nil)
+
+ that can (add %new_bits) by:
+ unless (%new_bits is a "List"):
+ %new_bits = [%new_bits]
+ for % in %new_bits:
+ if (% == ""): do next %
+ #if ((% isn't text) and (% isn't a (Code))):
+ % = (%::as lua)
+ %its.bits::add %
+ %its::mark as dirty
+
+ whose (trailing line length) means:
+ if (%its._trailing_line_len == (nil)):
+ %its._trailing_line_len = (size of ((%its::text)::matching "[^\n]*$"))
+ return %its._trailing_line_len
+
+ whose (number of lines) means:
+ unless %its._num_lines:
+ %num_lines = 1
+ for % in %its:
+ if (% is text):
+ %num_lines += (size of (%::all matches of "\n"))
+ ..else:
+ %num_lines += ((%::number of lines) - 1)
+
+ %its._num_lines = %num_lines
+
+ return %its._num_lines
+
+ whose [is multiline, is multi-line] all mean ((%its::number of lines) > 1)
+ whose [is one line, is single line] all mean ((%its::number of lines) == 1)
+ that can (add %values joined with %joiner) by:
+ %its::add %values joined with %joiner or %joiner
+ that can [add %values joined with %joiner or %wrapping_joiner] by:
+ %line_len = 0
+ %bits = %its.bits
+ for %value in %values at %i:
+ if (%i > 1):
+ if (%line_len > 80):
+ %bits::add %wrapping_joiner
+ %line_len = 0
+ ..else: %bits::add %joiner
+
+ %bits::add %value
+ unless (%value is text):
+ %value = (%value::text)
+ %line = (%value::matching "\n([^\n]*)$")
+ if %line:
+ %line_len = (size of %line)
+ ..else:
+ %line_len += (size of %value)
+ %its::mark as dirty
+
+ that can (prepend %) by:
+ #if ((% isn't text) and (% isn't a %its.__type)):
+ % = (%::as lua)
+ %its.bits::add % at index 1
+ %its::mark as dirty
+
+ that can (parenthesize) by:
+ %its.bits::add "(" at index 1
+ %its.bits::add ")"
+ %its::mark as dirty
+
+a (Lua Buffer) is a thing:
+ that has [..]
+ text, lua code, nomsu code, trailing line length, size, number of lines,
+ is multiline, is multi-line, is one line, is single line,
+ ..like a (Code Buffer)
+ that can [..]
+ set up, mark as dirty, add %, prepend %, parenthesize,
+ add % joined with %, add % joined with % or %,
+ ..like a (Code Buffer)
+
+ that can (add free vars %vars) by:
+ if ((size of %vars) == 0): return
+ %seen = (%v = (yes) for %v in %its.free_vars)
+ for %var in %vars:
+ assume (%var is text)
+ unless %seen.%var:
+ %its.free_vars::add %var
+ %seen.%var = (yes)
+
+ %its::mark as dirty
+
+ that can (remove free vars %vars) by:
+ if ((size of %vars) == 0): return
+ %removals = {}
+ for %var in %vars:
+ assume (%var is text)
+ %removals.%var = (yes)
+
+ %stack = [%its]
+ repeat while ((size of %stack) > 0):
+ %lua = (%stack::pop)
+ for %i in (size of %lua.free_vars) to 1 by -1:
+ if %removals.(%lua.free_vars.%i):
+ %lua.free_vars::remove at index %i
+
+ for % in %lua.bits:
+ unless (% is text): %stack::add %
+
+ %its::mark as dirty
+
+ that can (declare locals) by (%its::declare locals (nil))
+ that can (declare locals %to_declare) by:
+ unless %to_declare:
+ %to_declare = []
+ %seen = {}
+ for %lua in recursive %its:
+ for %var in %lua.free_vars:
+ unless %seen.%var:
+ %seen.%var = (yes)
+ %to_declare::add %var
+
+ for % in %lua.bits:
+ unless (% is text): recurse %lua on %
+
+ if ((size of %to_declare) > 0):
+ %its::remove free vars %to_declare
+ %its::prepend "local \(%to_declare::joined with ", ");\n"
+ return %to_declare
+
+ whose (as statements) means (%its::as statements with "")
+ whose (as statements with %prefix) means:
+ unless %its.is_value: return %its
+ %statements = (a Lua Buffer with {source:%its.source})
+ if ((%prefix or "") != ""):
+ %statements::add %prefix
+ %statements::add %its
+ %statements::add ";"
+ return %statements
+
+ that can (mark as value) by:
+ %its.is_value = (yes)
+
+ that can (mark as variable) by:
+ %its.is_variable = (yes)
+ %its.is_value = (yes)
+
+ that can (variables) by:
+ %vars = []
+ for %code in recursive %its:
+ if %code.is_variable:
+ %vars::add (%code::text)
+ for % in %code.bits:
+ unless (% is text): recurse %code on %
+
+ return %vars
+
+a (Nomsu Buffer) is a thing:
+ that has [..]
+ text, lua code, nomsu code, trailing line length, size, number of lines,
+ is multiline, is multi-line, is one line, is single line,
+ ..like a (Code Buffer)
+ that can [..]
+ set up, mark as dirty, add %, prepend %, parenthesize,
+ add % joined with %, add % joined with % or %,
+ ..like a (Code Buffer)