force-lang 0.0.13 → 0.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/src/read.js CHANGED
@@ -1,319 +1,441 @@
1
- const log = require('bunny-logger');
2
- const JSON5 = require('json5');
3
- var TokenStream = require('./token-stream');
1
+ import log from 'bunny-logger';
2
+ import JSON5 from 'json5';
3
+ import TokenStream from './token-stream.js';
4
4
 
5
- class Read{
6
- tokenize(e){
7
- return new TokenStream(e.split(''));
8
- }
9
- is_delimiter(e){
10
- if(this.is_whitespace(e) || this.is_eof(e)) return true;
11
- return false;
12
- }
13
- is_whitespace(e){
14
- const ws = [' ','\n','\r','\t'];
15
- return ws.includes(e);
16
- }
17
- is_digit(e){
18
- if(this.is_delimiter(e)) return false;
19
- const num = e - '0';
20
- return num>=0 && num<=9 ? true : false ;
21
- }
22
- is_hex_digit(e){
23
- if(this.is_eof(e)) return false;
24
- const hex_letters = ['a','b,','c','d','e','f'];
25
- if(this.is_digit(e) || hex_letters.includes(e.toLowerCase())) return true;
26
- return false;
27
- }
28
- is_bin_digit(e){
29
- if(this.is_eof(e)) return false;
30
- return e == 0 || e == 1 ? true : false ;
31
- }
32
- is_num(e){
33
- if( (e.peek() == '+' && this.is_digit(e.lookahead(1))) ||
34
- (e.peek() == '-' ) && this.is_digit(e.lookahead(1))||
35
- this.is_digit(e.peek())
36
- ){
37
- return true;
38
- }
39
- return false;
40
- }
41
- is_eof(e){
42
- return e===false;
43
- }
44
- is_bool(e){
45
- if((e.peek() == 'T') || (e.peek() == 'F'))
46
- if(this.is_delimiter(e.lookahead(1))) return true;
47
- return false;
48
- }
49
- eat_whitespaces(e){
50
- try{
51
- while(this.is_whitespace(e.peek())){
52
- e.advance();
53
- }
54
- }catch(e){
5
+ class Read {
6
+ tokenize(e) {
7
+ return new TokenStream(e.split(''));
8
+ }
55
9
 
56
- }
57
- }
58
- is_string(e){
59
- return (e == '"')? true : false ;
60
- }
61
- is_string_single_quote(e){
62
- return (e == "'")? true : false ;
63
- }
64
- is_json(e){
65
- return (e === '{' || e === '[')? true : false ;
66
- }
67
- eat_line_comment(e){
68
- while(e.peek()!='\n' && e.peek()!='\r' && !this.is_eof(e.peek())){
69
- e.advance();
70
- }
71
- this.eat_whitespaces(e);
72
- }
73
- eat_comments(e){
74
- if(e.peek()=='#' && e.lookahead(1)=='!'){
75
- this.eat_line_comment(e);
76
- }
77
- if(e.peek()=='/' && e.lookahead(1)=='/'){
78
- this.eat_line_comment(e);
79
- }
80
- if(e.peek()=='\\'){
81
- this.eat_line_comment(e);
82
- }
83
- if(e.peek()=='-' && e.lookahead(1)=='-'){
84
- this.eat_line_comment(e);
85
- }
86
- if(e.peek()=='/' && e.lookahead(1)=='*'){
87
- while(e.peek()!='*' || e.lookahead(1)!='/'){
88
- if(this.is_eof(e.peek())) return;
89
- e.advance();
90
- }
91
- e.advance();
92
- e.advance();
93
- }
94
- }
95
- eat_string(e){
96
- var str = '';
97
- try{
98
- if(this.is_string(e.peek())) e.advance();
99
- while(!this.is_string(e.peek())){
100
- if(e.peek()=='\\'){
101
- switch(e.lookahead(1)){
102
- case 'n':
103
- str += '\n';
104
- e.advance();e.advance();
105
- break;
106
- case 'r':
107
- str += '\r';
108
- e.advance();e.advance();
109
- break;
110
- case '\\':
111
- str += '\\';
112
- e.advance();e.advance();
113
- break;
114
- case '"':
115
- str += '"';
116
- e.advance();e.advance();
117
- break;
118
- default:
119
- str += e.advance();
120
- break;
121
- }
122
- }else
123
- str += e.advance();
124
- }
125
- e.advance();
126
- }catch(e){
10
+ is_delimiter(e) {
11
+ if (this.is_whitespace(e) || this.is_eof(e)) {
12
+ return true;
13
+ }
14
+ return false;
15
+ }
127
16
 
128
- }
129
- return str;
130
- }
131
- eat_string_single_quote(e){
132
- var str = '';
133
- try{
134
- if(this.is_string_single_quote(e.peek())) e.advance();
135
- while(!this.is_string_single_quote(e.peek())){
136
- if(e.peek()=='\\'){
137
- switch(e.lookahead(1)){
138
- case 'n':
139
- str += '\n';
140
- e.advance();e.advance();
141
- break;
142
- case 'r':
143
- str += '\r';
144
- e.advance();e.advance();
145
- break;
146
- case '\\':
147
- str += '\\';
148
- e.advance();e.advance();
149
- break;
150
- case '"':
151
- str += '"';
152
- e.advance();e.advance();
153
- break;
154
- default:
155
- str += e.advance();
156
- break;
157
- }
158
- }else
159
- str += e.advance();
160
- }
161
- e.advance();
162
- }catch(e){
17
+ is_whitespace(e) {
18
+ const ws = [' ', '\n', '\r', '\t'];
19
+ return ws.includes(e);
20
+ }
163
21
 
164
- }
165
- return str;
166
- }
167
- eat_number(e){
168
- let sign = 1;
169
- var num=0;
170
- var fract=false;
171
- var fract_num=0;
172
- try{
173
- if(e.peek() == '-') {sign = -1;e.advance();}
174
- if(e.peek()=='0' && e.lookahead(1) == 'x') return sign*this.eat_hex(e);
175
- if(e.peek()=='0' && e.lookahead(1) == 'b') return sign*this.eat_bin(e);
176
- while(!this.is_delimiter(e.peek())){
177
- this.eat_comments(e);
178
- if(!fract && this.is_digit(e.peek())) num = num*10 + (e.advance()-'0');
179
- else if(fract && this.is_digit(e.peek())) fract_num = fract_num*10 + (e.advance()-'0');
180
- else if(e.peek()=='.'){fract=true;e.advance();}
181
- else {
182
- log.error('syntax error. invalid number');
183
- e.print_err();
184
- process.exit(1);
185
- }
186
- }
187
- }catch(e){
22
+ is_digit(e) {
23
+ if (this.is_delimiter(e)) {
24
+ return false;
25
+ }
26
+ const num = e - '0';
27
+ return !!(num >= 0 && num <= 9);
28
+ }
188
29
 
189
- }
190
- return fract ? sign*parseFloat(`${num}.${fract_num}`) : sign*num;
191
- }
192
- eat_hex(e){
193
- var str = '';
194
- try{
195
- if(e.peek()=='0' && e.lookahead(1) == 'x'){e.advance();e.advance();}
196
- while(!this.is_delimiter(e.peek())){
197
- this.eat_comments(e);
198
- if(this.is_hex_digit(e.peek())){
199
- str += e.advance();
200
- }
201
- else {
202
- log.error('syntax error. invalid number');
203
- e.print_err();
204
- process.exit(1);
205
- }
206
- }
207
- }catch(e){
30
+ is_comment(e) {
31
+ if (e.peek() == '#' && e.lookahead(1) == '!') {
32
+ return true;
33
+ }
34
+ if (e.peek() == '/' && e.lookahead(1) == '/') {
35
+ return true;
36
+ this.eat_line_comment(e);
37
+ }
38
+ if (e.peek() == '\\') {
39
+ return true;
40
+ }
41
+ if (e.peek() == '-' && e.lookahead(1) == '-') {
42
+ return true;
43
+ }
44
+ return false;
45
+ }
208
46
 
209
- }
210
- return parseInt(str,16);
211
- }
212
- eat_bin(e){
213
- var str = '';
214
- try{
215
- if(e.peek()=='0' && e.lookahead(1) == 'b'){e.advance();e.advance();}
216
- while(!this.is_delimiter(e.peek())){
217
- this.eat_comments(e);
218
- if(this.is_bin_digit(e.peek())){
219
- str += e.advance();
220
- }
221
- else {
222
- log.error('syntax error. invalid number');
223
- e.print_err();
224
- process.exit(1);
225
- }
226
- }
227
- }catch(e){
47
+ is_hex_digit(e) {
48
+ if (this.is_eof(e)) {
49
+ return false;
50
+ }
51
+ const hex_letters = ['a', 'b,', 'c', 'd', 'e', 'f'];
52
+ if (this.is_digit(e) || hex_letters.includes(e.toLowerCase())) {
53
+ return true;
54
+ }
55
+ return false;
56
+ }
228
57
 
229
- }
230
- return parseInt(str,2);
231
- }
232
- eat_bool(e){
233
- var str = '';
234
- try{
235
- while(!this.is_delimiter(e.peek())){
236
- this.eat_comments(e);
237
- str += e.advance();
238
- }
239
- }catch(e){
58
+ is_bin_digit(e) {
59
+ if (this.is_eof(e)) {
60
+ return false;
61
+ }
62
+ return !!(e == 0 || e == 1);
63
+ }
240
64
 
241
- }
242
- return str;
243
- }
244
- eat_word(e){
245
- var str = '';
246
- try{
247
- while(!this.is_delimiter(e.peek())){
248
- this.eat_comments(e);
249
- str += e.advance();
250
- }
251
- }catch(e){
65
+ is_num(e) {
66
+ if (
67
+ (e.peek() == '+' && this.is_digit(e.lookahead(1))) ||
68
+ (e.peek() == '-' && this.is_digit(e.lookahead(1))) ||
69
+ this.is_digit(e.peek())
70
+ ) {
71
+ return true;
72
+ }
73
+ return false;
74
+ }
252
75
 
253
- }
254
- return str;
255
- }
256
- eat_json(e){
257
- if(!this.is_json(e.peek())) return '{}';
258
- var opening_char, closing_char;
259
- if(e.peek() === '{'){
260
- opening_char = '{';
261
- closing_char = '}';
262
- }
263
- if(e.peek() === '['){
264
- opening_char = '[';
265
- closing_char = ']';
266
- }
267
- var str = '';
268
- var level = 0;
269
- var instring = 0;
270
- var json_line = e._line;
271
- var json_col = e._col;
272
-
273
- do{
274
- this.eat_comments(e);
275
- var x=e.advance();
276
- //if(x==='"' || x==="'") instring=instring++ mod 2
277
- if(x==='"' || x==="'"){
278
- let closing_str=x;
279
- let c,sstr='';
280
- while((c=e.advance()) != closing_str){
281
- sstr +=c;
282
- }
283
- x= `${closing_str}${sstr}${closing_str}`;
284
- }
285
- if(x===opening_char) level++;
286
- if(x===closing_char) level--;
287
- str += x;
288
- }while(e.peek()!==false && level !=0 /*&& x!==closing_char*/);
289
- //log.info(str);
290
- try{
291
- return JSON5.parse(str);
292
- }catch(err){
293
- log.error(`error in json obj at line ${json_line}, col ${json_col}`);
294
- if(e._filename) log.error(`in ${e._filename} file`);
295
- log.error(err);
296
- }
297
- }
298
- where(e){
299
- return {"file":e._filename, "line":e._line, "col":e._col};
300
- }
301
- read(e, filename=null){
302
- try{
303
- if(filename) {e.set_filename(filename);}
304
- this.eat_whitespaces(e);
305
- this.eat_comments(e);
306
- if(this.is_eof(e.peek())) return false;
307
- if(this.is_num(e)) return {"_type":"TC_NUM", "_where": this.where(e), "_datum": this.eat_number(e)};
308
- if(this.is_string(e.peek())) return {"_type":"TC_STR", "_where": this.where(e), "_datum": this.eat_string(e)};
309
- if(this.is_string_single_quote(e.peek())) return {"_type":"TC_STR", "_where": this.where(e), "_datum": this.eat_string_single_quote(e)};
310
- if(this.is_json(e.peek())) return {"_type":"TC_JSON", "_where": this.where(e), "_datum": this.eat_json(e)};
311
- if(this.is_bool(e)) return {"_type":"TC_BOOL", "_where": this.where(e), "_datum": this.eat_bool(e)};
312
- return {"_type":"TC_WORD", "_where": this.where(e), "_datum": this.eat_word(e)};
313
- }catch(e){
314
- return false;
315
- }
316
- }
317
- };
76
+ is_eof(e) {
77
+ return e === false;
78
+ }
318
79
 
319
- module.exports = new Read();
80
+ is_bool(e) {
81
+ if (e.peek() == 'T' || e.peek() == 'F') {
82
+ if (this.is_delimiter(e.lookahead(1))) {
83
+ return true;
84
+ }
85
+ }
86
+ return false;
87
+ }
88
+
89
+ eat_whitespaces(e) {
90
+ try {
91
+ while (this.is_whitespace(e.peek())) {
92
+ e.advance();
93
+ }
94
+ } catch (e) {}
95
+ }
96
+
97
+ is_string(e) {
98
+ return e == '"';
99
+ }
100
+
101
+ is_string_single_quote(e) {
102
+ return e == "'";
103
+ }
104
+
105
+ is_json(e) {
106
+ return !!(e === '{' || e === '[');
107
+ }
108
+
109
+ eat_line_comment(e) {
110
+ while (e.peek() != '\n' && e.peek() != '\r' && !this.is_eof(e.peek())) {
111
+ e.advance();
112
+ }
113
+ this.eat_whitespaces(e);
114
+ }
115
+
116
+ eat_comments(e) {
117
+ if (e.peek() == '#' && e.lookahead(1) == '!') {
118
+ this.eat_line_comment(e);
119
+ }
120
+ if (e.peek() == '/' && e.lookahead(1) == '/') {
121
+ this.eat_line_comment(e);
122
+ }
123
+ if (e.peek() == '\\') {
124
+ this.eat_line_comment(e);
125
+ }
126
+ if (e.peek() == '-' && e.lookahead(1) == '-') {
127
+ this.eat_line_comment(e);
128
+ }
129
+ if (e.peek() == '/' && e.lookahead(1) == '*') {
130
+ while (e.peek() != '*' || e.lookahead(1) != '/') {
131
+ if (this.is_eof(e.peek())) {
132
+ return;
133
+ }
134
+ e.advance();
135
+ }
136
+ e.advance();
137
+ e.advance();
138
+ }
139
+ }
140
+
141
+ eat_string(e) {
142
+ let str = '';
143
+ try {
144
+ if (this.is_string(e.peek())) {
145
+ e.advance();
146
+ }
147
+ while (!this.is_string(e.peek())) {
148
+ if (e.peek() == '\\') {
149
+ switch (e.lookahead(1)) {
150
+ case 'n':
151
+ str += '\n';
152
+ e.advance();
153
+ e.advance();
154
+ break;
155
+ case 'r':
156
+ str += '\r';
157
+ e.advance();
158
+ e.advance();
159
+ break;
160
+ case '\\':
161
+ str += '\\';
162
+ e.advance();
163
+ e.advance();
164
+ break;
165
+ case '"':
166
+ str += '"';
167
+ e.advance();
168
+ e.advance();
169
+ break;
170
+ default:
171
+ str += e.advance();
172
+ break;
173
+ }
174
+ } else {
175
+ str += e.advance();
176
+ }
177
+ }
178
+ e.advance();
179
+ } catch (e) {}
180
+ return str;
181
+ }
182
+
183
+ eat_string_single_quote(e) {
184
+ let str = '';
185
+ try {
186
+ if (this.is_string_single_quote(e.peek())) {
187
+ e.advance();
188
+ }
189
+ while (!this.is_string_single_quote(e.peek())) {
190
+ if (e.peek() == '\\') {
191
+ switch (e.lookahead(1)) {
192
+ case 'n':
193
+ str += '\n';
194
+ e.advance();
195
+ e.advance();
196
+ break;
197
+ case 'r':
198
+ str += '\r';
199
+ e.advance();
200
+ e.advance();
201
+ break;
202
+ case '\\':
203
+ str += '\\';
204
+ e.advance();
205
+ e.advance();
206
+ break;
207
+ case '"':
208
+ str += '"';
209
+ e.advance();
210
+ e.advance();
211
+ break;
212
+ default:
213
+ str += e.advance();
214
+ break;
215
+ }
216
+ } else {
217
+ str += e.advance();
218
+ }
219
+ }
220
+ e.advance();
221
+ } catch (e) {}
222
+ return str;
223
+ }
224
+
225
+ eat_number(e) {
226
+ let sign = 1;
227
+ let num = 0;
228
+ let fract = false;
229
+ let fract_num = 0;
230
+ try {
231
+ if (e.peek() == '-') {
232
+ sign = -1;
233
+ e.advance();
234
+ }
235
+ if (e.peek() == '0' && e.lookahead(1) == 'x') {
236
+ return sign * this.eat_hex(e);
237
+ }
238
+ if (e.peek() == '0' && e.lookahead(1) == 'b') {
239
+ return sign * this.eat_bin(e);
240
+ }
241
+ while (!this.is_delimiter(e.peek())) {
242
+ this.eat_comments(e);
243
+ if (!fract && this.is_digit(e.peek())) {
244
+ num = num * 10 + (e.advance() - '0');
245
+ } else if (fract && this.is_digit(e.peek())) {
246
+ fract_num = fract_num * 10 + (e.advance() - '0');
247
+ } else if (e.peek() == '.') {
248
+ fract = true;
249
+ e.advance();
250
+ } else {
251
+ log.error('syntax error. invalid number');
252
+ e.print_err();
253
+ process.exit(1);
254
+ }
255
+ }
256
+ } catch (e) {}
257
+ return fract ? sign * parseFloat(`${num}.${fract_num}`) : sign * num;
258
+ }
259
+
260
+ eat_hex(e) {
261
+ let str = '';
262
+ try {
263
+ if (e.peek() == '0' && e.lookahead(1) == 'x') {
264
+ e.advance();
265
+ e.advance();
266
+ }
267
+ while (!this.is_delimiter(e.peek())) {
268
+ this.eat_comments(e);
269
+ if (this.is_hex_digit(e.peek())) {
270
+ str += e.advance();
271
+ } else {
272
+ log.error('syntax error. invalid number');
273
+ e.print_err();
274
+ process.exit(1);
275
+ }
276
+ }
277
+ } catch (e) {}
278
+ return parseInt(str, 16);
279
+ }
280
+
281
+ eat_bin(e) {
282
+ let str = '';
283
+ try {
284
+ if (e.peek() == '0' && e.lookahead(1) == 'b') {
285
+ e.advance();
286
+ e.advance();
287
+ }
288
+ while (!this.is_delimiter(e.peek())) {
289
+ this.eat_comments(e);
290
+ if (this.is_bin_digit(e.peek())) {
291
+ str += e.advance();
292
+ } else {
293
+ log.error('syntax error. invalid number');
294
+ e.print_err();
295
+ process.exit(1);
296
+ }
297
+ }
298
+ } catch (e) {}
299
+ return parseInt(str, 2);
300
+ }
301
+
302
+ eat_bool(e) {
303
+ let str = '';
304
+ try {
305
+ while (!this.is_delimiter(e.peek())) {
306
+ this.eat_comments(e);
307
+ str += e.advance();
308
+ }
309
+ } catch (e) {}
310
+ return str;
311
+ }
312
+
313
+ eat_word(e) {
314
+ let str = '';
315
+ try {
316
+ while (!this.is_delimiter(e.peek())) {
317
+ this.eat_comments(e);
318
+ str += e.advance();
319
+ }
320
+ } catch (e) {}
321
+ return str;
322
+ }
323
+
324
+ eat_json(e) {
325
+ if (!this.is_json(e.peek())) {
326
+ return '{}';
327
+ }
328
+ let opening_char;
329
+ let closing_char;
330
+ if (e.peek() === '{') {
331
+ opening_char = '{';
332
+ closing_char = '}';
333
+ }
334
+ if (e.peek() === '[') {
335
+ opening_char = '[';
336
+ closing_char = ']';
337
+ }
338
+ let str = '';
339
+ let level = 0;
340
+ const instring = 0;
341
+ const json_line = e._line;
342
+ const json_col = e._col;
343
+
344
+ do {
345
+ this.eat_comments(e);
346
+ let x = e.advance();
347
+ // if(x==='"' || x==="'") instring=instring++ mod 2
348
+ if (x === '"' || x === "'") {
349
+ const closing_str = x;
350
+ let c;
351
+ let sstr = '';
352
+ while ((c = e.advance()) != closing_str) {
353
+ sstr += c;
354
+ }
355
+ x = `${closing_str}${sstr}${closing_str}`;
356
+ }
357
+ if (x === opening_char) {
358
+ level++;
359
+ }
360
+ if (x === closing_char) {
361
+ level--;
362
+ }
363
+ str += x;
364
+ } while (e.peek() !== false && level != 0 /* && x!==closing_char */);
365
+ // log.info(str);
366
+ try {
367
+ return JSON5.parse(str);
368
+ } catch (err) {
369
+ log.error(`error in json obj at line ${json_line}, col ${json_col}`);
370
+ if (e._filename) {
371
+ log.error(`in ${e._filename} file`);
372
+ }
373
+ log.error(err);
374
+ }
375
+ }
376
+
377
+ where(e) {
378
+ return { file: e._filename, line: e._line, col: e._col };
379
+ }
380
+
381
+ read(e, filename = null) {
382
+ try {
383
+ if (filename) {
384
+ e.set_filename(filename);
385
+ }
386
+ // if(this.is_whitespace(e)) {this.eat_whitespaces(e);return {"_type":"TC_NOP", "_where": this.where(e), "_datum": null}}
387
+ this.eat_whitespaces(e);
388
+ if (this.is_comment(e)) {
389
+ this.eat_comments(e);
390
+ return { _type: 'TC_NOP', _where: this.where(e), _datum: null };
391
+ }
392
+ if (this.is_eof(e.peek())) {
393
+ return false;
394
+ }
395
+ if (this.is_num(e)) {
396
+ return {
397
+ _type: 'TC_NUM',
398
+ _where: this.where(e),
399
+ _datum: this.eat_number(e),
400
+ };
401
+ }
402
+ if (this.is_string(e.peek())) {
403
+ return {
404
+ _type: 'TC_STR',
405
+ _where: this.where(e),
406
+ _datum: this.eat_string(e),
407
+ };
408
+ }
409
+ if (this.is_string_single_quote(e.peek())) {
410
+ return {
411
+ _type: 'TC_STR',
412
+ _where: this.where(e),
413
+ _datum: this.eat_string_single_quote(e),
414
+ };
415
+ }
416
+ if (this.is_json(e.peek())) {
417
+ return {
418
+ _type: 'TC_JSON',
419
+ _where: this.where(e),
420
+ _datum: this.eat_json(e),
421
+ };
422
+ }
423
+ if (this.is_bool(e)) {
424
+ return {
425
+ _type: 'TC_BOOL',
426
+ _where: this.where(e),
427
+ _datum: this.eat_bool(e),
428
+ };
429
+ }
430
+ return {
431
+ _type: 'TC_WORD',
432
+ _where: this.where(e),
433
+ _datum: this.eat_word(e),
434
+ };
435
+ } catch (e) {
436
+ return false;
437
+ }
438
+ }
439
+ }
440
+
441
+ export default new Read();