Forward progress on getting nomnom working.
This commit is contained in:
parent
7b127fca61
commit
678344182b
@ -1,6 +1,6 @@
|
||||
use "lib/object.nom"
|
||||
|
||||
#%types = [..]
|
||||
# The types are [..]
|
||||
"Number", "Var", "Block", "EscapedNomsu", "Text", "List", "Dict", "DictEntry",
|
||||
"IndexChain", "Action", "FileChunks", "Error", "Comment"
|
||||
|
||||
|
@ -6,6 +6,7 @@ use "lib/object.nom"
|
||||
|
||||
object (Code):
|
||||
my action [set up]:
|
||||
assume %me.source
|
||||
%old_bits = %me.bits
|
||||
%me.bits = []
|
||||
if (%me.source is text):
|
||||
@ -13,19 +14,24 @@ object (Code):
|
||||
for % in %old_bits:
|
||||
%me::add %
|
||||
|
||||
%depth = 0
|
||||
my action [as text]:
|
||||
external %depth = (%depth + 1)
|
||||
if (%depth > 10):
|
||||
lua> "require('ldt').breakpoint()"
|
||||
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)
|
||||
for %bit in %me.bits:
|
||||
if (%bit is text):
|
||||
%spaces = (%bit::matching "\n([ ]*)[^\n]*$")
|
||||
if %spaces: %indent = (size of %spaces.1)
|
||||
..else:
|
||||
% = "\%"
|
||||
%bit = "\%bit"
|
||||
if (%indent > 0):
|
||||
% = (%::with "\n" -> "\n\(" "::* %indent)")
|
||||
%buff::add %
|
||||
%bit = (%bit::with "\n" -> "\n\(" "::* %indent)")
|
||||
%buff::add %bit
|
||||
%me.__str = (%buff::joined)
|
||||
external %depth = (%depth - 1)
|
||||
return %me.__str
|
||||
|
||||
my action [as lua] (..)
|
||||
@ -76,19 +82,20 @@ object (Code):
|
||||
my action [add %values joined with %joiner or %wrapping_joiner]:
|
||||
%line_len = 0
|
||||
%bits = %me.bits
|
||||
for %i = % in %values:
|
||||
for %value in %values at %i:
|
||||
assume (%value != %me)
|
||||
if (%i > 1):
|
||||
if (%line_len > 80):
|
||||
%bits::add %wrapping_joiner
|
||||
%line_len = 0
|
||||
..else:
|
||||
%bits::add %joiner
|
||||
%bits::add %
|
||||
%line = ("\%"::matching "\n([^\n]*)$")
|
||||
%bits::add %value
|
||||
%line = ("\%value"::matching "\n([^\n]*)$")
|
||||
if %line:
|
||||
%line_len = (size of %line)
|
||||
..else:
|
||||
%line_len += (size of %)
|
||||
%line_len += (size of %value)
|
||||
%me::mark as dirty
|
||||
|
||||
my action [prepend %]:
|
||||
@ -155,7 +162,7 @@ object (Lua Code) extends (Code):
|
||||
my action [as statements %prefix %suffix]:
|
||||
unless %me.is_value:
|
||||
return %me
|
||||
%statements = (Lua Code %me.source [])
|
||||
%statements = (Lua Code from %me.source [])
|
||||
if (%prefix != ""):
|
||||
%statements::add %prefix
|
||||
%statements::add %me
|
||||
|
@ -1,6 +1,14 @@
|
||||
# This file contains the code to convert syntax trees to Lua code
|
||||
|
||||
#use "nomnom/code_obj.nom"
|
||||
use "nomnom/code_obj.nom"
|
||||
use "nomnom/parser.nom"
|
||||
use "nomnom/pretty_errors.nom"
|
||||
|
||||
local action [report compile error at %pos %err]:
|
||||
barf "Compile error at \%pos: \%err"
|
||||
|
||||
local action [report compile error at %pos %err hint %hint]:
|
||||
barf "Compile error at \%pos: \%err\n\%hint"
|
||||
|
||||
action [compile %tree using %compile_actions]:
|
||||
assume (%tree is a "Syntax Tree")
|
||||
@ -15,17 +23,17 @@ action [compile %tree using %compile_actions]:
|
||||
%compile_action = %compile_actions.%stub
|
||||
# Don't apply compiler actions to methods
|
||||
if (%compile_action and (not %tree.target)):
|
||||
%args = [%tree, %compile_actions]
|
||||
%args = ["tree", "compile_actions"]
|
||||
for % in (%tree::get args): %args::add %
|
||||
%result = (call %compile_action with %args)
|
||||
if (%result == (nil)):
|
||||
compile error at %tree.source "\
|
||||
report compile error at %tree.source "\
|
||||
..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):
|
||||
compile error at %tree.source "\
|
||||
report compile error at %tree.source "\
|
||||
..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."
|
||||
@ -39,9 +47,9 @@ action [compile %tree using %compile_actions]:
|
||||
%lua::add [%target_lua, ":"]
|
||||
..else:
|
||||
%lua::add ["(", %target_lua, "):"]
|
||||
%lua:add [%stub as lua id, "("]
|
||||
%lua::add [%stub as lua id, "("]
|
||||
%args = []
|
||||
for %tok in %tree:
|
||||
for %tok in %tree at %i:
|
||||
if (%tok is text): do next %tok
|
||||
# TODO: maybe translate Lua comments
|
||||
if (%tok.type == "Comment"): do next %tok
|
||||
@ -67,16 +75,17 @@ action [compile %tree using %compile_actions]:
|
||||
%arg_lua = (compile %tok using %compile_actions)
|
||||
unless %arg_lua.is_value:
|
||||
if (%tok.type == "Action"):
|
||||
compile error at %tok "\
|
||||
report compile error at %tok "\
|
||||
..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."
|
||||
..else:
|
||||
compile error at %tok "\
|
||||
report compile error at %tok "\
|
||||
..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 ")"
|
||||
@ -94,7 +103,7 @@ action [compile %tree using %compile_actions]:
|
||||
return %lua
|
||||
|
||||
"Text":
|
||||
%lua = (Lua Code from %tree)
|
||||
%lua = (Lua Value from %tree)
|
||||
%lua_bits = []
|
||||
%string_buffer = ""
|
||||
for % in %tree:
|
||||
@ -104,12 +113,12 @@ action [compile %tree using %compile_actions]:
|
||||
if (%string_buffer != ""):
|
||||
%lua_bits::add (%string_buffer::as lua)
|
||||
%string_buffer = ""
|
||||
%bit_lua = (compile %bit using %compile_actions)
|
||||
%bit_lua = (compile % using %compile_actions)
|
||||
unless %bit_lua.is_value:
|
||||
compile error at %bit "\
|
||||
report compile error at % "\
|
||||
..Can't use this as a string interpolation value, since it doesn't have a value."
|
||||
if (%bit.type != "Text"):
|
||||
%bit_lua = (Lua Value from %bit ["tostring(",%bit_lua,")"])
|
||||
if (%.type != "Text"):
|
||||
%bit_lua = (Lua Value from % ["tostring(",%bit_lua,")"])
|
||||
%lua_bits::add %bit_lua
|
||||
|
||||
if ((%string_buffer != "") or ((size of %lua_bits) == 0)):
|
||||
@ -136,13 +145,13 @@ action [compile %tree using %compile_actions]:
|
||||
set {%key:%tree.1, %value:%tree.2}
|
||||
%key_lua = (compile %key using %compile_actions)
|
||||
unless %key_lua.is_value:
|
||||
compile error at %tree.1 "\
|
||||
report compile error at %tree.1 "\
|
||||
..Can't use this as a dict key, since it's not an expression."
|
||||
%value_lua = (..)
|
||||
(compile %value using %compile_actions) if %value
|
||||
..else (Lua Value from %key ["true"])
|
||||
unless %value_lua.is_value:
|
||||
compile error at %tree.2 "\
|
||||
report compile error at %tree.2 "\
|
||||
..Can't use this as a dict value, since it's not an expression."
|
||||
%key_str = ("\%key_lua"::matching "^[\"']([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
|
||||
if:
|
||||
@ -159,7 +168,7 @@ action [compile %tree using %compile_actions]:
|
||||
"IndexChain":
|
||||
%lua = (compile %tree.1 using %compile_actions)
|
||||
unless %lua.is_value:
|
||||
compile error at %tree.1 "\
|
||||
report compile error at %tree.1 "\
|
||||
..Can't index into this, since it's not an expression."
|
||||
%first_char = "\%lua".1
|
||||
if (any of [%first_char == "{", %first_char == "\"", %first_char == "["]):
|
||||
@ -169,7 +178,7 @@ action [compile %tree using %compile_actions]:
|
||||
%key = %tree.%i
|
||||
%key_lua = (compile %key using %compile_actions)
|
||||
unless %key_lua.is_value:
|
||||
compile error at %key "\
|
||||
report compile error at %key "\
|
||||
..Can't use this as an index, since it's not an expression."
|
||||
%key_lua_str = "\%key_lua"
|
||||
%lua_id = (%key_lua_str::matching "^['\"]([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
|
||||
@ -205,3 +214,4 @@ action [compile %tree using %compile_actions]:
|
||||
|
||||
else:
|
||||
barf "Unknown type: \(%tree.type)"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# This file contains the code to convert syntax trees to Nomsu code
|
||||
#use "nomnom/code_obj.nom"
|
||||
#use "nomnom/parser.nom"
|
||||
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 [decompile %tree inline]:
|
||||
@ -21,7 +21,7 @@ action [decompile %tree inline]:
|
||||
any of [..]
|
||||
%i == 1,
|
||||
%tree.(%i - 1) isn't text,
|
||||
(%bit::is a nomsu operator) == (%tree.(%i - 1)::is a nomsu operator)
|
||||
(%bit is a nomsu operator) == (%tree.(%i - 1) is a nomsu operator)
|
||||
..: %nomsu::add " "
|
||||
%nomsu::add %bit
|
||||
..else:
|
||||
@ -86,7 +86,7 @@ action [decompile %tree inline]:
|
||||
|
||||
"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 = (decompile %key inline)
|
||||
@ -105,7 +105,7 @@ action [decompile %tree inline]:
|
||||
if (..)
|
||||
all of [..]
|
||||
%i > 1, %bit.type == "Text", (size of %bit) == 1, %bit.1 is text,
|
||||
%bit.1::is a nomsu identifier
|
||||
%bit.1 is a nomsu identifier
|
||||
..:%nomsu::add %bit.1
|
||||
..else:
|
||||
%bit_nomsu = (decompile %bit inline)
|
||||
@ -214,7 +214,7 @@ action [decompile %tree]:
|
||||
unless (..)
|
||||
all of [..]
|
||||
%tree.(%i - 1) is text
|
||||
(%tree.(%i - 1)::is a nomsu operator) != (%bit::is a nomsu operator)
|
||||
(%tree.(%i - 1) is a nomsu operator) != (%bit is a nomsu operator)
|
||||
..: %nomsu::add %next_space
|
||||
%nomsu::add %bit
|
||||
%next_space = " "
|
||||
@ -317,7 +317,7 @@ action [decompile %tree]:
|
||||
|
||||
"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::add %key.1
|
||||
..else:
|
||||
%nomsu::add (decompile %key inline)
|
||||
|
@ -9,6 +9,8 @@ set {..}
|
||||
(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])
|
||||
|
||||
%source_code_for_tree = {}
|
||||
%defs = (..)
|
||||
@ -27,7 +29,7 @@ set {..}
|
||||
|
||||
Tree: [%t, %userdata] ->:
|
||||
%source = (..)
|
||||
Source {filename:%userdata.filename, start:%tree.start, stop:%tree.stop}
|
||||
Source {filename:%userdata.filename, start:%t.start, stop:%t.stop}
|
||||
set {%t.start: nil, %t.stop: nil}
|
||||
%t = (Syntax Tree %t)
|
||||
(Syntax Tree).source_code_for_tree.%t = %userdata.source
|
||||
@ -44,12 +46,12 @@ set {..}
|
||||
|
||||
%id_patt = (((P "") - (R "09")) * ((%defs.utf8_char + (R "az") + (R "AZ") + (P "_") + (R "09"))^1 * -1))
|
||||
%operator_patt = ((S "'`~!@$^&*+=|<>?/-")^1 * -1)
|
||||
%text_methods = (""'s metatable).__methods
|
||||
%text_methods.("is a nomsu identifier"::as lua id) = (..)
|
||||
[%str] -> (call %id_patt.match with [%id_patt, %str])
|
||||
%text_methods.("is a nomsu id"::as lua id) = %text_methods.("is a nomsu identifier"::as lua id)
|
||||
%text_methods.("is a nomsu operator"::as lua id) = (..)
|
||||
[%str] -> (call %operator_patt.match with [%operator_patt, %str])
|
||||
|
||||
action [%text is a nomsu id, %text is a nomsu identifier] (..)
|
||||
lpeg pattern %id_patt's match of %text
|
||||
|
||||
action [%text is a nomsu operator] (..)
|
||||
lpeg pattern %operator_patt's match of %text
|
||||
|
||||
%peg_tidier = (..)
|
||||
lpeg re pattern "\
|
||||
@ -68,7 +70,7 @@ set {..}
|
||||
action [make parser from %peg] (make parser from %peg using (nil))
|
||||
|
||||
action [make parser from %peg using %make_tree]:
|
||||
%peg = (call %peg_tidier.match with [%peg_tidier, %peg])
|
||||
%peg = (lpeg pattern %peg_tidier's match of %peg)
|
||||
%peg = (lpeg re pattern %peg using %defs)
|
||||
local action [parse %input from %filename]:
|
||||
%input = "\%input"
|
||||
@ -76,7 +78,7 @@ action [make parser from %peg using %make_tree]:
|
||||
%userdata = {..}
|
||||
make_tree: %make_tree or ([%]-> (: set %'s metatable to %tree_mt; return %))
|
||||
filename:%filename, source:%input
|
||||
%tree = (call %peg.match with [%peg, %input, (nil), %userdata])
|
||||
%tree = (lpeg pattern %peg's match of %input with %userdata)
|
||||
assume %tree or barf "File \%filename failed to parse:\n\%input"
|
||||
return %tree
|
||||
return (action (parse 1 from 2))
|
||||
|
Loading…
Reference in New Issue
Block a user