[sql] SQL "works" but it's too dang slow

This commit is contained in:
John Doty 2024-11-15 19:46:51 -08:00
parent c23dbe3e8f
commit 2d10e91f9e
4 changed files with 1218 additions and 452 deletions

View file

@ -129,14 +129,17 @@ function render_state(state, input_editor) {
* otherwise just queue it for submission. * otherwise just queue it for submission.
*/ */
function post_document(worker, kind, state, document) { function post_document(worker, kind, state, document) {
console.log("Received document", kind)
if (window.localStorage) { if (window.localStorage) {
window.localStorage.setItem(kind, document); window.localStorage.setItem(kind, document);
} }
let new_state = {...state}; let new_state = {...state};
if (new_state.pending) { if (new_state.pending) {
console.log("Document parked", kind)
new_state.next = document; new_state.next = document;
} else { } else {
console.log("Document submitted", kind)
new_state.pending = document; new_state.pending = document;
new_state.next = null; new_state.next = null;
worker.postMessage({kind, data: document}); worker.postMessage({kind, data: document});
@ -151,6 +154,7 @@ function post_document(worker, kind, state, document) {
function rotate_document(worker, kind, state) { function rotate_document(worker, kind, state) {
let new_state = {...state, last: state.pending, pending: null}; let new_state = {...state, last: state.pending, pending: null};
if (new_state.next) { if (new_state.next) {
console.log("Rotating document", kind)
new_state.pending = new_state.next; new_state.pending = new_state.next;
new_state.next = null; new_state.next = null;
worker.postMessage({kind, data: new_state.pending}); worker.postMessage({kind, data: new_state.pending});

View file

@ -176,19 +176,21 @@ const pyodide_promise = setup_python();
async function load_grammar_module(code) { async function load_grammar_module(code) {
const pyodide = self.pyodide; const pyodide = self.pyodide;
// console.log("Running..."); console.log("eval_grammar: Running");
const my_fn = pyodide.globals.get("eval_grammar"); const my_fn = pyodide.globals.get("eval_grammar");
my_fn(code); my_fn(code);
my_fn.destroy(); my_fn.destroy();
console.log("eval_grammar: Done");
} }
async function parse_document(code) { async function parse_document(code) {
const pyodide = self.pyodide; const pyodide = self.pyodide;
// console.log("Running..."); console.log("eval_document: Running");
const my_fn = pyodide.globals.get("eval_document"); const my_fn = pyodide.globals.get("eval_document");
my_fn(code); my_fn(code);
my_fn.destroy(); my_fn.destroy();
console.log("eval_document: Done");
} }
self.onmessage = async function(event) { self.onmessage = async function(event) {
@ -197,8 +199,10 @@ self.onmessage = async function(event) {
try { try {
const { kind, data } = event.data; const { kind, data } = event.data;
if (kind === "grammar") { if (kind === "grammar") {
console.log("Worker received grammar")
await load_grammar_module(data); await load_grammar_module(data);
} else if (kind === "input") { } else if (kind === "input") {
console.log("Worker received input")
await parse_document(data); await parse_document(data);
} }
} catch (e) { } catch (e) {

File diff suppressed because it is too large Load diff

View file

@ -1116,7 +1116,9 @@ class ParserGenerator:
# Check to make sure they didn't use anything that will give us # Check to make sure they didn't use anything that will give us
# heartburn later. # heartburn later.
reserved = [a for a in alphabet if (a.startswith("__") and not a.startswith("__gen_")) or a == "$"] reserved = [
a for a in alphabet if (a.startswith("__") and not a.startswith("__gen_")) or a == "$"
]
if reserved: if reserved:
raise ValueError( raise ValueError(
"Can't use {symbols} in grammars, {what} reserved.".format( "Can't use {symbols} in grammars, {what} reserved.".format(
@ -1619,6 +1621,7 @@ class Terminal(Rule):
_CURRENT_DEFINITION: str = "__global" _CURRENT_DEFINITION: str = "__global"
_CURRENT_GEN_INDEX: int = 0 _CURRENT_GEN_INDEX: int = 0
class NonTerminal(Rule): class NonTerminal(Rule):
"""A non-terminal, or a production, in the grammar. """A non-terminal, or a production, in the grammar.
@ -1699,7 +1702,6 @@ class NonTerminal(Rule):
_CURRENT_DEFINITION = prev_defn _CURRENT_DEFINITION = prev_defn
_CURRENT_GEN_INDEX = prev_idx _CURRENT_GEN_INDEX = prev_idx
return self._body return self._body
def flatten( def flatten(
@ -1827,10 +1829,11 @@ def one_or_more(*args: Rule) -> Rule:
global _CURRENT_DEFINITION global _CURRENT_DEFINITION
global _CURRENT_GEN_INDEX global _CURRENT_GEN_INDEX
tail : NonTerminal | None = None tail: NonTerminal | None = None
def impl() -> Rule: def impl() -> Rule:
nonlocal tail nonlocal tail
assert(tail is not None) assert tail is not None
return opt(tail) + seq(*args) return opt(tail) + seq(*args)
tail = NonTerminal( tail = NonTerminal(
@ -1842,6 +1845,7 @@ def one_or_more(*args: Rule) -> Rule:
return tail return tail
def zero_or_more(*args: Rule) -> Rule: def zero_or_more(*args: Rule) -> Rule:
"""Generate a rule that matches a repetition of zero or more of the specified """Generate a rule that matches a repetition of zero or more of the specified
rule. rule.
@ -1852,6 +1856,7 @@ def zero_or_more(*args: Rule) -> Rule:
""" """
return opt(one_or_more(*args)) return opt(one_or_more(*args))
@typing.overload @typing.overload
def rule(f: typing.Callable, /) -> NonTerminal: ... def rule(f: typing.Callable, /) -> NonTerminal: ...
@ -2848,9 +2853,12 @@ class TriviaMode(enum.Enum):
# Finally, the grammar class. # Finally, the grammar class.
############################################################################### ###############################################################################
PrecedenceList = list[typing.Tuple[Assoc, list[Terminal|NonTerminal]]] PrecedenceList = list[typing.Tuple[Assoc, list[Terminal | NonTerminal]]]
def gather_grammar(start: NonTerminal, trivia: list[Terminal]) -> tuple[dict[str,NonTerminal], dict[str,Terminal]]:
def gather_grammar(
start: NonTerminal, trivia: list[Terminal]
) -> tuple[dict[str, NonTerminal], dict[str, Terminal]]:
"""Starting from the given NonTerminal, gather all of the symbols """Starting from the given NonTerminal, gather all of the symbols
(NonTerminals and Terminals) that make up the grammar. (NonTerminals and Terminals) that make up the grammar.
""" """
@ -2894,9 +2902,11 @@ def gather_grammar(start: NonTerminal, trivia: list[Terminal]) -> tuple[dict[str
existing = named_rules.get(rule.name) existing = named_rules.get(rule.name)
if existing is not None: if existing is not None:
# TODO TEST # TODO TEST
raise ValueError(f"""Found more than one rule named {rule.name}: raise ValueError(
f"""Found more than one rule named {rule.name}:
- {existing.definition_location} - {existing.definition_location}
- {rule.definition_location}""") - {rule.definition_location}"""
)
named_rules[rule.name] = rule named_rules[rule.name] = rule
named_terminals: dict[str, Terminal] = {} named_terminals: dict[str, Terminal] = {}
@ -2904,16 +2914,20 @@ def gather_grammar(start: NonTerminal, trivia: list[Terminal]) -> tuple[dict[str
existing = named_terminals.get(terminal.name) existing = named_terminals.get(terminal.name)
if existing is not None: if existing is not None:
# TODO TEST # TODO TEST
raise ValueError(f"""Found more than one terminal named {terminal.name}: raise ValueError(
f"""Found more than one terminal named {terminal.name}:
- {existing.definition_location} - {existing.definition_location}
- {terminal.definition_location}""") - {terminal.definition_location}"""
)
existing_rule = named_rules.get(terminal.name) existing_rule = named_rules.get(terminal.name)
if existing_rule is not None: if existing_rule is not None:
# TODO TEST # TODO TEST
raise ValueError(f"""Found a terminal and a rule both named {terminal.name}: raise ValueError(
f"""Found a terminal and a rule both named {terminal.name}:
- The rule was defined at {existing_rule.definition_location} - The rule was defined at {existing_rule.definition_location}
- The terminal was defined at {terminal.definition_location}""") - The terminal was defined at {terminal.definition_location}"""
)
named_terminals[terminal.name] = terminal named_terminals[terminal.name] = terminal
@ -3010,7 +3024,7 @@ class Grammar:
generate_nonterminal_dict- less useful to people, probably, but it is generate_nonterminal_dict- less useful to people, probably, but it is
the input form needed by the Generator. the input form needed by the Generator.
""" """
grammar: list[tuple[str,list[str]]] = [ grammar: list[tuple[str, list[str]]] = [
(rule.name, [s.name for s in production]) (rule.name, [s.name for s in production])
for rule in self._nonterminals.values() for rule in self._nonterminals.values()
for production in rule.body for production in rule.body