godprotocol 1.0.7991 → 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.
Files changed (88) hide show
  1. package/Executables/callables.js +131 -0
  2. package/Executables/executables.js +230 -0
  3. package/Executables/functions/adminstrator/adm_register.js +29 -0
  4. package/Executables/functions/adminstrator/native_components.js +10 -0
  5. package/Executables/functions/adminstrator/query_selectors.js +10 -0
  6. package/Executables/functions/adminstrator/render.js +24 -0
  7. package/Executables/functions/array_register.js +161 -0
  8. package/Executables/functions/assign.js +19 -0
  9. package/Executables/functions/display.js +55 -0
  10. package/Executables/functions/folder.js +95 -0
  11. package/Executables/functions/folder_register.js +87 -0
  12. package/Executables/functions/importcheck.js +13 -0
  13. package/Executables/functions/indices.js +56 -0
  14. package/Executables/functions/len.js +22 -0
  15. package/Executables/functions/methods/array.js +272 -0
  16. package/Executables/functions/methods/string.js +197 -0
  17. package/Executables/functions/methods/twain.js +148 -0
  18. package/Executables/functions/op.js +15 -0
  19. package/Executables/functions/price_register.js +30 -0
  20. package/Executables/functions/pricing.js +26 -0
  21. package/Executables/functions/servers/account.js +81 -0
  22. package/Executables/functions/servers/account_register.js +56 -0
  23. package/Executables/functions/servers/block.js +21 -0
  24. package/Executables/functions/servers/block_register.js +18 -0
  25. package/Executables/functions/servers/chain.js +42 -0
  26. package/Executables/functions/servers/chain_register.js +28 -0
  27. package/Executables/functions/set_error_catch.js +34 -0
  28. package/Executables/functions/string_register.js +130 -0
  29. package/Executables/functions/twain_register.js +56 -0
  30. package/Executables/functions/typecast.js +43 -0
  31. package/Executables/functions/utils.js +9 -0
  32. package/Executables/stack.js +53 -0
  33. package/Index.js +2 -7
  34. package/Loader_sequence/main.js +535 -119
  35. package/Loader_sequence/repository.js +33 -0
  36. package/Objects/Account.js +220 -54
  37. package/Objects/Block.js +46 -16
  38. package/Objects/Blockweb.js +14 -0
  39. package/Objects/Chain.js +163 -16
  40. package/Objects/Fee.js +33 -0
  41. package/Objects/Filesystem.js +100 -26
  42. package/Objects/Frame.js +10 -3
  43. package/Objects/Manager.js +272 -46
  44. package/Objects/Opcodes.js +60 -10
  45. package/Objects/Oracle.js +90 -5
  46. package/Objects/Protocol.js +5 -0
  47. package/Objects/Virtual_machine.js +145 -53
  48. package/Trinity.js +20 -0
  49. package/callables.js +172 -0
  50. package/framer.js +111 -52
  51. package/opcodes/add.js +6 -6
  52. package/opcodes/indices.js +82 -0
  53. package/opcodes/jmp.js +12 -11
  54. package/opcodes/std.js +7 -2
  55. package/opcodes.js +72 -14
  56. package/package.json +6 -5
  57. package/readme.md +1 -1
  58. package/starter_scripts/constants.seq +11 -0
  59. package/utils/create_server.js +34 -27
  60. package/utils/hash.js +2 -2
  61. package/utils/logger.js +79 -0
  62. package/utils/services.js +5 -3
  63. package/utils/type_coersion.js +3 -0
  64. package/utils/vm_utils.js +292 -0
  65. package/.babelrc +0 -3
  66. package/build/Account.js +0 -162
  67. package/build/Block.js +0 -65
  68. package/build/Blockweb.js +0 -36
  69. package/build/Chain.js +0 -119
  70. package/build/Explorer.js +0 -47
  71. package/build/Filesystem.js +0 -127
  72. package/build/Frame.js +0 -52
  73. package/build/Index.js +0 -15
  74. package/build/Manager.js +0 -99
  75. package/build/Opcodes.js +0 -39
  76. package/build/Oracle.js +0 -42
  77. package/build/Virtual_machine.js +0 -128
  78. package/build/add.js +0 -41
  79. package/build/create_server.js +0 -119
  80. package/build/framer.js +0 -57
  81. package/build/functions.js +0 -82
  82. package/build/hash.js +0 -14
  83. package/build/jmp.js +0 -19
  84. package/build/main.js +0 -283
  85. package/build/opcodes.js +0 -42
  86. package/build/privacy.js +0 -27
  87. package/build/services.js +0 -50
  88. package/build/std.js +0 -11
