|
| 1 | +from ec_classes import FatalError, RuntimeError |
| 2 | +from ec_handler import Handler |
| 3 | +from PyP100 import PyP100 |
| 4 | + |
| 5 | +class RBR(Handler): |
| 6 | + |
| 7 | + def __init__(self, compiler): |
| 8 | + Handler.__init__(self, compiler) |
| 9 | + |
| 10 | + def getName(self): |
| 11 | + return 'graphics' |
| 12 | + |
| 13 | + ############################################################################# |
| 14 | + # Keyword handlers |
| 15 | + |
| 16 | + def k_attach(self, command): |
| 17 | + if self.nextIsSymbol(): |
| 18 | + record = self.getSymbolRecord() |
| 19 | + command['name'] = record['name'] |
| 20 | + if self.nextIs('to'): |
| 21 | + value = self.nextValue() |
| 22 | + command['id'] = value |
| 23 | + self.add(command) |
| 24 | + return True |
| 25 | + |
| 26 | + def r_attach(self, command): |
| 27 | + target = self.getVariable(command['name']) |
| 28 | + id = self.getRuntimeValue(command['id']) |
| 29 | + element = getElement(id) |
| 30 | + if element == None: |
| 31 | + FatalError(self.program.compiler, f'There is no screen element with id \'{id}\'') |
| 32 | + return -1 |
| 33 | + self.putSymbolValue(target, {'type': 'text', 'content': id}) |
| 34 | + return self.nextPC() |
| 35 | + |
| 36 | + def k_canvas(self, command): |
| 37 | + return self.compileVariable(command, 'canvas', False) |
| 38 | + |
| 39 | + def r_canvas(self, command): |
| 40 | + return self.nextPC() |
| 41 | + |
| 42 | + def k_close(self, command): |
| 43 | + if self.nextToken() == 'screen': |
| 44 | + self.add(command) |
| 45 | + return True |
| 46 | + |
| 47 | + def r_close(self, command): |
| 48 | + closeScreen() |
| 49 | + return self.nextPC() |
| 50 | + |
| 51 | + def k_create(self, command): |
| 52 | + if self.nextToken() == 'screen': |
| 53 | + while True: |
| 54 | + token = self.peek() |
| 55 | + if token == 'at': |
| 56 | + self.nextToken() |
| 57 | + command['left'] = self.nextValue() |
| 58 | + command['top'] = self.nextValue() |
| 59 | + elif token == 'size': |
| 60 | + self.nextToken() |
| 61 | + command['width'] = self.nextValue() |
| 62 | + command['height'] = self.nextValue() |
| 63 | + elif token == 'fill': |
| 64 | + self.nextToken() |
| 65 | + command['fill'] = self.nextValue() |
| 66 | + else: |
| 67 | + break |
| 68 | + self.add(command) |
| 69 | + return True |
| 70 | + return False |
| 71 | + |
| 72 | + def r_create(self, command): |
| 73 | + createScreen(command) |
| 74 | + return self.nextPC() |
| 75 | + |
| 76 | + def k_ellipse(self, command): |
| 77 | + return self.compileVariable(command, 'ellipse', False) |
| 78 | + |
| 79 | + def r_ellipse(self, command): |
| 80 | + return self.nextPC() |
| 81 | + |
| 82 | + def k_image(self, command): |
| 83 | + return self.compileVariable(command, 'image', False) |
| 84 | + |
| 85 | + def r_image(self, command): |
| 86 | + return self.nextPC() |
| 87 | + |
| 88 | + def k_on(self, command): |
| 89 | + token = self.nextToken() |
| 90 | + command['type'] = token |
| 91 | + if token == 'click': |
| 92 | + command['event'] = token |
| 93 | + if self.peek() == 'in': |
| 94 | + self.nextToken() |
| 95 | + if self.nextIs('screen'): |
| 96 | + command['target'] = None |
| 97 | + elif self.isSymbol(): |
| 98 | + target = self.getSymbolRecord() |
| 99 | + command['target'] = target['name'] |
| 100 | + else: |
| 101 | + FatalError(self.program.compiler, f'{self.getToken()} is not a screen element') |
| 102 | + return False |
| 103 | + command['goto'] = self.getPC() + 2 |
| 104 | + self.add(command) |
| 105 | + self.nextToken() |
| 106 | + pcNext = self.getPC() |
| 107 | + cmd = {} |
| 108 | + cmd['domain'] = 'core' |
| 109 | + cmd['lino'] = command['lino'] |
| 110 | + cmd['keyword'] = 'gotoPC' |
| 111 | + cmd['goto'] = 0 |
| 112 | + cmd['debug'] = False |
| 113 | + self.addCommand(cmd) |
| 114 | + self.compileOne() |
| 115 | + cmd = {} |
| 116 | + cmd['domain'] = 'core' |
| 117 | + cmd['lino'] = command['lino'] |
| 118 | + cmd['keyword'] = 'stop' |
| 119 | + cmd['debug'] = False |
| 120 | + self.addCommand(cmd) |
| 121 | + # Fixup the link |
| 122 | + self.getCommandAt(pcNext)['goto'] = self.getPC() |
| 123 | + return True |
| 124 | + elif token == 'tick': |
| 125 | + command['event'] = token |
| 126 | + command['goto'] = self.getPC() + 2 |
| 127 | + self.add(command) |
| 128 | + self.nextToken() |
| 129 | + pcNext = self.getPC() |
| 130 | + cmd = {} |
| 131 | + cmd['domain'] = 'core' |
| 132 | + cmd['lino'] = command['lino'] |
| 133 | + cmd['keyword'] = 'gotoPC' |
| 134 | + cmd['goto'] = 0 |
| 135 | + cmd['debug'] = False |
| 136 | + self.addCommand(cmd) |
| 137 | + self.compileOne() |
| 138 | + cmd = {} |
| 139 | + cmd['domain'] = 'core' |
| 140 | + cmd['lino'] = command['lino'] |
| 141 | + cmd['keyword'] = 'stop' |
| 142 | + cmd['debug'] = False |
| 143 | + self.addCommand(cmd) |
| 144 | + # Fixup the link |
| 145 | + self.getCommandAt(pcNext)['goto'] = self.getPC() |
| 146 | + return True |
| 147 | + return False |
| 148 | + |
| 149 | + def r_on(self, command): |
| 150 | + pc = command['goto'] |
| 151 | + if command['type'] == 'click': |
| 152 | + event = command['event'] |
| 153 | + if event == 'click': |
| 154 | + target = command['target'] |
| 155 | + if target == None: |
| 156 | + value = 'screen' |
| 157 | + else: |
| 158 | + widget = self.getVariable(target) |
| 159 | + value = widget['value'][widget['index']] |
| 160 | + setOnClick(value['content'], lambda: self.run(pc)) |
| 161 | + elif command['type'] == 'tick': |
| 162 | + setOnTick(lambda: self.run(pc)) |
| 163 | + return self.nextPC() |
| 164 | + |
| 165 | + def k_rectangle(self, command): |
| 166 | + return self.compileVariable(command, 'rectangle', False) |
| 167 | + |
| 168 | + def r_rectangle(self, command): |
| 169 | + return self.nextPC() |
| 170 | + |
| 171 | + def k_render(self, command): |
| 172 | + if self.nextIsSymbol(): |
| 173 | + record = self.getSymbolRecord() |
| 174 | + name = record['name'] |
| 175 | + type = record['type'] |
| 176 | + command['type'] = type |
| 177 | + if type == 'variable': |
| 178 | + command['name'] = name |
| 179 | + if self.peek() == 'in': |
| 180 | + self.nextToken() |
| 181 | + if self.nextIsSymbol(): |
| 182 | + record = self.getSymbolRecord() |
| 183 | + type = record['type'] |
| 184 | + name = record['name'] |
| 185 | + if type in ['rectangle', 'ellipse']: |
| 186 | + command['parent'] = record['name'] |
| 187 | + self.add(command) |
| 188 | + return True |
| 189 | + else: |
| 190 | + self.warning(f'{name} cannot be a parent of another element') |
| 191 | + return False |
| 192 | + command['parent'] = 'screen' |
| 193 | + self.add(command) |
| 194 | + return True |
| 195 | + FatalError(self.program.compiler, f'This variable type cannot be rendered') |
| 196 | + return False |
| 197 | + FatalError(self.program.compiler, 'Nothing specified to render') |
| 198 | + return False |
| 199 | + |
| 200 | + def r_render(self, command): |
| 201 | + variable = self.getVariable(command['name']) |
| 202 | + parent = command['parent'] |
| 203 | + value = self.getRuntimeValue(variable) |
| 204 | + result = render(value, parent) |
| 205 | + if result != None: |
| 206 | + RuntimeError(f'Rendering error: {result}') |
| 207 | + return self.nextPC() |
| 208 | + |
| 209 | + def k_show(self, command): |
| 210 | + if self.nextIs('screen'): |
| 211 | + command['name'] = None |
| 212 | + self.add(command) |
| 213 | + return True |
| 214 | + return False |
| 215 | + |
| 216 | + def r_show(self, command): |
| 217 | + showScreen() |
| 218 | + return self.nextPC() |
| 219 | + |
| 220 | + def k_text(self, command): |
| 221 | + return self.compileVariable(command, 'text', False) |
| 222 | + |
| 223 | + def r_text(self, command): |
| 224 | + return self.nextPC() |
| 225 | + |
| 226 | + ############################################################################# |
| 227 | + # Compile a value in this domain |
| 228 | + def compileValue(self): |
| 229 | + value = {} |
| 230 | + value['domain'] = 'graphics' |
| 231 | + if self.tokenIs('the'): |
| 232 | + self.nextToken() |
| 233 | + token = self.getToken() |
| 234 | + if token == 'xxxxx': |
| 235 | + return value |
| 236 | + |
| 237 | + return None |
| 238 | + |
| 239 | + ############################################################################# |
| 240 | + # Modify a value or leave it unchanged. |
| 241 | + def modifyValue(self, value): |
| 242 | + return value |
| 243 | + |
| 244 | + ############################################################################# |
| 245 | + # Value handlers |
| 246 | + |
| 247 | + def v_xxxxx(self, v): |
| 248 | + value = {} |
| 249 | + return value |
| 250 | + |
| 251 | + ############################################################################# |
| 252 | + # Compile a condition |
| 253 | + def compileCondition(self): |
| 254 | + condition = {} |
| 255 | + return condition |
| 256 | + |
| 257 | + ############################################################################# |
| 258 | + # Condition handlers |
0 commit comments