mirror of
https://github.com/Noratrieb/GRSBPL.git
synced 2026-01-14 11:45:02 +01:00
for real
This commit is contained in:
parent
0b96e0dd0d
commit
e8967b3273
4 changed files with 237 additions and 0 deletions
159
README.md
Normal file
159
README.md
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
# GRSBPL - Generic Random Stack Based Programming Language
|
||||
|
||||
## line numbers are broken I know
|
||||
|
||||
uses some form of reverse polish notation
|
||||
|
||||
```
|
||||
1 5 * 5 +
|
||||
> 10
|
||||
```
|
||||
|
||||
There is a stack and variables. Operations are done on the stack, and you can store results in variables (a bit like in
|
||||
the JVM). The stack contains integer values. Floating point numbers are not supported.
|
||||
|
||||
When the program finishes (run to the end of the program), the last value on the stack is returned. If the stack is
|
||||
clear, 0 is always returned. If there is an error during execution, -1 is returned along with an error message to
|
||||
stderr.
|
||||
|
||||
## Operators and keywords:
|
||||
|
||||
### Values
|
||||
|
||||
* any number `<number>` -> push the numeric value of n
|
||||
* any character `'<character>'` -> push c as its escaped ascii value
|
||||
* `&<ident>` -> pop and store it in a variable
|
||||
* `@<ident>` -> load variable and push it, does not consume the variable
|
||||
|
||||
### Binary Operators
|
||||
|
||||
* `+` -> add two values on the stack, pops both and pushes the result
|
||||
* `-` -> subtract two values on the stack, pops both and pushes the result
|
||||
* `*` -> multiply two values on the stack, pops both and pushes the result
|
||||
* `/` -> divide, pops both and pushes the result
|
||||
* `%` -> mod, pops both and pushes the result
|
||||
* `bnot` bitwise not on stack value
|
||||
* `and` bitwise and
|
||||
* `or` bitwise or
|
||||
* `xor` bitwise xor
|
||||
|
||||
### Other operators
|
||||
|
||||
* `not` -> invert stack value (!=0 -> 0, 0 -> 1)
|
||||
* `dup` -> duplicate the value on the stack
|
||||
* `swap` -> swaps the 2 top stack values
|
||||
* `pop`-> pop a value and discard it
|
||||
|
||||
### IO
|
||||
|
||||
* `out` -> pop and output it to the console as ascii
|
||||
* `nout` -> pop and output as a number to the console
|
||||
* `in` -> push input char as ascii to the stack
|
||||
|
||||
### Control flow
|
||||
|
||||
* `:<ident>` -> define a label
|
||||
* `goto <ident>` -> goto a label if the value on the stack is !=0, peek
|
||||
* `function <ident> <digit>` -> define a function with the arg count, always return a single number
|
||||
* `<ident>` -> call a function, args have to be in the stack
|
||||
* `return` -> return from a function
|
||||
|
||||
### Other
|
||||
|
||||
* `# comment #` text between # is ignored
|
||||
* `# comment\n` text after # is ignored
|
||||
|
||||
`<ident>`: \w+, not a keyword
|
||||
`<number>`: \d+
|
||||
`<digit>`: \d
|
||||
`<character>`: single character
|
||||
|
||||
Character escape sequences:
|
||||
\n, \r, \\, \0, \', \b, \f
|
||||
Same meaning as in Java
|
||||
|
||||
## Functions
|
||||
|
||||
When a function is called, a new stack frame for that function is created. The amount of args that function expects is
|
||||
then popped of the stack and pushed onto that new stack frame, keeping the same order. After a function is finished, it
|
||||
can return, deleting the stack frame and all local variables, and returning the top value on the stack. This value is
|
||||
then pushed onto the parent stack. Execution now continues.
|
||||
|
||||
Since there are no blocks, a function missing a return keyword will simply continue to execute until it reaches the end
|
||||
or jumps due to gotos.
|
||||
|
||||
Function 'bodies' (there are no bodies) are not ignored by the main flow, and have to be explicitly skipped by gotos.
|
||||
It's recommended to place all functions at the end, and have one goto that ends the program by jumping to a label at the
|
||||
end
|
||||
|
||||
## Examples:
|
||||
|
||||
FizzBuzz
|
||||
|
||||
```grsbpl
|
||||
1 &i # init loop counter
|
||||
:start # set start label
|
||||
@i 100 - not goto exit # if i is 100, exit
|
||||
@i 15 % not goto print_fizz_buzz # fizzbuzz
|
||||
@i 5 % not goto print_buzz # buzz
|
||||
@i 3 % not goto print_fizz # fizz
|
||||
@i nout '\n' out # normal number
|
||||
:end # go back here after printing
|
||||
@i 1 + &i # increment i
|
||||
1 goto start # go back to the start
|
||||
|
||||
:print_fizz_buzz
|
||||
'F' out 'i' out 'z' out 'z' out 'B' out 'u' out 'z' out 'z' out '\n' out
|
||||
goto end
|
||||
:print_fizz
|
||||
'F' out 'i' out 'z' out 'z' out '\n' out
|
||||
goto end
|
||||
:print_buzz
|
||||
'B' out 'u' out 'z' out 'z' out '\n' out
|
||||
goto end
|
||||
|
||||
:exit 0
|
||||
```
|
||||
|
||||
Add function
|
||||
|
||||
```grsbpl
|
||||
1 2 add
|
||||
|
||||
function add 2
|
||||
+ return
|
||||
```
|
||||
|
||||
Recursive Factorial
|
||||
|
||||
```grsbpl
|
||||
10 factorial 1 goto exit
|
||||
|
||||
function factorial 1
|
||||
dup not goto isZero
|
||||
&del dup 1 - factorial * return
|
||||
:isZero
|
||||
1 return
|
||||
|
||||
:exit swap
|
||||
```
|
||||
|
||||
## Some Tips
|
||||
|
||||
* Increment a variable:
|
||||
`@i 1 + &i`
|
||||
* Goto if equal
|
||||
`@i 100 - not goto finished`
|
||||
* Goto not equal
|
||||
`@i 100 - goto finished`
|
||||
* Exit the program
|
||||
`... goto exit ... :exit 0`
|
||||
* Exit with exit code depending on the branch
|
||||
```grsbpl
|
||||
...
|
||||
69 swap goto exit # push 69 to the 2nd stack position
|
||||
...
|
||||
5 swap goto exit # push 5 to the 2nd stack position
|
||||
...
|
||||
:exit &del # pop the top stack value to expose the pushed value
|
||||
```
|
||||
38
errors.md
Normal file
38
errors.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# All GRSBPL Error Messages
|
||||
|
||||
## Syntax Errors
|
||||
|
||||
- Any uncaught exception occurs during lexing:
|
||||
`Unknown Syntax Error. <exceptionname>: <exceptionmessage>`
|
||||
|
||||
- Invalid character escaped:
|
||||
`Invalid escape sequence <escaped>`
|
||||
|
||||
- Integer parse failed (can only happen because number is too big)
|
||||
`Value not an integer: <number>`
|
||||
|
||||
## Runtime Errors
|
||||
|
||||
- Label not found
|
||||
`Label '<name>' not found`
|
||||
|
||||
- Function not found
|
||||
`Function '<name>' not found`
|
||||
|
||||
- Stack empty on return
|
||||
`Function has to return some value, but no value was found on the stack`
|
||||
|
||||
- Pop called on empty stack
|
||||
`Cannot pop empty stack`
|
||||
|
||||
- No stack frame left after return
|
||||
`Tried to return outside of function, probably forgot to skip a function`
|
||||
|
||||
- Stackoverflow - limit 1 000 000
|
||||
`Stackoverflow. Limit of <STACK_LIMIT> stack frames reached.`
|
||||
|
||||
- Invalid token found
|
||||
`Excepted token '<name>' but found '<name>'`
|
||||
|
||||
- Failed to read input from stdin
|
||||
`[VM] - Error reading input`
|
||||
9
fizzbuzz.grsbpl
Normal file
9
fizzbuzz.grsbpl
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
10 factorial 1 goto exit
|
||||
|
||||
function factorial 1
|
||||
dup not goto isZero
|
||||
pop dup 1 - factorial * return
|
||||
:isZero
|
||||
1 pop return
|
||||
|
||||
:exit pop dup nout
|
||||
31
pom.xml
Normal file
31
pom.xml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.github.nilstrieb</groupId>
|
||||
<artifactId>GRSBPL</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.6.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.6.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>14</maven.compiler.source>
|
||||
<maven.compiler.target>14</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
Loading…
Add table
Add a link
Reference in a new issue