diff options
Diffstat (limited to 'nomnom/code_obj.nom')
| -rw-r--r-- | nomnom/code_obj.nom | 210 |
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) |
