A tiny programming language

Write a program that runs programs.

What to build

An interpreter for a very small language, combining most of this course.

Requirements

  • set NAME VALUE creates or replaces a variable.
  • add NAME VALUE and mul NAME VALUE change an existing variable.
  • print NAME prints a variable's value.
  • An unknown variable prints error: unknown NAME.
  • A value that is not a whole number prints error: bad number VALUE.

Input

The first line has n. Each of the next n lines is a command.

Output

One line for each print or error.

Constraints

n is from 1 to 200.

Example

Input:

4
set x 5
add x 3
mul x 2
print x

Output:

16

Why it works

This is how real interpreters are organised: one loop reads statements, a table stores names, and errors are reported without bringing the whole program down.

Examples

Example 1 · Input
4
set x 5
add x 3
mul x 2
print x
Expected output
16
Example 2 · Input
2
print y
add y 1
Expected output
error: unknown y
error: unknown y

Prompts inside input() are ignored when checking, so input("n: ") is fine.

Hints

Hint 1

Store the variables in a dictionary.

Hint 2

Use a custom exception, and raise it for a variable that does not exist or a value that is not a number.

Hint 3

Put the try inside the loop, so that one bad line does not stop the rest.

Solution

Show one correct solution (try it yourself first)
class LanguageError(Exception):
    pass

variables = {}

def number(text):
    try:
        return int(text)
    except ValueError:
        raise LanguageError(f"bad number {text}")

def lookup(name):
    if name not in variables:
        raise LanguageError(f"unknown {name}")
    return variables[name]

def run(parts):
    command = parts[0]
    name = parts[1]
    if command == "set":
        variables[name] = number(parts[2])
    elif command == "add":
        variables[name] = lookup(name) + number(parts[2])
    elif command == "mul":
        variables[name] = lookup(name) * number(parts[2])
    else:
        print(lookup(name))

n = int(input())
for _ in range(n):
    try:
        run(input().split())
    except LanguageError as error:
        print(f"error: {error}")

Lesson: What comes next →