Mo - Modern, Expressive, Fast Programming Language
Project description
Mo Language
Mo is a lightweight, dynamically-typed scripting language with a clean syntax, a bytecode compiler, and a growing standard library.
fn greet(name) {
print("Hello, " + name + "!")
}
greet("world")
Installation
pip install mo-language
After installing, use the mo command:
mo program.mo
Windows users: If
mois not found after install, add Python's Scripts folder to your PATH.
Mac/Linux users: Ifmois not found, run the command the installer prints.
Language Guide
Variables
let x = 42
let name = "Mo"
let flag = true
let nothing = null
Reassign with = (no let):
x = x + 1
Types
| Type | Example |
|---|---|
| Number | 3.14, 100 |
| String | "hello" |
| Bool | true, false |
| Null | null |
| List | [1, 2, 3] |
| Dict | {"key": "value"} |
Operators
1 + 2 # arithmetic: + - * /
x == y # equality: == !=
x < y # comparison: < > <= >=
true && false # logical: && ||
!true # not
String concatenation uses +:
let msg = "Hello, " + "world"
Control Flow
if x > 0 {
print("positive")
} else if x < 0 {
print("negative")
} else {
print("zero")
}
let i = 0
while i < 5 {
print(i)
i = i + 1
}
for item in [1, 2, 3] {
print(item)
}
Functions
fn add(a, b) {
return a + b
}
let result = add(3, 4) # 7
Functions are first-class values:
let double = fn(x) { return x * 2 }
Lists
let nums = [10, 20, 30]
print(nums[0]) # 10
push(nums, 40) # append
let last = pop(nums) # remove last
print(len(nums)) # 3
Dicts
let user = {"name": "Alice", "age": 30}
print(user["name"]) # Alice
user["age"] = 31
for k in keys(user) {
print(k + ": " + str(user[k]))
}
Dict keys can also be accessed with .:
print(user.name)
user.age = 32
Classes
class Animal {
fn init(name) {
self.name = name
}
fn speak() {
print(self.name + " makes a sound")
}
}
class Dog extends Animal {
fn speak() {
print(self.name + " barks")
}
}
let d = Dog("Rex")
d.speak() # Rex barks
Error Handling
try {
throw "something went wrong"
} catch e {
print("Caught: " + e)
}
Imports
import "std/math"
print(math_sqrt(16)) # 4.0
Standard Library
All stdlib modules are imported with import "std/<name>".
std/math
import "std/math"
math_sqrt(x) # square root
math_pow(x, n) # power
math_abs(x) # absolute value
math_floor(x) # floor
math_ceil(x) # ceiling
math_round(x) # round
math_min(a, b) # minimum
math_max(a, b) # maximum
math_log(x) # natural log
math_sin(x) # sine (radians)
math_cos(x) # cosine
math_tan(x) # tangent
math_pi() # π ≈ 3.14159
std/random
import "std/random"
random_int(1, 10) # random integer in [min, max]
random_float() # random float in [0, 1)
random_pick([1,2,3]) # random element from list
std/time
import "std/time"
time_now() # Unix timestamp (float)
time_ms() # milliseconds since epoch
time_sleep(1.5) # sleep for N seconds
time_format(ts, fmt) # format timestamp, e.g. "%Y-%m-%d"
time_str(ts) # ISO date string
std/json
import "std/json"
json_parse('{"a": 1}') # string → dict/list
json_stringify(obj) # dict/list → string
json_pretty(obj) # pretty-printed string
std/file
import "std/file"
read("file.txt") # read file as string
write("file.txt", content) # write string to file (overwrite)
append("file.txt", content) # append to file
exists("file.txt") # true/false
delete_file("file.txt") # delete file
list_dir(".") # list directory → list of names
std/http
Requires no extra packages (uses Python's built-in http.server).
import "std/http"
serve(8080, fn(req) {
return text("Hello, " + req.path)
})
Helper response builders:
text(body) # 200 text/plain
html(body) # 200 text/html
json_resp(data) # 200 application/json
redirect(url) # 302
not_found() # 404
bad_request(msg) # 400
error(msg) # 500
HTTP client:
let res = fetch("https://example.com/api")
let res = fetch_post("https://example.com/api", json_stringify(data))
std/os
import "std/os"
os_name() # "posix" or "nt"
os_cwd() # current working directory
os_home() # home directory
os_env("PATH") # environment variable value
os_cpus() # number of CPU cores
std/path
import "std/path"
path_join("dir", "file.txt") # join path segments
path_dir("/a/b/c.txt") # "/a/b"
path_base("/a/b/c.txt") # "c.txt"
path_ext("/a/b/c.txt") # ".txt"
path_abs("relative.txt") # absolute path
std/url
import "std/url"
url_parse("https://example.com/p?q=1") # dict with host, path, query, …
url_encode("hello world") # "hello+world"
url_decode("hello+world") # "hello world"
std/process
import "std/process"
proc_args() # list of command-line arguments
proc_pid() # current process ID
proc_exit(0) # exit with code
proc_env("HOME") # environment variable (alias for os_env)
std/crypto
import "std/crypto"
crypto_md5("hello") # hex digest string
crypto_sha1("hello") # hex digest string
crypto_sha256("hello") # hex digest string
Built-in Functions
| Function | Description |
|---|---|
print(x) |
Print value |
len(x) |
Length of string/list/dict |
str(x) |
Convert to string |
num(x) |
Convert to number |
type(x) |
Type name string |
range(n) / range(a,b) |
List of integers |
push(list, val) |
Append to list |
pop(list) |
Remove and return last element |
keys(dict) |
List of dict keys |
has(dict, key) |
True if key exists |
delete(dict, key) |
Remove key from dict |
input(prompt) |
Read line from stdin |
floor(x) |
Floor |
ceil(x) |
Ceil |
round(x) |
Round |
abs(x) |
Absolute value |
Testing
Run pytest Suite (Recommended)
pip install pytest
pytest tests/test_basic.py -v
The pytest suite covers core language features:
- Variables, operators, functions
- Lists, control flow (if/while/for)
- Exceptions (try/catch/throw)
- Built-in functions
Run Python Test Runner
python tests/test_runner.py # run all tests
python tests/test_runner.py -v # verbose mode
python tests/test_runner.py test.mo # run specific file
The test runner discovers .mo test files in tests/, runs them with mo, and checks exit code.
Run Mo Test Files Directly
mo tests/run_tests.mo
Note: Some test files may have parser compatibility issues with newer language features.
Example test metadata file (tests/foo.mo.meta.json):
{
"exit_code": 0,
"output": "42"
}
CLI Reference
mo program.mo # run with bytecode VM (default)
mo --interp program.mo # run with tree-walk interpreter
mo --dis program.mo # disassemble bytecode
mo # interactive REPL
Requirements
- Python 3.9+
- No external dependencies (stdlib only)
std/http fetch functions use urllib (built-in). For advanced HTTP needs, install requests separately.
Advanced Features
Type System
let x: int = 42 # type annotation
let y = 10 # int # type comment
is_number(x) # check type
is_string(x)
is_bool(x)
is_list(x)
is_dict(x)
cast(x, "string") # type cast
std/regex
import "std/regex"
regex_match("^[a-z]+", "hello") # true/false
regex_replace("cat", "the cat sat", "dog") # "the dog sat"
regex_split("\\s+", "a b c") # ["a", "b", "c"]
std/sqlite
import "std/sqlite"
let db = sqlite_open("data.db")
let rows = sqlite_exec(db, "SELECT * FROM users WHERE age > ?", [18])
for row in rows {
print(row["name"])
}
sqlite_close(db)
std/yaml
import "std/yaml"
yaml_parse("key: value") # string → dict
yaml_stringify({"key": "val"}) # dict → string
std/xml
import "std/xml"
xml_parse("<root><item>text</item></root>") # string → element
xml_to_string(elem) # element → string
std/csv
import "std/csv"
csv_read("data.csv") # list of dicts
csv_write("output.csv", [{"a": "1"}]) # write list of dicts
std/net
import "std/net"
let sock = net_listen(8080)
while true {
let conn = net_accept(sock)
let data = net_recv(conn)
net_send(conn, "HTTP/1.0 200 OK\r\n\r\nHello")
net_close(conn)
}
std/gui
GUI module using Python's tkinter (requires pip install pillow for images).
import "std/gui"
let win = window("My Game", 800, 600)
rectangle(100, 100, 50, 50, "#00ff00")
circle(300, 200, 30, "#ff0000")
text(100, 160, "Player", 16, "#ffffff")
line(0, 0, 800, 600, "#888888")
on_click(fn(pos) {
print("Clicked at: " + str(pos))
})
on_key(fn(key) {
print("Pressed: " + key)
})
loop()
std/audio
import "std/audio"
audio_play("sound.mp3")
Package Manager
Mo has a package ecosystem for sharing reusable modules.
Search packages
mo search redis
mo search http
Install packages
mo install user/repo # from GitHub
mo install user/repo@v1.0.0 # specific version
mo install https://example.com/foo.mo # direct URL
List installed packages
mo list
Remove a package
mo remove <package-name>
Publish a package
mo publish
See mo publish for detailed publishing instructions.
LSP (Language Server Protocol)
Mo includes an LSP server for IDE editor support (hover, completion, diagnostics).
Start LSP Server
mo lsp # Start via stdio
mo lsp --stdio # Explicit stdio mode
mo lsp --tcp --port 8765 # TCP mode on port 8765
VS Code Extension
A VS Code extension scaffold is provided in mo-vlang/:
package.json- VS Code extension configurationsyntaxes/mo.tmLanguage.json- Syntax highlightingsrc/extension.ts- LSP client
To install the extension:
cd mo-vlang
npm install
code .
# Press F5 to run the extension in development mode
Supported Features
- Hover: Hover over variables to see their type
- Completion: Auto-complete keywords and symbols
- Diagnostics: Real-time syntax error reporting
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mo_language-0.2.0.tar.gz.
File metadata
- Download URL: mo_language-0.2.0.tar.gz
- Upload date:
- Size: 114.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d10a738fd2f01d44a2dcee5f6074167f0244577ace5e37bc5e162a41e7715b46
|
|
| MD5 |
b44f87df1a1cfd035fa7e1f61c9101ba
|
|
| BLAKE2b-256 |
c854e5ecd0deebed972b36c5463bbb4367cb27be69ab2115252fdf79e8c119b2
|
File details
Details for the file mo_language-0.2.0-cp39-cp39-macosx_10_9_universal2.whl.
File metadata
- Download URL: mo_language-0.2.0-cp39-cp39-macosx_10_9_universal2.whl
- Upload date:
- Size: 180.7 kB
- Tags: CPython 3.9, macOS 10.9+ universal2 (ARM64, x86-64)
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8d0a7024b1e7e8527d5e9b302089f933068f6709588b756febf9116dbaca26d
|
|
| MD5 |
231be7ab3455a17bcf75744e767858a1
|
|
| BLAKE2b-256 |
3f97f5adb7102f1700fe5275a5fe4ca710f685a7d38b28201fc7e38f606c1c11
|