force-lang 0.0.12 → 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/eval.js CHANGED
@@ -1,308 +1,463 @@
1
- const log = require('bunny-logger');
2
- var TokenStream = require('./token-stream');
3
- const read = require('./read');
4
- const env = require('./env');
5
- //const NativeLib = require('./native_lib');
6
- const loadfile = require('./load-file');
7
- const err = require('./error');
1
+ import log from 'bunny-logger';
2
+ import TokenStream from './token-stream.js';
3
+ import read from './read.js';
4
+ import env from './env.js';
5
+ // const NativeLib = require('./native_lib');
6
+ import loadfile from './load-file.js';
7
+ import err from './error.js';
8
8
 
9
+ class Eval {
10
+ constructor() {
11
+ this.mode = 'interpret';
12
+ this.s = env.s;
13
+ this._load_lib = true;
14
+ // if(this._load_lib) this.load_lib();
15
+ }
9
16
 
10
- class Eval{
17
+ async load_lib() {
18
+ const x = await loadfile.load(`${import.meta.dirname}/lib.j`);
19
+ await this.eval(x);
20
+ }
11
21
 
12
- constructor(){
13
- this.mode = 'interpret';
14
- this.s = env.s;
15
- this._load_lib = true;
16
- //if(this._load_lib) this.load_lib();
17
- }
22
+ // deprecated ??
23
+ load_lib_sync() {
24
+ const x = loadfile.loadsync(`${import.meta.dirname}/lib.j`);
25
+ this.eval(x);
26
+ }
18
27
 
19
- async load_lib(){
20
- var x = await loadfile.load(__dirname + '/lib.j');
21
- this.eval(x);
22
- }
28
+ see_func(func_name) {
29
+ const x = env.lookup(func_name);
30
+ if (!x) {
31
+ log.info('no word found...');
32
+ return;
33
+ }
34
+ switch (x._datum._type) {
35
+ case 'TC_NATIVE_FUNC':
36
+ log.info(`: ${x._name}`);
37
+ log.info('<native func> ;');
38
+ break;
39
+ case 'TC_COMP_FUNC':
40
+ log.info(`: ${x._name}`);
41
+ process.stdout.write(` `);
42
+ for (const n of x._datum._datum) {
43
+ process.stdout.write(`${n._datum} `);
44
+ }
45
+ log.info('');
46
+ break;
47
+ default:
48
+ log.info('not a word...');
49
+ break;
50
+ }
51
+ }
23
52
 
24
- load_lib_sync(){
25
- var x = loadfile.loadsync(__dirname + '/lib.j');
26
- this.eval(x);
27
- }
53
+ set_mode(x) {
54
+ if (x === 'interpret' || x === 'compile') {
55
+ this.mode = x;
56
+ }
57
+ }
28
58
 
29
- see_func(func_name){
30
- var x=env.lookup(func_name);
31
- if(!x){
32
- log.info('no word found...');
33
- return;
34
- }
35
- switch(x._datum._type){
36
- case 'TC_NATIVE_FUNC':
37
- log.info(`: ${x._name}`);
38
- log.info('<native func> ;');
39
- break;
40
- case 'TC_COMP_FUNC':
41
- log.info(`: ${x._name}`);
42
- process.stdout.write(` `);
43
- for(var n of x._datum._datum){
44
- process.stdout.write(`${n._datum} `);
45
- }
46
- log.info('');
47
- break;
48
- default:
49
- log.info('not a word...');
50
- break;
51
- }
52
- }
59
+ where_to_str(where) {
60
+ let str = '';
61
+ if (where.file) {
62
+ str += `in ${where.file} `;
63
+ }
64
+ str += `at ${where.line},${where.col}`;
65
+ return str;
66
+ }
53
67
 
54
- set_mode(x){
55
- if(x === 'interpret' || x === 'compile'){
56
- this.mode = x;
57
- }
58
- }
68
+ eval_lambda(stream, list) {
69
+ this.mode = 'compile';
70
+ let y;
71
+ const body = [];
72
+ // var func_name = read.read(stream);
73
+ let level = 0;
74
+ const list_copy = list;
75
+ if (list) {
76
+ while ((y = list_copy.shift())) {
77
+ if (y._datum == '(') {
78
+ level++;
79
+ }
80
+ if (y._datum == ')') {
81
+ if (level == 0) {
82
+ this.mode = 'interpret';
83
+ break;
84
+ }
85
+ level--;
86
+ }
87
+ body.push(y);
88
+ }
89
+ } else {
90
+ while ((y = read.read(stream)) != false) {
91
+ if (y._datum == '(') {
92
+ level++;
93
+ }
94
+ if (y._datum == ')') {
95
+ if (level == 0) {
96
+ this.mode = 'interpret';
97
+ break;
98
+ }
99
+ level--;
100
+ }
101
+ body.push(y);
102
+ }
103
+ }
104
+ env.s.push({ _type: 'TC_LAMBDA_FUNC', _datum: body });
105
+ return list_copy;
106
+ }
59
107
 
60
- where_to_str(where){
61
- var str = '';
62
- if(where.file) str += 'in ' + where.file +' ';
63
- str += 'at ' + where.line +','+ where.col;
64
- return str;
65
- }
66
- eval_if(stream, list){
67
- //log.info('if.:.');
68
- var y;
69
- var body = [];
70
- var else_body = [];
71
- var then_body = [];
72
- var level=0;
73
- if(list){
74
- //var list_copy=JSON.parse(JSON.stringify(list));
75
- var list_copy=list;
76
- while(y=list_copy.shift()){
77
- if(y._datum=='if') {level++;}
78
- if(y._datum=='then') { if(level==0){then_body = body; break;}else{level--;}}
79
- if(y._datum=='else') { if(level==0) {else_body = body; body = []; continue;}}
80
- body.push(y);
81
- }
82
- } else {
83
- while((y=read.read(stream))!=false){
84
- if(y._datum=='if') {level++;}
85
- if(y._datum=='then') { if(level==0){then_body = body; break;}else{level--;}}
86
- if(y._datum=='else') { if(level==0) {else_body = body; body = []; continue;}}
87
- body.push(y);
88
- }
89
- }
90
- //log.info({else_body});
91
- //log.info({then_body});
92
- if(env.is_true(env.s.pop())){
93
- this.eval_parsed(then_body);
94
- } else {
95
- this.eval_parsed(else_body);
96
- }
97
- return list_copy;
98
- }
99
- eval_while(stream, list){
100
- //log.info('while.:.');
101
- var y;
102
- var body = [];
103
- var test_body = [];
104
- var while_body = [];
105
- var level=0;
106
- var list_copy=list;
107
- if(list){
108
- // //var list_copy=JSON.parse(JSON.stringify(list));
109
- // var list_copy=list;
110
- while(y=list_copy.shift()){
111
- if(y._datum=='begin') {level++;}
112
- if(y._datum=='repeat') { if(level==0){while_body = body; break;}else{level--;}}
113
- if(y._datum=='while') { if(level==0) {test_body = body; body = []; continue;}}
114
- body.push(y);
115
- }
116
- } else {
117
- while((y=read.read(stream))!=false){
118
- if(y._datum=='begin') {level++;}
119
- if(y._datum=='repeat') { if(level==0){while_body = body; break;}else{level--;}}
120
- if(y._datum=='while') { if(level==0) {test_body = body; body = []; continue;}}
121
- body.push(y);
122
- }
123
- }
124
- //log.info({test_body});
125
- //log.info({while_body});
126
- while(true){
127
- this.eval_parsed(test_body);
128
- if(!env.is_true(env.s.pop())) break;
129
- this.eval_parsed(while_body);
130
- }
131
- return list_copy;
132
- }
133
- eval_case(stream, list){
134
- //log.info('case.:.');
135
- var y;
136
- var body = [];
137
- var test_body = [];
138
- var case_body = [];
139
- var case_list = [];
140
- var level=0;
141
- var list_copy=list;
142
- if(list){
143
- while(y=list_copy.shift()){
144
- if(y._datum=='case') {level++;}
145
- if(y._datum=='endcase') { if(level==0){break;}else{level--;}}
146
- if(y._datum=='of') { if(level==0) {test_body = body; body = []; continue;}}
147
- if(y._datum=='endof') { if(level==0) {case_body = body; body = []; case_list.push({test_body, case_body});continue;}}
148
- body.push(y);
149
- }
150
- } else {
151
- while((y=read.read(stream))!=false){
152
- if(y._datum=='case') {level++;}
153
- if(y._datum=='endcase') { if(level==0){break;}else{level--;}}
154
- if(y._datum=='of') { if(level==0) {test_body = body; body = []; continue;}}
155
- if(y._datum=='endof') { if(level==0) {case_body = body; body = []; case_list.push({test_body, case_body});continue;}}
156
- body.push(y);
157
- }
158
- }
159
- //log.info({case_list});
160
- //let x = env.s.pop();
161
- for(var item of case_list){
162
- //log.info(item.test_body);
163
- this.eval_parsed(item.test_body);
164
- let y = env.s.pop();
165
- if(env.is_true(y) /*|| x._datum == y._datum*/){
166
- //log.info(item.case_body);//????
167
- this.eval_parsed(item.case_body);
168
- break;
169
- }
170
- }
171
- return list_copy;
172
- }
173
- eval_parsed_step(e){
174
- var y;
175
- if(this.mode == 'interpret'){
176
- if(e._type == 'TC_NUM') this.s.push(e);
177
- if(e._type == 'TC_STR') this.s.push(e);
178
- if(e._type == 'TC_JSON') this.s.push(e);
179
- if(e._type == 'TC_BOOL') this.s.push(e);
180
- if(e._type == 'TC_WORD'){
181
- if(y=env.lookup(e._datum)){
182
- switch(y._datum._type){
183
- case 'TC_NATIVE_FUNC':
184
- err.add_stack(e);
185
- y._datum._datum.call();
186
- err.pop_stack();
187
- break;
188
- case 'TC_COMP_FUNC':
189
- err.add_stack(e);
190
- this.eval_parsed(y._datum._datum);
191
- err.pop_stack();
192
- break;
193
- case 'TC_FUNC_JS':
194
- //this.eval_parsed(y._datum._datum);
195
- log.info('js func...');
196
- break;
197
- default:
198
- this.s.push(y);
199
- //log.error(`unknown type ${y._datum._type} for ${y._name}`);
200
- //log.error(this.where_to_str(y));
201
- break;
202
- }
203
- }else{
204
- env.s.push(err.throw(`word not found '${e._datum}' ${this.where_to_str(e._where)}`));
205
- }
206
- }
207
- if(err.require_handle(` ${e._datum} ${this.where_to_str(e._where)}`)) this.eval('handle');;
208
- }
209
- if(this.mode == 'compile'){
210
- if(e._type == 'TC_WORD'){
211
- if(e._datum == ';'){
212
- this.mode = 'interpret';
213
- return;
214
- }
215
- }
216
- }
217
- }
218
- eval_parsed(e){
219
- var item;
220
- var list_copy=JSON.parse(JSON.stringify(e));
221
- //for(var item of e){
222
- while(item=list_copy.shift()){
223
- if(item._datum == 'if'){
224
- //log.info('if.:.');
225
- list_copy=this.eval_if(null,list_copy);
226
- continue;
227
- }
228
- if(item._datum == 'begin'){
229
- list_copy=this.eval_while(null,list_copy);
230
- continue;
231
- }
232
- if(item._datum == 'case'){
233
- list_copy=this.eval_case(null,list_copy);
234
- continue;
235
- }
236
- if(item._datum == ';' || item._datum == 'exit') break;
237
- this.eval_parsed_step(item);
238
- }
239
- }
240
- eval(e, filename=null){
241
- var stream = read.tokenize(e);
242
- var x;
243
- while((x=read.read(stream, filename))!=false){
244
- //log.info(x);
245
- if(x._type == 'TC_WORD'){
246
- if(x._datum == 'var'){
247
- var newvar = read.read(stream);
248
- env.set(newvar._datum, {_type: 'TC_NUM', _datum: 0}, 'TC_VAR', newvar._where);
249
- continue;
250
- }
251
- if(x._datum == ':'){
252
- this.mode = 'compile';
253
- var y;
254
- var body = [];
255
- var func_name = read.read(stream);
256
- while((y=read.read(stream))!=false){
257
- body.push(y);
258
- if(y._datum==';') {this.mode = 'interpret'; break;}
259
- }
260
- env.set(func_name._datum, {_type: 'TC_COMP_FUNC', _datum: body}, 'TC_COMP_FUNC', func_name._where);
261
- continue;
262
- }
263
- if(x._datum == '('){
264
- this.mode = 'compile';
265
- var y;
266
- var body = [];
267
- //var func_name = read.read(stream);
268
- var level=0;
269
- while((y=read.read(stream))!=false){
270
- if(y._datum=='(') level++;
271
- if(y._datum==')') {
272
- if(level==0) {
273
- this.mode = 'interpret'; break;
274
- }
275
- level--;
276
- }
277
- body.push(y);
278
- }
279
- //env.set(func_name._datum, {_type: 'TC_LAMBDA_FUNC', _datum: body}, 'TC_LAMBDA_FUNC', func_name._where);
280
- env.s.push({_type: 'TC_LAMBDA_FUNC', _datum: body})
281
- continue;
282
- }
283
- if(x._datum == 'see'){
284
- var func_name = read.read(stream);
285
- this.see_func(func_name._datum);
286
- continue;
287
- }
288
- if(x._datum == 'if'){
289
- this.eval_if(stream);
290
- continue;
291
- }
292
- if(x._datum == 'begin'){
293
- this.eval_while(stream);
294
- continue;
295
- }
296
- if(x._datum == 'case'){
297
- this.eval_case(stream);
298
- continue;
299
- }
300
- }
301
- this.eval_parsed_step(x);
302
- }
303
- //this.s.print();
304
- //env.print_debug();
305
- }
306
- };
108
+ async eval_if(stream, list) {
109
+ // log.info('if.:.');
110
+ let y;
111
+ let body = [];
112
+ let else_body = [];
113
+ let then_body = [];
114
+ let level = 0;
115
+ if (list) {
116
+ // var list_copy=JSON.parse(JSON.stringify(list));
117
+ var list_copy = list;
118
+ while ((y = list_copy.shift())) {
119
+ if (y._datum == 'if') {
120
+ level++;
121
+ }
122
+ if (y._datum == 'then') {
123
+ if (level == 0) {
124
+ then_body = body;
125
+ break;
126
+ } else {
127
+ level--;
128
+ }
129
+ }
130
+ if (y._datum == 'else') {
131
+ if (level == 0) {
132
+ else_body = body;
133
+ body = [];
134
+ continue;
135
+ }
136
+ }
137
+ body.push(y);
138
+ }
139
+ } else {
140
+ while ((y = read.read(stream)) != false) {
141
+ if (y._datum == 'if') {
142
+ level++;
143
+ }
144
+ if (y._datum == 'then') {
145
+ if (level == 0) {
146
+ then_body = body;
147
+ break;
148
+ } else {
149
+ level--;
150
+ }
151
+ }
152
+ if (y._datum == 'else') {
153
+ if (level == 0) {
154
+ else_body = body;
155
+ body = [];
156
+ continue;
157
+ }
158
+ }
159
+ body.push(y);
160
+ }
161
+ }
162
+ // log.info({else_body});
163
+ // log.info({then_body});
164
+ if (env.is_true(env.s.pop())) {
165
+ await this.eval_parsed(then_body);
166
+ } else {
167
+ await this.eval_parsed(else_body);
168
+ }
169
+ return list_copy;
170
+ }
307
171
 
308
- module.exports = new Eval();
172
+ async eval_while(stream, list) {
173
+ // log.info('while.:.');
174
+ let y;
175
+ let body = [];
176
+ let test_body = [];
177
+ let while_body = [];
178
+ let level = 0;
179
+ const list_copy = list;
180
+ if (list) {
181
+ // //var list_copy=JSON.parse(JSON.stringify(list));
182
+ // var list_copy=list;
183
+ while ((y = list_copy.shift())) {
184
+ if (y._datum == 'begin') {
185
+ level++;
186
+ }
187
+ if (y._datum == 'repeat') {
188
+ if (level == 0) {
189
+ while_body = body;
190
+ break;
191
+ } else {
192
+ level--;
193
+ }
194
+ }
195
+ if (y._datum == 'while') {
196
+ if (level == 0) {
197
+ test_body = body;
198
+ body = [];
199
+ continue;
200
+ }
201
+ }
202
+ body.push(y);
203
+ }
204
+ } else {
205
+ while ((y = read.read(stream)) != false) {
206
+ if (y._datum == 'begin') {
207
+ level++;
208
+ }
209
+ if (y._datum == 'repeat') {
210
+ if (level == 0) {
211
+ while_body = body;
212
+ break;
213
+ } else {
214
+ level--;
215
+ }
216
+ }
217
+ if (y._datum == 'while') {
218
+ if (level == 0) {
219
+ test_body = body;
220
+ body = [];
221
+ continue;
222
+ }
223
+ }
224
+ body.push(y);
225
+ }
226
+ }
227
+ // log.info({test_body});
228
+ // log.info({while_body});
229
+ while (true) {
230
+ await this.eval_parsed(test_body);
231
+ if (!env.is_true(env.s.pop())) {
232
+ break;
233
+ }
234
+ await this.eval_parsed(while_body);
235
+ }
236
+ return list_copy;
237
+ }
238
+
239
+ async eval_case(stream, list) {
240
+ // log.info('case.:.');
241
+ let y;
242
+ let body = [];
243
+ let test_body = [];
244
+ let case_body = [];
245
+ const case_list = [];
246
+ let level = 0;
247
+ const list_copy = list;
248
+ if (list) {
249
+ while ((y = list_copy.shift())) {
250
+ if (y._datum == 'case') {
251
+ level++;
252
+ }
253
+ if (y._datum == 'endcase') {
254
+ if (level == 0) {
255
+ break;
256
+ } else {
257
+ level--;
258
+ }
259
+ }
260
+ if (y._datum == 'of') {
261
+ if (level == 0) {
262
+ test_body = body;
263
+ body = [];
264
+ continue;
265
+ }
266
+ }
267
+ if (y._datum == 'endof') {
268
+ if (level == 0) {
269
+ case_body = body;
270
+ body = [];
271
+ case_list.push({ test_body, case_body });
272
+ continue;
273
+ }
274
+ }
275
+ body.push(y);
276
+ }
277
+ } else {
278
+ while ((y = read.read(stream)) != false) {
279
+ if (y._datum == 'case') {
280
+ level++;
281
+ }
282
+ if (y._datum == 'endcase') {
283
+ if (level == 0) {
284
+ break;
285
+ } else {
286
+ level--;
287
+ }
288
+ }
289
+ if (y._datum == 'of') {
290
+ if (level == 0) {
291
+ test_body = body;
292
+ body = [];
293
+ continue;
294
+ }
295
+ }
296
+ if (y._datum == 'endof') {
297
+ if (level == 0) {
298
+ case_body = body;
299
+ body = [];
300
+ case_list.push({ test_body, case_body });
301
+ continue;
302
+ }
303
+ }
304
+ body.push(y);
305
+ }
306
+ }
307
+ // log.info({case_list});
308
+ // let x = env.s.pop();
309
+ for (const item of case_list) {
310
+ // log.info(item.test_body);
311
+ await this.eval_parsed(item.test_body);
312
+ const y = env.s.pop();
313
+ if (env.is_true(y) /* || x._datum == y._datum */) {
314
+ // log.info(item.case_body);//????
315
+ await this.eval_parsed(item.case_body);
316
+ break;
317
+ }
318
+ }
319
+ return list_copy;
320
+ }
321
+
322
+ async eval_parsed_step(e) {
323
+ let y;
324
+ if (this.mode == 'interpret') {
325
+ if (e._type == 'TC_NUM') {
326
+ this.s.push(e);
327
+ }
328
+ if (e._type == 'TC_STR') {
329
+ this.s.push(e);
330
+ }
331
+ if (e._type == 'TC_JSON') {
332
+ this.s.push(e);
333
+ }
334
+ if (e._type == 'TC_BOOL') {
335
+ this.s.push(e);
336
+ }
337
+ if (e._type == 'TC_WORD') {
338
+ if ((y = env.lookup(e._datum))) {
339
+ switch (y._datum._type) {
340
+ case 'TC_NATIVE_FUNC':
341
+ err.add_stack(e);
342
+ await y._datum._datum.call();
343
+ err.pop_stack();
344
+ break;
345
+ case 'TC_COMP_FUNC':
346
+ err.add_stack(e);
347
+ await this.eval_parsed(y._datum._datum);
348
+ err.pop_stack();
349
+ break;
350
+ case 'TC_FUNC_JS':
351
+ // await this.eval_parsed(y._datum._datum);
352
+ log.info('js func...');
353
+ break;
354
+ default:
355
+ this.s.push(y);
356
+ // log.error(`unknown type ${y._datum._type} for ${y._name}`);
357
+ // log.error(this.where_to_str(y));
358
+ break;
359
+ }
360
+ } else {
361
+ env.s.push(err.throw(`word not found '${e._datum}' ${this.where_to_str(e._where)}`));
362
+ }
363
+ }
364
+ if (err.require_handle(` ${e._datum} ${this.where_to_str(e._where)}`)) {
365
+ await this.eval('handle');
366
+ }
367
+ }
368
+ if (this.mode == 'compile') {
369
+ if (e._type == 'TC_WORD') {
370
+ if (e._datum == ';') {
371
+ this.mode = 'interpret';
372
+ }
373
+ }
374
+ }
375
+ }
376
+
377
+ async eval_parsed(e) {
378
+ let item;
379
+ let list_copy = JSON.parse(JSON.stringify(e));
380
+ // for(var item of e){
381
+ while ((item = list_copy.shift())) {
382
+ if (item._datum == '(') {
383
+ list_copy = this.eval_lambda(null, list_copy);
384
+ continue;
385
+ }
386
+ if (item._datum == 'if') {
387
+ list_copy = await this.eval_if(null, list_copy);
388
+ continue;
389
+ }
390
+ if (item._datum == 'begin') {
391
+ list_copy = await this.eval_while(null, list_copy);
392
+ continue;
393
+ }
394
+ if (item._datum == 'case') {
395
+ list_copy = await this.eval_case(null, list_copy);
396
+ continue;
397
+ }
398
+ if (item._datum == ';' || item._datum == 'exit') {
399
+ break;
400
+ }
401
+ await this.eval_parsed_step(item);
402
+ }
403
+ }
404
+
405
+ async eval(e, filename = null) {
406
+ const stream = read.tokenize(e);
407
+ let x;
408
+ while ((x = read.read(stream, filename)) != false) {
409
+ // log.info(x);
410
+ if (x._type == 'TC_NOP') {
411
+ continue;
412
+ }
413
+ if (x._type == 'TC_WORD') {
414
+ if (x._datum == 'var') {
415
+ const newvar = read.read(stream);
416
+ env.set(newvar._datum, { _type: 'TC_NUM', _datum: 0 }, 'TC_VAR', newvar._where);
417
+ continue;
418
+ }
419
+ if (x._datum == ':') {
420
+ this.mode = 'compile';
421
+ var y;
422
+ const body = [];
423
+ var func_name = read.read(stream);
424
+ while ((y = read.read(stream)) != false) {
425
+ body.push(y);
426
+ if (y._datum == ';') {
427
+ this.mode = 'interpret';
428
+ break;
429
+ }
430
+ }
431
+ env.set(func_name._datum, { _type: 'TC_COMP_FUNC', _datum: body }, 'TC_COMP_FUNC', func_name._where);
432
+ continue;
433
+ }
434
+ if (x._datum == '(') {
435
+ this.eval_lambda(stream);
436
+ continue;
437
+ }
438
+ if (x._datum == 'see') {
439
+ var func_name = read.read(stream);
440
+ this.see_func(func_name._datum);
441
+ continue;
442
+ }
443
+ if (x._datum == 'if') {
444
+ await this.eval_if(stream);
445
+ continue;
446
+ }
447
+ if (x._datum == 'begin') {
448
+ await this.eval_while(stream);
449
+ continue;
450
+ }
451
+ if (x._datum == 'case') {
452
+ await this.eval_case(stream);
453
+ continue;
454
+ }
455
+ }
456
+ await this.eval_parsed_step(x);
457
+ }
458
+ // this.s.print();
459
+ // env.print_debug();
460
+ }
461
+ }
462
+
463
+ export default new Eval();