Inderjit Gill 1 week ago
parent
commit
3a76fcb691
3 changed files with 359 additions and 100 deletions
  1. 151
    59
      core/sen-core/src/compiler.rs
  2. 159
    38
      core/sen-core/src/gene.rs
  3. 49
    3
      core/sen-core/src/parser.rs

+ 151
- 59
core/sen-core/src/compiler.rs View File

@@ -24,7 +24,7 @@ use crate::keywords::{string_to_keyword_hash, Keyword};
24 24
 use crate::mathutil;
25 25
 use crate::native::Native;
26 26
 use crate::opcodes::{opcode_stack_offset, Opcode};
27
-use crate::parser::Node;
27
+use crate::parser::{Node, NodeMeta};
28 28
 
29 29
 const MEMORY_LOCAL_SIZE: usize = 40;
30 30
 
@@ -95,13 +95,53 @@ pub fn assign_genotype_to_ast(ast: &mut [Node], genotype: &mut Genotype) -> Resu
95 95
     genotype.current_gene_index = 0;
96 96
 
97 97
     for n in ast {
98
-        assign_genes_to_nodes(n, genotype);
98
+        assign_genes_to_nodes(n, genotype)?;
99 99
     }
100 100
 
101 101
     Ok(())
102 102
 }
103 103
 
