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)