Browse Source

Prettier

master
Dylan Baker 4 years ago
parent
commit
3b6525e29f
3 changed files with 123 additions and 117 deletions
  1. 36
    32
      src/compiler.js
  2. 48
    48
      src/lexer.js
  3. 39
    37
      src/parser.js

+ 36
- 32
src/compiler.js View File

@@ -1,66 +1,70 @@
1
-const selfClosingTags = require('./util/selfClosingTags')
1
+const selfClosingTags = require("./util/selfClosingTags");
2 2
 
3 3
 module.exports = class Compiler {
4 4
   constructor(tree, context) {
5
-    this.tree = tree
6
-    this.context = context
7
-    this.pos = 0
8
-    this.result = ''
5
+    this.tree = tree;
6
+    this.context = context;
7
+    this.pos = 0;
8
+    this.result = "";
9 9
   }
10 10
 
11 11
   compile() {
12 12
     this.tree.forEach(node => {
13 13
       switch (node.constructor.name) {
14
-        case 'Application':
15
-          this.result += this.application(node)
14
+        case "Application":
15
+          this.result += this.application(node);
16 16
           break;
17
-        case 'Identifier':
18
-          this.result += this.lookup(node)
17
+        case "Identifier":
18
+          this.result += this.lookup(node);
19 19
           break;
20
-        case 'String':
20
+        case "String":
21 21
           this.result += node.value;
22 22
           break;
23 23
       }
24
-    })
24
+    });
25 25
 
26
-    return this.result
26
+    return this.result;
27 27
   }
28 28
 
29 29
   application(node) {
30
-    let result = `<${node.functionName.name}`
30
+    let result = `<${node.functionName.name}`;
31 31
 
32
-    node.args.filter(arg => arg.constructor.name === 'Attribute').forEach(arg => {
33
-      result += ` ${arg.name}`
32
+    node.args
33
+      .filter(arg => arg.constructor.name === "Attribute")
34
+      .forEach(arg => {
35
+        result += ` ${arg.name}`;
34 36
 
35
-      let compiler = new Compiler([arg.value], this.context)
36
-      let attrValue = compiler.compile()
37
+        let compiler = new Compiler([arg.value], this.context);
38
+        let attrValue = compiler.compile();
37 39
 
38
-      if (attrValue) {
39
-       result += `="${attrValue}"`
40
-      }
41
-    })
40
+        if (attrValue) {
41
+          result += `="${attrValue}"`;
42
+        }
43
+      });
42 44
 
43
-    result += '>'
45
+    result += ">";
44 46
 
45
-    node.args.filter(arg => arg.constructor.name !== 'Attribute').forEach(arg => {
46
-      let compiler = new Compiler([arg], this.context)
47
-      result += compiler.compile()
48
-    })
47
+    node.args
48
+      .filter(arg => arg.constructor.name !== "Attribute")
49
+      .forEach(arg => {
50
+        let compiler = new Compiler([arg], this.context);
51
+        result += compiler.compile();
52
+      });
49 53
 
50 54
     if (!selfClosingTags.includes(node.functionName.name)) {
51
-      result += `</${node.functionName.name}>`
55
+      result += `</${node.functionName.name}>`;
52 56
     }
53 57
 
54
-    return result
58
+    return result;
55 59
   }
56 60
 
57 61
   lookup(identifier) {
58
-    let result = this.context[identifier.name]
62
+    let result = this.context[identifier.name];
59 63
 
60 64
     if (!result) {
61
-      throw `Undefined variable '${identifier.name}'`
65
+      throw `Undefined variable '${identifier.name}'`;
62 66
     }
63 67
 
64
-    return result
68
+    return result;
65 69
   }
66
-}
70
+};

+ 48
- 48
src/lexer.js View File

@@ -1,104 +1,104 @@
1
-const TokenStream = require('./tokenStream')
2
-const tokenTypes = require('./tokenTypes')
1
+const TokenStream = require("./tokenStream");
2
+const tokenTypes = require("./tokenTypes");
3 3
 
