Minimialized Programming Language
Jump to navigation
Jump to search
Minimialized Programming Language is designed by PSTF.
It is really minimialized, and I will design the One-character version of it.
Definition
Commands
program = { statement }
statement = if_stmt | while_stmt | let_stmt | call_stmt | return_stmt | io_stmt
if_stmt = "if" expr "then" { statement } [ "else" { statement } ] "end"
while_stmt = "while" expr "do" { statement } "end"
let_stmt = "let" ID "=" expr
call_stmt = "call" ID "(" [ expr { "," expr } ] ")"
return_stmt = "return" expr
io_stmt = ("print" expr) | ("read" ID) | ("printch" expr) | ("readch" ID)
expr = term { ("+" | "-" | "==" | "<" | "!=") term }
term = factor { ("*" | "/") factor }
factor = INT | CHAR | STRING | ID | "(" expr ")" | ("-" factor)
| ID "[" expr "]" | "[" [ expr { "," expr } ] "]"
CHAR = "'" (any character) "'"
STRING = '"' (any characters) '"'
Data types
We use integers, booleans, character, and list.
0 represents false, while other values represent true.
Identifier
Any continuous string consisting of lowercase letters, uppercase letters, Arabic numerals, and underscores is a valid identifier, except for the following:
- It has the same name as an existing keyword. Solution: Add 'my' in front or slightly modify the format.
- Starts with a number. Solution: Add an underscore before the number.
Functions
Functions uniformly use global variables instead of parameters. To be more precise, a function is actually a subroutine.
List Processing
append(list, value)will append something to the list.length(list)will return the size of the list.chr(value)will return the corresponding character with the encoding point of value.ord(value)will return the corresponding encoding point of the character value.
Example Programs
Hello, World!
let string = "Hello, World!"
let i = 0
while i < length(string) do
printch string[i]
end
Fibonacci
read n
call fib
print result
return 0
function fib
if n < 2 then
let result = n
return 0
else
let n1 = n - 1
let n2 = n - 2
let n = n1
call fib
let temp = result
let n = n2
call fib
let result = temp + result
return 0
end
end
Intepreter
Python
import sys
class MinilangInterpreter:
def __init__(self):
self.vars = {}
self.functions = {}
self.output = []
def parse(self, code):
lines = [line.strip() for line in code.split('\n') if line.strip()]
functions = {}
main_code = []
i = 0
while i < len(lines):
if lines[i] == 'function':
func_name = lines[i+1]
i += 2
func_body = []
while i < len(lines) and lines[i] != 'end':
func_body.append(lines[i])
i += 1
functions[func_name] = func_body
else:
main_code.append(lines[i])
i += 1
return main_code, functions
def eval_expr(self, expr):
expr = expr.strip()
# Handle string literals
if expr.startswith('"') and expr.endswith('"'):
return list(expr[1:-1])
# Handle character literals
if expr.startswith("'") and expr.endswith("'") and len(expr) == 3:
return expr[1]
# Handle list literals
if expr.startswith('[') and expr.endswith(']'):
if expr == '[]':
return []
elements = expr[1:-1].split(',')
return [self.eval_expr(elem.strip()) for elem in elements]
# Handle list indexing: var[expr]
if '[' in expr and expr.endswith(']'):
var_name, index_expr = expr.split('[', 1)
index_expr = index_expr[:-1] # Remove trailing ]
var_name = var_name.strip()
index = self.eval_expr(index_expr)
if var_name in self.vars and isinstance(self.vars[var_name], list):
if isinstance(index, int) and 0 <= index < len(self.vars[var_name]):
return self.vars[var_name][index]
return 0
# Handle built-in functions
if expr.startswith('length(') and expr.endswith(')'):
list_expr = expr[7:-1]
lst = self.eval_expr(list_expr)
return len(lst) if isinstance(lst, list) else 0
if expr.startswith('chr(') and expr.endswith(')'):
num_expr = expr[4:-1]
num = self.eval_expr(num_expr)
return chr(num) if isinstance(num, int) else ' '
if expr.startswith('ord(') and expr.endswith(')'):
char_expr = expr[4:-1]
char = self.eval_expr(char_expr)
return ord(char) if isinstance(char, str) and len(char) == 1 else 0
# Integer literals
if expr.isdigit() or (expr[0] == '-' and expr[1:].isdigit()):
return int(expr)
# Variables
if expr in self.vars:
return self.vars[expr]
# Comparisons
if '==' in expr:
left, right = expr.split('==', 1)
return 1 if self.eval_expr(left) == self.eval_expr(right) else 0
if '!=' in expr:
left, right = expr.split('!=', 1)
return 1 if self.eval_expr(left) != self.eval_expr(right) else 0
if '<' in expr:
left, right = expr.split('<', 1)
return 1 if self.eval_expr(left) < self.eval_expr(right) else 0
# Arithmetic
if '+' in expr:
left, right = expr.split('+', 1)
left_val = self.eval_expr(left)
right_val = self.eval_expr(right)
# Handle string concatenation or arithmetic addition
if isinstance(left_val, str) and isinstance(right_val, str):
return left_val + right_val
elif isinstance(left_val, int) and isinstance(right_val, int):
return left_val + right_val
else:
return 0
if '-' in expr and expr.count('-') == 1 and not expr.startswith('-'):
left, right = expr.split('-', 1)
return self.eval_expr(left) - self.eval_expr(right)
if '*' in expr:
left, right = expr.split('*', 1)
return self.eval_expr(left) * self.eval_expr(right)
if '/' in expr:
left, right = expr.split('/', 1)
right_val = self.eval_expr(right)
return self.eval_expr(left) // right_val if right_val != 0 else 0
# Unary minus
if expr.startswith('-'):
return -self.eval_expr(expr[1:])
# Parentheses
if expr.startswith('(') and expr.endswith(')'):
return self.eval_expr(expr[1:-1])
return 0
def execute(self, code, is_function=False):
i = 0
while i < len(code):
line = code[i]
if line.startswith('let '):
# Handle let x = expr and let x[index] = expr
rest = line[4:].strip()
if '[' in rest and ']=' in rest:
# List assignment: let var[index] = expr
var_name, rest = rest.split('[', 1)
index_expr, expr = rest.split(']=', 1)
var_name = var_name.strip()
index = self.eval_expr(index_expr)
value = self.eval_expr(expr.strip())
if var_name in self.vars and isinstance(self.vars[var_name], list):
if isinstance(index, int) and 0 <= index < len(self.vars[var_name]):
self.vars[var_name][index] = value
else:
# Regular assignment
parts = rest.split('=', 1)
var = parts[0].strip()
expr = parts[1].strip()
self.vars[var] = self.eval_expr(expr)
elif line.startswith('if '):
# if expr then ... [else ...] end
cond = line[3:].split('then', 1)[0].strip()
if self.eval_expr(cond):
j = i + 1
block = []
while j < len(code) and code[j] != 'else' and code[j] != 'end':
block.append(code[j])
j += 1
self.execute(block, is_function)
while j < len(code) and code[j] != 'end':
j += 1
i = j
else:
j = i + 1
while j < len(code) and code[j] != 'else':
j += 1
if j < len(code) and code[j] == 'else':
j += 1
block = []
while j < len(code) and code[j] != 'end':
block.append(code[j])
j += 1
self.execute(block, is_function)
i = j
elif line.startswith('while '):
# while expr do ... end
cond = line[6:].split('do', 1)[0].strip()
j = i + 1
block = []
while j < len(code) and code[j] != 'end':
block.append(code[j])
j += 1
while self.eval_expr(cond):
self.execute(block.copy(), is_function)
i = j
elif line.startswith('call '):
# call function or built-in
rest = line[5:].strip()
if rest.startswith('append(') and rest.endswith(')'):
# Built-in append function
args = rest[7:-1].split(',', 1)
if len(args) == 2:
list_expr = args[0].strip()
value_expr = args[1].strip()
lst = self.eval_expr(list_expr)
value = self.eval_expr(value_expr)
if isinstance(lst, list):
lst.append(value)
else:
# User-defined function
func_name = rest.split('(')[0].strip()
if func_name in self.functions:
self.execute(self.functions[func_name].copy(), True)
elif line.startswith('return '):
expr = line[7:].strip()
return self.eval_expr(expr)
elif line.startswith('print '):
expr = line[6:].strip()
value = self.eval_expr(expr)
if isinstance(value, list):
# Print list as string
self.output.append(''.join(str(c) for c in value))
else:
self.output.append(str(value))
elif line.startswith('printch '):
expr = line[8:].strip()
value = self.eval_expr(expr)
if isinstance(value, str) and len(value) == 1:
self.output.append(value)
elif isinstance(value, int):
self.output.append(chr(value))
else:
self.output.append('?')
elif line.startswith('read '):
var = line[5:].strip()
try:
value = int(input())
self.vars[var] = value
except:
self.vars[var] = 0
elif line.startswith('readch '):
var = line[7:].strip()
try:
char = input()[0] # Get first character
self.vars[var] = char
except:
self.vars[var] = ' '
i += 1
return 0
def run(self, code):
main_code, self.functions = self.parse(code)
self.execute(main_code)
return ''.join(self.output)
# Example usage and tests
if __name__ == "__main__":
interpreter = MinilangInterpreter()
# Test string reversal
reverse_code = """
let text = "hello"
let reversed = []
let i = length(text) - 1
while i >= 0 do
call append(reversed, text[i])
let i = i - 1
end
let i = 0
while i < length(reversed) do
printch reversed[i]
let i = i + 1
end
"""
print("String reversal test:")
print(interpreter.run(reverse_code))
print()
# Test list operations
list_code = """
let numbers = [1, 2, 3, 4, 5]
let sum = 0
let i = 0
while i < length(numbers) do
let sum = sum + numbers[i]
let i = i + 1
end
print "Sum: "
print sum
"""
print("List sum test:")
interpreter2 = MinilangInterpreter()
print(interpreter2.run(list_code))