stred-go

Stred: Streaming Tree Editor. Like sed but for JSON. This is the go implementation
git clone https://shtanton.xyz/git/stred-go.git
Log | Files | Refs | README

command.go (4776B)


      1 package main
      2 
      3 import (
      4 	"main/subex"
      5 	"main/walk"
      6 	"fmt"
      7 )
      8 
      9 type Command interface {
     10 	exec(*ProgramState)
     11 	String() string
     12 }
     13 
     14 type PrintValueCommand struct {}
     15 func (cmd PrintValueCommand) exec(state *ProgramState) {
     16 	err := state.out.Write(walk.WalkItem {
     17 		Path: state.path,
     18 		Value: state.value,
     19 	})
     20 	if err != nil {
     21 		panic("Error while outputting")
     22 	}
     23 	state.pc++
     24 }
     25 func (cmd PrintValueCommand) String() string {
     26 	return "p"
     27 }
     28 
     29 type NextCommand struct {}
     30 func (cmd NextCommand) exec(state *ProgramState) {
     31 	nextItem, err := state.in.Read()
     32 	if err != nil {
     33 		panic("Missing next value")
     34 	}
     35 	state.value = nextItem.Value
     36 	state.path = nextItem.Path
     37 	state.pc++
     38 }
     39 func (cmd NextCommand) String() string {
     40 	return "n"
     41 }
     42 
     43 type AppendNextCommand struct {}
     44 func (cmd AppendNextCommand) exec(state *ProgramState) {
     45 	nextItem, err := state.in.Read()
     46 	if err != nil {
     47 		panic("Missing next value")
     48 	}
     49 	state.value = append(state.value, nextItem.Value...)
     50 	state.path = nextItem.Path
     51 	state.pc++
     52 }
     53 func (cmd AppendNextCommand) String() string {
     54 	return "N"
     55 }
     56 
     57 type DeleteValueCommand struct {}
     58 func (cmd DeleteValueCommand) exec(state *ProgramState) {
     59 	state.value = nil
     60 	state.pc++
     61 }
     62 func (cmd DeleteValueCommand) String() string {
     63 	return "d"
     64 }
     65 
     66 type DeletePathCommand struct {}
     67 func (cmd DeletePathCommand) exec(state *ProgramState) {
     68 	state.path = nil
     69 	state.pc++
     70 }
     71 func (cmd DeletePathCommand) String() string {
     72 	return "D"
     73 }
     74 
     75 func runSubex(state subex.Transducer, in walk.ValueList) (walk.ValueList, bool) {
     76 	out, error := subex.RunTransducer(state, in)
     77 	if error {
     78 		return nil, true
     79 	}
     80 	return out, false
     81 }
     82 
     83 type SubstituteValueCommand struct {
     84 	subex subex.Transducer
     85 }
     86 func (cmd SubstituteValueCommand) exec(state *ProgramState) {
     87 	newValue, err := runSubex(cmd.subex, state.value)
     88 	if err {
     89 		state.pc++
     90 	} else {
     91 		state.pc += 2
     92 		state.value = newValue
     93 	}
     94 }
     95 func (cmd SubstituteValueCommand) String() string {
     96 	return "s/.../"
     97 }
     98 
     99 type SubstitutePathCommand struct {
    100 	subex subex.Transducer
    101 }
    102 func (cmd SubstitutePathCommand) exec(state *ProgramState) {
    103 	newPath, err := runSubex(cmd.subex, state.path)
    104 	if err {
    105 		state.pc++
    106 	} else {
    107 		state.pc += 2
    108 		state.path = newPath
    109 	}
    110 }
    111 func (cmd SubstitutePathCommand) String() string {
    112 	return "S/.../"
    113 }
    114 
    115 type NoopCommand struct {}
    116 func (cmd NoopCommand) exec(state *ProgramState) {
    117 	state.pc++
    118 }
    119 func (cmd NoopCommand) String() string {
    120 	return "o"
    121 }
    122 
    123 type SwapXRegCommand struct {}
    124 func (cmd SwapXRegCommand) exec(state *ProgramState) {
    125 	v := state.value
    126 	state.value = state.xreg
    127 	state.xreg = v
    128 	state.pc++
    129 }
    130 func (cmd SwapXRegCommand) String() string {
    131 	return "x"
    132 }
    133 
    134 type AppendXRegCommand struct {}
    135 func (cmd AppendXRegCommand) exec(state *ProgramState) {
    136 	state.xreg = append(state.xreg, state.value...)
    137 	state.pc++
    138 }
    139 func (cmd AppendXRegCommand) String() string {
    140 	return "X"
    141 }
    142 
    143 type SwapYRegCommand struct {}
    144 func (cmd SwapYRegCommand) exec(state *ProgramState) {
    145 	v := state.value
    146 	state.value = state.yreg
    147 	state.yreg = v
    148 	state.pc++
    149 }
    150 func (cmd SwapYRegCommand) String() string {
    151 	return "y"
    152 }
    153 
    154 type AppendYRegCommand struct {}
    155 func (cmd AppendYRegCommand) exec(state *ProgramState) {
    156 	state.yreg = append(state.yreg, state.value...)
    157 	state.pc++
    158 }
    159 func (cmd AppendYRegCommand) String() string {
    160 	return "Y"
    161 }
    162 
    163 type SwapZRegCommand struct {}
    164 func (cmd SwapZRegCommand) exec(state *ProgramState) {
    165 	v := state.value
    166 	state.value = state.zreg
    167 	state.zreg = v
    168 	state.pc++
    169 }
    170 func (cmd SwapZRegCommand) String() string {
    171 	return "z"
    172 }
    173 
    174 type AppendZRegCommand struct {}
    175 func (cmd AppendZRegCommand) exec(state *ProgramState) {
    176 	state.zreg = append(state.zreg, state.value...)
    177 	state.pc++
    178 }
    179 func (cmd AppendZRegCommand) String() string {
    180 	return "Z"
    181 }
    182 
    183 type SwapPathCommand struct {}
    184 func (cmd SwapPathCommand) exec(state *ProgramState) {
    185 	v := state.value
    186 	state.value = state.path
    187 	state.path = v
    188 	state.pc++
    189 }
    190 func (cmd SwapPathCommand) String() string {
    191 	return "k"
    192 }
    193 
    194 type AppendPathCommand struct {}
    195 func (cmd AppendPathCommand) exec(state *ProgramState) {
    196 	state.path = append(state.path, state.value...)
    197 	state.pc++
    198 }
    199 func (cmd AppendPathCommand) String() string {
    200 	return "K"
    201 }
    202 
    203 type JumpCommand struct {
    204 	destination int
    205 }
    206 func (cmd JumpCommand) exec(state *ProgramState) {
    207 	state.pc = cmd.destination
    208 }
    209 func (cmd JumpCommand) String() string {
    210 	return fmt.Sprintf("b%v", cmd.destination)
    211 }
    212 
    213 // Placeholder as the branch destination may not have been parsed when the branch command is
    214 // Should never appear in a program to actually be run
    215 type BranchPlaceholderCommand struct {
    216 	label rune
    217 }
    218 func (cmd BranchPlaceholderCommand) exec(state *ProgramState) {
    219 	panic("Tried to execute a BranchPlaceholderCommand!!!")
    220 }
    221 func (cmd BranchPlaceholderCommand) String() string {
    222 	return fmt.Sprintf("b%c", cmd.label)
    223 }