Skip to content

Commit 8fadb3f

Browse files
committed
Count the number of bytes a program uses
1 parent a24dba4 commit 8fadb3f

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

herbert/counter.py

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import itertools
2+
3+
4+
def count_bytes(parse_tree):
5+
assert parse_tree.data == 'h'
6+
7+
*pdefs, main = parse_tree.children
8+
9+
return sum(itertools.chain(
10+
map(_count_pdef, pdefs),
11+
map(_count_seq, main.children)
12+
))
13+
14+
15+
def _count_pdef(pdef):
16+
assert pdef.data == 'pdef'
17+
18+
try:
19+
name, params, body = pdef.children
20+
params = params.children
21+
except:
22+
name, body = pdef.children
23+
params = []
24+
25+
return 1 + len(params) + sum(map(_count_seq, body.children))
26+
27+
28+
def _count_seq(x):
29+
if hasattr(x, 'type'):
30+
assert x.type == 'COMMAND' or x.type == 'PARAM'
31+
return 1
32+
else:
33+
assert x.data == 'pcall'
34+
35+
try:
36+
name, args = x.children
37+
args = args.children
38+
except ValueError:
39+
name = x.children[0]
40+
args = []
41+
42+
return 1 + sum(map(_count_arg, args))
43+
44+
45+
def _count_arg(arg):
46+
if arg.data == 'var':
47+
return 1
48+
49+
if arg.data == 'sexpr':
50+
return sum(map(_count_seq, arg.children))
51+
52+
assert arg.data == 'expr'
53+
54+
l = len(arg.children)
55+
if l % 2 == 1:
56+
l += 1
57+
l //= 2
58+
59+
return l

tests/test_counter.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import unittest
2+
3+
from herbert.counter import count_bytes
4+
from herbert.parser import parse
5+
6+
7+
def count(program):
8+
return count_bytes(parse(program))
9+
10+
11+
class CountBytesTestCase(unittest.TestCase):
12+
def test_example1(self):
13+
program = 'slr'
14+
15+
self.assertEqual(count(program), 3)
16+
17+
def test_example2(self):
18+
program = 'a:sa\na'
19+
20+
self.assertEqual(count(program), 4)
21+
22+
def test_example3(self):
23+
program = 'a(A):sa(A-1)\na(4)'
24+
25+
self.assertEqual(count(program), 8)
26+
27+
def test_example4(self):
28+
program = 'a(A,B,C):f(B)Ca(A-1,B,C)\nf(A):sf(A-1)\na(4,5,rslsr)'
29+
30+
self.assertEqual(count(program), 26)
31+
32+
def test_example5(self):
33+
program = 'f(A,B,C,D,E,F):sAf(AA,B,F-C+D+2,-D+1,E-1,sFl)\nf(sl,5,-1,100,10,r)'
34+
35+
self.assertEqual(count(program), 32)

0 commit comments

Comments
 (0)