@makano/rew 1.2.90 → 1.2.91

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,7 +5,7 @@ const future = require('../functions/future');
5
5
  const sleep = require('../functions/sleep');
6
6
  const { match } = require('../functions/match');
7
7
  const { map } = require('../functions/map');
8
- const { typex, typeis, typedef, typei, int, float, num, str, bool } = require('../functions/types');
8
+ const { typex, typeis, typedef, typei, int, float, num, str, bool, typef } = require('../functions/types');
9
9
  const { isEmpty, clone, deepClone, merge, uniqueId, compose, curry, getters, setters } = require('../functions/core');
10
10
  const { print, input, clear, printf } = require('../functions/stdout');
11
11
  const { curl } = require('../functions/curl');
@@ -31,6 +31,7 @@ module.exports = {
31
31
  typei,
32
32
  typeis,
33
33
  typedef,
34
+ typef,
34
35
 
35
36
  int,
36
37
  float,
@@ -14,8 +14,19 @@ function getType(value) {
14
14
  return typeof value === 'object' ? (Array.isArray(value) ? 'array' : typeof value) : typeof value;
15
15
  }
16
16
 
17
+ class Type{
18
+ constructor(o){
19
+ for(let i in o){
20
+ this[i] = o[i];
21
+ }
22
+ }
23
+ }
24
+
17
25
  function typedef(value, strict = false) {
18
- return {
26
+ if(typeof value == "function" && value.type instanceof Type){
27
+ value = value.type;
28
+ }
29
+ return value instanceof Type ? value : new Type({
19
30
  strict,
20
31
  defaultValue: value,
21
32
  class:
@@ -27,12 +38,36 @@ function typedef(value, strict = false) {
27
38
  type: getType(value),
28
39
  isConstucted: typeof value === 'object' && value !== null && !Array.isArray(value),
29
40
  isEmpty: typeof value == 'object' ? !Object.keys(value).length : typeof value == 'string' ? value == '' : typeof value !== 'function',
30
- };
41
+ });
42
+ }
43
+
44
+ function typef(fn, returnType) {
45
+ if(typeof returnType == "function"){
46
+ const ref = fn;
47
+ fn = returnType;
48
+ returnType = ref;
49
+ }
50
+ if (typeof fn !== 'function') {
51
+ throw new Error('First argument must be a function');
52
+ }
53
+ if (typeof returnType == 'function' && returnType.type instanceof Type) returnType = returnType.type;
54
+ const wrappedFn = function(...args){
55
+ const result = fn.call(this, ...args);
56
+ if(!typeis(result, wrappedFn.returnType)){
57
+ throw new TypeError(`Function ${fn.name || '<anonymous>'} does not return it's own return type.`);
58
+ }
59
+ return result;
60
+ }
61
+ wrappedFn.returnType = returnType;
62
+ return wrappedFn;
63
+ }
64
+ typef.is = function(func, returnType){
65
+ return typeis(func.returnType.defaultValue, returnType);
31
66
  }
32
67
 
33
68
  function typeis(obj, typeDef) {
34
69
  // Resolve Type
35
- if (typeof typeDef == 'function' && typeDef.type) typeDef = typeDef.type;
70
+ if (typeof typeDef == 'function' && typeDef.type instanceof Type) typeDef = typeDef.type;
36
71
 
37
72
  if (typeDef.isConstucted && typeDef.class && !(obj instanceof typeDef.class)) {
38
73
  return false;
@@ -112,6 +147,7 @@ module.exports = {
112
147
  typei,
113
148
  typeis,
114
149
  typedef,
150
+ typef,
115
151
 
116
152
  int,
117
153
  float,
@@ -153,7 +153,7 @@ function declareAlias(aliases, token) {
153
153
  aliasValue = (token, tokens, code, hooks, index, setIndex) => {
154
154
  const nextToken = tokens[index+1]
155
155
  let nextToken2 = gnextToken(index, 3, tokens);
156
- if (nextToken.value == '(' || tokens[index+2]?.value == '(') {
156
+ if (nextToken?.value == '(' || tokens[index+2]?.value == '(') {
157
157
  let params = '';
158
158
  index += 2;
159
159
  let openBrackets = 1;
@@ -204,7 +204,21 @@ function declareAlias(aliases, token) {
204
204
  }
205
205
  }
206
206
 
207
-
207
+ const stdTypes = (isPublic) => {
208
+ let r = '';
209
+ const dec = (name, fn) => {
210
+ r += `#declare${isPublic?'*':''} key "=${name}" = ${fn || name};\n`
211
+ }
212
+ dec('int');
213
+ dec('str');
214
+ dec('float');
215
+ dec('num');
216
+ dec('bool');
217
+ dec('typedef');
218
+ dec('typef');
219
+ dec('struct');
220
+ return r;
221
+ };
208
222
  const includeFile = (includeContent, options) => {
209
223
  straceLog('INCLUDE()', includeContent);
210
224
  const dontInclude = includeContent.startsWith('*');
@@ -212,27 +226,36 @@ const includeFile = (includeContent, options) => {
212
226
  includeContent = includeContent.slice(1);
213
227
  straceLog('==> IGNORING OUTPUT', includeContent);
214
228
  };
215
- let filename = options.filename ? path.resolve(path.dirname(options.filename), includeContent) : includeContent;
216
- const _inc = (filename) => '\n'+ compileRewStuff(readFileSync(filename).toString(), {
217
- ...options,
218
- filename,
219
- included: true
220
- })+'\n';
229
+ const fp = path.resolve(path.dirname(options.filename || ''), includeContent);
230
+ let packageName = options.filename ? (existsSync(fp) ? fp : includeContent) : includeContent;
231
+ const file = packageName.startsWith('./') || packageName.startsWith('../');
232
+ if(!(file) && packageName.match('/')) packageName = packageName.split('/').pop();
233
+ if(file) packageName = path.extname(packageName) ? packageName.replace(path.extname(packageName), '.h.coffee') : packageName;
234
+ if(file && !packageName.endsWith('.h.coffee')) packageName += '.h.coffee';
235
+ if(includeContent == 'std') packageName = 'std';
236
+
237
+ const _inc = (filename, c) => {
238
+ options.included = true;
239
+ options.filename = filename;
240
+ return '\n'+ compileRewStuff(c ? filename : readFileSync(filename).toString(), options)+'\n'
241
+ };
221
242
  let r = '';
222
- if (existsSync(filename)) {
223
- straceLog('==> INCLUDE FILE', filename);
224
- r = _inc(filename);
243
+ if(packageName == 'std'){
244
+ r = _inc(stdTypes(dontInclude), true);
245
+ } else if (existsSync(packageName)) {
246
+ straceLog('==> INCLUDE FILE', packageName);
247
+ r = _inc(packageName);
225
248
  } else {
226
249
  const packageName = includeContent.match('/') ? includeContent.split('/')[0] : includeContent;
227
250
  const headerFile = includeContent.match('/') ? includeContent.replace(packageName+'/', '') : 'main.h.coffee';
228
251
  const pathname = path.join(CONFIG_PATH, packageName, 'app', headerFile);
229
- straceLog('==> INCLUDE PACKAGE', filename);
252
+ straceLog('==> INCLUDE PACKAGE', packageName);
230
253
  if(existsSync(pathname)) r = _inc(pathname);
231
254
  }
232
- if(!dontInclude){
233
- return r;
255
+ if(dontInclude){
256
+ return 'intentional-nothing';
234
257
  }
235
- return "";
258
+ return r;
236
259
  }
237
260
 
238
261
  function useImp(token, options){
@@ -245,16 +268,22 @@ function useImp(token, options){
245
268
  const value = token.value.slice(1, -1);
246
269
  let packageName = value.slice(1);
247
270
  token.value = dem+packageName+dem;
248
- const file = packageName.startsWith('./') || packageName.startsWith('../');
249
- if(!(file) && packageName.match('/')) packageName = packageName.split('/').pop();
250
- if(file) packageName = path.extname(packageName) ? packageName.replace(path.extname(packageName), '.h.coffee') : packageName;
251
- if(file && !packageName.endsWith('.h.coffee')) packageName += '.h.coffee';
252
271
  straceLog('IMP() with HEADER for', packageName);
253
272
  return includeFile(packageName, options);
254
273
  }
255
274
  return '';
256
275
  }
257
276
 
277
+ function updateAliases(aliases, o = execOptions._syntaxAliases){
278
+ for(let h in o){
279
+ for(let i in o[h]){
280
+ if(!aliases[h]) aliases[h] = {};
281
+ aliases[h][i] = o[h][i]
282
+ }
283
+ }
284
+ return aliases;
285
+ }
286
+
258
287
  function compileRewStuff(content, options) {
259
288
  straceLog('TOKENIZE() for CURRENTFILE');
260
289
  const tokens = tokenizeCoffeeScript(content);
@@ -309,28 +338,6 @@ function compileRewStuff(content, options) {
309
338
  }
310
339
  }
311
340
 
312
- if (token.type === 'IDENTIFIER' && token.value === 'imp') {
313
- straceLog('IMP() Detected');
314
- let { token: t1 } = gnextToken(i, 1, tokens) || {};
315
- let { token: t2 } = gnextToken(i, 2, tokens) || {};
316
- let r = '';
317
-
318
- if(t1.value == '('){
319
- if(t2.type == 'STRING'){
320
- r = useImp(t2, options);
321
- }
322
- } else if(t1.type == 'STRING'){
323
- r = useImp(t1, options);
324
- }
325
-
326
- if(r) {
327
- aliases = {
328
- ...aliases,
329
- ...execOptions._syntaxAliases
330
- }
331
- }
332
- }
333
-
334
341
  if (token.type === 'COMMENT' && token.value.slice(1).trim().startsWith('@jsx')) {
335
342
  options.jsx = true;
336
343
  straceLog('JSX() ENABLE WITH COMMENTS');
@@ -390,6 +397,7 @@ function compileRewStuff(content, options) {
390
397
  if (nextToken.type === 'STRING') {
391
398
  straceLog('==> SIMPLE');
392
399
  result += `inc ${nextToken.value}`;
400
+ if(useImp(nameToken, options)) updateAliases(aliases);
393
401
  i += n;
394
402
  } else if (nextToken.value === '{') {
395
403
  const closingBraceToken = fnextToken(ind, tokens, 'OTHER', '}');
@@ -405,6 +413,7 @@ function compileRewStuff(content, options) {
405
413
 
406
414
  straceLog('==>', exports, 'from', nameToken.value);
407
415
 
416
+ if(useImp(nameToken, options)) updateAliases(aliases);
408
417
  result += `{ ${exports} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken.value}`;
409
418
  i = nameToken.ti;
410
419
  }
@@ -415,6 +424,7 @@ function compileRewStuff(content, options) {
415
424
  const nextToken = fnextToken(asToken.ti + 1, tokens, 'IDENTIFIER');
416
425
  defaultName = nextToken.value;
417
426
  straceLog('==>', defaultName, 'from', nameToken.value);
427
+ if(useImp(nameToken, options)) updateAliases(aliases);
418
428
  result += `${defaultName} ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken.value}`;
419
429
  i = ind + 6;
420
430
  }
@@ -433,10 +443,12 @@ function compileRewStuff(content, options) {
433
443
  .filter((t, i, arr) => !arr[i+1]?.match(':') && !arr[i-1]?.match(':'))
434
444
  .join(', ');
435
445
  straceLog('==>', defaultName, 'and', exports, 'from', nameToken.value);
446
+ if(useImp(nameToken, options)) updateAliases(aliases);
436
447
  result += `{ default: ${defaultName}, ${exports} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken?.value || ''}`;
437
448
  i = closingBraceToken.ti + 4;
438
449
  }
439
450
  } else {
451
+ if(useImp(nameToken || {}, options)) updateAliases(aliases);
440
452
  result += `{ default: ${defaultName} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken?.value || ''}`;
441
453
  i = ind + 2;
442
454
  }
@@ -464,6 +476,25 @@ function compileRewStuff(content, options) {
464
476
  continue;
465
477
  }
466
478
 
479
+ if (token.type === 'IDENTIFIER' && (token.value === 'imp' || token.value === 'inc')) {
480
+ straceLog('IMP() Detected');
481
+ let { token: t1 } = gnextToken(i, 1, tokens) || {};
482
+ let { token: t2 } = gnextToken(i, 2, tokens) || {};
483
+ let r = '';
484
+
485
+ if(t1?.value == '('){
486
+ if(t2?.type == 'STRING'){
487
+ r = useImp(t2, options);
488
+ }
489
+ } else if(t1?.type == 'STRING'){
490
+ r = useImp(t1, options);
491
+ }
492
+
493
+ if(r) {
494
+ updateAliases(aliases);
495
+ }
496
+ }
497
+
467
498
  if (
468
499
  token.type === 'IDENTIFIER' &&
469
500
  token.value === 'pub' &&
@@ -516,16 +547,18 @@ function compileRewStuff(content, options) {
516
547
 
517
548
  if (token.type === "COMMENT" && token.value.startsWith('#include')) {
518
549
  const includeContent = token.value.split(' ')[1].trim() || '';
519
- const r = includeFile(includeContent, options);
550
+ const _o = {...options};
551
+ const r = includeFile(includeContent, _o);
520
552
  if(r){
521
- result += r;
522
- aliases = {
523
- ...aliases,
524
- ...execOptions._syntaxAliases
525
- }
553
+ result += r == 'intentional-nothing' ? '' : r;
554
+ updateAliases(aliases, _o.aliases);
526
555
  }
527
556
  }
528
557
  }
558
+
559
+ if(options.included){
560
+ options.aliases = aliases;
561
+ }
529
562
  // console.log(aliases);
530
563
  // console.log(result);
531
564
  return result;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makano/rew",
3
- "version": "1.2.90",
3
+ "version": "1.2.91",
4
4
  "description": "A simple coffescript runtime and app manager",
5
5
  "main": "main.js",
6
6
  "directories": {