@makano/rew 1.2.90 → 1.2.92

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,37 @@ 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
+ wrappedFn.type = returnType;
63
+ return wrappedFn;
64
+ }
65
+ typef.is = function(func, returnType){
66
+ return typeis(func.returnType.defaultValue, returnType);
31
67
  }
32
68
 
33
69
  function typeis(obj, typeDef) {
34
70
  // Resolve Type
35
- if (typeof typeDef == 'function' && typeDef.type) typeDef = typeDef.type;
71
+ if (typeof typeDef == 'function' && typeDef.type instanceof Type) typeDef = typeDef.type;
36
72
 
37
73
  if (typeDef.isConstucted && typeDef.class && !(obj instanceof typeDef.class)) {
38
74
  return false;
@@ -112,6 +148,7 @@ module.exports = {
112
148
  typei,
113
149
  typeis,
114
150
  typedef,
151
+ typef,
115
152
 
116
153
  int,
117
154
  float,
@@ -86,6 +86,15 @@ function tokenizeCoffeeScript(code) {
86
86
  }
87
87
  tokens.push({ type: 'IDENTIFIER', value: identifier });
88
88
  i--; // Move back one character to recheck
89
+ } else if (/[a-f0-9.n]/.test(char)) {
90
+ let num = char;
91
+ i++;
92
+ while (i < code.length && /[a-f0-9.n]/.test(code[i])) {
93
+ num += code[i];
94
+ i++;
95
+ }
96
+ tokens.push({ type: 'NUMBER', value: num });
97
+ i--; // Move back one character to recheck
89
98
  } else {
90
99
  // Other characters
91
100
  tokens.push({ type: 'OTHER', value: char });
@@ -153,7 +162,7 @@ function declareAlias(aliases, token) {
153
162
  aliasValue = (token, tokens, code, hooks, index, setIndex) => {
154
163
  const nextToken = tokens[index+1]
155
164
  let nextToken2 = gnextToken(index, 3, tokens);
156
- if (nextToken.value == '(' || tokens[index+2]?.value == '(') {
165
+ if (nextToken?.value == '(' || tokens[index+2]?.value == '(') {
157
166
  let params = '';
158
167
  index += 2;
159
168
  let openBrackets = 1;
@@ -172,7 +181,7 @@ function declareAlias(aliases, token) {
172
181
  let nextToken = gnextToken(index, offset+1, tokens);
173
182
  const args = nextToken.token.value;
174
183
  setIndex(ti + offset);
175
- return `${nextToken2.value} = ${token.value} ${args && args !== '(' ? `${args},` : ''} ${params.trim()}, ${args == '(' ? args : ''}`;
184
+ return `${nextToken2.value} = ${token.value} ${args && args !== '(' && args !== '-' && args !== '=' ? `${args},` : ''} ${params.trim()}, ${args == '(' || args == '=' || args == '-' ? args : ''}`.replace(/,(| )$/, '');
176
185
  } else if(nextToken?.value == ' ' && (isDecOnly || nextToken2?.token.value == '=' || nextToken2?.token.value == ':')){
177
186
  nextToken.value = '';
178
187
  if(isDecOnly){
@@ -204,7 +213,21 @@ function declareAlias(aliases, token) {
204
213
  }
205
214
  }
206
215
 
207
-
216
+ const stdTypes = (isPublic) => {
217
+ let r = '';
218
+ const dec = (name, fn) => {
219
+ r += `#declare${isPublic?'*':''} key "=${name}" = ${fn || name};\n`
220
+ }
221
+ dec('int');
222
+ dec('str');
223
+ dec('float');
224
+ dec('num');
225
+ dec('bool');
226
+ dec('typedef');
227
+ dec('typef');
228
+ dec('struct');
229
+ return r;
230
+ };
208
231
  const includeFile = (includeContent, options) => {
209
232
  straceLog('INCLUDE()', includeContent);
210
233
  const dontInclude = includeContent.startsWith('*');
@@ -212,27 +235,36 @@ const includeFile = (includeContent, options) => {
212
235
  includeContent = includeContent.slice(1);
213
236
  straceLog('==> IGNORING OUTPUT', includeContent);
214
237
  };
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';
238
+ const fp = path.resolve(path.dirname(options.filename || ''), includeContent);
239
+ let packageName = options.filename ? (existsSync(fp) ? fp : includeContent) : includeContent;
240
+ const file = packageName.startsWith('./') || packageName.startsWith('../');
241
+ if(!(file) && packageName.match('/')) packageName = packageName.split('/').pop();
242
+ if(file) packageName = path.extname(packageName) ? packageName.replace(path.extname(packageName), '.h.coffee') : packageName;
243
+ if(file && !packageName.endsWith('.h.coffee')) packageName += '.h.coffee';
244
+ if(includeContent == 'std') packageName = 'std';
245
+
246
+ const _inc = (filename, c) => {
247
+ options.included = true;
248
+ options.filename = filename;
249
+ return '\n'+ compileRewStuff(c ? filename : readFileSync(filename).toString(), options)+'\n'
250
+ };
221
251
  let r = '';
222
- if (existsSync(filename)) {
223
- straceLog('==> INCLUDE FILE', filename);
224
- r = _inc(filename);
252
+ if(packageName == 'std'){
253
+ r = _inc(stdTypes(dontInclude), true);
254
+ } else if (existsSync(packageName)) {
255
+ straceLog('==> INCLUDE FILE', packageName);
256
+ r = _inc(packageName);
225
257
  } else {
226
258
  const packageName = includeContent.match('/') ? includeContent.split('/')[0] : includeContent;
227
259
  const headerFile = includeContent.match('/') ? includeContent.replace(packageName+'/', '') : 'main.h.coffee';
228
260
  const pathname = path.join(CONFIG_PATH, packageName, 'app', headerFile);
229
- straceLog('==> INCLUDE PACKAGE', filename);
261
+ straceLog('==> INCLUDE PACKAGE', packageName);
230
262
  if(existsSync(pathname)) r = _inc(pathname);
231
263
  }
232
- if(!dontInclude){
233
- return r;
264
+ if(dontInclude){
265
+ return 'intentional-nothing';
234
266
  }
235
- return "";
267
+ return r;
236
268
  }
237
269
 
238
270
  function useImp(token, options){
@@ -245,16 +277,22 @@ function useImp(token, options){
245
277
  const value = token.value.slice(1, -1);
246
278
  let packageName = value.slice(1);
247
279
  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
280
  straceLog('IMP() with HEADER for', packageName);
253
281
  return includeFile(packageName, options);
254
282
  }
255
283
  return '';
256
284
  }
257
285
 
286
+ function updateAliases(aliases, o = execOptions._syntaxAliases){
287
+ for(let h in o){
288
+ for(let i in o[h]){
289
+ if(!aliases[h]) aliases[h] = {};
290
+ aliases[h][i] = o[h][i]
291
+ }
292
+ }
293
+ return aliases;
294
+ }
295
+
258
296
  function compileRewStuff(content, options) {
259
297
  straceLog('TOKENIZE() for CURRENTFILE');
260
298
  const tokens = tokenizeCoffeeScript(content);
@@ -309,28 +347,6 @@ function compileRewStuff(content, options) {
309
347
  }
310
348
  }
311
349
 
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
350
  if (token.type === 'COMMENT' && token.value.slice(1).trim().startsWith('@jsx')) {
335
351
  options.jsx = true;
336
352
  straceLog('JSX() ENABLE WITH COMMENTS');
@@ -390,6 +406,7 @@ function compileRewStuff(content, options) {
390
406
  if (nextToken.type === 'STRING') {
391
407
  straceLog('==> SIMPLE');
392
408
  result += `inc ${nextToken.value}`;
409
+ if(useImp(nameToken, options)) updateAliases(aliases);
393
410
  i += n;
394
411
  } else if (nextToken.value === '{') {
395
412
  const closingBraceToken = fnextToken(ind, tokens, 'OTHER', '}');
@@ -405,6 +422,7 @@ function compileRewStuff(content, options) {
405
422
 
406
423
  straceLog('==>', exports, 'from', nameToken.value);
407
424
 
425
+ if(useImp(nameToken, options)) updateAliases(aliases);
408
426
  result += `{ ${exports} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken.value}`;
409
427
  i = nameToken.ti;
410
428
  }
@@ -415,6 +433,7 @@ function compileRewStuff(content, options) {
415
433
  const nextToken = fnextToken(asToken.ti + 1, tokens, 'IDENTIFIER');
416
434
  defaultName = nextToken.value;
417
435
  straceLog('==>', defaultName, 'from', nameToken.value);
436
+ if(useImp(nameToken, options)) updateAliases(aliases);
418
437
  result += `${defaultName} ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken.value}`;
419
438
  i = ind + 6;
420
439
  }
@@ -433,10 +452,12 @@ function compileRewStuff(content, options) {
433
452
  .filter((t, i, arr) => !arr[i+1]?.match(':') && !arr[i-1]?.match(':'))
434
453
  .join(', ');
435
454
  straceLog('==>', defaultName, 'and', exports, 'from', nameToken.value);
455
+ if(useImp(nameToken, options)) updateAliases(aliases);
436
456
  result += `{ default: ${defaultName}, ${exports} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken?.value || ''}`;
437
457
  i = closingBraceToken.ti + 4;
438
458
  }
439
459
  } else {
460
+ if(useImp(nameToken || {}, options)) updateAliases(aliases);
440
461
  result += `{ default: ${defaultName} } ${options.type == 'coffee' ? '=' : ':='} inc ${nameToken?.value || ''}`;
441
462
  i = ind + 2;
442
463
  }
@@ -464,6 +485,25 @@ function compileRewStuff(content, options) {
464
485
  continue;
465
486
  }
466
487
 
488
+ if (token.type === 'IDENTIFIER' && (token.value === 'imp' || token.value === 'inc')) {
489
+ straceLog('IMP() Detected');
490
+ let { token: t1 } = gnextToken(i, 1, tokens) || {};
491
+ let { token: t2 } = gnextToken(i, 2, tokens) || {};
492
+ let r = '';
493
+
494
+ if(t1?.value == '('){
495
+ if(t2?.type == 'STRING'){
496
+ r = useImp(t2, options);
497
+ }
498
+ } else if(t1?.type == 'STRING'){
499
+ r = useImp(t1, options);
500
+ }
501
+
502
+ if(r) {
503
+ updateAliases(aliases);
504
+ }
505
+ }
506
+
467
507
  if (
468
508
  token.type === 'IDENTIFIER' &&
469
509
  token.value === 'pub' &&
@@ -516,16 +556,18 @@ function compileRewStuff(content, options) {
516
556
 
517
557
  if (token.type === "COMMENT" && token.value.startsWith('#include')) {
518
558
  const includeContent = token.value.split(' ')[1].trim() || '';
519
- const r = includeFile(includeContent, options);
559
+ const _o = {...options};
560
+ const r = includeFile(includeContent, _o);
520
561
  if(r){
521
- result += r;
522
- aliases = {
523
- ...aliases,
524
- ...execOptions._syntaxAliases
525
- }
562
+ result += r == 'intentional-nothing' ? '' : r;
563
+ updateAliases(aliases, _o.aliases);
526
564
  }
527
565
  }
528
566
  }
567
+
568
+ if(options.included){
569
+ options.aliases = aliases;
570
+ }
529
571
  // console.log(aliases);
530
572
  // console.log(result);
531
573
  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.92",
4
4
  "description": "A simple coffescript runtime and app manager",
5
5
  "main": "main.js",
6
6
  "directories": {