Oh oh oh oh oh

From Esolang
Jump to navigation Jump to search
This article is not detailed enough and needs to be expanded. Please help us by adding some more information.
Oh oh oh oh oh
Designed by User:As
Appeared in 2025
Memory system Accumulator-based
Dimensions one-dimensional
Computational class
Reference implementation Python
Influenced by Ooh
File extension(s) .5oh

Oh oh oh oh oh' /oʊ oʊ oʊ oʊ oʊ/ is a joke esoteric programming language that's based on a single command "oh" (well, and line breaks, which are also a command, but the code still looks like it's from a single instruction).

This language is maybe daughter to Ooh and its logic is similar or the same. I guess you could say it's Ooh, but longer.

Commands (Instructions)

Command What does it do?
oh Increment by 1
linefeed Output the accumulator as ASCII

So, this language is token-by-token? That's why you need to put whitespaces between oh .

The rest of the words, numbers and symbols in general, whether Unicode or ASCII, will (even must) be ignored by the interpreter.

What can a language do and what is its purpose?

The purpose of the language is to output ASCII, new ways to output ASCII...

But in general, the author made the language so that programmers would just remember Ooh.

Examples

Hello, World!

oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh

I think it outputs H, hirst letter of "Hello, World!". I'm just lazy to write full code, sorry.

XKCD Random Number

oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh oh

Interpreters

ChatGPT's GUI python interpreter

import tkinter as tk
from tkinter import filedialog, messagebox
import os

CURRENT_FILE = None

def decode_stream(text: str, flush_at_eof: bool = True) -> str:
    counter = 0
    output_chars = []
    lines = text.splitlines()
    for line in lines:
        if line.strip() == "":
            output_chars.append(chr(counter % 256))
            counter = 0
        else:
            tokens = line.split()
            for t in tokens:
                if t == "oh":
                    counter += 1
    if flush_at_eof and counter > 0:
        output_chars.append(chr(counter % 256))
    return "".join(output_chars)

root = tk.Tk()
root.title("oh o oh oh oh GUI.")
root.geometry("800x500")

input_frame = tk.Frame(root)
input_frame.pack(fill="both", expand=True, padx=6, pady=6)

textbox = tk.Text(input_frame, wrap="word", height=12)
textbox.pack(fill="both", expand=True, side="top")

output_label = tk.Label(input_frame, text="Output:")
output_label.pack(anchor="w")

output_text = tk.Text(input_frame, wrap="none", height=6)
output_text.pack(fill="both", expand=False, side="bottom")
output_text.config(state="disabled")

options_frame = tk.Frame(root)
options_frame.pack(fill="x")

flush_var = tk.BooleanVar(value=True)
chk_flush = tk.Checkbutton(options_frame, text="Flush at EOF (print remaining at end)", variable=flush_var)
chk_flush.pack(side="left", padx=6)

status_var = tk.StringVar(value="No file")
status_label = tk.Label(options_frame, textvariable=status_var)
status_label.pack(side="right", padx=6)

button_frame = tk.Frame(root)
button_frame.pack(fill="x", padx=6, pady=6)

def do_decode(show_popup=True):
    text = textbox.get("1.0", "end")
    out = decode_stream(text, flush_at_eof=flush_var.get())
    output_text.config(state="normal")
    output_text.delete("1.0", "end")
    output_text.insert("1.0", out)
    output_text.config(state="disabled")
    if show_popup:
        if len(out) == 0:
            messagebox.showinfo("Decoded", "No output produced.")
        elif len(out) <= 200:
            messagebox.showinfo("Decoded", out)
        else:
            messagebox.showinfo("Decoded", f"Output length: {len(out)} chars — see Output panel.")

def on_decode():
    do_decode(show_popup=True)

def on_clear():
    textbox.delete("1.0", "end")

def on_exit():
    root.destroy()

def on_open():
    global CURRENT_FILE
    path = filedialog.askopenfilename(defaultextension='.5oh', filetypes=[('oh files', '*.5oh'), ('All files', '*.*')])
    if not path:
        return
    try:
        with open(path, 'r', encoding='utf-8') as f:
            data = f.read()
    except Exception as e:
        messagebox.showerror("Error", f"Failed to open file:\n{e}")
        return
    textbox.delete('1.0', 'end')
    textbox.insert('1.0', data)
    CURRENT_FILE = path
    status_var.set(os.path.basename(path))

def on_save():
    global CURRENT_FILE
    if CURRENT_FILE is None:
        path = filedialog.asksaveasfilename(defaultextension='.5oh', filetypes=[('oh files', '*.5oh'), ('All files', '*.*')])
        if not path:
            return
        CURRENT_FILE = path
    else:
        path = CURRENT_FILE
    try:
        with open(path, 'w', encoding='utf-8') as f:
            f.write(textbox.get('1.0', 'end'))
    except Exception as e:
        messagebox.showerror('Error', f'Failed to save file:\n{e}')
        return
    status_var.set(os.path.basename(path))
    messagebox.showinfo('Saved', f'Saved as {os.path.basename(path)}')

def on_save_as():
    global CURRENT_FILE
    path = filedialog.asksaveasfilename(defaultextension='.5oh', filetypes=[('oh files', '*.5oh'), ('All files', '*.*')])
    if not path:
        return
    CURRENT_FILE = path
    on_save()

def on_run_file():
    path = filedialog.askopenfilename(defaultextension='.5oh', filetypes=[('oh files', '*.5oh'), ('All files', '*.*')])
    if not path:
        return
    try:
        with open(path, 'r', encoding='utf-8') as f:
            data = f.read()
    except Exception as e:
        messagebox.showerror('Error', f'Failed to open file:\n{e}')
        return
    textbox.delete('1.0', 'end')
    textbox.insert('1.0', data)
    do_decode(show_popup=False)
    messagebox.showinfo('Run', f'Executed {os.path.basename(path)} — see Output panel.')

btn_popup = tk.Button(button_frame, text="Decode", command=on_decode)
btn_clear = tk.Button(button_frame, text="Clear", command=on_clear)
btn_exit = tk.Button(button_frame, text="Exit", command=on_exit)
btn_save = tk.Button(button_frame, text="Download .5oh", command=on_save)
btn_open = tk.Button(button_frame, text="Open .5oh", command=on_open)
btn_save_as = tk.Button(button_frame, text="Save as .5oh", command=on_save_as)
btn_run_file = tk.Button(button_frame, text="Run .5oh file", command=on_run_file)

for b in (btn_clear, btn_save, btn_save_as, btn_open, btn_run_file, btn_exit):
    b.pack(side="left", expand=True, fill="x", padx=4, pady=4)

root.bind('<Control-d>', lambda e: on_decode())
root.bind('<Control-s>', lambda e: on_save())
root.bind('<Control-o>', lambda e: on_open())
root.bind('<Control-q>', lambda e: on_exit())

hint = ("Usage:\n"
        "- Write tokens 'oh' and others in the text area.\n"
        "- An empty line (LF, code 10) outputs the current character; counter resets.\n"
        "- If 'Flush at EOF' is checked, the last symbol prints even without a trailing empty line.\n"
        "- Files can be opened/saved with the .5oh extension.\n")

help_label = tk.Label(root, text=hint, justify='left')
help_label.pack(fill='x', padx=6, pady=(0,6))

root.mainloop()

Written by AI. And AI may be wrong

User:As's python interpreter (without output command, and files)

x=0
for t in input().split(" "):
    if t=="oh":x+=1

This interpreter is 100% wrong, bcs it hasn't one or more commands