diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2018-09-21 00:30:28 -0700 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2018-09-21 00:30:44 -0700 |
| commit | f2048235f5cc7ff02db39a0e2fe5c79c7f390e0b (patch) | |
| tree | 738faa0d4692e53d0fe2deb61399b6d7a9eedc9f /nomnom/code_obj.nom | |
| parent | 79d4bd5125de7ff220fbf8a8a5493d437ed16963 (diff) | |
Incremental checkin, currently not working, just saving progress.
Diffstat (limited to 'nomnom/code_obj.nom')
| -rw-r--r-- | nomnom/code_obj.nom | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/nomnom/code_obj.nom b/nomnom/code_obj.nom new file mode 100644 index 0000000..4df312e --- /dev/null +++ b/nomnom/code_obj.nom @@ -0,0 +1,180 @@ +# 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/object.nom" + +object (Code): + my action [set up]: + %old_bits = %me.bits + %me.bits = [] + if (%me.source is text): + %me.source = (Source from text %me.source) + for % in %old_bits: + %me::add % + + my action [as text]: + if (%me.__str == (nil)): + set {%buff:[], %indent:0} + for % in %me.bits: + if (% is text): + %spaces = (%::matching "\n([ ]*)[^\n]*$") + if %spaces.1: %indent = (size of %spaces) + ..else: + % = "\%" + if (%indent > 0): + % = (%::with "\n" -> "\n\(" "::* %indent)") + %buff::add % + %me.__str = (%buff::joined) + return %me.__str + + my action [as lua] (..) + "\(%me.class.name::as lua id)_1_2(\(%me.source::as lua), \(%me.bits::as lua))" + + my action [as nomsu] (..) + "(\(%me.class.name) \(%me.source::as nomsu) \(%me.bits::as nomsu))" + + my action [size] (size of "\%me") + + my action [mark as dirty]: + %me.__str = (nil) + %me._trailing_line_len = (nil) + %me._num_lines = (nil) + + my action [add %new_bits]: + 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) + %me.bits::add % + %me::mark as dirty + + my action [trailing line length]: + if (%me._trailing_line_len == (nil)): + %me._trailing_line_len = (size of ("\%me"::matching "[^\n]*$")) + return %me._trailing_line_len + + my action [number of lines]: + unless %me._num_lines: + %num_lines = 1 + for % in %me: + if (% is text): + %num_lines += (size of (%::all matches of "\n")) + ..else: + %num_lines += ((%::number of lines) - 1) + %me._num_lines = %num_lines + return %me._num_lines + + my action [is multiline, is multi-line] ((%me::number of lines) > 1) + my action [is one line, is single line] ((%me::number of lines) == 1) + + my action [add %values joined with %joiner]: + %me::add %values joined with %joiner or %joiner + + my action [add %values joined with %joiner or %wrapping_joiner]: + %line_len = 0 + %bits = %me.bits + for %i = % in %values: + if (%i > 1): + if (%line_len > 80): + %bits::add %wrapping_joiner + %line_len = 0 + ..else: + %bits::add %joiner + %bits::add % + %line = ("\%"::matching "\n([^\n]*)$") + if %line: + %line_len = (size of %line) + ..else: + %line_len += (size of %) + %me::mark as dirty + + my action [prepend %]: + if ((% isn't text) and (% isn't a %me.__type)): + % = (%::as lua) + %me.bits::add % at index 1 + %me::mark as dirty + + my action [parenthesize]: + %me.bits::add "(" at index 1 + %me.bits::add ")" + %me::mark as dirty + + +object (Lua Code) extends (Code): + my action [add free vars %vars]: + if ((size of %vars) == 0): return + %seen = (%v = (yes) for %v in %me.free_vars) + for %var in %vars: + assume (%var is text) + unless %seen.%var: + %me.free_vars::add %var + %seen.%var = (yes) + %me::mark as dirty + + my action [remove free vars %vars]: + if ((size of %vars) == 0): return + %removals = {} + for %var in %vars: + assume (%var is text) + %removals.%var = (yes) + + %stack = [%me] + 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 index %i + for % in %lua.bits: + if (% is a "Lua Code"): + %stack::add % + %me::mark as dirty + + my action [declare locals]: + set {%to_declare:[], %seen:{}} + for %lua in recursive %me: + for %var in %lua.free_vars: + unless %seen.%var: + %seen.%var = (yes) + %to_declare::add %var + for % in %lua.bits: + if (% is a "Lua Code"): + recurse %lua on % + return (%me::declare locals %to_declare) + + my action [declare locals %to_declare]: + if ((size of %to_declare) > 0): + %me::remove free vars %to_declare + %me::prepend "local \(%to_declare::joined with ", ");\n" + return %to_declare + + my action [as statements] (%me::as statements "" ";") + my action [as statements %prefix] (%me::as statements %prefix ";") + my action [as statements %prefix %suffix]: + unless %me.is_value: + return %me + %statements = (Lua Code %me.source []) + if (%prefix != ""): + %statements::add %prefix + %statements::add %me + if (%suffix != ""): + %statements::add %suffix + return %statements + + action [Lua Code from %tree] (..) + Lua Code {source:%tree.source, bits:[], is_value:(no), free_vars:[]} + action [Lua Code from %tree %bits] (..) + Lua Code {source:%tree.source, bits:%bits, is_value:(no), free_vars:[]} + + action [Lua Value from %tree] (..) + Lua Code {source:%tree.source, bits:[], is_value:(yes), free_vars:[]} + action [Lua Value from %tree %bits] (..) + Lua Code {source:%tree.source, bits:%bits, is_value:(yes), free_vars:[]} + +object (Nomsu Code) extends (Code): + action [Nomsu Code from %tree] (..) + Nomsu Code {source:%tree.source, bits:[]} + action [Nomsu Code from %tree %bits] (..) + Nomsu Code {source:%tree.source, bits:%bits} |
