Ruby on Spaces

Ruby on Spaces is a small experimental programming language built entirely in Python (with a Luau port for ver 2.1). It’s designed as a learning project in language design, parsing, and interpreter building, while still being usable for toy projects, scripting, or experimentation.

This language is minimal, hackable, and deliberately verbose. It’s not about performance — it’s about showing how a working interpreter can be constructed, extended, and modified.

If you are just here for the install go to Install page


Overview


Core Features


Example Programs

# Variables and math
x = 10
y = 20
z = x + y
print("Sum:", z)

# Conditionals
if (x < y)
    print("x is less than y")
end

# While loop
while (x < 15)
    print("x =", x)
    x = x + 1
end

# For-in loop
for item in [1, 2, 3]
    print("Item:", item)
end

# C-style for loop
for (i = 0; i < 3; i = i + 1)
    print("i:", i)
end

# Functions
def greet(name)
    print("Hello,", name)
end
greet("World")

# Methods on objects
person = {}
def person.new(self, name)
    self.name = name
end
def person.greet(self)
    print("Hi, I'm", self.name)
end
allen = person
allen.new("allen")
allen.greet()

Syntax Reference


Runtime Model


Extending the Language

Adding a builtin (Python)

def py_upper(args_wrapped):
    s = unwrap_from_py(args_wrapped[0])
    return wrap_for_py(s.upper())

env = make_global_env()
register_pyfunc(env, "upper", py_upper)
run('''
print(upper("hello, world"))
end
''')

Adding a builtin (Luau)

local ROSL = require(...)
local function concat(args)
  local vals = ROSL.unwrapArgs(args)
  return ROSL.wrap(vals[1]..vals[2])
end
local env = ROSL.BasicEnv()
ROSL.registorFunc(env, "concat", concat)
ROSL.run([[
  print(concat("Hello, ", "World"))
  end
]], env)

Adding keywords/syntax

Edit KEYWORDS, parser methods, runtime eval.

Adding operators

Change precedence in Parser.lbp, parsing in led, runtime eval.


Running

# Run a file
python ruby.py program.rbs

# REPL
python ruby.py
>>> x = 5
>>> def sq(n) return n*n end
>>> print(sq(x))

Grammar

program        ::= block EOF
block          ::= { stmt (NL | ";")* } [ "end" ]
stmt           ::= exprstmt | assign | defstmt | methoddef | returnstmt
                 | ifstmt | whilestmt | forstmt
exprstmt       ::= expression
assign         ::= lvalue "=" expression
defstmt        ::= "def" ID "(" [paramlist] ")" block "end"
methoddef      ::= "def" ID "." ID "(" [paramlist] ")" block "end"
returnstmt     ::= "return" expression
ifstmt         ::= "if" expression block "end"
whilestmt      ::= "while" "(" expression ")" block "end"
forstmt        ::= "for" "(" stmt ";" expression ";" stmt ")" block "end"
                 | "for" ID "in" expression block "end"
paramlist      ::= ID { "," ID }
expression     ::= primary { infixop expression }
primary        ::= NUMBER | STRING | "true" | "false" | "null" | ID
                 | "(" expression ")" | listliteral | dictliteral
                 | "-" expression | "+" expression
listliteral    ::= "[" [ expression { "," expression } ] "]"
dictliteral    ::= "{" [ dictentry { "," dictentry } ] "}"
dictentry      ::= (STRING | ID) ":" expression
infixop        ::= "+" | "-" | "*" | "/" | "<" | ">" | "<=" | ">="
                 | "==" | "!=" | "." | "[" expression "]" | call
call           ::= "(" [ expression { "," expression } ] ")"
lvalue         ::= ID | prop | index
prop           ::= expression "." ID
index          ::= expression "[" expression "]"

See the GitHub README for source and updates.