Lythnology/Implementations
Jump to navigation
Jump to search
Python (Made by Claude AI)
import random
import sys
def number_to_words(n):
ones = ["", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"]
teens = ["TEN", "ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN", "FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"]
tens = ["", "", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY"]
thousands = [
"", "THOUSAND", "MILLION", "BILLION", "TRILLION", "QUADRILLION", "QUINTILLION", "SEXTILLION", "SEPTILLION",
"OCTILLION", "NONILLION", "DECILLION", "UNDECILLION", "DUODECILLION", "TREDECILLION", "QUATTUORDECILLION",
"QUINDECILLION", "SEXDECILLION", "SEPTENDECILLION", "OCTODECILLION", "NOVEMDECILLION", "VIGINTILLION",
"UNVIGINTILLION", "DUOVIGINTILLION", "TREVIGINTILLION", "QUATTUORVIGINTILLION", "QUINVIGINTILLION",
"SEXVIGINTILLION", "SEPTENVIGINTILLION", "OCTOVIGINTILLION", "NOVEMVIGINTILLION", "TRIGINTILLION",
"UNTRIGINTILLION", "DUOTRIGINTILLION", "CENTILLION"
]
def chunk_to_words(chunk):
words = ""
h, rem = divmod(chunk, 100)
if h:
words += ones[h] + "HUNDRED"
if 10 <= rem < 20:
words += teens[rem - 10]
else:
t, o = divmod(rem, 10)
words += tens[t] + ones[o]
return words
if n == 0:
return "ZERO"
parts = []
chunk_index = 0
while n > 0:
n, chunk = divmod(n, 1000)
if chunk:
w = chunk_to_words(chunk)
if thousands[chunk_index]:
w += thousands[chunk_index]
parts.insert(0, w)
chunk_index += 1
return ''.join(parts)
def replace_numbers_with_words(s):
result, i = '', 0
while i < len(s):
if s[i].isdigit():
num = ''
while i < len(s) and s[i].isdigit():
num += s[i]; i += 1
result += number_to_words(int(num))
else:
result += s[i]; i += 1
return result
class LythnologyInterpreter:
def __init__(self):
self.words = {
"IF": {"affordances": ["conditional"], "values": ["IF"]},
"IS": {"affordances": ["assignment"], "values": ["IS"]},
"THEN": {"affordances": ["jump_target"], "values": ["THEN"]},
"TO": {"affordances": ["transform_connector"], "values": ["TO"]},
"TRANSFORMS": {"affordances": ["transformer"], "values": ["TRANSFORMS"]},
"WHEN": {"affordances": ["across_jump"], "values": ["WHEN"]},
"SAY": {"affordances": ["print"], "values": ["SAY"]},
"INPUT": {"affordances": ["input"], "values": ["INPUT"]},
"AND": {"affordances": ["concat_all"], "values": ["AND"]},
"WITH": {"affordances": ["concat"], "values": ["WITH"]},
"OR": {"affordances": ["random_choice"], "values": ["OR"]},
"NOT": {"affordances": ["negation"], "values": ["NOT"]},
"PAUSE": {"affordances": ["new_line"], "values": ["PAUSE"]}
}
self.program = []
self.position = 0
self.word_positions = {}
def parse_program(self, code):
lines = code.split('\n')
proc = []
for line in lines:
if '#' in line: line = line[:line.index('#')]
proc.append(line)
tokens = ' '.join(proc).split()
self.program = tokens
self.word_positions = {}
for idx, w in enumerate(self.program):
self.word_positions.setdefault(w, []).append(idx)
def create_word(self, w):
if w not in self.words:
self.words[w] = {"affordances": [], "values": [w]}
def get_word_value(self, w):
if w not in self.words: self.create_word(w)
return " ".join(self.words[w]["values"])
def run(self, code):
self.parse_program(code)
self.position = 0
while self.position < len(self.program):
self.evaluate_next_word()
#print(self.words)
def evaluate_next_word(self):
if self.position >= len(self.program): return False
current = self.program[self.position]
# ensure unknown words exist
if current not in self.words:
self.create_word(current)
self.position += 1
return True
self.position += 1
# 1) transformation peek
if "transform" in self.words[current]["affordances"]:
self.handle_transform()
if "print" in self.words[current]["affordances"]:
self.handle_print()
elif "print" in self.words[current]["affordances"]:
self.handle_print()
elif "assignment" in self.words[current]["affordances"]:
self.handle_assignment()
elif "new_line" in self.words[current]["affordances"]:
print("\n", end="")
elif "conditional" in self.words[current]["affordances"]:
self.handle_conditional()
elif "across_jump" in self.words[current]["affordances"]:
self.handle_across_jump()
elif "transformer" in self.words[current]["affordances"]:
self.handle_transformer()
return True
def handle_print(self):
if self.position < len(self.program):
w = self.program[self.position]; self.position += 1
self.create_word(w)
print(self.get_word_value(w), end=" ")
def handle_assignment(self):
# same as original assignment code
if self.position < 2 or self.position >= len(self.program): return
left = self.program[self.position - 2]
right = self.program[self.position]; self.position += 1
self.create_word(left); self.create_word(right)
if right == "INPUT":
user = input()
user = replace_numbers_with_words(user)
user = ''.join(c for c in user if c.isalpha() or c.isspace()).upper()
user = user.split()[0] if user else ""
self.words[left]["values"] = [user]; return
if self.position < len(self.program) and self.program[self.position] == "OR":
opts = [right]
while self.position < len(self.program) and self.program[self.position] == "OR":
self.position += 1
if self.position < len(self.program):
o = self.program[self.position]; opts.append(o)
self.create_word(o); self.position += 1
choice = random.choice(opts)
if choice in self.words:
self.words[left] = {"affordances": self.words[choice]["affordances"].copy(),
"values": self.words[choice]["values"].copy()}
else:
self.create_word(choice)
self.words[left]["values"] = [choice]
return
if self.position < len(self.program) and self.program[self.position] == "AND":
vals = self.words[right]["values"].copy()
affs = self.words[right]["affordances"].copy()
while self.position < len(self.program) and self.program[self.position] == "AND":
self.position += 1
if self.position < len(self.program):
nxt = self.program[self.position]; self.create_word(nxt)
vals.extend(self.words[nxt]["values"])
affs.extend(a for a in self.words[nxt]["affordances"] if a not in affs)
self.position += 1
self.words[left]["values"] = vals; self.words[left]["affordances"] = affs; return
if self.position < len(self.program) and self.program[self.position] == "WITH":
comb = ''.join(self.words[right]["values"])
while self.position < len(self.program) and self.program[self.position] == "WITH":
self.position += 1
if self.position < len(self.program):
nxt = self.program[self.position]; self.create_word(nxt)
comb += ''.join(self.words[nxt]["values"])
self.position += 1
self.words[left]["values"] = [comb]; return
if right in self.words:
self.words[left] = {"affordances": self.words[right]["affordances"].copy(),
"values": self.words[right]["values"].copy()}
else:
self.create_word(right)
self.words[left]["values"] = [right]
def handle_conditional(self):
if self.position + 1 >= len(self.program):
self.position = len(self.program)
return
l = self.program[self.position]
isw = self.program[self.position + 1]
if isw != "IS":
ti = self.position + 1
while ti < len(self.program) and self.program[ti] != "THEN":
ti += 1
self.position = ti + 1 if ti < len(self.program) else len(self.program)
return
self.position += 2
neg = False
if self.position < len(self.program) and self.program[self.position] == "NOT":
neg = True
self.position += 1
# Check if we're doing an AND comparison
using_and = False
comps = []
if self.position < len(self.program):
cw = self.program[self.position]
self.create_word(cw)
comps.append(cw)
self.position += 1
# Collect all comparison words, noting whether we're using AND or OR
while self.position + 1 < len(self.program) and (self.program[self.position] == "OR" or self.program[self.position] == "AND"):
connector = self.program[self.position]
if connector == "AND":
using_and = True
self.position += 1
ncw = self.program[self.position]
self.create_word(ncw)
comps.append(ncw)
self.position += 1
self.create_word(l)
left_vals = self.words[l]["values"]
# Handle different logic based on AND vs OR
if using_and:
# For AND, ALL conditions must be met
met = True
for cw in comps:
if not any(rv in left_vals for rv in self.words[cw]["values"]):
met = False
break
else:
# For OR, ANY condition must be met
met = False
for cw in comps:
if any(rv in left_vals for rv in self.words[cw]["values"]):
met = True
break
if neg:
met = not met
if not met:
ti = self.position
while ti < len(self.program) and self.program[ti] != "THEN":
ti += 1
if ti < len(self.program):
self.position = ti + 1
def handle_across_jump(self):
if self.position >= len(self.program):
return
tgt = self.program[self.position]
self.position += 1
if tgt not in self.word_positions:
return
# Find all positions of the target word
positions = self.word_positions[tgt]
# Current position is right after WHEN
current_pos = self.position - 1
# Need to find the next occurrence of target word
# or wrap around to the first occurrence if no next
next_positions = [p for p in positions if p > current_pos]
if next_positions:
# Jump to the next occurrence
self.position = min(next_positions) + 1
else:
# Wrap around to the first occurrence
self.position = min(positions) + 1
def handle_transformer(self):
if self.position<2: return
tr=self.program[self.position-2]
if "transform" not in self.words[tr]["affordances"]:
self.words[tr]["affordances"].append("transform")
seq_map={}
pos=self.position
while pos<len(self.program):
src=self.program[pos]; self.create_word(src); chain=[src]; pos+=1
while pos<len(self.program) and self.program[pos]=="TO": pos+=1; tgt=self.program[pos]; self.create_word(tgt); chain.append(tgt); pos+=1
for i in range(len(chain)-1): seq_map[chain[i]]=chain[i+1]
if not (pos+1<len(self.program) and self.program[pos+1]=="TO"): break
self.position=pos
self.words[tr]["transformations"]=seq_map
def handle_transform(self):
tr=self.program[self.position-1]
if self.position>=len(self.program): return
tgt=self.program[self.position]
if "transformations" not in self.words[tr]: return
self.create_word(tgt)
cur=''.join(self.words[tgt]["values"])
trans=self.words[tr]["transformations"]
if cur in trans:
nv=trans[cur]
if nv in self.words: self.words[tgt]["values"]=self.words[nv]["values"].copy()
else: self.create_word(nv); self.words[tgt]["values"]=[nv]
if __name__ == "__main__":
interp=LythnologyInterpreter()
if len(sys.argv)<2:
print("Usage: python lyth.py <filename>"); sys.exit(1)
with open(sys.argv[1],"r") as f: code=f.read()
interp.run(code)