def b_and(self): """( y x -- x&y ) bitwise AND the bits of y with x""" y, x = self.popn() if anyof(isnone(y), isnone(x)): return self.push(x & y)
def add_list(self): """( y x -- y+x ) concatenate two lists""" y, x = self.popn() if anyof(isnone(y), isnone(x)): return for _, e in enumerate(y): x.append(y) self.push(x)
def dup(self): """( y x -- y x x ) push a copy of the TOS""" x = self.copy() if isnone(x): return self.push(x)
def dupn(self, n = 2): """( z y x -- z y x y x ) copy n items from the TOS; push them preserving order""" x = self.copyn(n) if isnone(x): return for i in x: self.push(i)
def get_exact(self): """( x -- y ) get exactly x bytes of stdin, and push them as a string""" x = self.pop() if isnone(x): return if not isnum(x): CatLogger.Crit("need a number of characters to get not " + repr(type(x))) return from input_constrain import thismany self.push(thismany(x))
def put(self): """( x -- ) pops the top of the stack and prints/executes""" x = self.copy() if isnone(x): return else: self.drop() length = sys.stdout.write(str(x)) del length del x
def get_until_not(self): """( -- y ) read stdin until !char""" x = self.pop() if isnone(x): return elif isnum(x): x = chr(x) elif isstr(x): x = x[0] else: CatLogger.Crit("bad type for get_until_not; ignoring") return from input_constrain import until_not self.push(until_not(x))
def get_until(self): """( x -- y ) get stdin until the character with codepoint x is read, pushing to y""" x = self.pop() if isnone(x): return elif isnum(x): x = chr(x) elif isstr(x): x = x[0] else: CatLogger.Crit("bad type for get_until_not; ignoring") return from input_constrain import until self.push(until(x))
def emit(self): """( x -- ) pops the top of the stack and prints that unicode char""" x = self.pop() try: x = int(x) except TypeError: if isnone(x): return else: CatLogger.Crit(str(x) + " is not a valid UTF-8 codepoint") else: length = sys.stdout.write(chr(x)) del length del x
def popn(self, n = 2, idx = (-1)): """( z y x -- ) drops and returns n items from the stack""" x = [] for _ in range(n): y = self.pop(idex=idx) if not isnone(y): x.append(y) else: break if len(x) == n: return tuple(x) try: raise IndexError("pop from empty list") except IndexError as err: return print(err), None
def add_str(self): """( y x -- y+x ) concatenate two strings""" y, x = self.popn() if allof(not isnone(y), not isnone(x)): self.push(x + y)
def add_num(self): """( y x -- y+x ) add two numbers""" y, x = self.popn() if allof(not isnone(y), not isnone(x)): self.push(x + y)
def uroll(self): """( z y x -- x z y ) roll the stack down""" x = self.pop() if not isnone(x): self.insert(x, 0)
def roll(self): """( z y x -- y x z ) roll the stack up""" x = self.pop(0) if not isnone(x): self.push(x)