4 4
 module.exports = class Lexer {
5 5
   scan(source) {
6
-    let pos = 0
7
-    let line = 1
8
-    let tokenStream = new TokenStream()
9
-    let allowSpecialCharactersInLiterals = false
6
+    let pos = 0;
7
+    let line = 1;
8
+    let tokenStream = new TokenStream();
9
+    let allowSpecialCharactersInLiterals = false;
10 10
 
11 11
     while (pos < source.length) {
12 12
       if (source[pos].match(/\(/) && !allowSpecialCharactersInLiterals) {
13 13
         tokenStream.tokens.push({
14 14
           type: tokenTypes.OPAREN,
15
-          line: line,
16
-        })
17
-        pos++
15
+          line: line
16
+        });
17
+        pos++;
18 18
       } else if (source[pos].match(/\)/)) {
19 19
         tokenStream.tokens.push({
20 20
           type: tokenTypes.CPAREN,
21
-          line: line,
22
-        })
23
-        pos++
21
+          line: line
22
+        });
23
+        pos++;
24 24
       } else if (source[pos].match(/["]/)) {
25
-        allowSpecialCharactersInLiterals = !allowSpecialCharactersInLiterals
25
+        allowSpecialCharactersInLiterals = !allowSpecialCharactersInLiterals;
26 26
         tokenStream.tokens.push({
27 27
           type: tokenTypes.QUOTE,
28
-          line: line,
29
-        })
30
-        pos++
28
+          line: line
29
+        });
30
+        pos++;
31 31
       } else if (source[pos].match(/:/)) {
32
-        let value = /:([^()'"\s]+)/.exec(source.slice(pos))[1].trim()
32
+        let value = /:([^()'"\s]+)/.exec(source.slice(pos))[1].trim();
33 33
         tokenStream.tokens.push({
34 34
           type: tokenTypes.ATTRIBUTE,
35 35
           line: line,
36
-          value: value,
37
-        })
38
-        pos += value.length + 1 // the +1 is to account for the colon
36
+          value: value
37
+        });
38
+        pos += value.length + 1; // the +1 is to account for the colon
39 39
       } else if (source[pos].match(/\'/)) {
40
-        let value = /'([^()"\s]+)/.exec(source.slice(pos))[1].trim()
40
+        let value = /'([^()"\s]+)/.exec(source.slice(pos))[1].trim();
41 41
         tokenStream.tokens.push({
42 42
           type: tokenTypes.SYMBOL,
43 43
           line: line,
44
-          value: value,
45
-        })
46
-        pos += value.length + 1 // the +1 is to account for the apostrophe
44
+          value: value
45
+        });
46
+        pos += value.length + 1; // the +1 is to account for the apostrophe
47 47
       } else if (source[pos].match(/\d/)) {
48
-        let number = ''
48
+        let number = "";
49 49
         while (source[pos] && source[pos].match(/\d/)) {
50
-          number += source[pos]
51
-          pos++
50
+          number += source[pos];
51
+          pos++;
52 52
         }
53 53
         tokenStream.tokens.push({
54 54
           type: tokenTypes.NUMBER,
55 55
           line: line,
56
-          value: parseFloat(number),
57
-        })
56
+          value: parseFloat(number)
57
+        });
58 58
       } else if (source.slice(pos).match(/^#(t|f)/)) {
59
-        pos++
59
+        pos++;
60 60
         tokenStream.tokens.push({
61 61
           type: tokenTypes.BOOLEAN,
62 62
           line: line,
63
-          value: source[pos] === 't' ? true : false
64
-        })
65
-        pos++
63
+          value: source[pos] === "t" ? true : false
64
+        });
65
+        pos++;
66 66
       } else if (source[pos].match(/\n/)) {
67
-        line++
68
-        pos++
67
+        line++;
68
+        pos++;
69 69
       } else if (source[pos].match(/\s/)) {
70
-        pos++
70
+        pos++;
71 71
       } else {
72
-        let endPattern = /[^()"':\s]+/
72
+        let endPattern = /[^()"':\s]+/;
73 73
 
74 74
         if (allowSpecialCharactersInLiterals) {
75
-          endPattern = /[^"']+/
75
+          endPattern = /[^"']+/;
76 76
         }
77 77
 
78
-        let value = endPattern.exec(source.slice(pos))[0].trim()
78
+        let value = endPattern.exec(source.slice(pos))[0].trim();
79 79
 
80 80
         if (allowSpecialCharactersInLiterals) {
81 81
           tokenStream.tokens.push({
82 82
             type: tokenTypes.LITERAL,
83 83
             line: line,
84
-            value: value,
85
-          })
84
+            value: value
85
+          });
86 86
         } else {
87 87
           tokenStream.tokens.push({
88 88
             type: tokenTypes.IDENTIFIER,
89 89
             line: line,
90
-            value: value.trim(),
91
-          })
90
+            value: value.trim()
91
+          });
92 92
         }
93 93
 
94
-        pos += value.length
94
+        pos += value.length;
95 95
       }
96 96
     }
97 97
 
98 98
     tokenStream.tokens.push({
99 99
       type: tokenTypes.EOF,
100
-      line: line,
101
-    })
102
-    return tokenStream
100
+      line: line
101
+    });
102
+    return tokenStream;
103 103
   }
104
-}
104
+};

+ 39
- 37
src/parser.js View File

@@ -1,113 +1,115 @@
1
-const Error = require('./Error')
1
+const Error = require("./Error");
2 2
 
3
-const AST = require('./ast')
3
+const AST = require("./ast");
4 4
 
5
-const tokenTypes = require('./tokenTypes')
5
+const tokenTypes = require("./tokenTypes");
6 6
 
