def map_(env) -> "(sequence1 c -- sequence2)": "Maps a code object over each item of a sequence and collects the results as a new list." seq, code = env.stack.popN(2) res = [] for item in seq.val: if isinstance(item, Token): env.stack.push(item) else: env.stack.push(Token("lit_any", item)) env.eval(code.val) res.append(env.stack.pop()) env.stack.push(Token("lit_list", res))
def filter_(env) -> "(sequence1 c -- sequence2)": "Filters a sequence." seq, code = env.stack.popN(2) res = [] for item in seq.val: if isinstance(item, Token): item = item else: item = Token("lit_any", item) env.stack.push(item) env.eval(code.val) cond = env.stack.pop().val if cond: res.append(item) env.stack.push(Token("lit_list", res))
def try_(env): tclause, eclauses = env.stack.popN(2) try: env.eval(tclause.val) except BaseException as e: bases = getBaseNames(e.__class__) for (name, handler) in eclauses.val: if name.val in bases: env.stack.push( Token("lit_list", [Token("lit_any", val) for val in e.args])) env.eval(handler.val) break else: raise e
def first(env) -> "(sequence -- a)": seq = env.stack.pop() a = seq.val[1:] if isinstance(a, Token): env.stack.push(a) else: env.stack.push(Token("lit_any", a))
def open_(env): name, flags = env.stack.popN(2) path = env.getDir() path = os.path.join(path, name.val) f = open(path, flags.val) t = Token("lit_file", f) env.stack.push(t)
def open_(env) -> "(s s -- file)": "Pops a string naming a file path and a string used as open flags, returns a file object" name, flags = env.stack.popN(2) path = env.getDir() path = os.path.join(path, name.val) f = open(path, flags.val) t = Token("file", f) env.stack.push(t)
def nth(env) -> "(sequence n -- a)": "Returns the nth item of a sequence (eg. list or string)" seq, n = env.stack.popN(2) a = seq.val[n.val] if isinstance(a, Token): env.stack.push(a) else: env.stack.push(Token("lit_any", a))
def unpack(env) -> "(sequence -- a...)": "Unpacks a sequence" seq = env.stack.pop() if seq.type == "lit_string": seq = [Token("lit_string", c) for c in seq.val] else: seq = seq.val env.stack.push(*seq)
def lt_(env) -> "(a1 a2 -- b)": "Returns true if a1 > a2" a, b = env.stack.popN(2) try: val = a > b except TypeError: val = False env.stack.push(Token("lit_bool", val))
def for_each(env) -> "(sequence c -- )": "Calls a code object for each item of a sequence" seq, code = env.stack.popN(2) for item in seq.val: if isinstance(item, Token): env.stack.push(item) else: env.stack.push(Token("lit_any", item)) env.eval(code.val)
def set_nth(env) -> "(sequence a n -- sequence)": seq, a, n = env.stack.popN(3) if seq.type == "lit_string": s = seq.val newstr = s[0:n.val] + a.val + s[n.val+1:] env.stack.push(Token("lit_string", newstr)) else: seq.val[n.val] = a env.stack.push(seq)
def to_string(env) -> "(a -- s)": 'Pops a value a from the stack and converts it to a string' a = env.stack.pop() if a.type == 'lit_code': a = "Code: %s" % str(a.val) else: a = a.val v = str(a) env.stack.push(Token("lit_string", v))
def to_symbol(env) -> "(a -- sym)": 'Pops a value a from the stack and converts it to a symbol' a = env.stack.pop().val if a.type == 'lit_code': a = "Code.%s" % str(a.val) else: a = a.val v = str(a) env.stack.push(Token("lit_symbol", v))
def run_shell(env) -> "(s1 -- l)": """Runs s1 as a shell command string and returns a two item list [return-code output] Note that this run using the subprocess module with shell=True, which can be a security risk!""" args = env.stack.pop().val args = shlex.split(args) try: out = subprocess.check_output( args, stderr=subprocess.STDOUT, shell=True, ) ret = 0 except subprocess.CalledProcessError as e: out = e.output ret = e.returncode env.stack.push( Token('lit_list', [Token('lit_int', ret), Token('lit_string', out.decode(enc))]))
def run(env) -> "(s1 -- l)": """Runs s1 as a shell command string and returns a two item list [return-code output] Note that this run using the subprocess module with shell=False, so if you need to use a built in shell command use run.shell""" args = env.stack.pop().val args = shlex.split(args) try: out = subprocess.check_output( args, stderr=subprocess.STDOUT, shell=False, ) ret = 0 except subprocess.CalledProcessError as e: out = e.output ret = e.returncode env.stack.push( Token('lit_list', [Token('lit_int', ret), Token('lit_string', out.decode(enc))]))
def reduce_(env) -> "(sequence1 a c -- a)": "Reduces a sequence to a single value" seq, start, code = env.stack.popN(3) for item in seq.val: if isinstance(item, Token): item = item else: item = Token("lit_any", item) env.stack.push(start, item) env.eval(code.val) start = env.stack.pop() env.stack.push(start)
def not_(env) -> "(b1 -- b)": "Returns true if b1 and b2 are true" b1 = env.stack.pop() env.stack.push(Token("lit_bool", not b1.val))
def to_bool(env) -> "(a -- b)": 'Pops a value a from the stack and converts it to a bool' a = env.stack.pop().val v = bool(a) env.stack.push(Token("lit_bool", v))
def to_float(env) -> "(a -- f)": 'Pops a value a from the stack and converts it to a float' a = env.stack.pop().val v = float(a) env.stack.push(Token("lit_float", v))
def to_int(env) -> "(a -- i)": 'Pops a value a from the stack and converts it to an int' a = env.stack.pop().val v = int(a) env.stack.push(Token("lit_int", v))
def readall(env): f = env.stack.pop() cont = f.val.read() env.stack.push(Token("lit_string", cont), f)
def plus(env) -> "(n n -- n)": "Adds two numbers" a, b = env.stack.popN(2) t = a.type env.stack.push(Token(t, a.val + b.val))
def div(env) -> "(n n -- n)": 'Returns the modulo of 2 numbers' a, b = env.stack.popN(2) env.stack.push(Token("lit_float", a.val % b.val))
def div(env) -> "(n n -- n)": 'Divides 2 numbers' a, b = env.stack.popN(2) env.stack.push(Token("lit_float", a.val / b.val))
def mul(env) -> "(n n -- n)": 'Multiplies 2 numbers' a, b = env.stack.popN(2) t = a.type env.stack.push(Token(t, a.val * b.val))
def sub(env) -> "(n n -- n)": "Subtracts 2 numbers" a, b = env.stack.popN(2) t = a.type env.stack.push(Token(t, a.val - b.val))
def and_(env) -> "(b1 b2 -- b)": "Returns true if b1 and b2 are true" b1, b2 = env.stack.popN(2) env.stack.push(Token("lit_any", b1.val and b2.val))
def input_(env) -> "(a -- s)": 'Shows a, prompts for input, and returns it as a string' a = env.stack.pop().val s = input(a) env.stack.push(Token("lit_string", s))
def eq_(env) -> "(a1 a2 -- b)": "Returns true if the top two values on the stack equal each other" a, b = env.stack.popN(2) eq = a == b env.stack.push(Token("lit_bool", eq))
def readn(env): f, n = env.stack.popN(2) cont = f.val.read(n.val) env.stack.push(Token("lit_string", cont), f)