Recently, I completed a course on programming languages where I learned how programming languages are designed and how to implement them (specifically in this class, I built and implemented a subset of javascript). Closer to the end of the course I was thinking about potentially using those skills to build a simple language in Roblox, implementing some really basic things (basic variables, lists, loops, math, prints, if/elses) and potentially building a game to teach some of the basics of programming to newer users.
The game itself would proabably be a set of simple lessons, that teach users how to use each of the implemented functionalities and gives them a window with a console output and an area to type their code. I think this would be something nice to create for those who dont have any expereince in programming, as sometimes they can be intimidated by all the features packed into Roblox Studio and have no idea where to start (at least, thatâs how it was for me when I was at that stage) and give them somewhere to learn the fundamentals of programming on roblox.
This was just an idea I had and Iâm not sure if Iâll ever go through with it, so I wanted to put it out there for anyone who would be interested in developing it or sharing some ideas.
Edit: There also could be a lot of challenges making this comply with Roblox TOS and rules (e.g. text filtering on variable names and print statements)
Some more specific ideas on how I was going to implement this:
Stack/heap would be implemented as dicts [var name â value], as using a dict to represent these would make it easier to allow for dynamic typing (like Lua).
Only strings, numbers, and booleans would be implemented
Potentially implement functions? This was pretty hard to do in my javascript implementation but that was also because I had to use a language that was really difficult in the first place (OCaml sucks)
Lists/loops werenât things we covered the implementation of in my class but I think if you wanted to build an educational tool these would be important to implement.
Actually really interested in this idea. I have tried multiple times but that was a while ago. I would like to ask if you would use a plugin or use a roblox studio mod to insert a new language into studio. The main issue with this would actually be running the scripts. How would you go about that?
I wouldnât worry about this because of the filter function provided. And as long as the players donât see the messages, you should be good.
While I think itâs a great idea as a personal project, on ROBLOX I donât think it will have much practical use outside of it being a personal project. You mentioned that it can be used to teach others how to program but Iâm not sure how many people want to learn programming through an unknown language you invented.
But that aside, it sounds like a great thing you can do for yourself I just donât think you should expect it to have much use outside of being a learning experience for you.
Wouldnât recommend Luau for making a language but you can still use it.
Then again, anything youâd like to do.
Would be extremely simple to make a lexer with a for loop and string.gmatch (could possibly use string patterns) instead of constantly subbing out each character.
The rest would also be simple, not sure if you did a course on bytecode or tree walk but
Bytecode might be more difficult in Luau. Why?
Bytecode might be more complex due to:
Having linear execution
Being stack-based
Registers
Jump Labels
Stack functions
And overall having NO access to memory or memory functions/methods.
I created a lexer in Luau, if I can find it Iâll drop the source code.
Anyways, I wish you the best of luck on this. If youâre stuck, please remember to do your research and at least take a break.
How I implemented it for the course was basically designing functions that did all the basic steps individually (lexing, parsing, tokenizing, evaluating, ect.) and then fed a string of code to a program that called all the functions and evaluated the output. My idea was basically doing the same thing, except putting it in a module script that you basically just called module.runthiscode("your string of code here") and let the module call all the neccesary functions in order, and give you back your output. Havenât put too much thought into it, so thats all I really had for now
Ideally I would be implementing a subset of Lua so it would be more applicable, but yeah there would probably be better ways to learn programming than this. Just thought it was a fun way to make a personal project more usable by other people
Thats a valid concern, if I did this myself it would definitely be a lot of looking back on my javascript interpreter and my notes from the course (and a lot of debugging but I try not to think about that too much). I was thinking of using dicts to ârepresentâ memory to get around directly accessing it and use as many other shortcuts as Lua gives me, but it would dfinitely still be a challenge.
Would be a nice idea honestly. You could even make your own âstackâ or environment with push and pop functions and the internals just being an array (literally what a stack is).
Found the Lexer, here it is:
Luau Lexer
--Created by TheUnderratedDev
--Date: Unknown
--If you don't understand this, visit https://craftinginterpreters.com/ to learn more about lexers and programming languages
--This could have been optimized more with other things, but I'd rather do it how you would do it in C++/JS with little string patterns and a "switch statement" being a for loop
local Source = [[
local a = "d"
require(a)
]]
local Data = {}
--Util data for the lexer
local Specials = {
Current = 0,
Advance = 0
}
--Lexemes array containing lexemes and their token
local Lexemes = {
["("] = "LPAREN",
[")"] = "RPAREN",
["="] = "EQUAL"
}
--Keywords array
local Keywords = {
["require"] = "REQUIRE",
["getfenv"] = "GETFUNCTIONENV",
["local"] = "LOCAL",
["tonumber"] = "TONUMBER",
}
--Adds a token to the array
function addToken(type, val)
Data[#Data + 1] = {
Token = type,
Value = val
}
end
--Just formats and prints out the tokens
function toString()
local main = ""
for i, v in pairs(Data) do
local other = " { TOKEN: %s, VALUE: %s }\n"
main ..= string.format(other, v.Token, v.Value)
end
return string.format("{\n%s}", main)
end
--Checks if the identifier is a built in keyword, if it is then create a token of the keyword, if not make an identifier token
function keyword()
local start = Specials.Current
local str = string.sub(Source, start, -1)
local collected = ""
local count = 0
for i in string.gmatch(str, ".") do
if (not string.match(i, "%w")) then
break
end
count += 1
collected ..= i
end
local Find = Keywords[collected]
if (Find) then
addToken(Find, collected)
else
addToken("IDENTIFIER", collected)
end
return count - 1
end
--Checks if the current is a number, if so then continue checking if the preceding characters are also numbers. This supports decimals
function number()
local start = Specials.Current
local str = string.sub(Source, start, -1)
local collected = ""
local count = 0
for i in string.gmatch(str, ".") do
if (i == ".") then
count += 1
collected ..= "."
continue
end
if (not string.match(i, "%d")) then
break
end
count += 1
collected ..= i
end
local num = tonumber(collected)
if (num) then
addToken("NUMBER", collected)
end
return count - 1
end
--WIP
function strng()
local start = Specials.Current + 1
local str = string.sub(Source, start, -1)
local collected = ""
local ended = false
local count = 0
for i in string.gmatch(str, ".") do
if (i == "\"") then
count += 1
ended = true
break
end
count += 1
collected ..= i
end
addToken("STRING", collected)
return count
end
--MAIN
for i in string.gmatch(Source, ".") do
Specials.Current += 1
--Whitespace? Continue
if (string.match(i, "%s")) then
continue
end
--Checks if it should skip the current character and advance the for loop to a set number. If Specials.Advance is 2, skip 2 iterations
if (Specials.Advance > 0) then
Specials.Advance -= 1
continue
end
--Finding out if the current is a special character like "(" and returning the token for it
local Find = Lexemes[i]
--If found then add the token and continue
if (Find) then
addToken(Find, i)
continue
end
--If the current is an alphabetic character then call the keyword function
if (string.match(i, "%a")) then
Specials.Advance = keyword()
continue
end
--If the current is a number, call the number function
if (string.match(i, "%d")) then
Specials.Advance = number()
continue
end
end
print(toString()) -- Prints all tokens
If you run this with Luau (or MAYBE Roblox), youâll get this result: