def act(self, token): word = token.word if word == ':': if self.compile: print('Already in compile mode!') return False self.compile = Compile() elif word == ';': if not self.compile: print('Not in compile mode!') return False self.compile.finish(self) self.compile = None elif self.compile: try: self.compile.take(token) except CompileException as e: print(e) self.compile = None elif word == 'variable': if self.lex: name = next(self.lex) if name.isstringliteral: raise ForthException('Expected name, not string') name = name.word index = self.memory.create_var(name) self.on(name, lambda s: s.istack.push(index)) else: raise ForthException("No name variable name given") elif word == 'constant': if self.lex: name = next(self.lex) if name.isstringliteral: raise ForthException('Expected name, not string') name = name.word n1 = self.istack.pop() self.on(name, lambda s: s.istack.push(n1)) else: raise ForthException("No name variable name given") elif isInt(word): self.istack.push(int(word)) elif isFloat(word): self.fstack.push(float(word)) elif token.isstringliteral: print(word, end='') elif word in self.dict: self.dict[word](self) else: raise ForthException('Unknown Token: ' + word) return True
def __parse_string(self): ''' Helper method to consume and return input until a trailing " is found ''' # Skip the ." and space self.index += 3 text = self.__take_until(lambda c: c == '"') if not self.__curr() == '"': raise ForthException('Incomplete string') self.index += 1 return Token(text, True)
def __parse_comment(self): ''' Helper method to consume input until a trailing ) is found ''' self.__take_until(lambda c: c == ')') if not self.__curr() == ')': raise ForthException('Incomplete comment') self.index += 1
def pop(self): if self.is_empty(): raise ForthException('Stack underflow') self.length -= 1 return self.stack.pop()
def peek(self, level=1): if level > self.length: raise ForthException('Stack underflow') return self.stack[-level]
def set_val(self, addr, val): if addr < 0 or addr >= self.used: raise ForthException('Address out of bounds ' + repr(addr)) self.memory[addr] = val
def get_val(self, addr): if addr < 0 or addr >= self.used: raise ForthException('Address out of bounds ' + repr(addr)) return self.memory[addr]
def get_var(self, name): if not name in self.vars: raise ForthException('No variable named ' + name) return self.vars[name]
def create_var(self, name): if name in self.vars: raise ForthException('Variable already exists ' + name) index = self.allot() self.vars[name] = index return index