-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathspec.txt
189 lines (148 loc) · 7.05 KB
/
spec.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
Random collections of ideas:
Files/streams/channels:
No difference is made between input and output files, and the default file 0
includes both stdin and stdout. This unifies files/stdio with sockets.
In a fork, you may need to close uninteresting files manually.
(Maybe it could be statically analyzed and only keep references to used files?)
Maybe: limit files to 0-9, accept single-character files without separators
Fork semantics:
fork takes a command including its address (typically a block, but if there's
only one command in the fork you can specify it directly), within that block
cycles begin from the beginning of the block, quit stops the thread.
Inside the fork, you can redirect and close files etc. without affecting the
files outside the fork.
Extended cargo hold:
Commands using the hold space will take another register id, which is an
arbitrary string (without whitespace).
The unnamed register is the normal hold space.
Registers starting with ! are temporary and will be cleared at forks and at
each cycle.
A fork keeps register values at the time of the fork, and changes are only
visible inside the thread. For communication between threads, use regexp
interrupts.
TODO: ?reg as command argument anywhere replaces it with the register contents
TODO: Move register to register without touching pattern space
(but could be implemented with a temp reg)
TODO: The register ! is empty (and writes are ignored)? or maybe not useful.
Address syntax (normal):
n line number
$ *on* the last line (not after)
=> lines with $ need to check hIsEOF, but this shouldn't be done
otherwise since it might involve waiting for more data and would block.
//
\// (custom regexp separator)
! (after address) negate
Address extensions:
I regexp interrupt delivery
0 before beginning
Maybe: $$ for after eof ($ is run on the last line, not after it)
Addresses match on pattern space, reading from other files happens by using n
or N with an ifd. EOF is only applicable for file 0.
Normal sed doesn't (generally) accept 0 as a line number (except for 0,/re/
which is different from 1,/re/ if the first line matches).
An address 0 here matches *before* the first input line. This lets you run
commands for setting up. Pattern space will be "abstract" here and not match
any regexps (including those for an empty string).
On the before-first line, only commands with address 0 or in blocks with
address 0 will run at all. Unconditional commands will *not* run. Unconditional
*blocks*, however, *will* run.
Likewise for the magical address/state I.
On line 0, using pattern space will fail and regexps will not match.
On IRQs, pattern space is available but the contents does not come from the
input.
TODO: Change before-first and IRQ addresses - if the program has any 0 or I
address, the whole program will run on those addresses so the program has to
watch out and add the required conditions by itself.
If the whole program should run on address 0 without using input at all, it
would e.g. only need to put an explicit 0 on the first line.
If the program has no I addresses it will not accept regexp interrupts and if
it has no 0 addresses it will not run on the before-first line.
Command space:
Unused commands (POSIX): ABCeEfFIjJkKLmMoOQRSTuUvVWXYzZ
Unused commands (+GNU): ABCEfIjJkKmMoOQSuUVXYzZ
Added:
A server client wait for and accept a client on the server socket, assign
the client to the given file descriptor
free: B
C[fd] host:port open [fd] and connect to host:port
E eval sed code?
f [addr] [cmd] fork the following command. May be/usually a block.
May have addresses etc before the command, as usual, or
inside a block if the thread needs more commands.
Whitespace after f is optional.
free: I (regex interrupt address)
free: jJkK
L[ifd] host:port/flags
open [ifd] and listen to the given host:port (tcp)
:port on its own listens on all interfaces
space between ifd and :port is optional if there is no host.
Connections can be accepted using the A command.
Currently defined L flags:
f: fork
The L command is followed by a command (like fork), the
forked program will be run for each incoming connection,
with the client as fd 0.
(NB: not implemented)
m [message]
broadcast a message on the message bus (see regexintr.txt)
if messge is blank, pattern space will be sent instead.
o[ifd] file open file for reading
O[ofd] file open file for writing
S: connect SSL? (needs an SSL listen too, hmm...)
free: uUvVXYzZ
X [reg] indirect load: load register (reg) into reg
e.g. if hold space has "foo", "X" without register replaces
hold space with value of foo.
POSIX: (+ sedition reg/ifd/ofd arguments)
Addresses:
// regexp
\%% regexp with custom delim
0-9+ lines...
$ last-line address
Non-alphabetic:
{
= print line number
#
< fd1 fd2 rename fd2 to fd1, closing fd1 if open
< fd1 close fd1
![cmd] unless address (address is applied as usual though)
:label
alphabetic
a\ [ofd]
b jump to beginning, start next cycle
b label jump to label
c\ [ofd]
d [ifd] Starts new cycle, so has input-fd of next cycle
D [ifd] Starts new cycle, so has input-fd of next cycle
g [reg] "get" pattern <- reg
G [reg] "Get" pattern += \n + reg
h [reg] "hold" reg <- pattern
H [reg] "Hold" reg += \n + pattern
i\ [ofd] If the first line has i\ (or i whitespace \), it may be followed by output fd
i\ [ofd] Otherwise it works as in GNU with the special single-line optimization
l (silly)
n [ifd] print pattern space (if autoprint), thne replace pattern space
with next input line (from ifd)
N [ifd] pattern += \n + input(ifd)
p [ofd] print pattern space to ofd
P [ofd] print first line of pattern space to ofd
q [c] print (if autoprinting) and quit with exit status
Q (GNU) quit without autoprinting
r file read file into output (before next cycle)
s///
t label branch if subst (start next cycle if no label)
w file write pattern space to file (redundant with pP)
x [reg] exchange pattern <-> reg
y//
GNU:
e [cmd] execute
F print file name
L n "This command is considered a failed experiment"
R file read one line from file, queue it for processing as input next cycle
T label branch if *not* substituted
v version
W file write first line of pattern space to file
z clear pattern space
T seems useful, since there's probably no other way to do that
e is also "nice"
R is close to n with input file, but does not restart processing.