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