mirror of
https://github.com/HeyPuter/puter
synced 2024-11-14 22:06:00 +00:00
refactor(phoenix): Combine similar sed command classes
These make more sense combined into one Command which is controlled by constructor parameters: - b, t and T - d and D - g and G - h and H - p and P
This commit is contained in:
parent
0d4f907b66
commit
6de4c89c25
@ -144,13 +144,21 @@ export class AppendTextCommand extends Command {
|
||||
}
|
||||
|
||||
// 'b' - Branch to label
|
||||
// 't' - Branch if substitution successful
|
||||
// 'T' - Branch if substitution unsuccessful
|
||||
export class BranchCommand extends Command {
|
||||
constructor(addressRange, label) {
|
||||
constructor(addressRange, label, substitutionCondition) {
|
||||
super(addressRange);
|
||||
this.label = label;
|
||||
this.substitutionCondition = substitutionCondition;
|
||||
}
|
||||
|
||||
async run(context) {
|
||||
if (typeof this.substitutionCondition === 'boolean') {
|
||||
if (context.substitutionResult !== this.substitutionCondition)
|
||||
return JumpLocation.None;
|
||||
}
|
||||
|
||||
if (this.label) {
|
||||
context.jumpParameter = this.label;
|
||||
return JumpLocation.Label;
|
||||
@ -160,6 +168,7 @@ export class BranchCommand extends Command {
|
||||
|
||||
dump(indent) {
|
||||
return `${makeIndent(indent)}BRANCH:\n`
|
||||
+ `${makeIndent(indent+1)}CONDITION: ${this.substitutionCondition ?? 'ALWAYS'}\n`
|
||||
+ this.addressRange.dump(indent+1)
|
||||
+ `${makeIndent(indent+1)}LABEL: ${this.label ? `'${this.label}'` : 'END'}\n`;
|
||||
}
|
||||
@ -189,107 +198,73 @@ export class ReplaceCommand extends Command {
|
||||
}
|
||||
|
||||
// 'd' - Delete pattern
|
||||
// 'D' - Delete first line of pattern
|
||||
export class DeleteCommand extends Command {
|
||||
constructor(addressRange) {
|
||||
constructor(addressRange, firstLine = false) {
|
||||
super(addressRange);
|
||||
this.firstLine = firstLine;
|
||||
}
|
||||
|
||||
async run(context) {
|
||||
if (this.firstLine) {
|
||||
const [ first, rest ] = context.patternSpace.split('\n', 2);
|
||||
context.patternSpace = rest ?? '';
|
||||
if (rest === undefined)
|
||||
return JumpLocation.EndOfCycle;
|
||||
return JumpLocation.StartOfCycle;
|
||||
}
|
||||
context.patternSpace = '';
|
||||
return JumpLocation.EndOfCycle;
|
||||
}
|
||||
|
||||
dump(indent) {
|
||||
return `${makeIndent(indent)}DELETE:\n`
|
||||
+ this.addressRange.dump(indent+1);
|
||||
}
|
||||
}
|
||||
|
||||
// 'D' - Delete first line of pattern
|
||||
export class DeleteLineCommand extends Command {
|
||||
constructor(addressRange) {
|
||||
super(addressRange);
|
||||
}
|
||||
|
||||
async run(context) {
|
||||
const [ firstLine, rest ] = context.patternSpace.split('\n', 2);
|
||||
context.patternSpace = rest ?? '';
|
||||
if (rest === undefined) {
|
||||
return JumpLocation.EndOfCycle;
|
||||
}
|
||||
return JumpLocation.StartOfCycle;
|
||||
}
|
||||
|
||||
dump(indent) {
|
||||
return `${makeIndent(indent)}DELETE-LINE:\n`
|
||||
return `${makeIndent(indent)}DELETE: ${this.firstLine ? 'LINE' : 'ALL'}\n`
|
||||
+ this.addressRange.dump(indent+1);
|
||||
}
|
||||
}
|
||||
|
||||
// 'g' - Get the held line into the pattern
|
||||
export class GetCommand extends Command {
|
||||
constructor(addressRange) {
|
||||
super(addressRange);
|
||||
}
|
||||
|
||||
async run(context) {
|
||||
context.patternSpace = context.holdSpace;
|
||||
return JumpLocation.None;
|
||||
}
|
||||
|
||||
dump(indent) {
|
||||
return `${makeIndent(indent)}GET-HELD:\n`
|
||||
+ this.addressRange.dump(indent+1);
|
||||
}
|
||||
}
|
||||
|
||||
// 'G' - Get the held line and append it to the pattern
|
||||
export class GetAppendCommand extends Command {
|
||||
constructor(addressRange) {
|
||||
export class GetCommand extends Command {
|
||||
constructor(addressRange, append = false) {
|
||||
super(addressRange);
|
||||
this.append = append;
|
||||
}
|
||||
|
||||
async run(context) {
|
||||
context.patternSpace += '\n' + context.holdSpace;
|
||||
if (this.append) {
|
||||
context.patternSpace += '\n' + context.holdSpace;
|
||||
} else {
|
||||
context.patternSpace = context.holdSpace;
|
||||
}
|
||||
return JumpLocation.None;
|
||||
}
|
||||
|
||||
dump(indent) {
|
||||
return `${makeIndent(indent)}GET-HELD-APPEND:\n`
|
||||
return `${makeIndent(indent)}GET-HELD: ${this.append ? 'APPEND' : 'ALL'}\n`
|
||||
+ this.addressRange.dump(indent+1);
|
||||
}
|
||||
}
|
||||
|
||||
// 'h' - Hold the pattern
|
||||
export class HoldCommand extends Command {
|
||||
constructor(addressRange) {
|
||||
super(addressRange);
|
||||
}
|
||||
|
||||
async run(context) {
|
||||
context.holdSpace = context.patternSpace;
|
||||
return JumpLocation.None;
|
||||
}
|
||||
|
||||
dump(indent) {
|
||||
return `${makeIndent(indent)}HOLD:\n`
|
||||
+ this.addressRange.dump(indent+1);
|
||||
}
|
||||
}
|
||||
|
||||
// 'H' - Hold append the pattern
|
||||
export class HoldAppendCommand extends Command {
|
||||
constructor(addressRange) {
|
||||
export class HoldCommand extends Command {
|
||||
constructor(addressRange, append = false) {
|
||||
super(addressRange);
|
||||
this.append = append;
|
||||
}
|
||||
|
||||
async run(context) {
|
||||
context.holdSpace += '\n' + context.patternSpace;
|
||||
if (this.append) {
|
||||
context.holdSpace += '\n' + context.patternSpace;
|
||||
} else {
|
||||
context.holdSpace = context.patternSpace;
|
||||
}
|
||||
return JumpLocation.None;
|
||||
}
|
||||
|
||||
dump(indent) {
|
||||
return `${makeIndent(indent)}HOLD-APPEND:\n`
|
||||
return `${makeIndent(indent)}HOLD: ${this.append ? 'APPEND' : 'ALL'}\n`
|
||||
+ this.addressRange.dump(indent+1);
|
||||
}
|
||||
}
|
||||
@ -354,36 +329,25 @@ export class DebugPrintCommand extends Command {
|
||||
}
|
||||
|
||||
// 'p' - Print pattern
|
||||
export class PrintCommand extends Command {
|
||||
constructor(addressRange) {
|
||||
super(addressRange);
|
||||
}
|
||||
|
||||
async run(context) {
|
||||
await context.out.write(context.patternSpace + '\n');
|
||||
return JumpLocation.None;
|
||||
}
|
||||
|
||||
dump(indent) {
|
||||
return `${makeIndent(indent)}PRINT:\n`
|
||||
+ this.addressRange.dump(indent+1);
|
||||
}
|
||||
}
|
||||
|
||||
// 'P' - Print first line of pattern
|
||||
export class PrintLineCommand extends Command {
|
||||
constructor(addressRange) {
|
||||
export class PrintCommand extends Command {
|
||||
constructor(addressRange, firstLine = false) {
|
||||
super(addressRange);
|
||||
this.firstLine = firstLine;
|
||||
}
|
||||
|
||||
async run(context) {
|
||||
const firstLine = context.patternSpace.split('\n', 2)[0];
|
||||
await context.out.write(firstLine + '\n');
|
||||
if (this.firstLine) {
|
||||
const firstLine = context.patternSpace.split('\n', 2)[0];
|
||||
await context.out.write(firstLine + '\n');
|
||||
} else {
|
||||
await context.out.write(context.patternSpace + '\n');
|
||||
}
|
||||
return JumpLocation.None;
|
||||
}
|
||||
|
||||
dump(indent) {
|
||||
return `${makeIndent(indent)}PRINT-LINE:\n`
|
||||
return `${makeIndent(indent)}PRINT: ${this.firstLine ? 'LINE' : 'ALL'}\n`
|
||||
+ this.addressRange.dump(indent+1);
|
||||
}
|
||||
}
|
||||
@ -478,35 +442,6 @@ export class SubstituteCommand extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
// 't' - Branch if substitution successful
|
||||
// 'T' - Branch if substitution unsuccessful
|
||||
export class ConditionalBranchCommand extends Command {
|
||||
constructor(addressRange, label, substitutionCondition) {
|
||||
super(addressRange);
|
||||
this.label = label;
|
||||
this.substitutionCondition = substitutionCondition;
|
||||
}
|
||||
|
||||
async run(context) {
|
||||
if (context.substitutionResult !== this.substitutionCondition) {
|
||||
return JumpLocation.None;
|
||||
}
|
||||
|
||||
if (this.label) {
|
||||
context.jumpParameter = this.label;
|
||||
return JumpLocation.Label;
|
||||
}
|
||||
return JumpLocation.EndOfCycle;
|
||||
}
|
||||
|
||||
dump(indent) {
|
||||
return `${makeIndent(indent)}CONDITIONAL-BRANCH:\n`
|
||||
+ this.addressRange.dump(indent+1)
|
||||
+ `${makeIndent(indent+1)}LABEL: ${this.label ? `'${this.label}'` : 'END'}\n`
|
||||
+ `${makeIndent(indent+1)}IF SUBSTITUTED = ${this.substitutionCondition}\n`;
|
||||
}
|
||||
}
|
||||
|
||||
// 'x' - Exchange hold and pattern
|
||||
export class ExchangeCommand extends Command {
|
||||
constructor(addressRange) {
|
||||
|
@ -20,22 +20,17 @@ import { Address, AddressRange } from './address.js';
|
||||
import {
|
||||
AppendTextCommand,
|
||||
BranchCommand,
|
||||
ConditionalBranchCommand,
|
||||
DebugPrintCommand,
|
||||
DeleteCommand,
|
||||
DeleteLineCommand,
|
||||
ExchangeCommand,
|
||||
GetAppendCommand,
|
||||
GetCommand,
|
||||
GroupEndCommand,
|
||||
GroupStartCommand,
|
||||
HoldAppendCommand,
|
||||
HoldCommand,
|
||||
InsertTextCommand,
|
||||
LabelCommand,
|
||||
LineNumberCommand,
|
||||
PrintCommand,
|
||||
PrintLineCommand,
|
||||
QuitCommand,
|
||||
ReplaceCommand,
|
||||
SubstituteCommand,
|
||||
@ -295,7 +290,7 @@ export const parseScript = (script_string, options) => {
|
||||
let group_depth = 0;
|
||||
for (const command of commands) {
|
||||
// Ensure branches all go to labels that exist
|
||||
if (command instanceof BranchCommand || command instanceof ConditionalBranchCommand) {
|
||||
if (command instanceof BranchCommand) {
|
||||
// Note: Branches to the end of the script don't have a label.
|
||||
if (command.label && !labels.has(command.label))
|
||||
throw new Error(`Label "${command.label}" does not exist in the script.`);
|
||||
@ -371,29 +366,20 @@ export const parseScript = (script_string, options) => {
|
||||
require_max_address_count(2);
|
||||
return new ReplaceCommand(address_range, func.value);
|
||||
}
|
||||
case 'd': {
|
||||
require_max_address_count(2);
|
||||
return new DeleteCommand(address_range);
|
||||
}
|
||||
case 'd':
|
||||
case 'D': {
|
||||
require_max_address_count(2);
|
||||
return new DeleteLineCommand(address_range);
|
||||
}
|
||||
case 'g': {
|
||||
require_max_address_count(2);
|
||||
return new GetCommand(address_range);
|
||||
return new DeleteCommand(address_range, func.$ === 'D');
|
||||
}
|
||||
case 'g':
|
||||
case 'G': {
|
||||
require_max_address_count(2);
|
||||
return new GetAppendCommand(address_range);
|
||||
}
|
||||
case 'h': {
|
||||
require_max_address_count(2);
|
||||
return new HoldCommand(address_range);
|
||||
return new GetCommand(address_range, func.$ === 'G');
|
||||
}
|
||||
case 'h':
|
||||
case 'H': {
|
||||
require_max_address_count(2);
|
||||
return new HoldAppendCommand(address_range);
|
||||
return new HoldCommand(address_range, func.$ === 'H');
|
||||
}
|
||||
case 'i': {
|
||||
require_max_address_count(1);
|
||||
@ -403,21 +389,15 @@ export const parseScript = (script_string, options) => {
|
||||
require_max_address_count(2);
|
||||
return new DebugPrintCommand(address_range);
|
||||
}
|
||||
case 'p': {
|
||||
require_max_address_count(2);
|
||||
return new PrintCommand(address_range);
|
||||
}
|
||||
case 'p':
|
||||
case 'P': {
|
||||
require_max_address_count(2);
|
||||
return new PrintLineCommand(address_range);
|
||||
}
|
||||
case 'q': {
|
||||
require_max_address_count(1);
|
||||
return new QuitCommand(address_range, false);
|
||||
return new PrintCommand(address_range, func.$ === 'P');
|
||||
}
|
||||
case 'q':
|
||||
case 'Q': {
|
||||
require_max_address_count(1);
|
||||
return new QuitCommand(address_range, true);
|
||||
return new QuitCommand(address_range, func.$ === 'Q');
|
||||
}
|
||||
case 's': {
|
||||
require_max_address_count(2);
|
||||
@ -427,7 +407,7 @@ export const parseScript = (script_string, options) => {
|
||||
case 't':
|
||||
case 'T': {
|
||||
require_max_address_count(2);
|
||||
return new ConditionalBranchCommand(address_range, func.value, func.$ === 't');
|
||||
return new BranchCommand(address_range, func.value, func.$ === 't');
|
||||
}
|
||||
case 'x': {
|
||||
require_max_address_count(2);
|
||||
|
Loading…
Reference in New Issue
Block a user