nomsu/nomnom/code_obj.nom
Bruce Hill 307dea1881 Changed stub convention to (foo 1 baz 2) -> foo_1_baz instead of
foo_1_baz_2, removed "smext", made some cleanup changes.
2018-11-02 14:39:23 -07:00

211 lines
7.1 KiB
Plaintext

#!/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)