- commit
- d945d21dd639aa6b4bfb382d4d5e7598ce45dfe9
- parent
- 61f967c8272d9e27bcf1b37e2713f7800d2baa27
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2024-07-06 17:29
expressions: unparse
Diffstat
| M | sheet/expression.py | 49 | ++++++++++++++++++++++++++++++++++++++++--------- |
| M | sheet/sheet.py | 4 | +++- |
2 files changed, 43 insertions, 10 deletions
diff --git a/sheet/expression.py b/sheet/expression.py
@@ -24,17 +24,17 @@ def parse_re(text, pattern): 24 24 25 25 def parse_string(text): 26 26 m, tail = parse_re(text, r'"[^"]*"')27 -1 return ('str', m[0][1:-1]), tail-1 27 return ('str', m[0][1:-1], m[0]), tail 28 28 29 29 30 30 def parse_float(text): 31 31 m, tail = parse_re(text, r'[0-9]+\.[0-9]+')32 -1 return ('float', float(m[0])), tail-1 32 return ('float', float(m[0]), m[0]), tail 33 33 34 34 35 35 def parse_int(text): 36 36 m, tail = parse_re(text, r'[0-9]+')37 -1 return ('int', int(m[0], 10)), tail-1 37 return ('int', int(m[0], 10), m[0]), tail 38 38 39 39 40 40 def col2x(col): @@ -74,21 +74,23 @@ def parse_brace(text): 74 74 _, tail = parse_re(text, r'\(') 75 75 exp, tail = parse_expression(tail) 76 76 _, tail = parse_re(tail, r'\)')77 -1 return exp, tail-1 77 return ('brace', exp), tail 78 78 79 79 80 80 def parse_call(text): 81 81 m, tail = parse_re(text, r'[a-zA-Z][a-zA-Z0-9]*') 82 82 _, tail = parse_re(tail, r'\(') 83 83 args = [] -1 84 commas = [] 84 85 if tail.startswith(')'):85 -1 return (m[0], args), tail[1:]-1 86 return (m[0], args, commas), tail[1:] 86 87 while True: 87 88 arg, tail = parse_expression(tail) 88 89 args.append(arg) 89 90 if tail.startswith(')'):90 -1 return (m[0], args), tail[1:]91 -1 _, tail = parse_re(tail, r',\s*')-1 91 return (m[0], args, commas), tail[1:] -1 92 c, tail = parse_re(tail, r',\s*') -1 93 commas.append(c[0]) 92 94 raise ParseError('no closing brace on function call') 93 95 94 96 @@ -112,7 +114,7 @@ def parse_expression2(text): 112 114 except ParseError: 113 115 break 114 116 rhs, tail = parse_expression3(tail)115 -1 lhs = m[0].strip(), lhs, rhs-1 117 lhs = m[0].strip(), lhs, rhs, m[0] 116 118 return lhs, tail 117 119 118 120 @@ -124,7 +126,7 @@ def parse_expression(text): 124 126 except ParseError: 125 127 break 126 128 rhs, tail = parse_expression2(tail)127 -1 lhs = m[0].strip(), lhs, rhs-1 129 lhs = m[0].strip(), lhs, rhs, m[0] 128 130 return lhs, tail 129 131 130 132 @@ -133,3 +135,32 @@ def parse(text): 133 135 if tail: 134 136 raise ParseError(f'unexpected tail: {tail}') 135 137 return expr -1 138 -1 139 -1 140 def unparse(expr): -1 141 if expr[0] in ['str', 'float', 'int']: -1 142 return expr[2] -1 143 elif expr[0] == 'ref': -1 144 s = '' -1 145 if expr[2][0]: -1 146 s += '$' -1 147 s += x2col(expr[1][0]) -1 148 if expr[2][1]: -1 149 s += '$' -1 150 s += str(expr[1][1] + 1) -1 151 return s -1 152 elif expr[0] == 'range': -1 153 return unparse(expr[1]) + ':' + unparse(expr[2]) -1 154 elif expr[0] == 'brace': -1 155 return '(' + unparse(expr[1]) + ')' -1 156 elif expr[0] in '+-*/': -1 157 return unparse(expr[1]) + expr[3] + unparse(expr[2]) -1 158 else: -1 159 name, args, commas = expr -1 160 assert len(args) == len(commas) + 1 -1 161 sargs = '' -1 162 if args: -1 163 for i, comma in enumerate(commas): -1 164 sargs += unparse(args[i]) + comma -1 165 sargs += unparse(args[-1]) -1 166 return f'{name}({sargs})'
diff --git a/sheet/sheet.py b/sheet/sheet.py
@@ -52,7 +52,7 @@ class Sheet: 52 52 pass 53 53 return raw 54 5455 -1 def call_function(self, name: str, args: list[tuple]) -> float|int|str:-1 55 def call_function(self, name: str, args: list[tuple], _commas: list[str]) -> float|int|str: 56 56 if name == 'sum': 57 57 if len(args) != 1 or args[0][0] != 'range': 58 58 raise ValueError(args) @@ -75,6 +75,8 @@ class Sheet: 75 75 return expr[1] 76 76 elif expr[0] == 'ref': 77 77 return self.get_value(expr[1]) -1 78 elif expr[0] == 'brace': -1 79 return self.evaluate(expr[1]) 78 80 elif expr[0] == 'err': 79 81 raise expr[1] 80 82 elif expr[0] == '+':