initial commit
This commit is contained in:
commit
cf86b463b2
|
@ -0,0 +1,5 @@
|
|||
# rforth
|
||||
|
||||
A bare-bones forth interpreter written in Python for the hell of it.
|
||||
|
||||
https://wiki.rmgr.dev/general/tech/rforth.html
|
|
@ -0,0 +1,211 @@
|
|||
stack = []
|
||||
compiling = False
|
||||
words = {}
|
||||
word_name = ""
|
||||
|
||||
def get_next(input_string):
|
||||
if len(input_string) > 1:
|
||||
return input_string[1:len(input_string)]
|
||||
else:
|
||||
return []
|
||||
def get_input():
|
||||
i = input()
|
||||
return i
|
||||
|
||||
def parse_input(input_string, say_ok=True):
|
||||
while len(input_string) > 0:
|
||||
string = str(input_string[0])
|
||||
if not compiling:
|
||||
if string.isnumeric():
|
||||
add_to_stack(string)
|
||||
elif string == "stack":
|
||||
show_stack()
|
||||
elif string == "+":
|
||||
add()
|
||||
elif string == "-":
|
||||
subtract()
|
||||
elif string == ".":
|
||||
output()
|
||||
elif string == "bye":
|
||||
exit()
|
||||
elif string == "emit":
|
||||
emit()
|
||||
elif string == ":":
|
||||
start_compiling()
|
||||
elif string in words:
|
||||
parse_input(words[string].split(" "), False)
|
||||
elif string == "words":
|
||||
show_words()
|
||||
elif string == ">":
|
||||
greater_than()
|
||||
elif string == "<":
|
||||
less_than()
|
||||
elif string == "=":
|
||||
equals()
|
||||
elif string == "if":
|
||||
input_string = _if(input_string)
|
||||
elif string == "dup":
|
||||
dup()
|
||||
elif string == "2dup":
|
||||
twodup()
|
||||
elif string == "swap":
|
||||
swap()
|
||||
elif string == "rot":
|
||||
rot()
|
||||
else:
|
||||
if string == ";":
|
||||
stop_compiling()
|
||||
else:
|
||||
add_to_new_word(string)
|
||||
input_string = get_next(input_string)
|
||||
if say_ok:
|
||||
print("ok.")
|
||||
|
||||
def rot():
|
||||
a = stack.pop(0)
|
||||
b = stack.pop(0)
|
||||
c = stack.pop(0)
|
||||
stack.insert(0,a)
|
||||
stack.insert(0,b)
|
||||
stack.insert(0,c)
|
||||
|
||||
def swap():
|
||||
a = stack.pop(0)
|
||||
b = stack.pop(0)
|
||||
stack.insert(0,a)
|
||||
stack.insert(0,b)
|
||||
|
||||
def _if(input_string):
|
||||
a = stack.pop(0)
|
||||
if int(a) == -1:
|
||||
then_index = scan_for_then(input_string)
|
||||
else_index = scan_for_else(input_string[0:then_index], then_index)
|
||||
if else_index == -1:
|
||||
return input_string[0:then_index]
|
||||
else:
|
||||
return input_string[0: else_index] + input_string[then_index : len(input_string)]
|
||||
else:
|
||||
then_index = scan_for_then(input_string)
|
||||
else_index = scan_for_else(input_string[0:then_index], then_index)
|
||||
|
||||
if else_index == -1:
|
||||
return input_string[then_index: len(input_string)]
|
||||
else:
|
||||
return input_string[else_index : len(input_string)]
|
||||
return input_string
|
||||
|
||||
def scan_for_else_or_then(input_string):
|
||||
for index in reversed(range(0, len(input_string))):
|
||||
if input_string[index] == "then":
|
||||
return input_string[index : len(input_string) - 1]
|
||||
elif input_string[index] == "else":
|
||||
return input_string[index : len(input_string) - 1]
|
||||
return index
|
||||
|
||||
def scan_for_else(input_string, then_index):
|
||||
for index in reversed(range(0, then_index)):
|
||||
if input_string[index] == "else":
|
||||
return index
|
||||
return -1
|
||||
|
||||
def scan_for_then(input_string):
|
||||
for index in reversed(range(0, len(input_string))):
|
||||
if input_string[index] == "then":
|
||||
return index
|
||||
# return input_string[index : len(input_string) - 1]
|
||||
return -1
|
||||
|
||||
def twodup():
|
||||
a = stack.pop(0)
|
||||
stack.insert(0,a)
|
||||
stack.insert(0,a)
|
||||
stack.insert(0,a)
|
||||
|
||||
def dup():
|
||||
a = stack.pop(0)
|
||||
stack.insert(0,a)
|
||||
stack.insert(0,a)
|
||||
|
||||
def greater_than():
|
||||
a = stack.pop(0)
|
||||
b = stack.pop(0)
|
||||
if a > b:
|
||||
stack.insert(0,-1)
|
||||
else:
|
||||
stack.insert(0,0)
|
||||
|
||||
def less_than():
|
||||
a = stack.pop(0)
|
||||
b = stack.pop(0)
|
||||
if a < b:
|
||||
stack.insert(0,-1)
|
||||
else:
|
||||
stack.insert(0,0)
|
||||
|
||||
def equals():
|
||||
a = stack.pop(0)
|
||||
b = stack.pop(0)
|
||||
if a == b:
|
||||
stack.insert(0,-1)
|
||||
else:
|
||||
stack.insert(0,0)
|
||||
|
||||
def show_words():
|
||||
print(words)
|
||||
|
||||
def add_to_new_word(value):
|
||||
global word_name
|
||||
if word_name == "":
|
||||
word_name = value
|
||||
words[word_name] = ""
|
||||
else:
|
||||
words[word_name] = words[word_name] + value + " "
|
||||
|
||||
def start_compiling():
|
||||
global compiling
|
||||
compiling = True
|
||||
|
||||
def stop_compiling():
|
||||
global compiling
|
||||
global word_name
|
||||
compiling = False
|
||||
words[word_name] = words[word_name].strip()
|
||||
word_name = ""
|
||||
|
||||
def emit():
|
||||
a = stack.pop(0)
|
||||
print(chr(a),end='')
|
||||
|
||||
def exit():
|
||||
print("l8r sk8r")
|
||||
quit()
|
||||
|
||||
def output():
|
||||
a = stack.pop(0)
|
||||
print(a)
|
||||
|
||||
def subtract():
|
||||
a = stack.pop(0)
|
||||
b = stack.pop(0)
|
||||
stack.insert(0, a-b)
|
||||
|
||||
def add():
|
||||
a = stack.pop(0)
|
||||
b = stack.pop(0)
|
||||
stack.insert(0, a+b)
|
||||
|
||||
def show_stack():
|
||||
print(stack)
|
||||
|
||||
def add_to_stack(value):
|
||||
stack.insert(0, int(value))
|
||||
|
||||
|
||||
def main():
|
||||
print("Welcome to rforth!")
|
||||
while True:
|
||||
i = get_input()
|
||||
parse_input(i.split(' '))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue