Litteraly everybody working in IT has at least touched code once and is able to write a simple Hello World program. It is however, a common occurance that it's hard for people to explain to interested non-IT people (for example family members) what they're doing on a daily basis. Most languages feature all kinds of fancy operators and syntax requirements that're very powerful, but prevent non-IT people from trying a little something out themselves. In these kind of situations, SRPL comes into play; the SupeR simPle Language!
Course requirements: Check the course markdown file for description of meeting course requirements.
SRPL can interpret a file, can be used as a shell and is able to compile files to assembly. To start the shell, execute python srpl.py in the commandline. To run 'main.srpl' execute python srpl.py main.srpl in the commandline. Please note that the newlines can be replaced by semicolons and that every line in the file needs to end with a space. To compile an SRPL sourcefile, execute python srpl.py example/source/even.srpl example/source/even.asm. The SRPL sourcecode in even.srpl will then be compiled to assembly in even.asm. For large code-bases one can (luckily) compile all SRPL source files in any parent-directory by executing compile in the SRPL shell.
The compiler has been written with compatibility and simplicity in mind; it's very efficient most of the times, but for example the checking of conditions is done in such a way that it's easier to read than it is fast. This checking of conditions is done by first storing the boolean representation in a register and then checking for it being larger than 0. This could also have been done with a more complex branch statement, but hey; the method described above is very suited to the ideology behind SRPL.
Furthermore, only the really used registers are pushed to the stack and there's a neat optimization that recognizes registers being used in either case of an if-statement. This results in registers being allowed to be used in both the if- and else-statement. Other than that, there's one more feature that's very suited to SRPL; informative comment generation. This allows for easy checks of the compiled assembly files.
Last but not least, the compiler has been tested extensively with the help of unit-tests. These can be found in the example directory and can be compiled with the compile command in the SRPL shell.
Everything has been documented with usability and neccesity in mind. This boils down to not documenting every method or function, but just making sure every 'type' of function has at least been documented once. Documenting every operator of a number for example, would be useless and even distracting.
The heart of this language is the number. Numbers can be an integer or a float. Furthermore, a true is seen as a Number larger than 0.
flush 5.3 plus 4 variable day is 6 flush day is_larger_than_or_equal_to 5 Of course a language should support simple math with taking the order of operations into account.
variable sum is 5 plus 3 variable product is sum multiplied_by 3 variable part is product divided_by 2.1 variable freezing is part min 90 Functions (when interpreted) can have zero or more parameters and can return zero or more values. Furthermore, a file can contain multiple functions.
task add with a and b contains flush a plus b end variable sum is execute add with 3 and 5 now flush sum While-loops are fully supported. An error is printed when loop is infinite.
variable i is 1 while i is_less_than 5 then variable i is i plus 1 end flush i For-loops are fully supported as of version 2.1. Not just a simple version though; with custom stepsize that can be both positive or negative.
task fact with n contains variable result is 1 for variable i is 2 to n then variable result is result multiplied_by i end flush result end If statements can have an optional else statement. Furthermore, all conventional conditions are supported. For a complete list; check out tokens.py.
variable fun is 5 flush if fun is_greater_than 8 then ; 22 else 10 end Functions are first-class citizens; they can be stored in variables and passed to functions.
task apply with number and lambda contains execute lambda with number now end task makeTwenty with n contains variable n is 20 flush n end variable applyCopy is apply variable wasntTwenty is 18 variable wasntTwenty is execute applyCopy with wastnZero & makeTwenty now flush wasntTwenty Unlike most other languages, functions and the file can return multiple values. This has been done since it's more natural to non-it people. Executing multiple tasks yields multiple results; not one single. As one can imagine, this doesn't work when it's compiled to assembly. Then only the last return statement is effective.
task multi contains flush 3 flush 5 execute multi now Error handling is also a little less conventional. It is able to determine when things are missing and it prints an error message in the terminal, but it still tries to continue. Very life-like again; when you fall with the bike on your way to the train-station, you (hopefully) stand up and continue your commute. You don't end your day there... If you're curious as to how this functions; try it out yourself.
task add with a and b contains flush a plus b end variable result is execute add with 3 & 5 now variable sum is add variable otherResult is execute sum with 4 & 5 now flush result flush otherResult variable i is 1 while i is_less_than 5 then variable i is i plus 1 end flush i task odd with n contains flush if n is_equal_to 0 then 0 else execute even with n min 1 now end end task even with n contains flush if n is_equal_to 0 then 1 else execute odd with n min 1 now end end variable evenCopy is even flush execute even with 4 now flush execute odd with 4 now flush execute evenCopy with 3 now flush execute odd with 3 now task apply with number and lambda contains execute lambda with number now end task makeTwenty with n contains variable n is 20 flush n end variable wasntTwenty is 18 variable wasntTwenty is execute apply with wastnZero & makeTwenty now flush wasntTwenty task sommig with n contains variable result is 0 while n is_greater_than_or_equal_to 1 then variable result is result plus n variable n is n min 1 end flush result end flush execute sommig with 5 now flush execute sommig with 34 now task fact with n contains variable result is 1 for variable i is 2 to n plus 1 then variable result is result multiplied_by i end flush result end flush execute fact with 5 now flush i task neg_for with n contains variable result is 1 for variable i is 10 to 0 step 0 min 2 then variable result is result plus i end flush result end flush execute neg_for with 5 now Output:
[8, 9, 5, 1, 0, 0, 1, 20, 15, 595, 120, 5, 31]