UNPKG

2.15 kBJavaScriptView Raw
1'use strict'
2
3const {
4 TokenTypeData,
5 Expr,
6 Token,
7 WrappedPrimitive
8} = require('./lang');
9const currentLine = require('./currentLine');
10const {paths} = require('./cache');
11
12function withPathInfo(value, key, currentPath) {
13 const isArray = typeof key === 'number'
14 const newPath = `${currentPath}${isArray ? `[${key}]` : `.${key}`}`
15 if (typeof value === 'undefined') {
16 throw new Error(`Undefined value in carmi expression: ${newPath} at ${currentLine()}`)
17 }
18
19 if (value && typeof value === 'object') {
20 paths.set(value, newPath)
21 }
22
23 return value
24}
25
26function convertArrayAndObjectsToExpr(v) {
27 if (typeof v === 'undefined') {
28 throw new Error('Carmi expressions can not contain undefined');
29 }
30
31 let path
32 if (v && typeof v === 'object') {
33 v = v || 'null'
34 path = paths.get(v)
35 if (!path) {
36 path = '{}'
37 paths.set(v, path)
38 }
39 }
40
41 if (v === null) {
42 return new Token('null');
43 } else if (v.constructor === Object) {
44 return createExpr(
45 new Token('object', currentLine()),
46 ...Object.keys(v).reduce((acc, key) => {
47 acc.push(key);
48 acc.push(withPathInfo(v[key], key, path));
49 return acc;
50 }, [])
51 );
52 } else if (v.constructor === Array) {
53 return createExpr(new Token('array', currentLine()), ...v.map((entry, index) => withPathInfo(entry, index, path)));
54 } else if (typeof v === 'boolean' || typeof v === 'string' || typeof v === 'number') {
55 return new WrappedPrimitive(v);
56 }
57 return v;
58}
59
60function createExpr(...args) {
61 args = args.map(token => {
62 token = convertArrayAndObjectsToExpr(token);
63 if (token instanceof WrappedPrimitive) {
64 return token.toJSON();
65 }
66 return token;
67 });
68 if (args[0] instanceof Token && TokenTypeData[args[0].$type]) {
69 const len = TokenTypeData[args[0].$type].len;
70 if (len && (args.length < len[0] || args.length > len[1])) {
71 throw new Error(
72 `invalid length for expression ${args[0].$type} length:${args.length} expected:${len[0]}-${len[1]}`
73 );
74 }
75 }
76 return Expr.apply(null, args);
77}
78
79module.exports = {
80 convertArrayAndObjectsToExpr,
81 createExpr
82}