Browse Source

Add length function; preserve Number node line numbers

master
Dylan Baker 5 years ago
parent
commit
da6ce44556
5 changed files with 37 additions and 8 deletions
  1. 11
    0
      src/core.js
  2. 3
    1
      src/parser.js
  3. 19
    3
      test/coreTest.js
  4. 2
    2
      test/evaluatorTest.js
  5. 2
    2
      test/parserTest.js

+ 11
- 0
src/core.js View File

1
 const AST = require('./ast')
1
 const AST = require('./ast')
2
+const OsloError = require('./osloError')
2
 
3
 
3
 module.exports = {
4
 module.exports = {
4
   '+': (a, b) => new AST.Number({ value: a.value + b.value }),
5
   '+': (a, b) => new AST.Number({ value: a.value + b.value }),
11
   '>=': (a, b) => new AST.Boolean({ value: a.value >= b.value }),
12
   '>=': (a, b) => new AST.Boolean({ value: a.value >= b.value }),
12
   '<=': (a, b) => new AST.Boolean({ value: a.value <= b.value }),
13
   '<=': (a, b) => new AST.Boolean({ value: a.value <= b.value }),
13
   'list': (...args) => { return new AST.List({ elements: args }) },
14
   'list': (...args) => { return new AST.List({ elements: args }) },
15
+  'length': xs => {
16
+    if (xs.constructor == AST.List) {
17
+      return new AST.Number({ value: xs.elements.length })
18
+    }
19
+
20
+    return new OsloError({
21
+      line: xs.line,
22
+      message: 'length: argument is not a list'
23
+    })
24
+  }
14
 }
25
 }

+ 3
- 1
src/parser.js View File

171
   }
171
   }
172
 
172
 
173
   number() {
173
   number() {
174
+    const token = this.tokenStream.eat(tokenTypes.NUMBER)
174
     return new AST.Number({
175
     return new AST.Number({
175
-      value: this.tokenStream.eat(tokenTypes.NUMBER).value,
176
+      line: token.line,
177
+      value: token.value,
176
     })
178
     })
177
   }
179
   }
178
 
180
 

+ 19
- 3
test/coreTest.js View File

10
   const tree = helpers.evaluate('(list 1 2 3)')
10
   const tree = helpers.evaluate('(list 1 2 3)')
11
   t.deepEqual(tree[0], new AST.List({
11
   t.deepEqual(tree[0], new AST.List({
12
     elements: [
12
     elements: [
13
-      new AST.Number({ value: 1 }),
14
-      new AST.Number({ value: 2 }),
15
-      new AST.Number({ value: 3 }),
13
+      new AST.Number({ value: 1, line: 1 }),
14
+      new AST.Number({ value: 2, line: 1 }),
15
+      new AST.Number({ value: 3, line: 1 }),
16
     ]
16
     ]
17
   }))
17
   }))
18
 })
18
 })
19
+
20
+test('length function', t => {
21
+  t.plan(2)
22
+
23
+  let tree = helpers.evaluate('(length (list 1 2 3))')
24
+  t.deepEqual(tree[0], new AST.Number({ value: 3 }))
25
+
26
+  tree = helpers.evaluate('(length 5)')
27
+  t.deepEqual(
28
+    tree,
29
+    new OsloError({
30
+      line: 1,
31
+      message: 'length: argument is not a list'
32
+    })
33
+  )
34
+})

+ 2
- 2
test/evaluatorTest.js View File

32
   t.plan(3)
32
   t.plan(3)
33
 
33
 
34
   let tree = helpers.evaluate('(if #t 1 0)')
34
   let tree = helpers.evaluate('(if #t 1 0)')
35
-  t.deepEqual(tree[0], new AST.Number({ value: 1 }))
35
+  t.deepEqual(tree[0], new AST.Number({ value: 1, line: 1 }))
36
 
36
 
37
   tree = helpers.evaluate('(if #f 1 0)')
37
   tree = helpers.evaluate('(if #f 1 0)')
38
-  t.deepEqual(tree[0], new AST.Number({ value: 0 }))
38
+  t.deepEqual(tree[0], new AST.Number({ value: 0, line: 1 }))
39
 
39
 
40
   tree = helpers.evaluate('(if (= (+ 4 9) (- 20 7)) (+ 10 9) (- 4 2))')
40
   tree = helpers.evaluate('(if (= (+ 4 9) (- 20 7)) (+ 10 9) (- 4 2))')
41
   t.deepEqual(tree[0], new AST.Number({ value: 19 }))
41
   t.deepEqual(tree[0], new AST.Number({ value: 19 }))

+ 2
- 2
test/parserTest.js View File

62
           function: new AST.Identifier({ name: '+', line: 1 }),
62
           function: new AST.Identifier({ name: '+', line: 1 }),
63
           args: [
63
           args: [
64
             new AST.Identifier({ name: 'n', line: 1 }),
64
             new AST.Identifier({ name: 'n', line: 1 }),
65
-            new AST.Number({ value: 1 }),
65
+            new AST.Number({ value: 1, line: 1 }),
66
           ],
66
           ],
67
         }),
67
         }),
68
       }),
68
       }),
69
-      args: [new AST.Number({ value: 5 })],
69
+      args: [new AST.Number({ value: 5, line: 1 })],
70
     }),
70
     }),
71
   ])
71
   ])
72
 })
72
 })

Loading…
Cancel
Save