Implemented rudimentary reduction scanner
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"name": "@efforting.tech/experiments",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"tree-sitter": "^0.25.0",
|
||||
"tree-sitter-javascript": "^0.25.0"
|
||||
|
||||
@@ -1,14 +1,109 @@
|
||||
import { Reduction_Scanner, Reduction_Settings } from '@efforting.tech/rule-processing/reduction-scanner';
|
||||
//import { Sub_Sequence_Rule } from '@efforting.tech/rule-processing/rules';
|
||||
import * as R from '@efforting.tech/rule-processing/rules';
|
||||
|
||||
import { inspect } from 'node:util';
|
||||
|
||||
/*
|
||||
Here's what needs addressing:
|
||||
|
||||
**`perform_reduction` refactor**
|
||||
- Remove the `start_index` loop — scanning is the condition's responsibility
|
||||
- RULE_MAJOR: iterate rules, call `rule.match(sequence, context)`, apply first that returns a match
|
||||
- POSITION_MAJOR: collect matches from all rules, apply the one with lowest `start_index` in result
|
||||
|
||||
**`Sequence_Condition.match` implementation**
|
||||
- Iterate positions internally
|
||||
- Return match result with `start_index`, `end_index`, captures
|
||||
- Return null if no match found anywhere
|
||||
|
||||
**Rule interface**
|
||||
- `rule.match(sequence, context)` → match result or null
|
||||
- `rule.action(scanner, sequence, match)` → performs the transformation
|
||||
- Decide: forwarding getters, bind in constructor, or scanner calls `rule.condition.match` directly
|
||||
|
||||
**Match result shape**
|
||||
- `{ rule, sequence, start_index, end_index, captures, ...extra_info }`
|
||||
- `captures` lazily evaluated via getter
|
||||
|
||||
**Normalization**
|
||||
- Decide when rules get normalized/compiled (construction, first transform, explicit `prepare()`)
|
||||
- Normalize bare functions to condition objects at that point
|
||||
|
||||
**`context` shape**
|
||||
- What does the scanner inject into context beyond `start_index`/`end_index`?
|
||||
- How does `extra_info` from resolver flow through to condition match?
|
||||
*/
|
||||
|
||||
|
||||
const rss = Reduction_Settings.load();
|
||||
|
||||
class Rule { //NOTE: This is somewhat of a place holder because we may want to declare specific transformations later rather than always having an opaque handler function
|
||||
constructor(condition, handler) {
|
||||
Object.assign(this, { condition, handler });
|
||||
}
|
||||
|
||||
get match() {
|
||||
return this.condition.match.bind(this.condition);
|
||||
}
|
||||
|
||||
get action() {
|
||||
return this.handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const N = new R.Predicate((i) => typeof i === 'number' || i.type == 'BINOP' );
|
||||
const ASTERISK = new R.Strict_Equality('*');
|
||||
const PLUS = new R.Strict_Equality('+');
|
||||
|
||||
|
||||
const rss = Reduction_Settings.load({
|
||||
// Switching this on or off affects whether add comes before mul or not
|
||||
//reduction_order: 'POSITION_MAJOR',
|
||||
});
|
||||
const rs = new Reduction_Scanner(rss);
|
||||
|
||||
rss.rules.push();
|
||||
|
||||
rss.rules.push(
|
||||
new Rule(
|
||||
new R.Sequence_Condition([N, ASTERISK, N]),
|
||||
(rs, sequence, match) => {
|
||||
const MS = match.match_start;
|
||||
const ME = match.match_end;
|
||||
sequence.splice(MS, ME - MS + 1, { type: 'BINOP', op: 'MUL', operands: [sequence[MS], sequence[ME]]});
|
||||
}
|
||||
),
|
||||
|
||||
new Rule(
|
||||
new R.Sequence_Condition([N, PLUS, N]),
|
||||
(rs, sequence, match) => {
|
||||
const MS = match.match_start;
|
||||
const ME = match.match_end;
|
||||
sequence.splice(MS, ME - MS + 1, { type: 'BINOP', op: 'ADD', operands: [sequence[MS], sequence[ME]]});
|
||||
},
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
const arr = [10, '+', 20, '*', 30];
|
||||
console.log(rs.perform_reduction(arr));
|
||||
console.log(arr);
|
||||
console.log(inspect(rs.transform(arr), { colors: true, depth: null }));
|
||||
|
||||
/* OUTPUT
|
||||
|
||||
[
|
||||
{
|
||||
type: 'BINOP',
|
||||
op: 'ADD',
|
||||
operands: [ 10, { type: 'BINOP', op: 'MUL', operands: [ 20, 30 ] } ]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// These are for testing conditions without reduction
|
||||
// const sc = new R.Sequence_Condition([N, PLUS, N]);
|
||||
// console.log(sc.match([10, '+', 20, '*', 30]));
|
||||
|
||||
Reference in New Issue
Block a user