-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCrabs.h
242 lines (197 loc) · 8.28 KB
/
Crabs.h
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// Copyright Kabuki Starship� <kabukistarship.com>.
#pragma once
#ifndef SCRIPT2_CRABS_DECL
#define SCRIPT2_CRABS_DECL
#include "Operand.h"
#if SEAM >= SCRIPT2_CRABS
namespace _ {
/* A full-duplex Crabs EXP (Expression) interpreter.
Crabs' (crabs(s)) must be word-aligned in order to run correctly
so it's best to scan and word align the data types in the same sweep.
Crabs' are composed of one B-Input (BIn) and one B-Output (BOut) socket. The
App/Driver/User writes to the stop of the Tx socket and the driver reads from
the beginning. The user writes are synchronous and the driver reads are
asynchronous.
# Ring Boofer Streaming Diagram
@code
|>---------------------- Ring Boofer ------------------------->|
________________________________________________________________
BOut |>-Boofer->|>-Sync User SScan->|>-Async Portal Rx-->|>-Boofer->|
|__________|___________________|____________________|__________|
________________________________________________________________
BIn |>-Boofer->|>-Async Portal Tx->|>-Sync User Writes->|>-Boofer->|
|__________|___________________|____________________|__________|
@endcode
Almost all block of memory in Script has something that grows up and another
that grows down.
# Stack Memory Layout
@code
|=========================|
| Evaluated Result |
| | |
| v |
|=========================|
| Boofer |
|=========================|
| Slot |
|=========================|
| Stack of Operand** |
+ |=========================|
| | Crabs struct |
0xN |=========================|
@endcode
*/
struct Crabs {
enum {
StackSizeMin = 16, //< Size of the crabs stack.
BooferSizeMin = 2, //< Min socket size.
};
ISC size, //< Offset to the BOut slot.
header_size, //< The total size of the header.
stack_count, //< Stack Operand count.
stack_size, //< Stack Operand socket size.
type, //< Current type being scanned.
num_states, //< Number of states on the state stack.
bytes_left, //< Countdown counter for parsing POD types.
params_left; //< Height of header and cursors stacks.
IUA bout_state, //< BOut streaming state.
bin_state, //< Slot streaming state.
last_bin_state, //< Last BIn state.
last_byte; //< Last IUA read.
CHC current_char; //< Current Unicode CHA being scanned.
IUB hash; //< Packed BSQ hash.
IUC timeout_us; //< Timeout time in microseconds.
ISD last_time; //< Last time the Stack was scanned.
const Op* result; //< Result of the EXR.
const ISC* header, //< Pointer to the header being verified.
* header_start; //< Start of the header being verified.
Operand* operand, //< Current Script Operand.
* root; //< Root-level scope Operand.
Slot& args; //< Arguments slot for running.
Slot slot; //< Slot for unpacking B-Sequences to.
};
/* Gets a pointer to the BIn slot. */
LIB_MEMBER IUW* CrabsBinAddress(Crabs* crabs);
/* Gets the crabs's socket. */
LIB_MEMBER IUA* CrabsBoofer(Crabs* crabs);
/* Gets a pointer to the BIn slot. */
LIB_MEMBER BIn* CrabsBIn(Crabs* crabs);
/* Gets a pointer to the BOut slot. */
LIB_MEMBER IUW* CrabsBOutAddress(Crabs* crabs);
/* Gets a pointer to the BOut slot. */
LIB_MEMBER BOut* CrabsBOut(Crabs* crabs);
/* Creates a Stack with equal sized rx and tx slots.
@param root The root-scope device.
@param unpacked_boofer The word-aligned expression socket.
@param unpacked_size Size of the unpacked socket. */
LIB_MEMBER Crabs* CrabsInit(IUW* socket, ISC boofer_size, ISC stack_count,
Operand* root, IUW* unpacked_boofer,
IUW unpacked_size);
/* Gets the base address of the device stack. */
inline Operand** CrabsStack(Crabs* crabs) {
return TPtr<Operand*>(&crabs->root);
}
/* Returns true if the Stack uses dynamic memory. */
// LIB_MEMBER BOL CrabsIsDynamic (Crabs* crabs);
LIB_MEMBER IUA* CrabsEndAddress(Crabs* crabs);
/* Resets this Stack to the new state. */
LIB_MEMBER const Op* CrabsReset(Crabs* crabs);
/* Pushes the operand at the given index of the current
device control onto the stack.
@return Returns nil upon success and a pointer to a CHA
upon failure. */
LIB_MEMBER const Op* Push(Crabs* crabs, Operand* operand);
/* Attempts to pop an Star off the stack and returns a pointer to a
CHA upon failure. */
LIB_MEMBER const Op* Pop(Crabs* crabs);
/* Exits the current state. */
LIB_MEMBER IUA CrabsExitState(Crabs* crabs);
/* Sets the new state onto the expression stack.
LIB_MEMBER const Op* CrabsSetState (Crabs* crabs, BInState state); */
/* Saves the current bin_state and sets the bin_state to the new state. */
LIB_MEMBER const Op* CrabsEnterState(Crabs* crabs, BInState state);
/* Streams a B-Output IUA. */
LIB_MEMBER IUA CrabsStreamBOut(Crabs* crabs);
/* Scans the BIn socket and marks the data as being ready to execute.
@param a The Stack to scan. */
LIB_MEMBER const Op* CrabsScanBIn(Crabs* crabs); // , Portal* io);
/* Returns true if the given Stack contains the given address. */
LIB_MEMBER BOL CrabsContains(Crabs* crabs, void* address);
/* Pushes a header onto the scan stack.*/
LIB_MEMBER const Op* CrabsScanHeader(Crabs* crabs, const ISC* header);
/* Gets the base address of the header stack. */
LIB_MEMBER const ISC* CrabsHeaderStack(Crabs* crabs);
/* Closes the current crabs and cues it for execution. */
LIB_MEMBER void CrabsClose(Crabs* crabs);
/* Cancels the current crabs. */
LIB_MEMBER void CrabsCancel(Crabs* crabs);
/* Cancels the current crabs and writes zeros to the socket. */
LIB_MEMBER void CrabsClear(Crabs* crabs);
/* Script Bell Op rings the bell of the given address. */
LIB_MEMBER void CrabsRingBell(Crabs* crabs, const CHA* address = "");
/* Script Ack-back Op replies an ACK to a Bell Op. */
LIB_MEMBER void CrabsAckBack(Crabs* crabs, const CHA* address = "");
/* Disconnects the expression. */
LIB_MEMBER const Op* CrabsForceDisconnect(Crabs* crabs, ERC error);
/* Reads the Crabs args from the crabs->slot.
inline const Op* CrabsArgs (Crabs* crabs, const ISC* params, void** args) {
const CHA* cursor = ArgsParse (crabs->args_cursor, crabs->args_end,
params, args);
if (!cursor) {
}
}*/
/* Pops the args off the Crabs Args Stack. */
inline const Op* CrabsArgs(Crabs* crabs, const ISC* params, void** args) {
A_ASSERT(params);
A_ASSERT(args);
Slot slot(CrabsBIn(crabs));
return slot.Read(params, args);
}
/* Pops the args off the Crabs Args Stack. */
inline const Op* CrabsArgs(Crabs* crabs, const Op& op, void** args) {
A_ASSERT(crabs);
A_ASSERT(args);
Slot slot(CrabsBIn(crabs));
return slot.Read(op.in, args);
}
/* Writes the result to the Crabs.
@param crabs The resulting expression.
@param op The Operation with result B-Sequence header.
@param args Pointers to the B-Sequence args. */
inline const Op* CrabsResult(Crabs* crabs, const Op& op, void** args) {
return BOutWrite(CrabsBOut(crabs), op.out, args);
}
/* Writes the result to the Crabs.
@param crabs The resulting expression.
@param op The Operation with result B-Sequence header.
@param args Pointers to the B-Sequence args. */
inline const Op* CrabsResult(Crabs* crabs, const ISC* params, void** args) {
if (!params) {
return nullptr;
}
return BOutWrite(CrabsBOut(crabs), params, args);
}
/* Writes the result to the Crabs.
@return NIL upon ?
@param crabs The resulting expression.
@param op The Operation with result B-Sequence header.
@param args Pointers to the B-Sequence args. */
inline const Op* CrabsResult(Crabs* crabs, const Op* op, void** args) {
if (!op) {
return nullptr;
}
return BOutWrite(CrabsBOut(crabs), op->out, args);
}
/* Returns the Operand header or writes it to the Crabs.
@param crabs The expression to write the Op header to.
@param header The Op header.
@return Returns the header if crabs is nil. */
LIB_MEMBER const Op* CrabsQuery(Crabs* crabs, const Op& header);
/* Returns the Op header or writes it to the Crabs.
@param crabs The expression to write the Op header to.
@param op The Op header.
@return Returns the header if crabs is nil. */
LIB_MEMBER const Op* CrabsQuery(Crabs* crabs, const Op* op);
} //< namespace _
#endif
#endif