104
-fn assign_genes_to_nodes(node: &mut Node, genotype: &mut Genotype) {
104
+fn hacky_assign_genes_to_each_node_in_vector(
105
+    elements: &mut Vec<Node>,
106
+    genotype: &mut Genotype,
107
+) -> Vec<Node> {
108
+    let mut res: Vec<Node> = Vec::new();
109
+
110
+    for n in elements {
111
+        match n {
112
+            Node::Vector(ns, _) => {
113
+                res.push(Node::Vector(
114
+                    ns.clone(),
115
+                    Some(NodeMeta::new_with_gene(
116
+                        genotype.genes[genotype.current_gene_index].clone(),
117
+                    )),
118
+                ));
119
+                genotype.current_gene_index += 1;
120
+            }
121
+            Node::Float(f, _) => {
122
+                res.push(Node::Float(
123
+                    *f,
124
+                    Some(NodeMeta::new_with_gene(
125
+                        genotype.genes[genotype.current_gene_index].clone(),
126
+                    )),
127
+                ));
128
+                genotype.current_gene_index += 1;
129
+            }
130
+            _ => {}
131
+        }
132
+    }
133
+
134
+    res
135
+}
136
+
137
+fn hacky_assign_genes_to_each_node_in_vector2(ns: &mut Vec<Node>, res: Vec<Node>) {
138
+    ns.clear();
139
+    for n in res {
140
+        ns.push(n);
141
+    }
142
+}
143
+
144
+fn assign_genes_to_nodes(node: &mut Node, genotype: &mut Genotype) -> Result<()> {
105 145
     match node {
106 146
         Node::List(ref mut ns, meta) => {
107 147
             if let Some(ref mut node_meta) = meta {
@@ -109,54 +149,27 @@ fn assign_genes_to_nodes(node: &mut Node, genotype: &mut Genotype) {
109 149
                 genotype.current_gene_index += 1;
110 150
             }
111 151
             for n in ns {
112
-                assign_genes_to_nodes(n, genotype);
113
-            }
114
-        }
115
-        Node::Vector(ref mut ns, _meta) => {
116
-            /*
117
-                        // grab a gene for every element in this vector
118
-                        if let Some(ref mut _node_meta) = meta {
119
-                            for n in ns {
120
-                                // add the meta
121
-                                match n {
122
-                                    Node::List(_, ref mut meta) => {
123
-                                        meta = &mut Some(NodeMeta::new_with_gene(genotype.genes[genotype.current_gene_index].clone()));
124
-                                        genotype.current_gene_index += 1;
125
-                                    }
126
-                                    Node::Vector(_, ref mut meta) => {
127
-                                        meta = &mut Some(NodeMeta::new_with_gene(genotype.genes[genotype.current_gene_index].clone()));
128
-                                        genotype.current_gene_index += 1;
129
-                                    }
130
-                                    Node::Float(_, ref mut meta) => {
131
-                                        meta = &mut Some(NodeMeta::new_with_gene(genotype.genes[genotype.current_gene_index].clone()));
132
-                                        genotype.current_gene_index += 1;
133
-                                    }
134
-                                    Node::Name(_, _, ref mut meta) => {
135
-                                        meta = &mut Some(NodeMeta::new_with_gene(genotype.genes[genotype.current_gene_index].clone()));
136
-                                        genotype.current_gene_index += 1;
137
-                                    }
138
-                                    Node::Label(_, _, ref mut meta) => {
139
-                                        meta = &mut Some(NodeMeta::new_with_gene(genotype.genes[genotype.current_gene_index].clone()));
140
-                                        genotype.current_gene_index += 1;
141
-                                    }
142
-                                    Node::String(_, ref mut meta) => {
143
-                                        meta = &mut Some(NodeMeta::new_with_gene(genotype.genes[genotype.current_gene_index].clone()));
144
-                                        genotype.current_gene_index += 1;
145
-                                    }
146
-                                    Node::Whitespace(_, ref mut meta) => {
147
-                                        meta = &mut Some(NodeMeta::new_with_gene(genotype.genes[genotype.current_gene_index].clone()));
148
-                                        genotype.current_gene_index += 1;
149
-                                    }
150
-                                    Node::Comment(_, ref mut meta) => {
151
-                                        meta = &mut Some(NodeMeta::new_with_gene(genotype.genes[genotype.current_gene_index].clone()));
152
-                                        genotype.current_gene_index += 1;
153
-                                    }
154
-                                }
155
-                            }
156
-                        }
157
-            */
158
-            for n in ns {
159
-                assign_genes_to_nodes(n, genotype);
152
+                assign_genes_to_nodes(n, genotype)?;
153
+            }
154
+        }
155
+        Node::Vector(ref mut ns, meta) => {
156
+            if meta.is_some() {
157
+                // if this just has 2 floats assign a gene to each node
158
+                // let children = semantic_children(ns);
159
+                // if children.len() == 2 && both_children_are_floats(&children) {
160
+                //     let res = hacky_assign_genes_to_each_node_in_vector(ns, genotype);
161
+                //     hacky_assign_genes_to_each_node_in_vector2(ns, res);
162
+                // } else {
163
+                //     let res = hacky_assign_genes_to_each_node_in_vector(ns, genotype);
164
+                //     hacky_assign_genes_to_each_node_in_vector2(ns, res);
165
+                // }
166
+
167
+                let res = hacky_assign_genes_to_each_node_in_vector(ns, genotype);
168
+                hacky_assign_genes_to_each_node_in_vector2(ns, res);
169
+            } else {
170
+                for n in ns {
171
+                    assign_genes_to_nodes(n, genotype)?;
172
+                }
160 173
             }
161 174
         }
162 175
         Node::Float(_, ref mut meta) => {
@@ -196,6 +209,8 @@ fn assign_genes_to_nodes(node: &mut Node, genotype: &mut Genotype) {
196 209
             }
197 210
         }
198 211
     }
212
+
213
+    Ok(())
199 214
 }
200 215
 
201 216
 #[derive(Copy, Clone, Debug, PartialEq)]
@@ -1140,10 +1155,11 @@ impl Compiler {
1140 1155
             }
1141 1156
             Node::Vector(children, _) => {
1142 1157
                 let children = semantic_children(children);
1143
-                if children.len() == 2 {
1144
-                    return self.compile_2d(compilation, &children[..]);
1158
+
1159
+                if children.len() == 2 && both_children_are_floats(&children) {
1160
+                    return self.compile_2d(compilation, ast, &children[..]);
1145 1161
                 } else {
1146
-                    return self.compile_vector(compilation, &children[..]);
1162
+                    return self.compile_vector(compilation, ast, &children[..]);
1147 1163
                 }
1148 1164
             }
1149 1165
             Node::Name(text, iname, _) => {
@@ -2186,19 +2202,82 @@ impl Compiler {
2186 2202
         Ok(())
2187 2203
     }
2188 2204
 
2189
-    fn compile_2d(&self, compilation: &mut Compilation, children: &[&Node]) -> Result<()> {
2190
-        for n in children {
2191
-            self.compile(compilation, n)?;
2205
+    fn compile_alterable_element(&self, compilation: &mut Compilation, node: &Node) -> Result<()> {
2206
+        match node {
2207
+            Node::Float(_, _) => {
2208
+                let f = self.get_float(node)?;
2209
+                compilation.emit_opcode_mem_f32(Opcode::LOAD, Mem::Constant, f)?;
2210
+            }
2211
+            Node::Vector(elements, _) => {
2212
+                // TODO: this codepath is never executed??
2213
+                let elements = semantic_children(elements);
2214
+                if elements.len() == 2 && both_children_are_floats(&elements) {
2215
+                    let (a, b) = self.get_2d(node)?;
2216
+                    compilation.emit_opcode_mem_f32(Opcode::LOAD, Mem::Constant, a)?;
2217
+                    compilation.emit_opcode_mem_f32(Opcode::LOAD, Mem::Constant, b)?;
2218
+                    compilation.emit_opcode(Opcode::SQUISH2)?;
2219
+                } else {
2220
+                    return Err(Error::Compiler(
2221
+                        "compile_alterable_element: expected a vector of length 2".to_string(),
2222
+                    ));
2223
+                }
2224
+            }
2225
+            _ => {
2226
+                return Err(Error::Compiler(
2227
+                    "compile_alterable_element: expected either a float element or a vector"
2228
+                        .to_string(),
2229
+                ));
2230
+            }
2231
+        }
2232
+
2233
+        Ok(())
2234
+    }
2235
+
2236
+    fn compile_2d(
2237
+        &self,
2238
+        compilation: &mut Compilation,
2239
+        node: &Node,
2240
+        children: &[&Node],
2241
+    ) -> Result<()> {
2242
+        // the node may contain alterable info
2243
+        let use_gene = node.is_alterable() && self.use_genes;
2244
+
2245
+        if node.has_gene() && use_gene {
2246
+            let (a, b) = self.get_2d(node)?;
2247
+            compilation.emit_opcode_mem_f32(Opcode::LOAD, Mem::Constant, a)?;
2248
+            compilation.emit_opcode_mem_f32(Opcode::LOAD, Mem::Constant, b)?;
2249
+        } else {
2250
+            for n in children {
2251
+                if use_gene {
2252
+                    self.compile_alterable_element(compilation, n)?;
2253
+                } else {
2254
+                    self.compile(compilation, n)?;
2255
+                }
2256
+            }
2192 2257
         }
2193 2258
         compilation.emit_opcode(Opcode::SQUISH2)?;
2259
+
2194 2260
         Ok(())
2195 2261
     }
2196 2262
 
2197
-    fn compile_vector(&self, compilation: &mut Compilation, children: &[&Node]) -> Result<()> {
2263
+    fn compile_vector(
2264
+        &self,
2265
+        compilation: &mut Compilation,
2266
+        node: &Node,
2267
+        children: &[&Node],
2268
+    ) -> Result<()> {
2198 2269
         // pushing from the VOID means creating a new, empty vector
2199 2270
         compilation.emit_opcode_mem_i32(Opcode::LOAD, Mem::Void, 0)?;
2271
+
2272
+        // if this is an alterable vector, we'll have to pull values for each element from the genes
2273
+        let use_gene = node.has_gene() && self.use_genes;
2274
+
2200 2275
         for n in children {
2201
-            self.compile(compilation, n)?;
2276
+            if use_gene {
2277
+                self.compile_alterable_element(compilation, n)?;
2278
+            } else {
2279
+                self.compile(compilation, n)?;
2280
+            }
2202 2281
             compilation.emit_opcode(Opcode::APPEND)?;
2203 2282
         }
2204 2283
 
@@ -2379,6 +2458,10 @@ impl Compiler {
2379 2458
     fn get_colour(&self, n: &Node) -> Result<Colour> {
2380 2459
         n.get_colour(self.use_genes)
2381 2460
     }
2461
+
2462
+    fn get_2d(&self, n: &Node) -> Result<(f32, f32)> {
2463
+        n.get_2d(self.use_genes)
2464
+    }
2382 2465
 }
2383 2466
 
2384 2467
 fn error_if_alterable(n: &Node, s: &str) -> Result<()> {
@@ -2423,6 +2506,15 @@ fn semantic_children(children: &[Node]) -> Vec<&Node> {
2423 2506
     ns
2424 2507
 }
2425 2508
 
2509
+fn both_children_are_floats(children: &Vec<&Node>) -> bool {
2510
+    if let Node::Float(_, _) = children[0] {
2511
+        if let Node::Float(_, _) = children[1] {
2512
+            return true;
2513
+        }
2514
+    }
2515
+    false
2516
+}
2517
+
2426 2518
 #[cfg(test)]
2427 2519
 mod tests {
2428 2520
     use super::*;

+ 159
- 38
core/sen-core/src/gene.rs View File

@@ -151,6 +151,36 @@ mod tests {
151 151
         Ok((var, genotype))
152 152
     }
153 153
 
154
+    fn geno_test(
155
+        expr: &str,
156
+        seed: i32,
157
+        genotype_length: usize,
158
+        expected_normal: f32,
159
+        expected_variant: f32,
160
+    ) {
161
+        let res = compile_and_execute(expr).unwrap();
162
+        is_float(&res, expected_normal);
163
+
164
+        let (res, genotype) = run_with_seeded_genotype(expr, seed).unwrap();
165
+        assert_eq!(genotype.genes.len(), genotype_length);
166
+        is_float(&res, expected_variant);
167
+    }
168
+
169
+    fn geno_test_2d(
170
+        expr: &str,
171
+        seed: i32,
172
+        genotype_length: usize,
173
+        expected_normal: (f32, f32),
174
+        expected_variant: (f32, f32),
175
+    ) {
176
+        let res = compile_and_execute(expr).unwrap();
177
+        is_2d(&res, expected_normal);
178
+
179
+        let (res, genotype) = run_with_seeded_genotype(expr, seed).unwrap();
180
+        assert_eq!(genotype.genes.len(), genotype_length);
181
+        is_2d(&res, expected_variant);
182
+    }
183
+
154 184
     fn compile_trait_list(s: &str) -> Result<TraitList> {
155 185
         let (ast, _) = parse(s).unwrap();
156 186
         TraitList::compile(&ast)
@@ -231,6 +261,15 @@ mod tests {
231 261
         }
232 262
     }
233 263
 
264
+    fn is_2d(var: &Var, expected: (f32, f32)) {
265
+        if let Var::V2D(x, y) = var {
266
+            assert_eq!(*x, expected.0);
267
+            assert_eq!(*y, expected.1);
268
+        } else {
269
+            assert!(false);
270
+        }
271
+    }
272
+
234 273
     fn is_col(var: &Var, expected: &Colour) {
235 274
         if let Var::Colour(col) = var {
236 275
             assert_eq!(col.format, expected.format);
@@ -260,56 +299,138 @@ mod tests {
260 299
 
261 300
     #[test]
262 301
     fn genotype_compile() {
263
-        {
264
-            let s = "(+ {3 (gen/scalar min: 10 max: 20)} {4 (gen/scalar min: 100 max: 105)})";
302
+        geno_test(
303
+            "(+ {3 (gen/scalar min: 10 max: 20)} {4 (gen/scalar min: 100 max: 105)})",
304
+            432,
305
+            2,
306
+            7.0,
307
+            122.79086,
308
+        );
309
+        geno_test("(+ 6 {3 (gen/int min: 1 max: 100)})", 432, 1, 9.0, 104.0);
310
+        geno_test(
311
+            "(+ 6 {3 (gen/scalar min: 1 max: 100)})",
312
+            432,
313
+            1,
314
+            9.0,
315
+            103.59401,
316
+        );
317
+        geno_test("(+ 6 {3 (gen/int min: 1 max: 100)})", 874, 1, 9.0, 60.0);
318
+        geno_test(
319
+            "(+ 6 {3 (gen/scalar min: 1 max: 100)})",
320
+            874,
321
+            1,
322
+            9.0,
323
+            59.47561,
324
+        );
325
+    }
265 326
 
266
-            let res = compile_and_execute(s).unwrap();
267
-            is_float(&res, 7.0);
327
+    #[test]
328
+    fn genotype_compile_stray() {
329
+        geno_test("{3 (gen/stray from: 3 by: 0.5)}", 432, 1, 3.0, 3.475697);
330
+        geno_test("{3 (gen/stray-int from: 3 by: 0.5)}", 432, 1, 3.0, 3.0);
331
+    }
268 332
 
269
-            let (res, genotype) = run_with_seeded_genotype(s, 432).unwrap();
270
-            is_float(&res, 122.79086);
271
-            assert_eq!(genotype.genes.len(), 2);
272
-        }
273
-        {
274
-            let s = "(+ 6 {3 (gen/int min: 1 max: 100)})";
333
+    #[test]
334
+    fn genotype_compile_stray_2d() {
335
+        // genotype has a length of 2
336
+        geno_test_2d(
337
+            "{[100 200] (gen/stray-2d from: [100 200] by: [10 10])}",
338
+            7524,
339
+            2,
340
+            (100.0, 200.0),
341
+            (93.04805, 197.49728),
342
+        );
343
+    }
275 344
 
276
-            let res = compile_and_execute(s).unwrap();
277
-            is_float(&res, 9.0);
345
+    #[test]
346
+    fn genotype_compile_vectors() {
347
+        // gen/2d in this expr will produce a genotype with 2 genes, each gene will be a V2D
278 348
 
279
-            let (res, genotype) = run_with_seeded_genotype(s, 432).unwrap();
280
-            is_float(&res, 104.0);
281
-            assert_eq!(genotype.genes.len(), 1);
282
-        }
283 349
         {
284
-            let s = "(+ 6 {3 (gen/scalar min: 1 max: 100)})";
285
-
286
-            let res = compile_and_execute(s).unwrap();
287
-            is_float(&res, 9.0);
350
+            let expr = "{[[0.1 0.2] [0.3 0.4]] (gen/2d)}";
351
+            let seed = 752;
352
+
353
+            // assert the default case [0.1 0.2] [0.3 0.4]:
354
+            let res = compile_and_execute(expr).unwrap();
355
+            if let Var::Vector(vs) = res {
356
+                assert_eq!(vs.len(), 2);
357
+                is_2d(&vs[0], (0.1, 0.2));
358
+                is_2d(&vs[1], (0.3, 0.4));
359
+            } else {
360
+                assert!(false);
361
+            }
362
+
363
+            let (res, genotype) = run_with_seeded_genotype(expr, seed).unwrap();
364
+            if let Var::Vector(vs) = res {
365
+                assert_eq!(vs.len(), 2);
366
+                is_2d(&vs[0], (0.9825403, 0.85869956));
367
+                is_2d(&vs[1], (0.59191173, 0.999328));
368
+            } else {
369
+                assert!(false);
370
+            }
288 371
 
289
-            let (res, genotype) = run_with_seeded_genotype(s, 432).unwrap();
290
-            is_float(&res, 103.59401);
291
-            assert_eq!(genotype.genes.len(), 1);
372
+            assert_eq!(genotype.genes.len(), 2);
292 373
         }
293
-        // different seeds
294
-        {
295
-            let s = "(+ 6 {3 (gen/int min: 1 max: 100)})";
296 374
 
297
-            let res = compile_and_execute(s).unwrap();
298
-            is_float(&res, 9.0);
375
+        {
376
+            let expr = "{[[0.1 0.2] [0.3 0.4]] (gen/2d min: 50 max: 60)}";
377
+            let seed = 752;
378
+
379
+            // assert the default case [0.1 0.2] [0.3 0.4]:
380
+            let res = compile_and_execute(expr).unwrap();
381
+            if let Var::Vector(vs) = res {
382
+                assert_eq!(vs.len(), 2);
383
+                is_2d(&vs[0], (0.1, 0.2));
384
+                is_2d(&vs[1], (0.3, 0.4));
385
+            } else {
386
+                assert!(false);
387
+            }
388
+
389
+            let (res, genotype) = run_with_seeded_genotype(expr, seed).unwrap();
390
+            if let Var::Vector(vs) = res {
391
+                assert_eq!(vs.len(), 2);
392
+                is_2d(&vs[0], (59.8254, 58.586998));
393
+                is_2d(&vs[1], (55.919117, 59.99328));
394
+            } else {
395
+                assert!(false);
396
+            }
299 397
 
300
-            let (res, genotype) = run_with_seeded_genotype(s, 874).unwrap();
301
-            is_float(&res, 60.0);
302
-            assert_eq!(genotype.genes.len(), 1);
398
+            assert_eq!(genotype.genes.len(), 2);
303 399
         }
304
-        {
305
-            let s = "(+ 6 {3 (gen/scalar min: 1 max: 100)})";
400
+    }
306 401
 
307
-            let res = compile_and_execute(s).unwrap();
308
-            is_float(&res, 9.0);
309 402
 
310
-            let (res, genotype) = run_with_seeded_genotype(s, 874).unwrap();
311
-            is_float(&res, 59.47561);
312
-            assert_eq!(genotype.genes.len(), 1);
403
+    #[test]
404
+    fn genotype_compile_multiple_floats() {
405
+        // gen/2d in this expr will produce a genotype with 2 genes, each gene will be a V2D
406
+
407
+        {
408
+            let expr = "{[0.977 0.416 0.171] (gen/scalar)}";
409
+            let seed = 922;
410
+
411
+            let res = compile_and_execute(expr).unwrap();
412
+            if let Var::Vector(vs) = res {
413
+                assert_eq!(vs.len(), 3);
414
+                is_float(&vs[0], 0.977);
415
+                is_float(&vs[1], 0.416);
416
+                is_float(&vs[2], 0.171);
417
+            } else {
418
+                assert!(false);
419
+            }
420
+
421
+            let (res, genotype) = run_with_seeded_genotype(expr, seed).unwrap();
422
+            if let Var::Vector(vs) = res {
423
+                assert_eq!(vs.len(), 3);
424
+                is_float(&vs[0], 0.6279464);
425
+                is_float(&vs[1], 0.46001887);
426
+                is_float(&vs[2], 0.51953447);
427
+            } else {
428
+                assert!(false);
429
+            }
430
+
431
+            assert_eq!(genotype.genes.len(), 3);
313 432
         }
433
+
314 434
     }
435
+
315 436
 }

+ 49
- 3
core/sen-core/src/parser.rs View File

@@ -23,7 +23,7 @@ use crate::keywords::Keyword;
23 23
 use crate::lexer::{tokenize, Token};
24 24
 use crate::native::Native;
25 25
 
26
-#[derive(Debug, PartialEq)]
26
+#[derive(Clone, Debug, PartialEq)]
27 27
 pub struct NodeMeta {
28 28
     pub gene: Option<Gene>,
29 29
     pub parameter_ast: Vec<Node>,
@@ -40,7 +40,7 @@ impl NodeMeta {
40 40
     }
41 41
 }
42 42
 
43
-#[derive(Debug, PartialEq)]
43
+#[derive(Clone, Debug, PartialEq)]
44 44
 pub enum Node {
45 45
     List(Vec<Node>, Option<NodeMeta>),
46 46
     Vector(Vec<Node>, Option<NodeMeta>),
@@ -139,10 +139,37 @@ impl Node {
139 139
         )))
140 140
     }
141 141
 
142
+    pub fn get_2d(&self, use_genes: bool) -> Result<(f32, f32)> {
143
+        if let Node::Vector(_, meta) = self {
144
+            if use_genes && meta.is_some() {
145
+                if let Some(meta) = meta {
146
+                    if let Some(gene) = &meta.gene {
147
+                        match gene {
148
+                            Gene::V2D(x, y) => return Ok((*x, *y)),
149
+                            _ => {
150
+                                return Err(Error::Compiler(
151
+                                    "Node::get_2d incompatible gene".to_string(),
152
+                                ));
153
+                            }
154
+                        }
155
+                    }
156
+                }
157
+            } else {
158
+                return Err(Error::Compiler(
159
+                    "Node::get_2d expected to use gene".to_string(),
160
+                ));
161
+            }
162
+        }
163
+        Err(Error::Compiler(format!(
164
+            "Node::get_2d expected Node::Vector not {:?}",
165
+            self
166
+        )))
167
+    }
168
+
142 169
     pub fn is_alterable(&self) -> bool {
143 170
         match self {
144 171
             Node::List(_, meta)
145
-            | Node::Vector(_, meta)
172
+                | Node::Vector(_, meta)
146 173
             | Node::Float(_, meta)
147 174
             | Node::Name(_, _, meta)
148 175
             | Node::Label(_, _, meta)
@@ -151,6 +178,25 @@ impl Node {
151 178
             | Node::Comment(_, meta) => return meta.is_some(),
152 179
         }
153 180
     }
181
+
182
+    pub fn has_gene(&self) -> bool {
183
+        match self {
184
+            Node::List(_, meta)
185
+                | Node::Vector(_, meta)
186
+                | Node::Float(_, meta)
187
+                | Node::Name(_, _, meta)
188
+                | Node::Label(_, _, meta)
189
+                | Node::String(_, meta)
190
+                | Node::Whitespace(_, meta)
191
+                | Node::Comment(_, meta) => {
192
+                    if let Some(meta) = meta {
193
+                        return meta.gene.is_some()
194
+                    } else {
195
+                        false
196
+                    }
197
+                }
198
+        }
199
+    }
154 200
 }
155 201
 
156 202
 struct NodeAndRemainder<'a> {