aboutsummaryrefslogtreecommitdiff
path: root/nomnom
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2018-10-31 15:05:17 -0700
committerBruce Hill <bruce@bruce-hill.com>2018-10-31 15:05:17 -0700
commit7a35e38d8778670fe0662f203e82638355db3bba (patch)
treecc9f813d1350f23d2b81a81b18f4f127668bfec9 /nomnom
parentf43d8c58f755a7f208d84b43071490ab356c5ac8 (diff)
Renamed (action %) -> (%'s meaning)
Diffstat (limited to 'nomnom')
-rw-r--r--nomnom/ast.nom53
-rw-r--r--nomnom/code_obj.nom132
-rw-r--r--nomnom/compile.nom124
-rw-r--r--nomnom/decompile.nom187
-rw-r--r--nomnom/files.nom78
-rw-r--r--nomnom/parser.nom49
-rw-r--r--nomnom/pretty_errors.nom50
-rw-r--r--nomnom/source.nom29
8 files changed, 363 insertions, 339 deletions
diff --git a/nomnom/ast.nom b/nomnom/ast.nom
index 816554c..4d261aa 100644
--- a/nomnom/ast.nom
+++ b/nomnom/ast.nom
@@ -1,9 +1,9 @@
+#!/usr/bin/env nomsu -V4.8.10
use "lib/object.nom"
# The types are [..]
"Number", "Var", "Block", "EscapedNomsu", "Text", "List", "Dict", "DictEntry",
"IndexChain", "Action", "FileChunks", "Error", "Comment"
-
object (Syntax Tree):
my action [set up]:
if (%me.type == "Action"):
@@ -11,38 +11,33 @@ object (Syntax Tree):
%argnum = 1
for %bit in %me:
if:
- (%bit is text): %stub_bits::add %bit
+ (%bit is text):
+ %stub_bits::add %bit
(%bit.type != "Comment"):
%stub_bits::add "\%argnum"
%argnum += 1
+
%me.stub = (%stub_bits::joined with " ")
if (%me.stub == "Lua Code 1 2"):
lua> "require('ldt').breakpoint()"
-
+
(Syntax Tree).source_code_for_tree = (..)
{} with fallback % -> (read file %.source.filename)
-
my action [children]:
%children = []
for % in %me:
- if ((% is a "Syntax Tree") and (%.type != "Comment")):
- %children::add %
+ if ((% is a "Syntax Tree") and (%.type != "Comment")): %children::add %
if ((%me.type == "Action") and %me.target):
%children::add %me.target
return %children
-
- my action [as lua] (..)
- "Syntax_Tree(\(call ({}'s metatable).as_lua with [%me]))"
-
- my action [as nomsu] (..)
- "(Syntax Tree \(call ({}'s metatable).as_nomsu with [%me]))"
-
- my action [as text] (..)
- "(Syntax Tree \(call ({}'s metatable).__tostring with [%me]))"
-
- my action [get source code] (..)
- (Syntax Tree).source_code_for_tree.%me
-
+
+ my action [as lua] "\
+ ..a_Syntax_Tree_with_1(\(call ({} 's metatable).as_lua with [%me]))"
+ my action [as nomsu] "\
+ ..(a Syntax Tree with \(call ({} 's metatable).as_nomsu with [%me]))"
+ my action [as text] "\
+ ..(Syntax Tree \(call ({} 's metatable).__tostring with [%me]))"
+ my action [get source code] (Syntax Tree).source_code_for_tree.%me
my action [map %fn]:
%replacement = (call %fn with [%me])
if %replacement:
@@ -58,25 +53,23 @@ object (Syntax Tree):
%replacement.%k = %v
if (%v is a "Syntax Tree"):
%r = (%v::map %fn)
- if ((%r == %v) or (%r == (nil))):
- do next %k
+ if ((%r == %v) or (%r == (nil))): do next %k
%changes = (yes)
%replacement.%k = %r
+
unless %changes: return %me
return (Syntax Tree %replacement)
-
+
my action [with %overrides]:
%new = (%k = %v for %k = %v in %me)
for %k = %v in %overrides: %new.%k = %v
return (Syntax Tree %new)
-
+
my action [== %other]:
unless (..)
all of [..]
- (type of %me) == (type of %other)
- (%me's metatable) == (%other's metatable)
- (size of %me) == (size of %other)
- %me.type == %other.type
+ (type of %me) == (type of %other), (%me 's metatable) == (%other 's metatable)
+ (size of %me) == (size of %other), %me.type == %other.type
..: return (no)
for %item in %me at %i:
@@ -86,11 +79,11 @@ object (Syntax Tree):
return (yes)
my action [get args]:
- assume (%me.type == "Action") or barf "Only actions have arguments, not \(%me.type)"
+ assume (%me.type == "Action") or barf "\
+ ..Only actions have arguments, not \(%me.type)"
%args = []
for % in %me:
- unless ((% is text) or (%.type == "Comment")):
- %args::add %
+ unless ((% is text) or (%.type == "Comment")): %args::add %
return %args
(Syntax Tree).map = (Syntax Tree).map_1
diff --git a/nomnom/code_obj.nom b/nomnom/code_obj.nom
index 363713c..8379f36 100644
--- a/nomnom/code_obj.nom
+++ b/nomnom/code_obj.nom
@@ -1,25 +1,19 @@
+#!/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/object.nom"
object (Hole):
- action [Hole from %lua]:
+ externally (Hole from %lua) means:
return (Hole {lua:%lua})
-
- my action [as lua]:
- return %me.lua
-
+ my action [as lua]: return %me.lua
my action [as nomsu]:
return "(Hole {lua:\(%me.lua)})"
-
my action [as text]:
barf "Not implemented"
-
my action [as smext]:
barf "Must fill in holes before smexting"
-
object (Code):
my action [set up]:
@@ -28,12 +22,10 @@ object (Code):
%me.bits = []
if (%me.source is text):
%me.source = (Source from text %me.source)
- for % in %old_bits:
- %me::add %
-
+ for % in %old_bits: %me::add %
+
my action [as text]:
barf "Not implemented"
-
my action [as smext]:
if (%me.__str == (nil)):
set {%buff:[], %indent:0}
@@ -45,32 +37,41 @@ object (Code):
%bit = (%bit::as smext)
if (%indent > 0):
%bit = (%bit::with "\n" -> "\n\(" "::* %indent)")
+
%buff::add %bit
+
%me.__str = (%buff::joined)
+
return %me.__str
-
+
my action [as lua]:
barf
- return "\(%me.class.name::as lua id)_from_1_2(\((%me.source::as lua) if %me.source else "nil"), \(%me.bits::as lua))"
-
- my action [as nomsu] (..)
- "(\(%me.class.name) \((%me.source::as nomsu) if %me.source else "(nil)") \(%me.bits::as nomsu))"
-
- my action [size] (size of (%me::as smext))
+ return "\
+ ..\(%me.class.name::as lua id)_from_1_2(\(..)
+ (%me.source::as lua) if %me.source else "nil"
+ .., \(%me.bits::as lua))"
+
+ my action [as nomsu] "\
+ ..(\(%me.class.name) \((%me.source::as nomsu) if %me.source else "(nil)") \(..)
+ %me.bits::as nomsu
+ ..)"
+ my action [size] (size of (%me::as smext))
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]:
@@ -86,15 +87,15 @@ object (Code):
%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
@@ -103,8 +104,8 @@ object (Code):
if (%line_len > 80):
%bits::add %wrapping_joiner
%line_len = 0
- ..else:
- %bits::add %joiner
+ ..else: %bits::add %joiner
+
%bits::add %value
unless (%value is text):
%value = (%value::as smext)
@@ -113,6 +114,7 @@ object (Code):
%line_len = (size of %line)
..else:
%line_len += (size of %value)
+
%me::mark as dirty
my action [prepend %]:
@@ -120,13 +122,12 @@ object (Code):
% = (%::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
@@ -136,6 +137,7 @@ object (Lua Code) extends (Code):
unless %seen.%var:
%me.free_vars::add %var
%seen.%var = (yes)
+
%me::mark as dirty
my action [remove free vars %vars]:
@@ -153,11 +155,13 @@ object (Lua Code) extends (Code):
lua> "table.remove(\%lua.free_vars, \%i)"
#TODO: reinstate this
#%lua.free_vars::remove at index %i
+
+
for % in %lua.bits:
- unless (% is text):
- %stack::add %
+ unless (% is text): %stack::add %
+
%me::mark as dirty
-
+
my action [declare locals] (%me::declare locals (nil))
my action [declare locals %to_declare]:
unless %to_declare:
@@ -167,19 +171,19 @@ object (Lua Code) extends (Code):
unless %seen.%var:
%seen.%var = (yes)
%to_declare::add %var
+
for % in %lua.bits:
- unless (% is text):
- recurse %lua on %
+ unless (% is text): recurse %lua on %
+
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
+ unless %me.is_value: return %me
%statements = (Lua Code from %me.source [])
if ((%prefix or "") != ""):
%statements::add %prefix
@@ -194,46 +198,48 @@ object (Lua Code) extends (Code):
if %code.is_variable:
%vars::add (%code::as smext)
for % in %code.bits:
- unless (% is text):
- recurse %code on %
+ unless (% is text): recurse %code on %
+
return %vars
-
- action [Lua Code from %source %bits]:
+
+ externally (Lua Code from %source %bits) means:
assume %source
unless (%bits is a "List"): %bits = [%bits]
- if (%source is a "Syntax Tree"): %source = %source.source
- return (..)
- Lua Code {source:%source, bits:%bits, is_value: no, free_vars:[]}
- action [Lua Code from %source] (Lua Code from %source [])
-
- action [Lua Value from %source %bits]:
+ if (%source is a "Syntax Tree"):
+ %source = %source.source
+ return (Lua Code {source:%source, bits:%bits, is_value:no, free_vars:[]})
+
+ externally (Lua Code from %source) means (Lua Code from %source [])
+ externally (Lua Value from %source %bits) means:
assume %source
unless (%bits is a "List"): %bits = [%bits]
- if (%source is a "Syntax Tree"): %source = %source.source
- return (..)
- Lua Code {source:%source, bits:%bits, is_value: yes, free_vars:[]}
- action [Lua Value from %source] (Lua Value from %source [])
-
- action [Lua Variable from %source] (Lua Variable from %source [])
- action [Lua Variable from %source %bits]:
+ if (%source is a "Syntax Tree"):
+ %source = %source.source
+ return (Lua Code {source:%source, bits:%bits, is_value:yes, free_vars:[]})
+
+ externally (Lua Value from %source) means (Lua Value from %source [])
+ externally (Lua Variable from %source) means (Lua Variable from %source [])
+ externally (Lua Variable from %source %bits) means:
assume %source
unless (%bits is a "List"): %bits = [%bits]
- if (%source is a "Syntax Tree"): %source = %source.source
+ if (%source is a "Syntax Tree"):
+ %source = %source.source
return (..)
- Lua Code {source:%source, bits:%bits, is_value: yes, is_variable: yes, free_vars:[]}
+ Lua Code {..}
+ source:%source, bits:%bits, is_value:yes, is_variable:yes, free_vars:[]
# TODO: remove this shim
(Lua Code).add_free_vars = (Lua Code).add_free_vars_1
(Lua Code).remove_free_vars = (Lua Code).remove_free_vars_1
(Lua Code).declare_locals = (Lua Code).declare_locals_1
(Lua Code).as_statements = (Lua Code).as_statements_1_2
-
object (Nomsu Code) extends (Code):
- action [Nomsu Code from %source %bits]:
+ externally (Nomsu Code from %source %bits) means:
if (%bits is text): %bits = [%bits]
- if (%source is a "Syntax Tree"): %source = %source.source
- return (..)
- Nomsu Code {source:%source, bits:%bits}
- action [Nomsu Code from %source] (Nomsu Code from %source [])
- action [Nomsu Code %bits] (Nomsu Code from (nil) %bits)
- action [Nomsu Code] (Nomsu Code from (nil) [])
+ if (%source is a "Syntax Tree"):
+ %source = %source.source
+ return (Nomsu Code {source:%source, bits:%bits})
+
+ externally (Nomsu Code from %source) means (Nomsu Code from %source [])
+ externally (Nomsu Code %bits) means (Nomsu Code from (nil) %bits)
+ externally (Nomsu Code) means (Nomsu Code from (nil) [])
diff --git a/nomnom/compile.nom b/nomnom/compile.nom
index 989bc04..18afe3c 100644
--- a/nomnom/compile.nom
+++ b/nomnom/compile.nom
@@ -1,24 +1,23 @@
+#!/usr/bin/env nomsu -V4.8.10
# This file contains the code to convert syntax trees to Lua code
-
use "nomnom/code_obj.nom"
use "nomnom/parser.nom"
use "nomnom/pretty_errors.nom"
-local action [report compile error at %tree %err]:
+externally (report compile error at %tree %err) means:
barf (pretty "Compile Error" error at %tree %err)
-local action [report compile error at %pos %err hint %hint]:
+externally (report compile error at %pos %err hint %hint) means:
barf (pretty "Compile Error" error at %tree %err hint %hint)
-action [barf any errors in %t]:
+externally (barf any errors in %t) means:
assume (%t is a "Syntax Tree")
%errs = []
for % in recursive %t:
- if (%.type == "Error"):
- %errs::add %
+ if (%.type == "Error"): %errs::add %
for %k = %v in %:
- if (%v is a "Syntax Tree"):
- recurse % on %v
+ if (%v is a "Syntax Tree"): recurse % on %v
+
sort %errs by % -> %.source
%errs = ((% as a pretty error) for % in %errs)
if ((size of %errs) > 0):
@@ -28,17 +27,19 @@ action [barf any errors in %t]:
%errs::add "\027[31;1m +\%n additional errors...\027[0m\n"
barf (%errs::joined with "\n\n")
-action [%tree compiled with %compile_actions]:
+externally (%tree compiled with %compile_actions) means:
assume (%tree is a "Syntax Tree")
if all of [..]
- %tree.version, action (Nomsu version)
- %tree.version != (Nomsu version)
- action (1 upgraded from 2 to 3)
- ..then: %tree = (upgrade %tree from %tree.version to (Nomsu version))
+ %tree.version, (Nomsu version)'s meaning, %tree.version != (Nomsu version)
+ (1 upgraded from 2 to 3)'s meaning
+ ..then:
+ %tree = (upgrade %tree from %tree.version to (Nomsu version))
+
if %tree.type is:
"Action":
%stub = %tree.stub
%compile_action = %compile_actions.%stub
+
# Don't apply compiler actions to methods
if (%compile_action and (not %tree.target)):
# TODO: restore this:
@@ -51,26 +52,35 @@ action [%tree compiled with %compile_actions]:
..The compile-time action here (\(%tree.stub)) failed to return any value."
..hint "\
..Look at the implementation of (\(%tree.stub)) and make sure it's returning something."
+
if (%result is a "Syntax Tree"):
if (%result == %tree):
report compile error at %tree "\
..The compile-time action here (\(%tree.stub)) is producing an endless loop."
..hint "\
..Look at the implementation of (\(%tree.stub)) and make sure it's not just returning the original tree."
+
return (%result compiled with %compile_actions)
+
return %result
-
+
%lua = (Lua Value from %tree)
- if %tree.target: # Method call
+ if %tree.target:
+ # Method call
%target_lua = (%tree.target compiled with %compile_actions)
- if (((%target_lua::as smext)::matches "^%(.*%)$") or ((%target_lua::as smext)::matches "^[_a-zA-Z][_a-zA-Z0-9]*$")):
+ if (..)
+ ((%target_lua::as smext)::matches "^%(.*%)$") or (..)
+ (%target_lua::as smext)::matches "^[_a-zA-Z][_a-zA-Z0-9]*$"
+ ..:
%lua::add [%target_lua, ":"]
..else:
%lua::add ["(", %target_lua, "):"]
+
%lua::add [%stub as lua id, "("]
%args = []
for %tok in %tree at %i:
if (%tok is text): do next %tok
+
# TODO: maybe don't translate Lua comments
#if (%tok.type == "Comment"): do next %tok
if (%tok.type == "Block"):
@@ -78,6 +88,7 @@ action [%tree compiled with %compile_actions]:
for %line in %tok:
#unless (%line.type == "Comment"):
%values::add (%line compiled with %compile_actions)
+
if all of (%.is_value for % in %values):
if ((size of %values) == 1):
%arg_lua = %values.1
@@ -91,65 +102,63 @@ action [%tree compiled with %compile_actions]:
if %v.is_value:
%v = (%v::as statements ("return " if (%i == (size of %values) else "")))
%arg_lua::add ["\n ", %v]
+
%arg_lua::add "\nend)())"
..else:
%arg_lua = (%tok compiled with %compile_actions)
unless %arg_lua.is_value:
if (%tok.type == "Action"):
report compile error at %tok "\
- ..Can't use this as an argument to (\%stub), since it's not \
- ..an expression, it produces: \%arg_lua"
+ ..Can't use this as an argument to (\%stub), since it's not an expression, it produces: \%arg_lua"
..hint "\
- ..Check the implementation of (\(%tok.stub)) to see if it \
- ..is actually meant to produce an expression."
+ ..Check the implementation of (\(%tok.stub)) to see if it is actually meant to produce an expression."
..else:
report compile error at %tok "\
- ..Can't use this as an argument to (\%stub), since it's \
- ..not an expression, it produces: \%arg_lua"
+ ..Can't use this as an argument to (\%stub), since it's not an expression, it produces: \%arg_lua"
+
assume (%arg_lua != %lua) or barf "Huh? \%tree .\%i = \%tok -> \%arg_lua"
%args::add %arg_lua
+
%lua::add %args joined with ", "
%lua::add ")"
return %lua
-
+
"EscapedNomsu":
#return (Lua Value from %tree ((%tree.1)::as lua))
-
- %lua = (Lua Value from %tree ["Syntax_Tree_1{type=", quote %tree.1.type])
+ %lua = (Lua Value from %tree ["a_Syntax_Tree_with_1{type=", quote %tree.(1).type])
set {%needs_comma:no, %i:1}
- local action [% as shmua]:
- if (% is a "Lua number"):
- return "\%"
+ (% as shmua) means:
+ if (% is a "Lua number"): return "\%"
if (% is a "Syntax Tree"):
return (% compiled with %compile_actions)
- if (% is text):
- return (quote %)
+ if (% is text): return (quote %)
return (%::as lua)
-
- for %k = %v in (((%tree.1.type == "EscapedNomsu") and %tree) or %tree.1):
+
+ for %k = %v in (((%tree.(1).type == "EscapedNomsu") and %tree) or %tree.1):
%lua::add ", "
if:
- (%k == %i):
- %i += 1
+ (%k == %i): %i += 1
((%k is text) and (%k::is a lua identifier)):
%lua::add [%k, "= "]
else:
%lua::add ["[", % as shmua, "]= "]
+
if (%k == "source"):
%lua::add (quote "\%v")
..else:
%lua::add (%v as shmua)
+
%lua::add "}"
return %lua
"Block":
%lua = (Lua Code from %tree)
%lua::add (..)
- ((%line compiled with %compile_actions)::as statements)
- ..for %line in %tree
+ ((%line compiled with %compile_actions)::as statements) for %line in %tree
..joined with "\n"
+
return %lua
-
+
"Text":
%lua = (Lua Value from %tree)
%lua_bits = []
@@ -158,49 +167,53 @@ action [%tree compiled with %compile_actions]:
if (% is text):
%string_buffer = "\%string_buffer\%"
do next %
+
if (%string_buffer != ""):
%lua_bits::add (%string_buffer::as lua)
%string_buffer = ""
+
%bit_lua = (% compiled with %compile_actions)
unless %bit_lua.is_value:
report compile error at % "\
..Can't use this as a string interpolation value, since it doesn't have a value."
+
if (%.type != "Text"):
- %bit_lua = (Lua Value from % ["tostring(",%bit_lua,")"])
+ %bit_lua = (Lua Value from % ["tostring(", %bit_lua, ")"])
%lua_bits::add %bit_lua
-
+
if ((%string_buffer != "") or ((size of %lua_bits) == 0)):
%lua_bits::add (%string_buffer::as lua)
-
- %lua::add %lua_bits joined with ("..")
- if ((size of %lua_bits) > 1):
- %lua::parenthesize
+ %lua::add %lua_bits joined with ".."
+ if ((size of %lua_bits) > 1): %lua::parenthesize
return %lua
-
+
"List":
%lua = (Lua Value from %tree ["List{"])
%lua::add ((% compiled with %compile_actions) for % in %tree) joined with ", " or ",\n "
%lua::add "}"
return %lua
-
+
"Dict":
%lua = (Lua Value from %tree ["Dict{"])
%lua::add ((% compiled with %compile_actions) for % in %tree) joined with ", " or ",\n "
%lua::add "}"
return %lua
-
+
"DictEntry":
set {%key:%tree.1, %value:%tree.2}
%key_lua = (%key compiled with %compile_actions)
unless %key_lua.is_value:
report compile error at %tree.1 "\
..Can't use this as a dict key, since it's not an expression."
+
%value_lua = (..)
- (%value compiled with %compile_actions) if %value
- ..else (Lua Value from %key ["true"])
+ (%value compiled with %compile_actions) if %value else (..)
+ Lua Value from %key ["true"]
+
unless %value_lua.is_value:
report compile error at %tree.2 "\
..Can't use this as a dict value, since it's not an expression."
+
%key_str = ((%key_lua::as smext)::matching "^[\"']([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
if:
%key_str:
@@ -210,6 +223,7 @@ action [%tree compiled with %compile_actions]:
Lua's parser if the inner expression is a long string. Lua
parses x[[[y]]] as x("[y]"), not as x["y"]
return (Lua Code from %tree ["[ ", %key_lua, "]=", %value_lua])
+
else:
return (Lua Code from %tree ["[", %key_lua, "]=", %value_lua])
@@ -218,16 +232,17 @@ action [%tree compiled with %compile_actions]:
unless %lua.is_value:
report compile error at %tree.1 "\
..Can't index into this, since it's not an expression."
+
%first_char = (%lua::as smext).1
if (any of [%first_char == "{", %first_char == "\"", %first_char == "["]):
%lua::parenthesize
-
for %i in 2 to (size of %tree):
%key = %tree.%i
%key_lua = (%key compiled with %compile_actions)
unless %key_lua.is_value:
report compile error at %key "\
..Can't use this as an index, since it's not an expression."
+
%key_lua_str = (%key_lua::as smext)
%lua_id = (%key_lua_str::matching "^['\"]([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
if:
@@ -238,20 +253,19 @@ action [%tree compiled with %compile_actions]:
Lua's parser if the inner expression is a long string. Lua
parses x[[[y]]] as x("[y]"), not as x["y"]
%lua::add ["[ ", %key_lua, " ]"]
+
else:
%lua::add ["[", %key_lua, "]"]
+
return %lua
-
+
"Number":
return (Lua Value from %tree ["\(%tree.1)"])
-
"Var":
return (Lua Variable from %tree [%tree.1::as lua id])
-
"FileChunks":
barf "\
- ..Can't convert FileChunks to a single block of lua, since each chunk's \
- ..compilation depends on the earlier chunks"
+ ..Can't convert FileChunks to a single block of lua, since each chunk's compilation depends on the earlier chunks"
"Comment":
# TODO: de-implement?
@@ -259,7 +273,5 @@ action [%tree compiled with %compile_actions]:
"Error":
barf (%tree as a pretty error)
-
else:
barf "Unknown type: \(%tree.type)"
-
diff --git a/nomnom/decompile.nom b/nomnom/decompile.nom
index fb64f7c..7db61c8 100644
--- a/nomnom/decompile.nom
+++ b/nomnom/decompile.nom
@@ -1,9 +1,10 @@
+#!/usr/bin/env nomsu -V4.8.10
# This file contains the code to convert syntax trees to Nomsu code
use "nomnom/code_obj.nom"
use "nomnom/parser.nom"
# TODO: maybe re-implement the fancy coroutine checker that aborts early if nomsu gets too long
-action [%tree decompiled inline]:
+externally (%tree decompiled inline) means:
assume (%tree is a "Syntax Tree")
if %tree.type is:
"Action":
@@ -11,18 +12,18 @@ action [%tree decompiled inline]:
if %tree.target:
%target_nomsu = (%tree.target decompiled inline)
if %tree.target.type is:
- ("Action", "Block"):
+ "Action" "Block":
%target_nomsu::parenthesize
+
%nomsu::add [%target_nomsu, "::"]
-
+
for %bit in %tree at %i:
if (%bit is text):
unless (..)
any of [..]
- %i == 1,
- %tree.(%i - 1) isn't text,
- (%bit is a nomsu operator) == (%tree.(%i - 1) is a nomsu operator)
+ %i == 1, %tree.(%i - 1) isn't text, (%bit is a nomsu operator) == (%tree.(%i - 1) is a nomsu operator)
..: %nomsu::add " "
+
%nomsu::add %bit
..else:
%arg_nomsu = (%bit decompiled inline)
@@ -30,39 +31,40 @@ action [%tree decompiled inline]:
%nomsu::add " "
if ((%bit.type == "Action") or (%bit.type == "Block")):
%arg_nomsu::parenthesize
+
%nomsu::add %arg_nomsu
+
return %nomsu
-
+
"EscapedNomsu":
%inner_nomsu = (%tree.1 decompiled inline)
unless (..)
any of [..]
- %tree.1.type == "List", %tree.1.type == "Dict",
- %tree.1.type == "Var"
- ..: %inner_nomsu::parenthesize
+ %tree.(1).type == "List", %tree.(1).type == "Dict", %tree.(1).type == "Var"
+ ..:
+ %inner_nomsu::parenthesize
+
%nomsu = (Nomsu Code from %tree ["\\", %inner_nomsu])
return %nomsu
-
+
"Block":
%nomsu = (Nomsu Code from %tree [":"])
for %line in %tree at %i:
- %nomsu::add [..]
- " " if (%i == 1) else "; "
- %line decompiled inline
+ %nomsu::add [" " if (%i == 1) else "; ", %line decompiled inline]
return %nomsu
-
+
"Text":
%nomsu = (Nomsu Code from %tree [])
for %text in recursive %tree:
for %bit in %text at %i:
- if (%bit is text):
- %nomsu::add %bit
+ if (%bit is text): %nomsu::add %bit
..else:
if %bit.type is:
"Text":
recurse %text on %bit
"Var":
%interp_nomsu = (%bit decompiled inline)
+
# Make sure "...\(%x)y..." isn't confused with "...\(%xy)..."
# TODO: make this more robust against "...\%x\("y").."
if (..)
@@ -70,32 +72,38 @@ action [%tree decompiled inline]:
not (%tree.(%i + 1)::matches "^[ \n\t,.:;#(){}%[%]]")
..: %interp_nomsu::parenthesize
%nomsu::add ["\\", %interp_nomsu]
- ("List", "Dict"):
+
+ "List" "Dict":
%nomsu::add ["\\", %bit decompiled inline]
else:
%nomsu::add ["\\(", %bit decompiled inline, ")"]
+
return (Nomsu Code from %tree ["\"", %nomsu, "\""])
-
- ("List", "Dict"):
+
+ "List" "Dict":
%nomsu = (Nomsu Code from %tree ["[" if (%tree.type == "List") else "{"])
for %item in %tree at %i:
if (%i > 1): %nomsu::add ", "
%nomsu::add (%item decompiled inline)
+
%nomsu::add ("]" if (%tree.type == "List") else "}")
return %nomsu
"DictEntry":
set {%key:%tree.1, %value:%tree.2}
- if (all of [%key.type == "Text", (size of %key) == 1, %key.1 is a nomsu identifier]):
+ if (..)
+ all of [%key.type == "Text", (size of %key) == 1, %key.1 is a nomsu identifier]
+ ..:
%nomsu = (Nomsu Code from %key [%key.1])
..else:
%nomsu = (%key decompiled inline)
-
+
if (%key.type == "Action"):
%nomsu::parenthesize
if %value:
%nomsu::add ":"
%nomsu::add (%value decompiled inline)
+
return %nomsu
"IndexChain":
@@ -104,46 +112,42 @@ action [%tree decompiled inline]:
if (%i > 1): %nomsu::add "."
if (..)
all of [..]
- %i > 1, %bit.type == "Text", (size of %bit) == 1, %bit.1 is text,
- %bit.1 is a nomsu identifier
- ..:%nomsu::add %bit.1
+ %i > 1, %bit.type == "Text", (size of %bit) == 1, %bit.1 is text, %bit.1 is a nomsu identifier
+ ..: %nomsu::add %bit.1
..else:
%bit_nomsu = (%bit decompiled inline)
if (..)
any of [..]
- %bit.type == "Action"
- %bit.type == "Block"
- %bit.type == "IndexChain"
+ %bit.type == "Action", %bit.type == "Block", %bit.type == "IndexChain"
(%bit.type == "Number") and (%i < (size of %tree))
- ..: %bit_nomsu::parenthesize
+ ..:
+ %bit_nomsu::parenthesize
+
%nomsu::add %bit_nomsu
+
return %nomsu
"Number":
return (Nomsu Code from %tree [(%tree.1 as hex) if %tree.hex else "\(%tree.1)"])
-
"Var":
return (Nomsu Code from %tree ["%\(%tree.1)"])
-
- "Comment":
- return (nil)
-
+ "Comment": return (nil)
"FileChunks":
barf "Can't inline a FileChunks"
-
"Error":
barf "Can't compile errors"
-
else:
barf "Unknown type: \(%tree.type)"
%MAX_LINE = 90
-action [%tree decompiled]:
+externally (%tree decompiled) means:
%nomsu = (Nomsu Code from %tree)
+
# For concision:
- local action [recurse on %t]:
+ (recurse on %t) means:
%space = (%MAX_LINE - (%nomsu::trailing line length))
- if (%space <= 0): go to (Use Indented)
+ if (%space <= 0):
+ go to (Use Indented)
for %subtree in recursive %tree:
if %subtree.type is:
"Block":
@@ -151,45 +155,50 @@ action [%tree decompiled]:
go to (Use Indented)
if ((size of "\(%subtree decompiled inline)") > 20):
go to (Use Indented)
+
for %k = %v in %subtree:
if (%v is a "Syntax Tree"):
recurse %subtree on %v
-
+
%inline_nomsu = (%t decompiled inline)
if (%inline_nomsu and ((size of "\%inline_nomsu") <= %space)):
return %inline_nomsu
-
=== (Use Indented) ===
%indented = (%t decompiled)
if (%t.type == "Action"):
- %indented = (Nomsu Code from %t ["(..)\n ", %indented])
+ %indented = (..)
+ Nomsu Code from %t [..]
+ "(..)\n ", %indented
+
return %indented
-
+
if %tree.type is:
"FileChunks":
- local action [%1 and %2 should clump]:
+ (%1 and %2 should clump) means:
if ((%1.type == "Action") and (%2.type == "Action")):
- if (%1.stub == "use 1"): return (%2.stub == "use 1")
+ if (%1.stub == "use 1"):
+ return (%2.stub == "use 1")
if (%1.stub == "test 1"): return (yes)
if (%2.stub == "test 1"): return (no)
+
return (not ((recurse on %1)::is multi-line))
+
for %chunk in %tree at %chunk_no:
if (%chunk_no > 1):
%nomsu::add "\n\n\("~"::* 80)\n\n"
if (%chunk.type == "Block"):
for %line in %chunk at %line_no:
if (%line_no > 1):
- if (%chunk.(%line_no - 1) and %line should clump):
- %nomsu::add "\n"
- ..else:
- %nomsu::add "\n\n"
+ if (%chunk.(%line_no - 1) and %line should clump): %nomsu::add "\n"
+ ..else: %nomsu::add "\n\n"
+
%nomsu::add (%line decompiled)
..else:
%nomsu::add (%chunk decompiled)
- unless ("\%nomsu"::matches "\n$"):
- %nomsu::add "\n"
+
+ unless ("\%nomsu"::matches "\n$"): %nomsu::add "\n"
return %nomsu
-
+
"Action":
%pos = %tree.source.start
%next_space = ""
@@ -200,33 +209,32 @@ action [%tree decompiled]:
%nomsu::add %target_nomsu
%pos = %tree.target.source.stop
%next_space = ("\n..::" if (%target_nomsu::is multi-line) else "::")
-
+
for %bit in %tree at %i:
if ((%next_space == " ") and ((%nomsu::trailing line length) > %MAX_LINE)):
%next_space = " \\\n"
-
+
%nomsu::add %next_space
-
if (%bit is text):
unless (..)
all of [..]
- %tree.(%i - 1) is text
- (%tree.(%i - 1) is a nomsu operator) != (%bit is a nomsu operator)
- ..: %nomsu::add %next_space
+ %tree.(%i - 1) is text, (%tree.(%i - 1) is a nomsu operator) != (%bit is a nomsu operator)
+ ..:
+ %nomsu::add %next_space
+
%nomsu::add %bit
%next_space = " "
do next %bit
-
+
%bit_nomsu = (recurse on %bit)
- if (%bit.type == "Comment"):
- %next_space = "\n"
+ if (%bit.type == "Comment"): %next_space = "\n"
..else:
%next_space = (" " if (%bit_nomsu::is one line) else "\n..")
if (%bit.type == "Action"):
%bit_nomsu::parenthesize
-
+
return %nomsu
-
+
"EscapedNomsu":
%nomsu::add "\\"
%val_nomsu = (recurse on %tree.1)
@@ -234,25 +242,25 @@ action [%tree decompiled]:
%val_nomsu::parenthesize
%nomsu::add %val_nomsu
return %nomsu
-
+
"Block":
for %line in %tree at %i:
- if ((%i > 1) and (%line.type == "Comment")):
- %nomsu::add "\n"
+ if ((%i > 1) and (%line.type == "Comment")): %nomsu::add "\n"
%line_nomsu = (recurse on %line)
%nomsu::add
if (%i < (size of %tree)):
- if ((%line_nomsu::number of lines) > 2):
- %nomsu::add "\n\n"
- ..else:
- %nomsu::add "\n"
- return (Nomsu Code from %tree [":\n ", %nomsu])
-
+ if ((%line_nomsu::number of lines) > 2): %nomsu::add "\n\n"
+ ..else: %nomsu::add "\n"
+
+ return (..)
+ Nomsu Code from %tree [..]
+ ":\n ", %nomsu
+
"Text":
# Multi-line text has more generous wrap margins
%max_line = ((1.5 * %MAX_LINE) rounded down)
%nomsu = (Nomsu Code from %tree)
- local action [add text from %tree]:
+ (add text from %tree) means:
for %bit in %tree at %i:
if (%bit is text):
# TODO: escape properly?
@@ -262,7 +270,7 @@ action [%tree decompiled]:
(%j > 1): %nomsu::add "\n"
(((size of %line) > 10) and ((%nomsu::trailing line length) > %max_line)):
%nomsu::add "\\\n.."
-
+
repeat while ((size of %line) > 0):
%space = (%max_line - (%nomsu::trailing line length))
%split = (%line::position of "[%p%s]" after %space)
@@ -284,18 +292,23 @@ action [%tree decompiled]:
"Var":
if ((%tree.(%i+1) is text) and (not (%tree.(%i+1)::matches "^[ \n\t,.:#(){}[%]]"))):
%interp_nomsu::parenthesize
- ("List", "Dict"):
+
+ "List" "Dict":
%interp_nomsu::parenthesize
+
%nomsu::add %interp_nomsu
- if (%interp_nomsu::is multi-line):
- %nomsu::add "\n.."
+ if (%interp_nomsu::is multi-line): %nomsu::add "\n.."
+
add text from %tree
- return (Nomsu Code from %tree ["\"\\\n ..", %nomsu, "\""])
-
- ("List", "Dict"):
+ return (..)
+ Nomsu Code from %tree [..]
+ "\"\\\n ..", %nomsu, "\""
+
+ "List" "Dict":
if ((size of %tree) == 0):
%nomsu::add ("[]" if (%tree.type == "List") else "{}")
return %nomsu
+
for %item in %tree at %i:
%item_nomsu = (%item decompiled inline)
if ((not %item_nomsu) or ((size of "\%item_nomsu") > %MAX_LINE)):
@@ -303,10 +316,10 @@ action [%tree decompiled]:
%nomsu::add %item_nomsu
if (%i < (size of %tree)):
if any of [..]
- %item_nomsu::is multi-line
- ((%nomsu::trailing line length) + (size of "\%item_nomsu")) >= %MAX_LINE
+ %item_nomsu::is multi-line, ((%nomsu::trailing line length) + (size of "\%item_nomsu")) >= %MAX_LINE
..: %nomsu::add "\n"
..else: %nomsu::add ", "
+
return (..)
Nomsu Code from %tree [..]
"[..]\n " if (%tree.type == "List") else "{..}\n "
@@ -314,10 +327,12 @@ action [%tree decompiled]:
"DictEntry":
set {%key:%tree.1, %value:%tree.2}
- if (all of [%key.type == "Text", (size of %key) == 1, %key.1 is a nomsu identifier]):
- %nomsu::add %key.1
+ if (..)
+ all of [%key.type == "Text", (size of %key) == 1, %key.1 is a nomsu identifier]
+ ..: %nomsu::add %key.1
..else:
%nomsu::add (%key decompiled inline)
+
if ((%key.type == "Action") or (%key.type == "Block")):
%nomsu::parenthesize
%nomsu::add [": ", recurse on %value]
@@ -327,11 +342,9 @@ action [%tree decompiled]:
%nomsu::add ["#", %tree.1::with "\n" -> "\n "]
return %nomsu
- ("IndexChain", "Number", "Var"):
+ "IndexChain" "Number" "Var":
return (%tree decompiled inline)
-
"Error":
barf "Cannot decompile an error"
-
else:
barf "Unknown type: \(%tree.type)"
diff --git a/nomnom/files.nom b/nomnom/files.nom
index e4b5aa2..352ddfa 100644
--- a/nomnom/files.nom
+++ b/nomnom/files.nom
@@ -1,3 +1,4 @@
+#!/usr/bin/env nomsu -V4.8.10
# Some file utilities for searching for files recursively and using package.nomsupath
use "lib/os.nom"
@@ -6,12 +7,12 @@ use "lib/os.nom"
%_BROWSE_CACHE = {}
# Create a fake file and put it in the cache
-action [spoof file %filename %contents]:
+externally (spoof file %filename %contents) means:
%_SPOOFED_FILES.%filename = %contents
return %contents
# Read a file's contents
-action [read file %filename]:
+externally (read file %filename) means:
%contents = %_FILE_CACHE.%filename
if %contents: return %contents
if (%filename == "stdin"):
@@ -23,7 +24,7 @@ action [read file %filename]:
%_FILE_CACHE.%filename = %contents
return %contents
-action [%path sanitized]:
+externally (%path sanitized) means:
%path = (%path::with "\\" -> "\\\\")
%path = (%path::with "`" -> "")
%path = (%path::with "\"" -> "\\\"")
@@ -34,87 +35,74 @@ action [%path sanitized]:
try:
%lfs = (=lua "require('lfs')")
..and if it succeeds:
- local action [filesystem has %filename]:
+ (filesystem has %filename) means:
%mode = (call %lfs.attributes with [%filename, "mode"])
if %mode is:
- ("file", "directory", "link", "char device"):
- return (yes)
+ "file" "directory" "link" "char device": return (yes)
else: return (no)
- action [file %path exists]:
- if (..)
- any of [..]
- %_SPOOFED_FILES.%path
- %path == "stdin"
- filesystem has %path
- ..: return (yes)
+ externally (file %path exists) means:
+ if (any of [%_SPOOFED_FILES.%path, %path == "stdin", filesystem has %path]):
+ return (yes)
for %nomsupath in (%package.nomsupath::all matches of "[^;]+"):
- if (filesystem has "\%nomsupath/\%path"):
- return (yes)
+ if (filesystem has "\(%nomsupath)/\%path"): return (yes)
return (no)
-
- action [files in %path]:
+
+ externally (files in %path) means:
unless %_BROWSE_CACHE.%path:
if (%_SPOOFED_FILES.%path or (%filename == "stdin")):
%_BROWSE_CACHE.%path = [%path]
..else:
if (call %lfs.attributes with [%filename, "mode"]) is:
- ("file", "char device"):
+ "file" "char device":
%_BROWSE_CACHE.%path = [%filename]
- ("directory", "link"):
+ "directory" "link":
for %nomsupath in (%package.nomsupath::all matches of "[^;]+"):
%files = []
- for %member in (call %lfs.dir with ["\%nomsupath/\%filename"]):
- if ((%member == ".") or (%member == "..")):
- do next %member
+ for %member in (call %lfs.dir with ["\(%nomsupath)/\%filename"]):
+ if ((%member == ".") or (%member == "..")): do next %member
for % in (files in %member): %files::add %
+
if ((size of %files) > 0):
%_BROWSE_CACHE.%path = %files
go to (Found Files)
-
+
%_BROWSE_CACHE.%path = []
+
else:
%_BROWSE_CACHE.%path = []
-
+
=== (Found Files) ===
return %_BROWSE_CACHE.%filename
-
..or if it barfs:
# LFS not found! Fall back to shell commands, if available.
unless (sh> "find . -maxdepth 0"):
barf "\
- ..Could not find 'luafilesystem' module and couldn't run system command 'find' \
- ..(this might happen on Windows). Please install 'luafilesystem' (which can be \
- ..found at \(..)
- "https://github.com/spacewander/luafilesystem"
- ..if %jit else "https://github.com/keplerproject/luafilesystem"
+ ..Could not find 'luafilesystem' module and couldn't run system command 'find' (this might happen on Windows). Please install \
+ ..'luafilesystem' (which can be found at \(..)
+ "https://github.com/spacewander/luafilesystem" if %jit else "\
+ ..https://github.com/keplerproject/luafilesystem"
.. or obtained through `luarocks install luafilesystem`)"
-
-
- action [file %path exists]:
- if (..)
- any of [..]
- %_SPOOFED_FILES.%path
- %path == "stdin"
- sh> "ls \(%path sanitized)"
+
+ externally (file %path exists) means:
+ if (any of [%_SPOOFED_FILES.%path, %path == "stdin", sh> "ls \(%path sanitized)"]) \
..: return (yes)
for %nomsupath in (%package.nomsupath::all matches of "[^;]+"):
- if (sh> "ls \(%nomsupath)/\(%path)"):
- return (yes)
+ if (sh> "ls \(%nomsupath)/\%path"): return (yes)
return (no)
-
- action [files in %path]:
+
+ externally (files in %path) means:
unless %_BROWSE_CACHE.%path:
if %_SPOOFED_FILES.%path:
%_BROWSE_CACHE.%path = [%_SPOOFED_FILES.%path]
..else:
for %nomsupath in (%package.nomsupath::all matches of "[^;]+"):
- %files = (sh> "find -L '\%path' -not -path '*/\\.*' -type f'")
+ %files = (sh> "find -L '\(%path)' -not -path '*/\\.*' -type f'")
if %files:
%_BROWSE_CACHE.%path = (%files::lines)
go to (Found Files)
+
%_BROWSE_CACHE.%path = []
-
+
=== (Found Files) ===
return %_BROWSE_CACHE.%path
-
diff --git a/nomnom/parser.nom b/nomnom/parser.nom
index dfd5253..13d6112 100644
--- a/nomnom/parser.nom
+++ b/nomnom/parser.nom
@@ -1,16 +1,17 @@
+#!/usr/bin/env nomsu -V4.8.10
# This file contains the parser, which converts text into abstract syntax trees
#use "nomonom/ast.nom"
-
%lpeg = (=lua "require('lpeg')")
%re = (=lua "require('re')")
call %lpeg.setmaxstack with [20000]
set {..}
- (action (P 1)): %lpeg.P, (action (R 1)): %lpeg.R, (action (Carg 1)): %lpeg.Carg,
- (action (S 1)): %lpeg.S,
- (action (Cc 1)): %lpeg.Cc, (action (lpeg re pattern 1)): %re.compile,
- (action (lpeg re pattern 1 using 2)): %re.compile
- (action (lpeg pattern 1's match of 2)): %lpeg.match
- (action (lpeg pattern 1's match of 2 with 3)): [%1, %2, %3] -> (call %lpeg.match with [%1, %2, nil, %3])
+ ((P 1)'s meaning):%lpeg.P, ((R 1)'s meaning):%lpeg.R
+ ((Carg 1)'s meaning):%lpeg.Carg, ((S 1)'s meaning):%lpeg.S
+ ((Cc 1)'s meaning):%lpeg.Cc, ((lpeg re pattern 1)'s meaning):%re.compile
+ ((lpeg re pattern 1 using 2)'s meaning):%re.compile
+ ((lpeg pattern 1's match of 2)'s meaning):%lpeg.match
+ ((lpeg pattern 1's match of 2 with 3)'s meaning): (..)
+ [%1, %2, %3] -> (call %lpeg.match with [%1, %2, nil, %3])
%source_code_for_tree = {}
%defs = (..)
@@ -34,28 +35,30 @@ set {..}
%t = (Syntax Tree %t)
(Syntax Tree).source_code_for_tree.%t = %userdata.source
return %t
-
..with fallback %key ->:
if:
(%key::matches "^ascii_(%d+)$"):
%i = (%key::matching "^ascii_(%d+)$")
return (call %string.char with [%i as a number])
+
(%key::matches "^number_(%d+)$"):
%i = (%key::matching "^number_(%d+)$")
return (Cc (%i as a number))
-%id_patt = (((P "") - (R "09")) * ((%defs.utf8_char + (R "az") + (R "AZ") + (P "_") + (R "09"))^1 * -1))
-%operator_patt = ((S "'`~!@$^&*+=|<>?/-")^1 * -1)
+%id_patt = (..)
+ ((P "") - (R "09")) * (..)
+ (%defs.utf8_char + (R "az") + (R "AZ") + (P "_") + (R "09")) ^ 1 * -1
-action [%text is a nomsu id, %text is a nomsu identifier] (..)
+%operator_patt = ((S "'`~!@$^&*+=|<>?/-") ^ 1 * -1)
+externally [%text is a nomsu id, %text is a nomsu identifier] all mean (..)
lpeg pattern %id_patt's match of %text
-action [%text is a nomsu operator] (..)
+externally (%text is a nomsu operator) means (..)
lpeg pattern %operator_patt's match of %text
%peg_tidier = (..)
lpeg re pattern "\
- file <- %nl* {~ (def/comment) (%nl+ (def/comment))* %nl* ~}
+ ..file <- %nl* {~ (def/comment) (%nl+ (def/comment))* %nl* ~}
def <- anon_def / captured_def
anon_def <-
({ident} (" "*) ":" {[^%nl]* (%nl+ " "+ [^%nl]*)*})
@@ -67,18 +70,22 @@ action [%text is a nomsu operator] (..)
comment <- "--" [^%nl]*
"
-action [make parser from %peg] (make parser from %peg using (nil))
-
-action [make parser from %peg using %make_tree]:
+externally (make parser from %peg) means (make parser from %peg using (nil))
+externally (make parser from %peg using %make_tree) means:
%peg = (lpeg pattern %peg_tidier's match of %peg)
%peg = (lpeg re pattern %peg using %defs)
- local action [%input from %filename parsed]:
+ (%input from %filename parsed) means:
%input = "\%input"
- %tree_mt = {__index: {source:%input, filename:%filename}}
+ %tree_mt = {__index:{source:%input, filename:%filename}}
%userdata = {..}
- make_tree: %make_tree or ([%]-> (: set %'s metatable to %tree_mt; return %))
+ make_tree:%make_tree or ([%] -> (: set %'s metatable to %tree_mt; return %))
filename:%filename, source:%input
+
%tree = (lpeg pattern %peg's match of %input with %userdata)
- assume %tree or barf "File \%filename failed to parse:\n\%input"
+ assume %tree or barf "\
+ ..File \%filename failed to parse:
+ \%input"
+
return %tree
- return (action (1 from 2 parsed))
+
+ return ((1 from 2 parsed)'s meaning)
diff --git a/nomnom/pretty_errors.nom b/nomnom/pretty_errors.nom
index f32b849..db4be5a 100644
--- a/nomnom/pretty_errors.nom
+++ b/nomnom/pretty_errors.nom
@@ -1,12 +1,11 @@
+#!/usr/bin/env nomsu -V4.8.10
# This file has code for converting errors to user-friendly format, with colors,
line numbers, code excerpts, and so on.
-
-local action [visible size of %text]:
+(visible size of %text) means:
return (size of (%text::with "\027%[[0-9;]*m" -> ""))
-local action [%text boxed]:
- %max_line = (..)
- max of ((visible size of %line) for %line in (%text::lines))
+(%text boxed) means:
+ %max_line = (max of ((visible size of %line) for %line in (%text::lines)))
%ret = (..)
"\n\%text"::with "\n([^\n]*)" -> (..)
[%] -> (..)
@@ -14,47 +13,45 @@ local action [%text boxed]:
return %ret.[2,-1]
%CONTEXT = 2
-action [pretty %title error at %tree %err hint %hint]:
+externally (pretty %title error at %tree %err hint %hint) means:
%source_code = (%tree::get source code)
%start = %tree.source.start
%stop = %tree.source.stop
%filename = (%tree.source.filename or "???")
-
%err_line = (%source_code::line at %start)
%err_linenum = (%source_code::line number at %start)
%err_linepos = (%source_code::line position at %start)
+
# TODO: better handle multi-line errors
- %err_size = (..)
- min of [..]
- %stop - %start
- (size of %err_line) - %err_linepos + 1
+ %err_size = (min of [%stop - %start, (size of %err_line) - %err_linepos + 1])
%nl_indicator = (" " if (%err_linepos > (size of %err_line)) else "")
%fmt_str = " %\(size of "\(%err_linenum + %CONTEXT)")d|"
- local action [num %i] (%fmt_str::formatted with %i)
+ (num %i) means (%fmt_str::formatted with %i)
%linenum_size = (size of (num 0))
-
%pointer = "\(" "::* (%err_linepos + %linenum_size - 1))"
if (%err_size >= 2):
%pointer += "╚\("═"::* (%err_size - 2))╝"
- ..else:
- %pointer += "⬆"
-
- %err_msg = "\027[33;41;1m\(%title or "Error") at \(%filename):\(%err_linenum)\027[0m"
+ ..else: %pointer += "⬆"
+
+ %err_msg = "\
+ ..\027[33;41;1m\(%title or "Error") at \%filename:\%err_linenum\027[0m"
for %i in (%err_linenum - %CONTEXT) to (%err_linenum - 1):
%line = (%source_code::line %i)
if %line:
%err_msg += "\n\027[2m\(num %i)\027[0m\(%line)\027[0m"
+
if %err_line:
%before = %err_line.[1, %err_linepos - 1]
%during = %err_line.[%err_linepos, %err_linepos + %err_size - 1]
%after = %err_line.[%err_linepos + %err_size, -1]
- %err_line = "\027[0m\(%before)\027[41;30m\(%during)\(%nl_indicator)\027[0m\(%after)"
+ %err_line = "\027[0m\(%before)\027[41;30m\%during\(%nl_indicator)\027[0m\%after"
%err_msg += "\n\027[2m\(num %err_linenum)\(%err_line)\027[0m"
+
%err_linenum_end = (%source_code::line number at %stop)
%err_linepos_end = (%source_code::line position at %stop)
%err_linenum_end or= %err_linenum
if (%err_linenum_end == %err_linenum):
- %err_msg += "\n\(%pointer)"
+ %err_msg += "\n\%pointer"
..else:
for %i in (%err_linenum + 1) to %err_linenum_end:
%line = (%source_code::line %i)
@@ -62,24 +59,27 @@ action [pretty %title error at %tree %err hint %hint]:
if (%i == %err_linenum_end):
%during = %line.[1, %err_linepos_end - 1]
%after = %line.[%err_linepos_end, -1]
- %err_msg += "\n\027[2m\(num %i)\027[0;41;30m\(%during)\027[0m\(%after)"
+ %err_msg += "\n\027[2m\(num %i)\027[0;41;30m\(%during)\027[0m\%after"
..else:
%err_msg += "\n\027[2m\(num %i)\027[0;41;30m\(%line)\027[0m"
-
+
%box_width = 70
%err_text = "\
- ..\027[47;31;1m\((" \(%err)"::wrapped to %box_width)::with "\n" -> "\n\027[47;31;1m ")"
+ ..\027[47;31;1m\((" \%err"::wrapped to %box_width)::with "\n" -> "\n\027[47;31;1m ")"
if %hint:
%err_text += "\n\027[47;30m\((" Suggestion: \(%hint)"::wrapped to %box_width)::with "\n" -> "\n\027[47;30m ")"
%err_msg += "\n\027[33;1m \((%err_text boxed)::with "\n" -> "\n ")"
-
+
+ %err_msg += "\n\027[33;1m \((%err_text boxed)::with "\n" -> "\n ")"
for %i in (%err_linenum_end + 1) to (%err_linenum_end + %CONTEXT):
%line = (%source_code::line %i)
if %line:
%err_msg += "\n\027[2m\(num %i)\027[0m\(%line)\027[0m"
+
return %err_msg
-action [pretty %title error at %tree %err] (pretty %title error at %tree %err (nil))
+externally (pretty %title error at %tree %err) means (..)
+ pretty %title error at %tree %err (nil)
-action [%err_tree as a pretty error] (..)
+externally (%err_tree as a pretty error) means (..)
pretty %err_tree.title error at %err_tree %err_tree.error hint %err_tree.hint
diff --git a/nomnom/source.nom b/nomnom/source.nom
index e05b314..c36216f 100644
--- a/nomnom/source.nom
+++ b/nomnom/source.nom
@@ -1,24 +1,28 @@
+#!/usr/bin/env nomsu -V4.8.10
use "lib/object.nom"
object (Source):
- action [Source from text %text]:
+ externally (Source from text %text) means:
%match = (%text::matching groups "^@(.-)%[(%d+):(%d+)%]$")
set {%filename:%match.1, %start:%match.2, %stop:%match.3}
unless %filename:
%match = (%text::matching groups "^@(.-)%[(%d+)%]$")
set {%filename:%match.1, %start:%match.2}
- return (Source {filename:%filename, start:(%start or 1) as number, stop: %stop as number})
-
+
+ return (..)
+ Source {filename:%filename, start:(%start or 1) as number, stop:%stop as number}
+
my action [as text] "\
..@\(%me.filename)[\(%me.start)\(":\(%me.stop)" if %me.stop else "")]"
-
my action [as lua] "\
- ..Source{filename=\(%me.filename::as lua), start=\(%me.start)\
- ..\(", stop=\(%me.stop)" if %stop else "")}"
-
+ ..Source{filename=\(%me.filename::as lua), start=\(%me.start)\(..)
+ ", stop=\(%me.stop)" if %stop else ""
+ ..}"
+
my action [as nomsu] "\
- ..(Source {filename:\(%me.filename::as nomsu), start:\(%me.start)\
- ..\(", stop:\(%me.stop)" if %stop else "")})"
+ ..(Source {filename:\(%me.filename::as nomsu), start:\(%me.start)\(..)
+ ", stop:\(%me.stop)" if %stop else ""
+ ..})"
my action [== %other] (..)
all of [..]
@@ -26,24 +30,25 @@ object (Source):
%me.filename == %other.filename
%me.start == %other.start
%me.stop == %other.stop
-
+
my action [< %other]:
assume %me.filename == %other.filename
if (%start == %other.start):
return ((%me.stop or %me.start) < (%other.stop or %other.start))
..else:
return (%me.start < %other.start)
-
+
my action [<= %other]:
assume %me.filename == %other.filename
if (%start == %other.start):
return ((%me.stop or %me.start) <= (%other.stop or %other.start))
..else:
return (%me.start <= %other.start)
-
+
my action [+ %offset]:
if ((type of %me) == "number"):
set {%me:%offset, %offset:%me}
..else:
assume (type of %offset) == "number"
+
return (Source {filename:%me.filename, start:%me.start + %offset, stop:%me.stop})