Automata Project for 3rd Year
- Create a virtual environment
python -m venv .env
- Activate environment For CMD
.env\scripts\activate
For bashsource .env/bin/activate
- Install UwU Console Script Package (below)
-
Install the UwU Console Script Package
python -m pip install ./packages/uwu
-
To install | uninstall packages from
requirements.txt
uwu install
uwu uninstall
- To install | uninstall individual packages
uwu install < package name >
uwu uninstall < package name >
- To run all tests
uwu test
- To run a specific test
uwu test test_*
uwu test *_test
-
To build UwU IDE
uwu build
-
To run lexer package
uwu lexer
. Lexed text is in./files/package-lexer.uwu
-
To run parser package
uwu parser
. Parsed text is in./files/package-parser.uwu
-
To run analyzer package
uwu analyzer
. Analyzed text is in./files/package-analyzer.uwu
-
To run the compiler package
uwu compile
. Compiled text is in./files/packages-compile.uwu
- For unit testing, we'll be using
pytest
- To create a test file, simply follow these file formats:
test_*.py
or*_test.py
- For more information, please refer to the official Pytest documentation
All programs must have a mainuwu function
- must have no arguments
- must return nothing (aka return type
san
)
>.< this is a comment
fwunc mainuwu-san() [[
pwint("hello", "world")~
]]
output: hello world
Printing to console can be done using the builtin pwint
function.
- takes a variable amount of arguments of any type.
- arguments are separated by space when printed
Taking input from user can be done using the builtin inpwt
function.
- takes one argument only (any type)
- arg will be printed to the console as the prompt
- will read user input until the user presses enter.
- user input will be implicitly converted to the type declared if
inpwt()
is the right hand side of a declaration/assignment inpwt()
can also be a standalone statement, not needing to be on the right hand side of a declaration/assignment
>.< this is a comment
fwunc mainuwu-san() [[
>.< inpwt is implicitly converted to senpai
name-senpai = inpwt("what is your first name?: ")~
pwint("hello", name, "\n")~
age-chan = 0~
>.< inpwt is implicitly converted even in assignments
>.< here, age is still a chan
age = inpwt("what is your age?: ")~
pwint(age, "was my age a few weeks ago!\n")~
>.< inpwt as a standalone statement
inpwt("Press Enter to exit...")~
]]
output:
what is your name?: uwu
hello uwu
what is your last name?: 1000
1000 was my age a few weeks ago!
Press Enter to exit...
- Variable declarations are in the format:
name-type = value~
- Assignments are done in the format:
name = value~
.
global-chan = 99~
fwunc mainuwu-san() [[
>.< this is constant
num-chan = 1~
>.< reassigning global variable
global = 0~
pwint(global, num, global2)~
]]
global2-chan = 2~
output: 0 1 2
Function declarations are in the format:
fwunc name-type(param-type, param2-type) [[ ... ]]
>.< this is a comment
fun main-san() [[
pwint(sum(2,3))~
]]
>.< args: two chan
>.< returns: chan
fun sum-chan(left-chan, right-chan) [[
wetuwn(left + right)~
]]
output: 5
chan
: integer
declaration:aqua-chan = 1~
kun
: float
declaration:shion-kun = 1.0~
senpai
: string
declaration:ojou-senpai = "hi"~
senpai
literals are enclosed in"
- indexing into a
senpai
value returns anothersenpai
value
aqua-senpai = "hello"~ peko-senpai = aqua[1]~
- indexing into a
sama
: boolean
declaration:lap-sama = fax~
(True)
declaration:lap-sama = cap~
(False)
san
: null- used for functions that never return anything
- identifiers that have this type can only have the value
nuww
(null)
function declaration:fwunc mainuwu-san() [[ ... ]]
declaration:aqua-san = nuww~
declare a constant by adding -dono
after the type declaration:
aqua-chan-dono = 1~ >.< constant int
shion-senpai-dono = "hwats!?" >.< constant string~
- Classes are user defined types with properties and methods
- Format:
cwass CwassName() [[
property1-chan~
fwunc method1-senpai() [[
wetuwn("woah")~
]]
]]
- Declare a variable with a
cwass
type in this format:
name-CwassName = CwassName()~
- Add constructor parameters to a class by:
cwass CwassName(constructorParam1-chan, constructorParam2-senpai) [[
property1-chan~
]]
fwunc mainuwu-san() [[
>.< all constructors must be initialized
var-CwassName = CwassName(1, "hello")~
]]
- Access properties and methods from a variable using
.
cwass CwassName(constructorParam1-chan, constructorParam2-senpai) [[
property1-chan~
fwunc method-senpai() [[
wetuwn("hello method")~
]]
]]
fwunc mainuwu-san() [[
var-CwassName = CwassName(1, "hello")~
pwint(
var.property1,
var.constructorParam1,
var.constructorParam2,
var.method()
)~
]]
- Inside a class, you do not need
self
orthis
to access properties and constructor params. Just use it as normal like so:
cwass CwassName(constructorParam1-chan) [[
property1-chan~
fwunc method1-chan() [[
wetuwn(property1 + constructorParam1)~
]]
]]
Use iwf
, ewse
, and ewif
for branching. Enclose condition in parentheses
fwunc mainuwu-san() [[
aqua-chan = inpwt("input a number: ")~
iwf (aqua > 1) [[
pwint(aqua, "is less than 1")
]] ewse iwf (aqua == 1) [[
pwint("one")
]] ewse [[
pwint(aqua, "is more than 1")
]]
]]
output:
input a number: 3
3 is more than 1
Execute block of code as long as condition stays true. Format:
fwunc mainuwu-san() [[
aqua-chan = 0~
whiwe (aqua < 18) [[
aqua = inpwt("How old are you?: ")~
]]
pwint("ok")~
]]
output:
How old are you?: 10
How old are you?: -1000
How old are you?: 18
ok
Format is:
fow (init~ condition~ update) [[ ... ]]
where:
init
is the initial value declarationcondition
is the stop condition of the for loopupdate
is the update assigned to the initial value on each iteration
>.< this is a comment
fwunc mainuwu-san() [[
>.< print 1 to 3
fow (i-chan = 1~ i <= 3~ i+1) [[
pwint(i)~
]]
pwint()~
>.< keep prompting the user until they type "uwu"
fow (
a-senpai = ""~
a == "uwu"~
a = inpwt("input owo: ")
) [[
pwint(a)~
]]
pwint("\ndone")~
]]
output:
1
2
3
' '
input owo: no
'no'
input owo: NO!
'NO!'
input owo: owo
'uwu'
done!