@@ -1,6 +1,9 @@
1
- let num_pattern = /^[+-]?\d+(\.\d+)?$/;
2
- // let str_pattern = /^["'][^"']*["']$/;
1
+ import { _id } from "generalised-datastore/utils/functions";
2
+ import Repository from "./repository";
3
+
4
+ let num_pattern = /^\d+(\.\d+)?$/;
3
5
  let var_pattern = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
6
+ let addr_pattern = /^(@\/|\.\.\/|\.\/)?([A-Za-z0-9_\-]+\/)*[A-Za-z0-9_\-]+$/
4
7
 
5
8
  class Loader {
6
9
  constructor(account) {
@@ -11,20 +14,28 @@ class Loader {
11
14
  this.instruction_indexes = new Array();
12
15
  this.instruction_stacks = [[]];
13
16
  this.stacks = new Array(account.physical_address);
17
+ this.markers = new Array();
18
+ this.program_configs = new Array();
19
+ this.programs_index = -1;
20
+
21
+ this.datatypes = new Array('twain', 'string','void', 'boolean', 'array', 'number')
22
+ this.configs = new Object()
23
+
24
+ // Code Repository
25
+ this.repository = new Repository(this);
14
26
  }
15
27
 
16
28
  instruction_index = () => {
17
- let index = this.instruction_indexes.slice(-1);
18
- index++;
19
- this.instruction_indexes.splice(-1, 1, index);
29
+ let len = this.instruction_indexes.length -1
30
+ this.instruction_indexes[len]++
20
31
 
21
- return index;
32
+ return this.instruction_indexes[len]
22
33
  };
23
34
 
24
35
  stack_instruction = (instruction) => {
25
36
  if (Array.isArray(instruction))
26
37
  return instruction.map((i) => this.stack_instruction(i));
27
-
38
+
28
39
  this.instruction_stacks.slice(-1)[0].push(instruction);
29
40
  };
30
41
 
@@ -40,23 +51,38 @@ class Loader {
40
51
  this.instructions.push(instruction);
41
52
  } else {
42
53
  this.stack_instruction(`cursor ${this.instruction_index()}`);
54
+
43
55
  this.stack_instruction(`write ${instruction}`);
44
56
  }
45
57
  };
46
58
 
47
- parse_tokens = (line, stop_char) => {
59
+ parse_tokens = (line, options) => {
60
+ options = options ||{}
61
+ let {stop_char, all_static, inline} = options;
62
+
48
63
  let tokens = new Array();
49
- let pos = 0,
50
- line_number = 0;
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
+ }
51
77
 
52
- let push_token = (value, type) =>
53
- tokens.push({ value, type, line: line_number, pos });
78
+ tokens.push(tok_obj);
79
+ };
54
80
 
55
81
  line = line.trim();
56
82
  while (pos < line.length) {
57
83
  let char = line[pos].trim();
58
84
 
59
- if (char === stop_char) return { tokens, pos };
85
+ if (char === stop_char) return { tokens, pos, all_static};
60
86
 
61
87
  if (!char) {
62
88
  pos++;
@@ -65,11 +91,21 @@ class Loader {
65
91
  }
66
92
 
67
93
  if (char === "\n") {
68
- line_number++;
69
94
  pos++;
70
- } else if (char === "@") {
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");
106
+ } else if (char === "@" || char === ".") {
71
107
  let acc = "";
72
- while (line[pos] && line[pos].trim()) {
108
+ while (line[pos] && line[pos].trim() && (line[pos] !== stop_char) && ![','].includes(line[pos]) ) {
73
109
  acc += line[pos];
74
110
  pos++;
75
111
  }
@@ -77,17 +113,33 @@ class Loader {
77
113
  } else if (char === ",") {
78
114
  pos++;
79
115
  } else if (char === ":") {
116
+
80
117
  push_token(char, "separator");
81
118
  pos++;
82
119
  } else if (char === "[") {
83
120
  pos++;
84
- let toks = this.parse_tokens(line.slice(pos), "]");
85
- push_token(toks.tokens, "array");
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
+
86
131
  pos += toks.pos + 1;
87
132
  } else if (char === "{") {
88
133
  pos++;
89
- let toks = this.parse_tokens(line.slice(pos), "}");
90
- push_token(toks.tokens, "twain");
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
91
143
  pos += toks.pos + 1;
92
144
  } else if (char === ">") {
93
145
  pos++;
@@ -101,7 +153,7 @@ class Loader {
101
153
  }
102
154
  pos++;
103
155
  push_token(acc, "string");
104
- } else if (num_pattern.test(char)) {
156
+ } else if (num_pattern.test(char) || char === "-") {
105
157
  let acc = char;
106
158
  pos++;
107
159
  while (
@@ -114,97 +166,190 @@ class Loader {
114
166
  pos++;
115
167
  }
116
168
  push_token(acc, "number");
117
- } else if (var_pattern.test(char)) {
118
- let acc = char;
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
+
119
177
  pos++;
120
- while (line[pos] && var_pattern.test(`${line[pos].trim()}`)) {
178
+ while (line[pos] && var_pattern.test(`${acc}${line[pos]}`)) {
121
179
  acc += line[pos];
122
180
  pos++;
123
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");
124
191
 
125
- push_token(acc, this.opcodes.includes(acc) ? "opcode" : "variable");
126
192
  }
127
193
  }
128
-
194
+
129
195
  return tokens;
130
196
  };
131
197
 
132
- parse = (token) => {
133
- if (token.type === "string" || token.type === "number") {
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){
134
215
  this.push_instruction([
135
- `link ${
136
- this.account.physical_address
137
- }/Datatypes/${`${token.type[0].toUpperCase()}${token.type.slice(1)}`}`,
138
- `write ${token.value}`,
139
- `pop ${token.type}`,
140
- ]);
141
- } else if (token.type === "array") {
142
- this.push_instruction(
143
- `link Accounts/${this.account.name}/Datatypes/Array`
144
- );
145
- token.value.map((item, i) => {
146
- this.parse(item);
216
+ 'cursor {output}',
217
+ 'write {datapath:-1}'
218
+ ])
219
+ this.push_instruction(`pop ${identifier.value}`)
220
+ }
147
221
 
222
+ this.pure = previous_pure
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}, ()=>{
148
235
  this.push_instruction([
149
- `cursor ${i}`,
150
- `write ${
151
- this.is_not_literal(item.type)
152
- ? "{metadata.output:-1}"
153
- : "{datapath:-1}"
154
- }`,
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}`,
155
241
  ]);
156
- });
157
- this.push_instruction(`pop Array`);
158
- } else if (token.type === "twain") {
159
- this.push_instruction(
160
- `link Accounts/${this.account.name}/Datatypes/Twain`
161
- );
162
- let curs = true;
242
+ })
163
243
 
164
- if (token.value)
165
- token.value.map((entry) => {
166
- if (entry.type === "separator") {
167
- curs = false;
168
- return;
169
- }
170
- this.parse(entry);
171
- if (curs) {
172
- {
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 {
173
294
  this.push_instruction(
174
- `cursor {*${
295
+ `write ${
175
296
  this.is_not_literal(entry.type)
176
- ? "metadata.output:-1"
177
- : "datapath:-1"
178
- }}`
297
+ ? "{metadata.output:-1}"
298
+ : "{datapath:-1}"
299
+ }`
179
300
  );
301
+ curs = true;
180
302
  }
181
- } else {
182
- this.push_instruction(
183
- `write ${
184
- this.is_not_literal(entry.type)
185
- ? "{metadata.output:-1}"
186
- : "{datapath:-1}"
187
- }`
188
- );
189
- curs = true;
190
- }
191
- });
192
- this.push_instruction(`pop Twain`);
303
+ });
304
+ }
305
+
306
+ this.push_instruction(`pop Twain`);
307
+
308
+ })
309
+
193
310
  } else if (token.type === "variable") {
311
+ let tok_value = token.value;
312
+
313
+ let is_nested = this.handle_nested(tok_value)
314
+
194
315
  this.push_instruction([
195
- `link ${`${this.stacks.slice(-1)[0]}/${token.value}`}`,
196
- `pop ${token.value}`,
316
+ `link ${is_nested?'{metadata.output:-1}': `${this.stacks.slice(-1)[0]}/${tok_value}`}`,
317
+ `pop ${tok_value}`,
197
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'])
198
323
  } else if (token.type === "address") this.parse_assignment(token);
199
324
  };
200
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
+
201
345
  is_not_literal = (type) =>
202
346
  !type || ["variable", "opcode", "address"].includes(type);
203
347
 
204
348
  parse_assignment = (line, linked) => {
205
349
  let tokens = linked || line.type ? line : this.parse_tokens(line);
206
350
 
207
- let identifier = tokens[0];
351
+ let identifier = tokens[0], is_nested, curr_program;
352
+
208
353
  if (linked || line.type) {
209
354
  let line_split = (line.value || line)
210
355
  .slice(line.value ? null : 1)
@@ -219,13 +364,26 @@ class Loader {
219
364
  if (line.type === "address")
220
365
  return this.push_instruction(`pop ${path[path.length - 1]}`);
221
366
  } else {
222
- this.push_instruction(`chain ${identifier.value}`);
223
- this.stack_instruction([
224
- `link ${this.stacks.slice(-1)[0]}`,
225
- `chain ${identifier.value}`,
226
- `pop ${identifier.value}`,
227
- "pop",
228
- ]);
367
+ curr_program = this.current_program();
368
+ curr_program && curr_program.dimensions.push({ name: identifier.value });
369
+
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
+
229
387
  }
230
388
 
231
389
  let prev_token;
@@ -234,25 +392,61 @@ class Loader {
234
392
  prev_token = tokens[1];
235
393
  } else {
236
394
  tokens.slice(1).map((tok) => {
237
- this.parse(tok);
395
+ this.parse(tok, {identifier});
238
396
  });
239
397
  prev_token = tokens.slice(-1)[0];
240
398
  }
241
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
+
242
423
  if (tokens.length > 1) {
243
- this.push_instruction([
244
- "cursor {output}",
245
- `write ${
246
- this.is_not_literal(prev_token && prev_token.type)
247
- ? "{metadata.output:-1}"
248
- : "{datapath:-1}"
249
- }`,
250
- `pop ${identifier.value}`,
251
- ]);
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
+
252
438
  } else this.push_instruction(`pop ${identifier.value}`);
439
+
440
+
441
+ };
442
+
443
+ current_program = () => {
444
+ return this.program_configs[this.programs_index];
253
445
  };
254
446
 
255
- parse_opcode = (line) => {
447
+ marker_pattern = /@[a-zA-Z_][a-zA-Z0-9_]*/;
448
+
449
+ parse_opcode = (line, assign) => {
256
450
  let tokens = Array.isArray(line) ? line : this.parse_tokens(line);
257
451
 
258
452
  let op = tokens[0];
@@ -265,11 +459,19 @@ class Loader {
265
459
  ]);
266
460
 
267
461
  tokens.slice(1).map((tok, i) => {
268
- this.parse(tok);
462
+ if (tok.type === "address" && tok.value.match(this.marker_pattern)) {
463
+ this.push_instruction([
464
+ `link ${this.account.physical_address}/Datatypes/Number`,
465
+ `write ${tok.value}`,
466
+ `pop Number`,
467
+ ]);
468
+ } else this.parse(tok);
469
+
269
470
  this.push_instruction([
270
471
  `cursor op${i}`,
271
472
  `write ${
272
- this.is_not_literal(tok.type)
473
+ tok.all_static || (this.is_not_literal(tok.type) &&
474
+ !(tok.type === "address" && tok.value.match(this.marker_pattern)))
273
475
  ? "{metadata.output:-1}"
274
476
  : "{datapath:-1}"
275
477
  }`,
@@ -288,11 +490,13 @@ class Loader {
288
490
  };
289
491
 
290
492
  resolve_addr = (addr) => {
493
+ let real_addr = addr;
291
494
  addr = addr.split("/");
292
495
 
293
- let real_addr = "";
294
-
295
- if (addr[0] === "@") {
496
+ if (addr.length === 1){
497
+ real_addr = addr.join('')
498
+ }
499
+ else if (addr[0] === "@") {
296
500
  addr[0] = this.account.physical_address;
297
501
  real_addr = addr.join("/");
298
502
  } else if (addr[0] === ".." || addr[0] === ".") {
@@ -311,11 +515,23 @@ class Loader {
311
515
  let curr_stack = this.stacks.slice(-1)[0].split("/");
312
516
  new_stack = new_stack.split("/");
313
517
 
518
+ let physical_address = new_stack.join("/");
519
+ let program = {
520
+ program_name: new_stack[new_stack.length - 1],
521
+ physical_address,
522
+ codes: [],
523
+ dimensions: [],
524
+ sub_programs: [],
525
+ _id: _id("programs"),
526
+ };
527
+ let curr_program = this.current_program();
528
+ if (curr_program) curr_program.sub_programs.push(program._id);
529
+
530
+ this.programs_index++;
531
+ this.program_configs.push(program);
532
+
314
533
  if (curr_stack[1] !== new_stack[1]) {
315
534
  } else {
316
- let i = 0;
317
- while (curr_stack[i] === new_stack[i]) i++;
318
-
319
535
  for (let j = 2; j < new_stack.length; j++)
320
536
  this.stack_instruction(`chain ${new_stack[j]}`);
321
537
 
@@ -347,43 +563,243 @@ class Loader {
347
563
  this.stack_instruction(`pop ${addr[j]}`);
348
564
 
349
565
  this.instructions.push(...this.instruction_stacks.splice(-1)[0]);
566
+ this.programs_index--;
350
567
 
351
568
  this.instruction_indexes.pop();
352
569
  };
353
570
 
571
+ revamp_marks = () => {
572
+ let instruction_stack = this.instruction_stacks.slice(-1)[0];
573
+
574
+ instruction_stack = instruction_stack.map((ins) =>
575
+ this.resolve_offset(ins, true)
576
+ );
577
+
578
+ this.instruction_stacks[this.instruction_stacks.length - 1] =
579
+ instruction_stack;
580
+ };
581
+
582
+ handle_marker = (line) => {
583
+ let splits = line.slice(1).split(" ");
584
+ let name = splits[0];
585
+
586
+ let curr_stack = this.stacks.slice(-1)[0];
587
+ let markers = this.markers[curr_stack];
588
+ if (!markers) {
589
+ markers = new Object();
590
+ this.markers[curr_stack] = markers;
591
+ }
592
+
593
+ markers[name] = this.instruction_indexes.slice(-1)[0];
594
+
595
+ this.revamp_marks();
596
+
597
+ return splits.slice(1).join(" ");
598
+ };
599
+
600
+ resolve_offset = (line, revamping) => {
601
+ let matches = line.match(this.marker_pattern),
602
+ value;
603
+ if (matches) {
604
+ let match = matches[0].slice(1);
605
+
606
+ let curr_stack = this.stacks.slice(-1)[0];
607
+ let markers = this.markers[curr_stack];
608
+ if (!markers) {
609
+ markers = new Object();
610
+ this.markers[curr_stack] = markers;
611
+ }
612
+ value = markers[match];
613
+ }
614
+
615
+ if (typeof value === "number")
616
+ {line = line.replace(
617
+ this.marker_pattern,
618
+ (revamping&&value>0?value+1: value+1).toString()
619
+ );
620
+
621
+ }
622
+
623
+ return line;
624
+ };
625
+
626
+ parse_comment = (line) => {
627
+ line = line.split(":");
628
+ if (line.length <= 1) return;
629
+
630
+ let curr_program = this.current_program();
631
+ let line1 = line[0].split(".");
632
+ let obj = curr_program;
633
+
634
+ for (let l = 0; l < line1.length - 1; l++) {
635
+ let term = line1[l];
636
+
637
+ if (term.trim() === "_id") break;
638
+
639
+ let n_term = Number(term);
640
+
641
+ if (n_term) {
642
+ obj = obj[n_term];
643
+ } else obj = obj[term];
644
+ }
645
+ if (!obj) return;
646
+
647
+ let index = line1[line1.length - 1];
648
+ let n_indx = Number(index);
649
+ if (!isNaN(n_indx)) index = n_indx;
650
+
651
+ if (index === "_id") return;
652
+
653
+ obj[index] = line.slice(1).join(":").trim();
654
+ };
655
+
656
+ spawn = () => {
657
+ let spaw = new Loader(this.account);
658
+ spaw.opcodes = [...this.opcodes];
659
+
660
+ return spaw;
661
+ };
662
+
663
+ line_count = 0
664
+
354
665
  compile = (codes) => {
355
666
  let code_array = codes.split("\n");
356
667
 
357
668
  for (let c = 0; c < code_array.length; c++) {
358
669
  let line = code_array[c].trim();
670
+ this.line_count++
671
+
672
+ let curr_program = this.current_program();
673
+ this.is_routine = line.startsWith(".") || line.startsWith("@");
674
+
675
+ this.handle_codes(line, curr_program);
676
+
359
677
  if (!line) continue;
360
678
 
361
- if (line === ";") this.pop();
362
- else if (line.startsWith("link ")) this.parse_routine(line);
363
- else if (line.startsWith(".") || line.startsWith("@"))
364
- this.parse_routine(line);
365
- else if (line.startsWith("//")) continue;
366
- else if (line.startsWith(">@")) this.parse_assignment(line, true);
367
- else if (line.startsWith(">")) this.parse_assignment(line);
368
- else this.parse_opcode(line);
679
+ if (line.startsWith(":")) {
680
+ line = this.handle_marker(line);
681
+ if (!line) continue;
682
+ }
683
+
684
+ if (this.config_flag){
685
+ this.handle_config(line)
686
+ this.config_flag = false;
687
+ continue;
688
+ }
689
+
690
+ line = this.resolve_offset(line);
691
+ if(line.startsWith('$')){
692
+ this.handle_decor(line)
693
+ continue
694
+ } else if (line === ";") this.pop();
695
+ else if (this.is_routine) this.parse_routine(line);
696
+ else if (line.startsWith("//")) this.parse_comment(line.slice(2).trim());
697
+ else if (line.startsWith(">@") || line.startsWith(">."))
698
+ this.parse_assignment(line, true);
699
+ else if (line.startsWith(">")){
700
+ let res =this.check_recursive(line)
701
+ this.parse_assignment(res);
702
+ } else this.parse_opcode(line);
703
+
704
+ (!curr_program || this.is_routine) &&
705
+ this.handle_codes(line, this.current_program());
706
+
707
+ if (this.pure> 0)this.pure--
708
+ }
709
+
710
+ this.no_static = false
711
+ };
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
+
746
+ handle_codes = (line, curr_program) => {
747
+ if (this.is_routine) {
748
+ let tilline = `~${line}`;
749
+ let prev_program = this.program_configs[this.programs_index - 1];
750
+ prev_program && prev_program.codes.push(tilline);
751
+
752
+ curr_program &&
753
+ !curr_program.codes.find((line) => !!line.trim()) &&
754
+ curr_program.codes.push(line);
369
755
  }
756
+
757
+ !this.is_routine && curr_program && curr_program.codes.push(line);
370
758
  };
371
759
 
372
- run = (codes, meta = { cb, pure }) => {
760
+ run = (codes, meta) => {
373
761
  if (!meta) meta = {};
374
- this.pure = pure;
762
+ let { pure, cb, options , unshift} = meta;
763
+ let{main, configs}=options ||{}
764
+ this.pure = pure? -1:0;
375
765
 
376
766
  this.compile(codes);
377
767
 
768
+ if (meta.instructions) return [...this.instructions];
769
+
378
770
  // console.log(JSON.stringify(this.instructions, null, 2), "hiya");
771
+ if(this.pure)this.account.log_output(this.instructions)
379
772
 
380
773
  this.account.load({
381
- program: { instructions: [...this.instructions] },
774
+ program: { instructions: [...this.instructions], unshift: !!unshift},
382
775
  callback: cb,
383
776
  });
384
- this.instructions = [];
777
+
778
+ let pragma = this.program_configs[0];
779
+ if (pragma)
780
+ pragma.main =
781
+ (main) || this.repository.oracle.hash(codes);
782
+ this.program_configs.map((config) => this.repository.add_program(config));
783
+
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();
385
796
  this.pure = false;
386
797
  };
798
+
799
+ set_config = (config)=>{
800
+ config&&
801
+ this.account.execute('config', {op0: config})
802
+ }
387
803
  }
388
804
 
389
805
  export default Loader;