From 3a93f316f2ec84d4ac113fc03f733f55d0eb000c Mon Sep 17 00:00:00 2001 From: Jim Jones Date: Sun, 19 Dec 2021 03:00:33 -0800 Subject: [PATCH 1/3] Add _ Y B/b E/e and W/w instructions --- ly.py | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 5 deletions(-) diff --git a/ly.py b/ly.py index 636ff4f..90b5ed0 100644 --- a/ly.py +++ b/ly.py @@ -4,12 +4,21 @@ # Created by LyricLy # Commented code is for debugging, uncomment at will. +# pylint: disable=invalid-name,missing-function-docstring,line-too-long,missing-class-docstring,unidiomatic-typecheck +# pylint: disable=too-many-statements,missing-module-docstring,too-many-branches,global-statement,unsubscriptable-object +# pylint: disable=self-cls-assignment,bad-continuation,used-before-assignment,too-many-locals,no-else-return,unused-variable +# pylint: disable=no-self-use,redefined-outer-name +# +# available lower case: gj +# available upper case: ACFOPU +# available both cases: BbHhKkMmTtVvXxZz +# available symbols...: #().@\^| + import argparse import time import random import sys import re -import time parser = argparse.ArgumentParser() parser.add_argument("filename", help="File to interpret.") @@ -139,6 +148,15 @@ def add_value(self, value): else: self.append(value) + def reset_value(self, value): + while stack: + stack.pop() + if type(value) == list: + for v in value: + self.append(v) + else: + self.append(value) + def take_input(): nonlocal input_function @@ -172,9 +190,9 @@ def dump_input(): while idx < len(program): char = program[idx] try: - next = program[idx + 1] + nxt = program[idx + 1] except IndexError: - next = None + nxt = None try: last = program[idx - 1] except IndexError: @@ -208,7 +226,7 @@ def function_execution(value): function_name, err_info[1], err_info[2]), file=sys.stderr) print(err_info[0], file=sys.stderr) return False - elif next == "{": + elif nxt == "{": pass elif char.isdigit(): stack.add_value(int(char)) @@ -301,6 +319,9 @@ def function_execution(value): elif char == "/": x, y = stack.pop_value(2) stack.add_value(y / x) + elif char == "_": + x, y = stack.pop_value(2) + stack.add_value(int(y / x)) elif char == "%": x = stack.pop_value() y = stack.pop_value() @@ -386,6 +407,34 @@ def function_execution(value): y = stack.pop_value() stack.add_value(x) stack.add_value(y) + elif char == "B": + v = stack.get_value() + if v is not None: + if stack_pointer > 0: + p = stack_pointer + stack_pointer -= 1 + else: + # since this changes the indexing we don't need to decrement the pointer + p = 1 + stacks.insert(0, Stack()) + stack = stacks[stack_pointer] + stack.add_value(v) + stack = stacks[p] + stack_pointer = p + elif char == "b": + v = stack[0] + if v is not None: + if stack_pointer > 0: + p = stack_pointer + stack_pointer -= 1 + else: + # since this changes the indexing we don't need to decrement the pointer + p = 1 + stacks.insert(0, Stack()) + stack = stacks[stack_pointer] + stack.add_value(v) + stack = stacks[p] + stack_pointer = p elif char == "<": if stack_pointer > 0: stack_pointer -= 1 @@ -393,6 +442,32 @@ def function_execution(value): # since this changes the indexing we don't need to decrement the pointer stacks.insert(0, Stack()) stack = stacks[stack_pointer] + elif char == "E": + v = stack.get_value() + if v is not None: + p = stack_pointer + try: + stacks[stack_pointer + 1] + except IndexError: + stacks.append(Stack()) + stack_pointer += 1 + stack = stacks[stack_pointer] + stack.add_value(v) + stack = stacks[p] + stack_pointer = p + elif char == "e": + v = stack[0] + if v is not None: + p = stack_pointer + try: + stacks[stack_pointer + 1] + except IndexError: + stacks.append(Stack()) + stack_pointer += 1 + stack = stacks[stack_pointer] + stack.add_value(v) + stack = stacks[p] + stack_pointer = p elif char == ">": try: stacks[stack_pointer + 1] @@ -486,6 +561,15 @@ def function_execution(value): stack.sort() elif char == "N": stack.add_value(-stack.pop_value()) + elif char == "Y": + w = stack.pop_value(implicit=False) + v = stack[w] + if w: + n = stack[:w] + stack[w+1:] + else: + n = stack[1:] + stack.reset_value(n+[v,]) + #stack = stacks[stack_pointer] elif char == "I": stack.add_value(stack[stack.pop_value(implicit=False)]) elif char == "R": @@ -494,7 +578,7 @@ def function_execution(value): for i in range(y, x + 1): stack.add_value(i) elif char == "'": - stack.add_value(ord(next)) + stack.add_value(ord(nxt)) idx += 1 elif char == "w": time.sleep(stack.pop_value()) @@ -508,6 +592,20 @@ def function_execution(value): stack.add_value(stack.pop_value() - 1) elif char == "~": stack.add_value(int(stack.pop_value(implicit=False) in stack)) + elif char == "q": + r = stack.pop_value() + l = len(stack) + s = r % l + if s: + n = stack[s:] + stack[:s] + stack.reset_value(n) + elif char == "Q": + r = stack.pop_value() + l = len(stack) + s = r % l + if s: + n = stack[-s:] + stack[:-s] + stack.reset_value(n) except errors as err: if output_function.__name__ == "function_execution": raise FunctionError("{}: {}$${}$${}".format( From b9c2e155b2d24d2a78771d6d3dedcaf972c14d12 Mon Sep 17 00:00:00 2001 From: Jim Jones Date: Sun, 19 Dec 2021 17:10:16 -0800 Subject: [PATCH 2/3] Add bitwise and, or, and xor instructions/commands --- ly.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) mode change 100644 => 100755 ly.py diff --git a/ly.py b/ly.py old mode 100644 new mode 100755 index 90b5ed0..b76b195 --- a/ly.py +++ b/ly.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 # Ly interpreter in Python # Created by LyricLy @@ -9,10 +9,10 @@ # pylint: disable=self-cls-assignment,bad-continuation,used-before-assignment,too-many-locals,no-else-return,unused-variable # pylint: disable=no-self-use,redefined-outer-name # -# available lower case: gj -# available upper case: ACFOPU -# available both cases: BbHhKkMmTtVvXxZz -# available symbols...: #().@\^| +# available lower case: gjx +# available upper case: CFPU +# available both cases: HhKkMmTtVvZz +# available symbols...: .@\| import argparse import time @@ -326,6 +326,15 @@ def function_execution(value): x = stack.pop_value() y = stack.pop_value() stack.add_value(y % x) + elif char == "A": + x, y = stack.pop_value(2) + stack.add_value(int(y & x)) + elif char == "O": + x, y = stack.pop_value(2) + stack.add_value(int(y | x)) + elif char == "X": + x, y = stack.pop_value(2) + stack.add_value(int(y ^ x)) elif char == "^": x, y = stack.pop_value(2) stack.add_value(y ** x) From 18b3b6bec6bf72d93a428aee0aa8e1c44e652554 Mon Sep 17 00:00:00 2001 From: Jim Jones Date: Sun, 19 Dec 2021 23:19:22 -0800 Subject: [PATCH 3/3] Ideas for more commands/instructions I added some additional commands that I think might be interesting. Let me know if any of them seem interesting asis or if you'd like to tweak how they work. Here's the new ones included in the code in the PR. The B/b/E/e ones are to make it possible to copy things from one stack to another without having to use the backup cell. And the Q/q ones let you treat the stack like a wheel you can spin in other direction. _ : Integer division A : bitwise "and" top two stack entries O : bitwise "or" top two stack entries X : bitwise "xor" top two stack entries B : push a copy of the top of the stack onto the stack to the left b : push a copy of the bottom of the stack onto the stack to the left E : push a copy of the top of the stack onto the stack to the right e : push a copy of the bottom of the stack onto the stack to the right Y : "yank" an entry from the stack, push it on the top (like "I" but it deletes what it copies) q : pops a number off the top of the stack, rotates the stack down that many times Q : pops a number off the top of the stack, rotates the stack up that many times --- ly.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ly.py b/ly.py index b76b195..9312799 100755 --- a/ly.py +++ b/ly.py @@ -4,16 +4,6 @@ # Created by LyricLy # Commented code is for debugging, uncomment at will. -# pylint: disable=invalid-name,missing-function-docstring,line-too-long,missing-class-docstring,unidiomatic-typecheck -# pylint: disable=too-many-statements,missing-module-docstring,too-many-branches,global-statement,unsubscriptable-object -# pylint: disable=self-cls-assignment,bad-continuation,used-before-assignment,too-many-locals,no-else-return,unused-variable -# pylint: disable=no-self-use,redefined-outer-name -# -# available lower case: gjx -# available upper case: CFPU -# available both cases: HhKkMmTtVvZz -# available symbols...: .@\| - import argparse import time import random