7 7
 module.exports = class Parser {
8 8
   constructor(tokenStream) {
9
-    this.tokenStream = tokenStream
9
+    this.tokenStream = tokenStream;
10 10
   }
11 11
 
12 12
   parse() {
13
-    let tree = []
13
+    let tree = [];
14 14
     while (this.tokenStream.peek().type !== tokenTypes.EOF) {
15
-      tree.push(this.expr())
15
+      tree.push(this.expr());
16 16
       if (this.tokenStream.error) {
17 17
         return {
18
-          error: this.tokenStream.error,
19
-        }
18
+          error: this.tokenStream.error
19
+        };
20 20
       }
21 21
     }
22
-    return tree
22
+    return tree;
23 23
   }
24 24
 
25 25
   expr() {
26
-    let token = this.tokenStream.peek()
26
+    let token = this.tokenStream.peek();
27 27
     switch (token.type) {
28 28
       case tokenTypes.ATTRIBUTE:
29
-        return this.attribute()
29
+        return this.attribute();
30 30
       case tokenTypes.BOOLEAN:
31
-        return this.bool()
31
+        return this.bool();
32 32
       case tokenTypes.IDENTIFIER:
33
-        return this.identifier()
33
+        return this.identifier();
34 34
       case tokenTypes.NUMBER:
35
-        return this.number()
35
+        return this.number();
36 36
       case tokenTypes.QUOTE:
37
-        return this.string()
37
+        return this.string();
38 38
       case tokenTypes.SYMBOL:
39
-        return this.symbol()
39
+        return this.symbol();
40 40
       case tokenTypes.OPAREN:
41
-        return this.form()
41
+        return this.form();
42 42
       default:
43
-        this.tokenStream.error = `Unexpected ${token.type} on line ${token.line}`
43
+        this.tokenStream.error = `Unexpected ${token.type} on line ${
44
+          token.line
45
+        }`;
44 46
         break;
45 47
     }
46 48
   }
47 49
 
48 50
   form() {
49
-    this.tokenStream.eat(tokenTypes.OPAREN)
51
+    this.tokenStream.eat(tokenTypes.OPAREN);
50 52
 
51
-    let node = new AST.Application()
53
+    let node = new AST.Application();
52 54
 
53
-    node.functionName = this.identifier()
54
-    node.args = []
55
+    node.functionName = this.identifier();
56
+    node.args = [];
55 57
 
56 58
     while (this.tokenStream.peek().type !== tokenTypes.CPAREN) {
57
-      node.args.push(this.expr())
59
+      node.args.push(this.expr());
58 60
     }
59 61
 
60
-    this.tokenStream.eat(tokenTypes.CPAREN)
62
+    this.tokenStream.eat(tokenTypes.CPAREN);
61 63
 
62
-    return node
64
+    return node;
63 65
   }
64 66
 
65 67
   attribute() {
66 68
     return new AST.Attribute({
67 69
       name: this.tokenStream.eat(tokenTypes.ATTRIBUTE).value,
68 70
       value: this.expr()
69
-    })
71
+    });
70 72
   }
71 73
 
72 74
   bool() {
73 75
     return new AST.Boolean({
74 76
       value: this.tokenStream.eat(tokenTypes.BOOLEAN).value
75
-    })
77
+    });
76 78
   }
77 79
 
78 80
   identifier() {
79 81
     return new AST.Identifier({
80 82
       name: this.tokenStream.eat(tokenTypes.IDENTIFIER).value
81
-    })
83
+    });
82 84
   }
83 85
 
84 86
   number() {
85 87
     return new AST.Number({
86 88
       value: this.tokenStream.eat(tokenTypes.NUMBER).value
87
-    })
89
+    });
88 90
   }
89 91
 
90 92
   string() {
91
-    this.tokenStream.eat(tokenTypes.QUOTE)
93
+    this.tokenStream.eat(tokenTypes.QUOTE);
92 94
 
93
-    let value = ''
95
+    let value = "";
94 96
 
95 97
     if (this.tokenStream.peek().type === tokenTypes.LITERAL) {
96
-      value = this.tokenStream.eat(tokenTypes.LITERAL).value
98
+      value = this.tokenStream.eat(tokenTypes.LITERAL).value;
97 99
     }
98 100
 
99 101
     let node = new AST.String({
100 102
       value: value
101
-    })
103
+    });
102 104
 
103
-    this.tokenStream.eat(tokenTypes.QUOTE)
105
+    this.tokenStream.eat(tokenTypes.QUOTE);
104 106
 
105
-    return node
107
+    return node;
106 108
   }
107 109
 
108 110
   symbol() {
109 111
     return new AST.Symbol({
110 112
       value: this.tokenStream.eat(tokenTypes.SYMBOL).value
111
-    })
113
+    });
112 114
   }
113
-}
115
+};

Loading…
Cancel
Save