godprotocol 1.0.842 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Executables/callables.js +131 -0
- package/Executables/executables.js +230 -0
- package/Executables/functions/adminstrator/adm_register.js +29 -0
- package/Executables/functions/adminstrator/native_components.js +10 -0
- package/Executables/functions/adminstrator/query_selectors.js +10 -0
- package/Executables/functions/adminstrator/render.js +24 -0
- package/Executables/functions/array_register.js +161 -0
- package/Executables/functions/assign.js +19 -0
- package/Executables/functions/display.js +55 -0
- package/Executables/functions/folder.js +95 -0
- package/Executables/functions/folder_register.js +87 -0
- package/Executables/functions/importcheck.js +13 -0
- package/Executables/functions/indices.js +56 -0
- package/Executables/functions/len.js +22 -0
- package/Executables/functions/methods/array.js +272 -0
- package/Executables/functions/methods/string.js +197 -0
- package/Executables/functions/methods/twain.js +148 -0
- package/Executables/functions/op.js +15 -0
- package/Executables/functions/price_register.js +30 -0
- package/Executables/functions/pricing.js +26 -0
- package/Executables/functions/servers/account.js +81 -0
- package/Executables/functions/servers/account_register.js +56 -0
- package/Executables/functions/servers/block.js +21 -0
- package/Executables/functions/servers/block_register.js +18 -0
- package/Executables/functions/servers/chain.js +42 -0
- package/Executables/functions/servers/chain_register.js +28 -0
- package/Executables/functions/set_error_catch.js +34 -0
- package/Executables/functions/string_register.js +130 -0
- package/Executables/functions/twain_register.js +56 -0
- package/Executables/functions/typecast.js +43 -0
- package/Executables/functions/utils.js +9 -0
- package/Executables/stack.js +53 -0
- package/Index.js +2 -55
- package/Loader_sequence/main.js +371 -124
- package/Loader_sequence/repository.js +1 -1
- package/Objects/Account.js +101 -34
- package/Objects/Block.js +24 -18
- package/Objects/Blockweb.js +1 -1
- package/Objects/Chain.js +127 -29
- package/Objects/Explorer.js +3 -17
- package/Objects/Fee.js +33 -0
- package/Objects/Filesystem.js +98 -25
- package/Objects/Frame.js +10 -3
- package/Objects/Manager.js +193 -23
- package/Objects/Opcodes.js +48 -10
- package/Objects/Oracle.js +11 -8
- package/Objects/Protocol.js +5 -0
- package/Objects/Virtual_machine.js +130 -59
- package/Trinity.js +20 -0
- package/callables.js +172 -0
- package/framer.js +65 -12
- package/opcodes/add.js +6 -1
- package/opcodes/indices.js +60 -6
- package/opcodes/jmp.js +2 -0
- package/opcodes/std.js +5 -2
- package/opcodes.js +56 -18
- package/package.json +2 -2
- package/starter_scripts/constants.seq +11 -0
- package/utils/create_server.js +15 -7
- package/utils/hash.js +2 -2
- package/utils/logger.js +79 -0
- package/utils/services.js +5 -3
- package/utils/type_coersion.js +3 -0
- package/utils/vm_utils.js +292 -0
package/Loader_sequence/main.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { _id } from "generalised-datastore/utils/functions";
|
|
2
2
|
import Repository from "./repository";
|
|
3
3
|
|
|
4
|
-
let num_pattern =
|
|
5
|
-
// let str_pattern = /^["'][^"']*["']$/;
|
|
4
|
+
let num_pattern = /^\d+(\.\d+)?$/;
|
|
6
5
|
let var_pattern = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
6
|
+
let addr_pattern = /^(@\/|\.\.\/|\.\/)?([A-Za-z0-9_\-]+\/)*[A-Za-z0-9_\-]+$/
|
|
7
7
|
|
|
8
8
|
class Loader {
|
|
9
9
|
constructor(account) {
|
|
@@ -17,23 +17,25 @@ class Loader {
|
|
|
17
17
|
this.markers = new Array();
|
|
18
18
|
this.program_configs = new Array();
|
|
19
19
|
this.programs_index = -1;
|
|
20
|
+
|
|
21
|
+
this.datatypes = new Array('twain', 'string','void', 'boolean', 'array', 'number')
|
|
22
|
+
this.configs = new Object()
|
|
20
23
|
|
|
21
24
|
// Code Repository
|
|
22
25
|
this.repository = new Repository(this);
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
instruction_index = () => {
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
this.instruction_indexes.splice(-1, 1, index);
|
|
29
|
+
let len = this.instruction_indexes.length -1
|
|
30
|
+
this.instruction_indexes[len]++
|
|
29
31
|
|
|
30
|
-
return
|
|
32
|
+
return this.instruction_indexes[len]
|
|
31
33
|
};
|
|
32
34
|
|
|
33
35
|
stack_instruction = (instruction) => {
|
|
34
36
|
if (Array.isArray(instruction))
|
|
35
37
|
return instruction.map((i) => this.stack_instruction(i));
|
|
36
|
-
|
|
38
|
+
|
|
37
39
|
this.instruction_stacks.slice(-1)[0].push(instruction);
|
|
38
40
|
};
|
|
39
41
|
|
|
@@ -49,24 +51,38 @@ class Loader {
|
|
|
49
51
|
this.instructions.push(instruction);
|
|
50
52
|
} else {
|
|
51
53
|
this.stack_instruction(`cursor ${this.instruction_index()}`);
|
|
54
|
+
|
|
52
55
|
this.stack_instruction(`write ${instruction}`);
|
|
53
56
|
}
|
|
54
57
|
};
|
|
55
58
|
|
|
56
|
-
parse_tokens = (line,
|
|
59
|
+
parse_tokens = (line, options) => {
|
|
60
|
+
options = options ||{}
|
|
61
|
+
let {stop_char, all_static, inline} = options;
|
|
62
|
+
|
|
57
63
|
let tokens = new Array();
|
|
58
|
-
let pos = 0
|
|
59
|
-
|
|
64
|
+
let pos = 0;
|
|
65
|
+
all_static = this.pure || this.no_static?false: all_static == undefined? true: all_static;
|
|
66
|
+
|
|
67
|
+
let push_token = (value, type) =>{
|
|
68
|
+
if (stop_char){
|
|
69
|
+
if (['variable','address', 'inline_address'].includes(type)) {
|
|
70
|
+
all_static = false
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
let tok_obj = { value, type, line: this.line_count, pos : pos-value.length}
|
|
74
|
+
if (['twain', 'array'].includes(type)){
|
|
75
|
+
tok_obj.all_static = all_static
|
|
76
|
+
}
|
|
60
77
|
|
|
61
|
-
|
|
62
|
-
|
|
78
|
+
tokens.push(tok_obj);
|
|
79
|
+
};
|
|
63
80
|
|
|
64
81
|
line = line.trim();
|
|
65
82
|
while (pos < line.length) {
|
|
66
83
|
let char = line[pos].trim();
|
|
67
84
|
|
|
68
|
-
|
|
69
|
-
if (char === stop_char) return { tokens, pos };
|
|
85
|
+
if (char === stop_char) return { tokens, pos, all_static};
|
|
70
86
|
|
|
71
87
|
if (!char) {
|
|
72
88
|
pos++;
|
|
@@ -75,11 +91,21 @@ class Loader {
|
|
|
75
91
|
}
|
|
76
92
|
|
|
77
93
|
if (char === "\n") {
|
|
78
|
-
line_number++;
|
|
79
94
|
pos++;
|
|
95
|
+
} else if (char === '/' && line[pos+1]==='/'){
|
|
96
|
+
pos = line.length
|
|
97
|
+
}else if (char === '%' && inline){
|
|
98
|
+
pos++
|
|
99
|
+
let acc = line[pos]
|
|
100
|
+
pos++
|
|
101
|
+
while (line[pos] && var_pattern.test(`${acc}${line[pos]}`)) {
|
|
102
|
+
acc += line[pos];
|
|
103
|
+
pos++;
|
|
104
|
+
}
|
|
105
|
+
push_token(acc, "inline_address");
|
|
80
106
|
} else if (char === "@" || char === ".") {
|
|
81
107
|
let acc = "";
|
|
82
|
-
while (line[pos] && line[pos].trim()) {
|
|
108
|
+
while (line[pos] && line[pos].trim() && (line[pos] !== stop_char) && ![','].includes(line[pos]) ) {
|
|
83
109
|
acc += line[pos];
|
|
84
110
|
pos++;
|
|
85
111
|
}
|
|
@@ -87,17 +113,33 @@ class Loader {
|
|
|
87
113
|
} else if (char === ",") {
|
|
88
114
|
pos++;
|
|
89
115
|
} else if (char === ":") {
|
|
116
|
+
|
|
90
117
|
push_token(char, "separator");
|
|
91
118
|
pos++;
|
|
92
119
|
} else if (char === "[") {
|
|
93
120
|
pos++;
|
|
94
|
-
let
|
|
95
|
-
|
|
121
|
+
let pre_stat = all_static
|
|
122
|
+
if(!stop_char && !this.pure)all_static = true;
|
|
123
|
+
|
|
124
|
+
let toks = this.parse_tokens(line.slice(pos),{stop_char: "]", all_static});
|
|
125
|
+
if(stop_char) all_static = toks.all_static && all_static
|
|
126
|
+
else all_static = toks.all_static
|
|
127
|
+
|
|
128
|
+
push_token([...toks.tokens], "array");
|
|
129
|
+
all_static = pre_stat
|
|
130
|
+
|
|
96
131
|
pos += toks.pos + 1;
|
|
97
132
|
} else if (char === "{") {
|
|
98
133
|
pos++;
|
|
99
|
-
let
|
|
100
|
-
|
|
134
|
+
let pre_stat = all_static
|
|
135
|
+
if(!stop_char && !this.pure)all_static = true;
|
|
136
|
+
|
|
137
|
+
let toks = this.parse_tokens(line.slice(pos), {stop_char: "}", all_static});
|
|
138
|
+
if(stop_char) all_static = toks.all_static && all_static
|
|
139
|
+
else all_static = toks.all_static
|
|
140
|
+
|
|
141
|
+
push_token([...toks.tokens], "twain");
|
|
142
|
+
all_static = pre_stat
|
|
101
143
|
pos += toks.pos + 1;
|
|
102
144
|
} else if (char === ">") {
|
|
103
145
|
pos++;
|
|
@@ -124,97 +166,190 @@ class Loader {
|
|
|
124
166
|
pos++;
|
|
125
167
|
}
|
|
126
168
|
push_token(acc, "number");
|
|
127
|
-
} else if (var_pattern.test(char)) {
|
|
128
|
-
let
|
|
169
|
+
} else if (var_pattern.test(char) || char === '(') {
|
|
170
|
+
let depthed = char==='('
|
|
171
|
+
let acc;
|
|
172
|
+
if (depthed){
|
|
173
|
+
pos++
|
|
174
|
+
acc =line[pos]
|
|
175
|
+
}else acc = char
|
|
176
|
+
|
|
129
177
|
pos++;
|
|
130
|
-
while (line[pos] && var_pattern.test(`${line[pos]
|
|
178
|
+
while (line[pos] && var_pattern.test(`${acc}${line[pos]}`)) {
|
|
131
179
|
acc += line[pos];
|
|
132
180
|
pos++;
|
|
133
181
|
}
|
|
182
|
+
|
|
183
|
+
if (depthed){
|
|
184
|
+
if (line[pos] !== ')')throw new Error('Unbounded')
|
|
185
|
+
acc = `(${acc})`
|
|
186
|
+
pos++
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
acc = acc.trim()
|
|
190
|
+
push_token(acc, ['True', 'False'].includes(acc)?'boolean': acc ==='Void'?'void':this.opcodes.includes(acc) ? "opcode" : "variable");
|
|
134
191
|
|
|
135
|
-
push_token(acc, this.opcodes.includes(acc) ? "opcode" : "variable");
|
|
136
192
|
}
|
|
137
193
|
}
|
|
138
|
-
|
|
194
|
+
|
|
139
195
|
return tokens;
|
|
140
196
|
};
|
|
141
197
|
|
|
142
|
-
|
|
143
|
-
|
|
198
|
+
static_parse = ({token, previous_pure, options, identifier}, fn)=>{
|
|
199
|
+
this.pure = token.all_static?'stack':previous_pure
|
|
200
|
+
|
|
201
|
+
let physical_address = this.stacks.slice(-1)[0]
|
|
202
|
+
if(!identifier && token.all_static && !options.all_static){
|
|
203
|
+
identifier = {value: this.account.manager.oracle.hash(token, 'sha-1')}
|
|
204
|
+
if (!isNaN(Number(identifier.value[0]))){
|
|
205
|
+
identifier.value = `_${identifier.value}`
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (token.all_static && !options.all_static){
|
|
209
|
+
this.push_instruction(`link ${physical_address}/${identifier.value}`)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
fn()
|
|
213
|
+
|
|
214
|
+
if (token.all_static && identifier &&!options.all_static){
|
|
144
215
|
this.push_instruction([
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
this.push_instruction(
|
|
153
|
-
`link Accounts/${this.account.name}/Datatypes/Array`
|
|
154
|
-
);
|
|
155
|
-
token.value.map((item, i) => {
|
|
156
|
-
this.parse(item);
|
|
216
|
+
'cursor {output}',
|
|
217
|
+
'write {datapath:-1}'
|
|
218
|
+
])
|
|
219
|
+
this.push_instruction(`pop ${identifier.value}`)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
this.pure = previous_pure
|
|
157
223
|
|
|
224
|
+
!options.all_static && token.all_static && !options.identifier &&
|
|
225
|
+
this.push_instruction([`link ${physical_address}/${identifier.value}`, `pop ${identifier.value}`])
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
parse = (token, options) => {
|
|
229
|
+
options = options || {}
|
|
230
|
+
let {identifier} = options;
|
|
231
|
+
|
|
232
|
+
let previous_pure = this.pure;
|
|
233
|
+
if (token.type === "string" || token.type === "number") {
|
|
234
|
+
this.static_parse({options, previous_pure, token, identifier}, ()=>{
|
|
158
235
|
this.push_instruction([
|
|
159
|
-
`
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}`,
|
|
236
|
+
`link ${
|
|
237
|
+
this.account.physical_address
|
|
238
|
+
}/Datatypes/${`${token.type[0].toUpperCase()}${token.type.slice(1)}`}`,
|
|
239
|
+
`write ${token.value}`,
|
|
240
|
+
`pop ${token.type}`,
|
|
165
241
|
]);
|
|
166
|
-
})
|
|
167
|
-
this.push_instruction(`pop Array`);
|
|
168
|
-
} else if (token.type === "twain") {
|
|
169
|
-
this.push_instruction(
|
|
170
|
-
`link Accounts/${this.account.name}/Datatypes/Twain`
|
|
171
|
-
);
|
|
172
|
-
let curs = true;
|
|
242
|
+
})
|
|
173
243
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
{
|
|
244
|
+
} else if (token.type === "array") {
|
|
245
|
+
|
|
246
|
+
this.static_parse({token, previous_pure, options, identifier}, ()=>{
|
|
247
|
+
this.push_instruction(
|
|
248
|
+
`link Accounts/${this.account.name}/Datatypes/Array`
|
|
249
|
+
);
|
|
250
|
+
if (token.value.length){
|
|
251
|
+
token.value.map((item, i) => {
|
|
252
|
+
this.parse(item, {all_static: this.pure === 'stack'});
|
|
253
|
+
|
|
254
|
+
this.push_instruction([
|
|
255
|
+
`cursor ${i}`,
|
|
256
|
+
`write ${
|
|
257
|
+
this.is_not_literal(item.type)
|
|
258
|
+
? "{metadata.output:-1}"
|
|
259
|
+
: "{datapath:-1}"
|
|
260
|
+
}`,
|
|
261
|
+
]);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
this.push_instruction(`pop Array`);
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
} else if (token.type === "twain") {
|
|
269
|
+
|
|
270
|
+
this.static_parse({token, previous_pure, options, identifier}, ()=>{
|
|
271
|
+
this.push_instruction(
|
|
272
|
+
`link Accounts/${this.account.name}/Datatypes/Twain`
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
if (token.value.length){
|
|
276
|
+
let curs = true;
|
|
277
|
+
token.value.map((entry) => {
|
|
278
|
+
if (entry.type === "separator") {
|
|
279
|
+
curs = false;
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
this.parse(entry, {all_static: this.pure === 'stack'});
|
|
283
|
+
if (curs) {
|
|
284
|
+
{
|
|
285
|
+
this.push_instruction(
|
|
286
|
+
`cursor {*${
|
|
287
|
+
this.is_not_literal(entry.type)
|
|
288
|
+
? "metadata.output:-1"
|
|
289
|
+
: "datapath:-1"
|
|
290
|
+
}}`
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
183
294
|
this.push_instruction(
|
|
184
|
-
`
|
|
295
|
+
`write ${
|
|
185
296
|
this.is_not_literal(entry.type)
|
|
186
|
-
? "metadata.output:-1"
|
|
187
|
-
: "datapath:-1"
|
|
188
|
-
}
|
|
297
|
+
? "{metadata.output:-1}"
|
|
298
|
+
: "{datapath:-1}"
|
|
299
|
+
}`
|
|
189
300
|
);
|
|
301
|
+
curs = true;
|
|
190
302
|
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
);
|
|
199
|
-
curs = true;
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
this.push_instruction(`pop Twain`);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
this.push_instruction(`pop Twain`);
|
|
307
|
+
|
|
308
|
+
})
|
|
309
|
+
|
|
203
310
|
} else if (token.type === "variable") {
|
|
311
|
+
let tok_value = token.value;
|
|
312
|
+
|
|
313
|
+
let is_nested = this.handle_nested(tok_value)
|
|
314
|
+
|
|
204
315
|
this.push_instruction([
|
|
205
|
-
`link ${`${this.stacks.slice(-1)[0]}/${
|
|
206
|
-
`pop ${
|
|
316
|
+
`link ${is_nested?'{metadata.output:-1}': `${this.stacks.slice(-1)[0]}/${tok_value}`}`,
|
|
317
|
+
`pop ${tok_value}`,
|
|
207
318
|
]);
|
|
319
|
+
}else if(token.type==='void'){
|
|
320
|
+
this.push_instruction([`link ${this.account.physical_address}/Datatypes/Void`, 'pop Void'])
|
|
321
|
+
}else if (token.type === 'boolean'){
|
|
322
|
+
this.push_instruction([`link ${this.account.physical_address}/Datatypes/Boolean`, `write ${token.value}`, 'pop Boolean'])
|
|
208
323
|
} else if (token.type === "address") this.parse_assignment(token);
|
|
209
324
|
};
|
|
210
325
|
|
|
326
|
+
handle_nested = tok_value=>{
|
|
327
|
+
let is_nested= tok_value.startsWith('(')
|
|
328
|
+
if (is_nested){
|
|
329
|
+
let val = tok_value.slice(1,-1)
|
|
330
|
+
if(val.startsWith('@') || val.startsWith('.')){
|
|
331
|
+
val = this.resolve_addr(val)
|
|
332
|
+
this.push_instruction([`link ${val}`, 'pop'])
|
|
333
|
+
} else this.push_instruction([`link ${`${this.current_program().physical_address}/${val}`}`, `pop ${val}`])
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return is_nested
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
throw_error=(msg, token)=>{
|
|
340
|
+
let pth = this.current_program()
|
|
341
|
+
pth = pth.physical_address
|
|
342
|
+
throw new Error(`${msg}:${this.line_count}/col:${token.pos}\n\t${pth||''}`)
|
|
343
|
+
}
|
|
344
|
+
|
|
211
345
|
is_not_literal = (type) =>
|
|
212
346
|
!type || ["variable", "opcode", "address"].includes(type);
|
|
213
347
|
|
|
214
348
|
parse_assignment = (line, linked) => {
|
|
215
349
|
let tokens = linked || line.type ? line : this.parse_tokens(line);
|
|
216
350
|
|
|
217
|
-
let identifier = tokens[0];
|
|
351
|
+
let identifier = tokens[0], is_nested, curr_program;
|
|
352
|
+
|
|
218
353
|
if (linked || line.type) {
|
|
219
354
|
let line_split = (line.value || line)
|
|
220
355
|
.slice(line.value ? null : 1)
|
|
@@ -229,16 +364,26 @@ class Loader {
|
|
|
229
364
|
if (line.type === "address")
|
|
230
365
|
return this.push_instruction(`pop ${path[path.length - 1]}`);
|
|
231
366
|
} else {
|
|
232
|
-
|
|
367
|
+
curr_program = this.current_program();
|
|
233
368
|
curr_program && curr_program.dimensions.push({ name: identifier.value });
|
|
234
369
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
370
|
+
is_nested = this.handle_nested(identifier.value)
|
|
371
|
+
|
|
372
|
+
this.push_instruction(`chain ${is_nested?'{metadata.output:-1}': identifier.value}`);
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
if (tokens.length > 1){
|
|
376
|
+
let pre_tok = tokens.slice(-1)[0]
|
|
377
|
+
if (pre_tok.all_static){}
|
|
378
|
+
else
|
|
379
|
+
!is_nested && this.stack_instruction([
|
|
380
|
+
`link ${this.stacks.slice(-1)[0]}`,
|
|
381
|
+
`chain ${identifier.value}`,
|
|
382
|
+
`pop ${identifier.value}`,
|
|
383
|
+
"pop",
|
|
384
|
+
]);
|
|
385
|
+
}
|
|
386
|
+
|
|
242
387
|
}
|
|
243
388
|
|
|
244
389
|
let prev_token;
|
|
@@ -247,22 +392,52 @@ class Loader {
|
|
|
247
392
|
prev_token = tokens[1];
|
|
248
393
|
} else {
|
|
249
394
|
tokens.slice(1).map((tok) => {
|
|
250
|
-
this.parse(tok);
|
|
395
|
+
this.parse(tok, {identifier});
|
|
251
396
|
});
|
|
252
397
|
prev_token = tokens.slice(-1)[0];
|
|
253
398
|
}
|
|
254
399
|
|
|
400
|
+
if (!this.pure&& !is_nested && identifier.type === 'variable'){
|
|
401
|
+
let config = this.configs[curr_program.physical_address]
|
|
402
|
+
if(!config){
|
|
403
|
+
config = {
|
|
404
|
+
parameters:[],
|
|
405
|
+
identifiers: [],
|
|
406
|
+
name: curr_program.program_name,
|
|
407
|
+
__address__: curr_program.physical_address,
|
|
408
|
+
type:'module'
|
|
409
|
+
}
|
|
410
|
+
this.configs[curr_program.physical_address] = config;
|
|
411
|
+
}else {
|
|
412
|
+
// console.log(config, 'conff')
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (tokens[1]&& this.datatypes.includes(tokens[1].type)){
|
|
416
|
+
config.parameters.push({name: identifier.value, object: tokens[1].static_value, position: config.parameters.length})
|
|
417
|
+
}else if (!tokens[1]){
|
|
418
|
+
config.parameters.push({name: identifier.value, address: `${this.account.physical_address}/Datatypes/Void`, position:config.parameters.length})
|
|
419
|
+
}
|
|
420
|
+
config.identifiers.push(identifier.value)
|
|
421
|
+
}
|
|
422
|
+
|
|
255
423
|
if (tokens.length > 1) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
424
|
+
if (prev_token && prev_token.all_static){
|
|
425
|
+
this.push_instruction([`pop ${identifier.value}`])
|
|
426
|
+
}else {
|
|
427
|
+
this.push_instruction([
|
|
428
|
+
"cursor {output}",
|
|
429
|
+
`write ${
|
|
430
|
+
this.is_not_literal(prev_token && prev_token.type)
|
|
431
|
+
? "{metadata.output:-1}"
|
|
432
|
+
: "{datapath:-1}"
|
|
433
|
+
}`,
|
|
434
|
+
`pop ${identifier.value}`,
|
|
435
|
+
]);
|
|
436
|
+
}
|
|
437
|
+
|
|
265
438
|
} else this.push_instruction(`pop ${identifier.value}`);
|
|
439
|
+
|
|
440
|
+
|
|
266
441
|
};
|
|
267
442
|
|
|
268
443
|
current_program = () => {
|
|
@@ -271,7 +446,7 @@ class Loader {
|
|
|
271
446
|
|
|
272
447
|
marker_pattern = /@[a-zA-Z_][a-zA-Z0-9_]*/;
|
|
273
448
|
|
|
274
|
-
parse_opcode = (line) => {
|
|
449
|
+
parse_opcode = (line, assign) => {
|
|
275
450
|
let tokens = Array.isArray(line) ? line : this.parse_tokens(line);
|
|
276
451
|
|
|
277
452
|
let op = tokens[0];
|
|
@@ -284,8 +459,6 @@ class Loader {
|
|
|
284
459
|
]);
|
|
285
460
|
|
|
286
461
|
tokens.slice(1).map((tok, i) => {
|
|
287
|
-
if (tok.type === "address") tok.value = this.resolve_addr(tok.value);
|
|
288
|
-
|
|
289
462
|
if (tok.type === "address" && tok.value.match(this.marker_pattern)) {
|
|
290
463
|
this.push_instruction([
|
|
291
464
|
`link ${this.account.physical_address}/Datatypes/Number`,
|
|
@@ -297,8 +470,8 @@ class Loader {
|
|
|
297
470
|
this.push_instruction([
|
|
298
471
|
`cursor op${i}`,
|
|
299
472
|
`write ${
|
|
300
|
-
this.is_not_literal(tok.type) &&
|
|
301
|
-
!(tok.type === "address" && tok.value.match(this.marker_pattern))
|
|
473
|
+
tok.all_static || (this.is_not_literal(tok.type) &&
|
|
474
|
+
!(tok.type === "address" && tok.value.match(this.marker_pattern)))
|
|
302
475
|
? "{metadata.output:-1}"
|
|
303
476
|
: "{datapath:-1}"
|
|
304
477
|
}`,
|
|
@@ -317,11 +490,13 @@ class Loader {
|
|
|
317
490
|
};
|
|
318
491
|
|
|
319
492
|
resolve_addr = (addr) => {
|
|
493
|
+
let real_addr = addr;
|
|
320
494
|
addr = addr.split("/");
|
|
321
495
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
496
|
+
if (addr.length === 1){
|
|
497
|
+
real_addr = addr.join('')
|
|
498
|
+
}
|
|
499
|
+
else if (addr[0] === "@") {
|
|
325
500
|
addr[0] = this.account.physical_address;
|
|
326
501
|
real_addr = addr.join("/");
|
|
327
502
|
} else if (addr[0] === ".." || addr[0] === ".") {
|
|
@@ -414,7 +589,8 @@ class Loader {
|
|
|
414
589
|
markers = new Object();
|
|
415
590
|
this.markers[curr_stack] = markers;
|
|
416
591
|
}
|
|
417
|
-
|
|
592
|
+
|
|
593
|
+
markers[name] = this.instruction_indexes.slice(-1)[0];
|
|
418
594
|
|
|
419
595
|
this.revamp_marks();
|
|
420
596
|
|
|
@@ -437,11 +613,13 @@ class Loader {
|
|
|
437
613
|
}
|
|
438
614
|
|
|
439
615
|
if (typeof value === "number")
|
|
440
|
-
line = line.replace(
|
|
616
|
+
{line = line.replace(
|
|
441
617
|
this.marker_pattern,
|
|
442
|
-
(revamping
|
|
618
|
+
(revamping&&value>0?value+1: value+1).toString()
|
|
443
619
|
);
|
|
444
620
|
|
|
621
|
+
}
|
|
622
|
+
|
|
445
623
|
return line;
|
|
446
624
|
};
|
|
447
625
|
|
|
@@ -476,14 +654,20 @@ class Loader {
|
|
|
476
654
|
};
|
|
477
655
|
|
|
478
656
|
spawn = () => {
|
|
479
|
-
|
|
657
|
+
let spaw = new Loader(this.account);
|
|
658
|
+
spaw.opcodes = [...this.opcodes];
|
|
659
|
+
|
|
660
|
+
return spaw;
|
|
480
661
|
};
|
|
481
662
|
|
|
663
|
+
line_count = 0
|
|
664
|
+
|
|
482
665
|
compile = (codes) => {
|
|
483
666
|
let code_array = codes.split("\n");
|
|
484
667
|
|
|
485
668
|
for (let c = 0; c < code_array.length; c++) {
|
|
486
669
|
let line = code_array[c].trim();
|
|
670
|
+
this.line_count++
|
|
487
671
|
|
|
488
672
|
let curr_program = this.current_program();
|
|
489
673
|
this.is_routine = line.startsWith(".") || line.startsWith("@");
|
|
@@ -494,25 +678,71 @@ class Loader {
|
|
|
494
678
|
|
|
495
679
|
if (line.startsWith(":")) {
|
|
496
680
|
line = this.handle_marker(line);
|
|
497
|
-
|
|
498
681
|
if (!line) continue;
|
|
499
682
|
}
|
|
500
683
|
|
|
501
|
-
|
|
684
|
+
if (this.config_flag){
|
|
685
|
+
this.handle_config(line)
|
|
686
|
+
this.config_flag = false;
|
|
687
|
+
continue;
|
|
688
|
+
}
|
|
502
689
|
|
|
503
|
-
|
|
690
|
+
line = this.resolve_offset(line);
|
|
691
|
+
if(line.startsWith('$')){
|
|
692
|
+
this.handle_decor(line)
|
|
693
|
+
continue
|
|
694
|
+
} else if (line === ";") this.pop();
|
|
504
695
|
else if (this.is_routine) this.parse_routine(line);
|
|
505
696
|
else if (line.startsWith("//")) this.parse_comment(line.slice(2).trim());
|
|
506
697
|
else if (line.startsWith(">@") || line.startsWith(">."))
|
|
507
698
|
this.parse_assignment(line, true);
|
|
508
|
-
else if (line.startsWith(">"))
|
|
509
|
-
|
|
699
|
+
else if (line.startsWith(">")){
|
|
700
|
+
let res =this.check_recursive(line)
|
|
701
|
+
this.parse_assignment(res);
|
|
702
|
+
} else this.parse_opcode(line);
|
|
510
703
|
|
|
511
704
|
(!curr_program || this.is_routine) &&
|
|
512
705
|
this.handle_codes(line, this.current_program());
|
|
513
|
-
|
|
706
|
+
|
|
707
|
+
if (this.pure> 0)this.pure--
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
this.no_static = false
|
|
514
711
|
};
|
|
515
712
|
|
|
713
|
+
handle_config = config=>{
|
|
714
|
+
this.pure = true
|
|
715
|
+
this.parse_opcode(`config ${config}`)
|
|
716
|
+
this.pure = false
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
check_recursive=line=>{
|
|
720
|
+
line = line.slice(1).split(' ').filter(l=>!!l)
|
|
721
|
+
|
|
722
|
+
let identifier = line[0]
|
|
723
|
+
|
|
724
|
+
let recurse = line.slice(1).find(l=>l===identifier);
|
|
725
|
+
if (recurse){
|
|
726
|
+
let new_var = `temp_${identifier}_${this.account.manager.oracle.hash(identifier, 'sha1')}`
|
|
727
|
+
this.parse_assignment(`>${new_var} ${identifier}`)
|
|
728
|
+
line = line.slice(1).map(l=>{
|
|
729
|
+
if(l===identifier)return new_var
|
|
730
|
+
return l
|
|
731
|
+
})
|
|
732
|
+
line.unshift(identifier)
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
line =`>${line.join(' ')}`
|
|
736
|
+
|
|
737
|
+
return line
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
handle_decor = line=>{
|
|
741
|
+
line= line.slice(1).split(' ')
|
|
742
|
+
|
|
743
|
+
this[line[0]] = Number(line[1]) || 1
|
|
744
|
+
}
|
|
745
|
+
|
|
516
746
|
handle_codes = (line, curr_program) => {
|
|
517
747
|
if (this.is_routine) {
|
|
518
748
|
let tilline = `~${line}`;
|
|
@@ -529,30 +759,47 @@ class Loader {
|
|
|
529
759
|
|
|
530
760
|
run = (codes, meta) => {
|
|
531
761
|
if (!meta) meta = {};
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
762
|
+
let { pure, cb, options , unshift} = meta;
|
|
763
|
+
let{main, configs}=options ||{}
|
|
764
|
+
this.pure = pure? -1:0;
|
|
535
765
|
|
|
536
766
|
this.compile(codes);
|
|
537
767
|
|
|
538
768
|
if (meta.instructions) return [...this.instructions];
|
|
539
769
|
|
|
540
770
|
// console.log(JSON.stringify(this.instructions, null, 2), "hiya");
|
|
771
|
+
if(this.pure)this.account.log_output(this.instructions)
|
|
541
772
|
|
|
542
773
|
this.account.load({
|
|
543
|
-
program: { instructions: [...this.instructions] },
|
|
774
|
+
program: { instructions: [...this.instructions], unshift: !!unshift},
|
|
544
775
|
callback: cb,
|
|
545
776
|
});
|
|
546
777
|
|
|
547
778
|
let pragma = this.program_configs[0];
|
|
548
|
-
if (pragma)
|
|
549
|
-
|
|
779
|
+
if (pragma)
|
|
780
|
+
pragma.main =
|
|
781
|
+
(main) || this.repository.oracle.hash(codes);
|
|
550
782
|
this.program_configs.map((config) => this.repository.add_program(config));
|
|
551
783
|
|
|
552
|
-
|
|
553
|
-
|
|
784
|
+
if(configs === 'pragma_only'){
|
|
785
|
+
this.set_config(this.configs[pragma.physical_address])
|
|
786
|
+
}else {
|
|
787
|
+
for (let addr in this.configs){
|
|
788
|
+
let config = this.configs[addr]
|
|
789
|
+
this.set_config(config)
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
this.configs = new Object()
|
|
793
|
+
|
|
794
|
+
this.program_configs = new Array();
|
|
795
|
+
this.instructions = new Array();
|
|
554
796
|
this.pure = false;
|
|
555
797
|
};
|
|
798
|
+
|
|
799
|
+
set_config = (config)=>{
|
|
800
|
+
config&&
|
|
801
|
+
this.account.execute('config', {op0: config})
|
|
802
|
+
}
|
|
556
803
|
}
|
|
557
804
|
|
|
558
805
|
export default Loader;
|