def k_open(self, command): if self.nextIsSymbol(): symbolRecord = self.getSymbolRecord() command['target'] = symbolRecord['name'] command['path'] = self.nextValue() if symbolRecord['keyword'] == 'file': if self.peek() == 'for': self.nextToken() token = self.nextToken() if token == 'appending': mode = 'a+' elif token == 'reading': mode = 'r' elif token == 'writing': mode = 'w' else: FatalError(f'self.compiler, Unknown file open mode {token}') return False command['mode'] = mode self.add(command) return True else: FatalError(self.compiler, f'Variable "{self.getToken()}" is not a file') else: self.warning(f'core.open: Variable "{self.getToken()}" not declared') return False
def k_print(self, command): value = self.nextValue() if value != None: command['value'] = value self.add(command) return True FatalError(self.program.compiler, 'I can\'t print this value') return False
def r_gosub(self, command): label = command['gosub'] + ':' address = self.symbols[label] if address != None: self.stack.append(self.nextPC()) return address FatalError(self.program.compiler, f'There is no label "{label + ":"}"') return None
def r_put(self, command): value = self.evaluate(command['value']) if value == None: return -1 symbolRecord = self.getVariable(command['target']) if not symbolRecord['valueHolder']: FatalError(self.program.compiler, f'{symbolRecord["name"]} does not hold a value') return -1 self.putSymbolValue(symbolRecord, value) return self.nextPC()
def r_fork(self, command): next = self.nextPC() label = command['fork'] try: label = self.symbols[label + ':'] except: FatalError(self.compiler, f'There is no label "{label + ":"}"') return None self.run(label) return next
def k_multiply(self, command): # Get the (first) value command['value1'] = self.nextValue() if self.nextToken() == 'by': command['value2'] = self.nextValue() if self.peek() == 'giving': self.nextToken() if (self.nextIsSymbol()): command['target'] = self.getToken() self.add(command) return True FatalError(f'self.compiler, Symbol expected') else: # First value must be a variable if command['value1']['type'] == 'symbol': command['target'] = command['value1']['name'] self.add(command) return True FatalError(f'self.compiler, First value must be a variable') return False
def incdec(self, command, mode): symbolRecord = self.getVariable(command['target']) if not symbolRecord['valueHolder']: FatalError(self.program.compiler, f'{symbolRecord["name"]} does not hold a value') return None value = self.getSymbolValue(symbolRecord) if mode == '+': value['content'] += 1 else: value['content'] -= 1 self.putSymbolValue(symbolRecord, value) return self.nextPC()
def k_put(self, command): command['value'] = self.nextValue() if self.nextIs('into'): if self.nextIsSymbol(): symbolRecord = self.getSymbolRecord() command['target'] = symbolRecord['name'] if symbolRecord['valueHolder']: self.add(command) return True elif symbolRecord['keyword'] == 'dictionary': if self.peek() == 'as': self.nextToken() command['keyword'] = 'putDict' command['key'] = self.nextValue() self.add(command) return True else: FatalError(self.program.compiler, f'Symbol {symbolRecord["name"]} is not a value holder') else: FatalError(self.program.compiler, f'No such variable: "{self.getToken()}"') return False
def k_get(self, command): self.add(command) if self.nextIsSymbol(): symbolRecord = self.getSymbolRecord() if symbolRecord['valueHolder']: command['target'] = self.getToken() else: FatalError(self.compiler, f'Variable "{symbolRecord["name"]}" does not hold a value') if self.nextIs('from'): command['url'] = self.nextValue() return True return False
def compileSymbol(self, command, name, valueHolder): if hasattr(self.symbols, name): FatalError( self, f'{self.code[self.pc].lino}: Duplicate symbol name "{name}"') return False self.symbols[name] = self.getPC() command['isSymbol'] = True command['used'] = False command['valueHolder'] = valueHolder command['name'] = name command['elements'] = 1 command['index'] = 0 command['value'] = [None] command['debug'] = False self.addCommand(command) return True
def compileToken(self): token = self.getToken() #print(token) if not token: return False self.mark() for domain in self.domains: handler = domain.keywordHandler(token) if handler: command = {} command['domain'] = domain.getName() command['lino'] = self.tokens[self.index].lino command['keyword'] = token command['debug'] = True result = handler(command) return result else: self.rewind() FatalError(self, f'No handler found for "{token}"') return False
def doValue(self, value): if value == None: FatalError(self.compiler, f'Undefined value (variable not initialized?)') return None result = {} valType = value['type'] if valType in ['boolean', 'int', 'text', 'object']: result = value elif valType == 'cat': content = '' for part in value['parts']: val = self.doValue(part) if val == None: return None val = str(val['content']) if val == None: return None content += val result['type'] = 'text' result['content'] = content elif valType == 'symbol': name = value['name'] symbolRecord = self.getSymbolRecord(name) if symbolRecord['value'] == [None]: RuntimeError(f'Variable "{name}" has no value') return None handler = self.domainList[symbolRecord['domain']].valueHandler( 'symbol') result = handler(symbolRecord) else: # Call the given domain to handle a value domain = self.domainList[value['domain']] handler = domain.valueHandler(value['type']) if handler: result = handler(value) return result
def r_goto(self, command): label = f'{command["goto"]}:' if self.symbols[label]: return self.symbols[label] FatalError(self.program.compiler, f'There is no label "{label}"') return None
def getToken(self): if self.index >= len(self.tokens): FatalError(self, 'Premature end of script') return self.tokens[self.index].token
def variableDoesNotHoldAValueError(self, name): raise FatalError(self.compiler, f'Variable "{name}" does not hold a value')
def nonNumericValueError(self): FatalError(self.compiler, 'Non-numeric value')