Compare commits
63 Commits
b19b4123d8
...
diamondnet
| Author | SHA1 | Date | |
|---|---|---|---|
| 945f70d756 | |||
| 5ff3e8a86a | |||
| 9dbef7f8a8 | |||
| c0a7698497 | |||
| c4ebca9ed9 | |||
| bfbcd376df | |||
| 28faf6142c | |||
| 063cdc92e3 | |||
| 0a962b569a | |||
| d7b0c4d818 | |||
| 93eec33e60 | |||
| ab4b7e6aae | |||
| 39dc320f5d | |||
| 1147383ece | |||
| cc896629f7 | |||
| 2fd344af82 | |||
| 4fc76e99da | |||
| cdd1d32cee | |||
| 3495268672 | |||
| 9e329968d1 | |||
| e56c560514 | |||
| 9cbe546e8a | |||
| d9790711c6 | |||
| 310fede3ec | |||
| a4eba4ae47 | |||
| e2a037befc | |||
| 872392c1c5 | |||
| 2e1e2e727b | |||
| 38681f72d7 | |||
| 9c8cd58449 | |||
| 074b473bb1 | |||
| a3b9cd2519 | |||
| 76205a613d | |||
| 7961195018 | |||
| e73e5a7ebc | |||
| 06ed44a010 | |||
| d8cc3ff9e0 | |||
| f32f76450a | |||
| cea66aa583 | |||
| 8d80416c5c | |||
| 0eb5670dfd | |||
| 8247ba36e4 | |||
| 76e36b7ca3 | |||
| 6596bfcc85 | |||
| a9bfc1b0e3 | |||
| c952be1fe6 | |||
| 1c5ca8d201 | |||
| e56e6de911 | |||
| 38b17e7db5 | |||
| e74e5ea548 | |||
| f5140e3833 | |||
| c01dd470e1 | |||
| 16660c6a8d | |||
| 5bd8519517 | |||
| 2f706e2285 | |||
| db99b9ac9f | |||
| e906734aca | |||
| 8da5a2bf93 | |||
| e9600d8500 | |||
| 1c0dfcc4b7 | |||
| f7f3972248 | |||
| 50d83aa228 | |||
| 14758df1ab |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "libraries"]
|
||||||
|
path = libraries
|
||||||
|
url = https://chookspace.com/ground/libraries
|
||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
## What is Ground?
|
## What is Ground?
|
||||||
|
|
||||||
Ground is an interpreter which processes and interprets Ground instructions. It is quite fast, and the syntax is simple.
|
Ground is a sigma interpreter which processes and interprets Ground instructions. It is quite fast, and the syntax is simple.
|
||||||
|
|
||||||
## What are the main features of Ground?
|
## What are the main features of Ground?
|
||||||
|
|
||||||
* **Simple syntax:** Ground doesn't have very many features, and that's intentional. It makes Ground easy to learn, and keeps it speedy.
|
* **Simple syntax:** Ground doesn't have very many features, and that's intentional. It makes Ground easy to learn, and keeps it speedy.
|
||||||
* **Super speed:** Ground code is faster than Python and JavaScript, and nearly as fast as C++ and Rust, while still being interpreted. (Tested using tests/to1000.grnd)
|
* **Super speed:** Ground code is faster than Python and JavaScript, and nearly as fast as C++ and Rust, while still being interpreted. (Tested using tests/to1000.grnd)
|
||||||
* **Tiny interpreter:** Ground contains 1154 lines of code (and 320 lines of comments) at the time of writing, and compiles in seconds.
|
* **Tiny interpreter:** Ground contains 1482 lines of code (and 382 lines of comments) at the time of writing, and compiles in seconds.
|
||||||
* **Portable:** Ground's code only uses features from the C++ standard library, using features from C++17 and prior.
|
* **Portable:** Ground's code only uses features from the C++ standard library, using features from C++17 and prior.
|
||||||
|
|
||||||
## How do I get started?
|
## How do I get started?
|
||||||
|
|||||||
107
docs/demos/calc.grnd
Executable file
107
docs/demos/calc.grnd
Executable file
@@ -0,0 +1,107 @@
|
|||||||
|
#!/usr/bin/env ground
|
||||||
|
|
||||||
|
@begin
|
||||||
|
stdout "Calculation: "
|
||||||
|
stdin &calc
|
||||||
|
getstrsize $calc &calcsize
|
||||||
|
set &counter 0
|
||||||
|
set &left ""
|
||||||
|
set &right ""
|
||||||
|
set &operator ' '
|
||||||
|
set &isRight false
|
||||||
|
|
||||||
|
## Preprocessing
|
||||||
|
|
||||||
|
# Loop to parse input
|
||||||
|
@loopstart
|
||||||
|
getstrcharat $calc $counter &char
|
||||||
|
|
||||||
|
# Remove any spaces (they're inconvenient)
|
||||||
|
equal $char ' ' &cond
|
||||||
|
if $cond %doneif
|
||||||
|
|
||||||
|
# Check for operators
|
||||||
|
# '+' operator
|
||||||
|
inequal '+' $char &cond
|
||||||
|
if $cond %minusOpCheck
|
||||||
|
set &operator $char
|
||||||
|
set &isRight true
|
||||||
|
jump %doneif
|
||||||
|
|
||||||
|
@minusOpCheck
|
||||||
|
# '-' operator
|
||||||
|
inequal '-' $char &cond
|
||||||
|
if $cond %multiplyOpCheck
|
||||||
|
set &operator $char
|
||||||
|
set &isRight true
|
||||||
|
jump %doneif
|
||||||
|
|
||||||
|
@multiplyOpCheck
|
||||||
|
# '*' operator
|
||||||
|
inequal '*' $char &cond
|
||||||
|
if $cond %divideOpCheck
|
||||||
|
set &operator $char
|
||||||
|
set &isRight true
|
||||||
|
jump %doneif
|
||||||
|
|
||||||
|
@divideOpCheck
|
||||||
|
# '/' operator
|
||||||
|
inequal '/' $char &cond
|
||||||
|
if $cond %endOpChecks
|
||||||
|
set &operator $char
|
||||||
|
set &isRight true
|
||||||
|
jump %doneif
|
||||||
|
|
||||||
|
@endOpChecks
|
||||||
|
if $isRight %isRight
|
||||||
|
add $left $char &left
|
||||||
|
jump %doneif
|
||||||
|
@isRight
|
||||||
|
add $right $char &right
|
||||||
|
@doneif
|
||||||
|
add 1 $counter &counter
|
||||||
|
inequal $counter $calcsize &cond
|
||||||
|
if $cond %loopstart
|
||||||
|
# End loop
|
||||||
|
|
||||||
|
## Computing
|
||||||
|
|
||||||
|
# Convert types
|
||||||
|
stod $left &left
|
||||||
|
stod $right &right
|
||||||
|
|
||||||
|
# Calculations
|
||||||
|
# Adding
|
||||||
|
inequal $operator '+' &cond
|
||||||
|
if $cond %subtract
|
||||||
|
add $left $right &result
|
||||||
|
stdlnout $result
|
||||||
|
jump %begin
|
||||||
|
|
||||||
|
# Subtracting
|
||||||
|
@subtract
|
||||||
|
inequal $operator '-' &cond
|
||||||
|
if $cond %multiply
|
||||||
|
subtract $left $right &result
|
||||||
|
stdlnout $result
|
||||||
|
jump %begin
|
||||||
|
|
||||||
|
# Multiplying
|
||||||
|
@multiply
|
||||||
|
inequal $operator '*' &cond
|
||||||
|
if $cond %divide
|
||||||
|
multiply $left $right &result
|
||||||
|
stdlnout $result
|
||||||
|
jump %begin
|
||||||
|
|
||||||
|
# Dividing
|
||||||
|
@divide
|
||||||
|
inequal $operator '/' &cond
|
||||||
|
if $cond %error
|
||||||
|
divide $left $right &result
|
||||||
|
stdlnout $result
|
||||||
|
jump %begin
|
||||||
|
|
||||||
|
@error
|
||||||
|
stdlnout "Uh oh something terribly terrible happened lmao"
|
||||||
|
jump %begin
|
||||||
70
docs/highlight.py
Normal file
70
docs/highlight.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
fileName = sys.argv[1]
|
||||||
|
thefile = open(fileName).readlines()
|
||||||
|
|
||||||
|
def isnumber(num):
|
||||||
|
try:
|
||||||
|
float(num)
|
||||||
|
return True
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
allstr = ""
|
||||||
|
color = ""
|
||||||
|
keywords = ["if", "jump", "end", "stdin", "stdout", "stdlnout", "set", "gettype", "exists", "setlist", "setlistat", "getlistat", "getlistsize", "listappend", "getstrsize", "getstrcharat", "add", "subtract", "multiply", "divide", "equal", "inequal", "not", "greater", "lesser", "stoi", "stod", "tostring", "fun", "return", "endfun", "pusharg", "call", "use", "extern", "error"]
|
||||||
|
|
||||||
|
for line in thefile:
|
||||||
|
allstr += line + " <br> "
|
||||||
|
|
||||||
|
lines = len(allstr.split("<br>"))-1
|
||||||
|
a = allstr.split()
|
||||||
|
|
||||||
|
for i in range(lines):
|
||||||
|
instr = False
|
||||||
|
incom = False
|
||||||
|
words = len(allstr.split("<br>")[i].split())
|
||||||
|
for j in range(words):
|
||||||
|
tempword = allstr.split("<br>")[i].split()[j]
|
||||||
|
if allstr.split("<br>")[i].split()[0][0] == "#":
|
||||||
|
color = "\033[37m"
|
||||||
|
elif allstr.split("<br>")[i].split()[0][0] == "@":
|
||||||
|
color = "\033[32m"
|
||||||
|
elif tempword in keywords:
|
||||||
|
color = "\033[95m"
|
||||||
|
elif isnumber(tempword) or tempword == "true" or tempword == "false":
|
||||||
|
color = "\033[96m"
|
||||||
|
elif tempword[0] == "#":
|
||||||
|
incom = True
|
||||||
|
color = "\033[37m"
|
||||||
|
elif tempword[0] == "&":
|
||||||
|
color = "\033[93m"
|
||||||
|
elif tempword[0] == "$":
|
||||||
|
color = "\033[33m"
|
||||||
|
elif tempword[0] == "%":
|
||||||
|
color = "\033[32m"
|
||||||
|
elif tempword[0] == "-":
|
||||||
|
color = "\033[34m"
|
||||||
|
elif tempword[0] == "!":
|
||||||
|
color = "\033[94m"
|
||||||
|
elif tempword[0] == "*":
|
||||||
|
color = "\033[93m"
|
||||||
|
elif tempword[0] == "\"":
|
||||||
|
color = "\033[92m"
|
||||||
|
instr = not instr
|
||||||
|
elif tempword[0] == "\'" and tempword[len(tempword)-1] == "\'":
|
||||||
|
color = "\033[92m"
|
||||||
|
elif instr:
|
||||||
|
color = "\033[92m"
|
||||||
|
elif incom:
|
||||||
|
color = "\033[37m"
|
||||||
|
else:
|
||||||
|
color = "\033[91m"
|
||||||
|
|
||||||
|
print(f'{color}{tempword}', end=" ")
|
||||||
|
print()
|
||||||
|
|
||||||
|
print("\033[00m", end="")
|
||||||
21
docs/library-guide.md
Normal file
21
docs/library-guide.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Guide to Writing Libraries in Ground
|
||||||
|
|
||||||
|
Ground has a "use" keyword which allows you to import libraries written in Ground, executing the code, and importing functions for use. This makes building reproducable bits of code very easy.
|
||||||
|
|
||||||
|
This is a guide of best practices which should be followed.
|
||||||
|
|
||||||
|
## .grnd file extension
|
||||||
|
|
||||||
|
The Ground interpreter will automatically append ".grnd" when you use a library. If you write `use "myLibrary"` Ground will look for "myLibrary.grnd". This is a must-do.
|
||||||
|
|
||||||
|
## camelCase Function and File Names
|
||||||
|
|
||||||
|
For consistency, please use camelCase (with a lower case first letter) when naming functions and file names.
|
||||||
|
|
||||||
|
## Don't use spaces
|
||||||
|
|
||||||
|
It is impossible to use spaces in Ground function names. Please do not use spaces in file names, even though it will work.
|
||||||
|
|
||||||
|
## Use functions for most operations
|
||||||
|
|
||||||
|
Where possible, create functions to do everything needed with your library. You can include some code for initialisation, but don't do the entirety of your operations outside of your functions.
|
||||||
@@ -50,6 +50,12 @@ Reference a list (a list reference) with an asterisk:
|
|||||||
setlist *myList $value1 $value2 # and so on
|
setlist *myList $value1 $value2 # and so on
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Add comments with a `#`:
|
||||||
|
|
||||||
|
```
|
||||||
|
# This is a comment
|
||||||
|
```
|
||||||
|
|
||||||
## Keywords
|
## Keywords
|
||||||
|
|
||||||
Note: &var can be replaced with any direct reference. $value can be replaced with a literal value or a value reference. %1 can be replaced with a line reference.
|
Note: &var can be replaced with any direct reference. $value can be replaced with a literal value or a value reference. %1 can be replaced with a line reference.
|
||||||
@@ -78,23 +84,23 @@ Usage: `end $intvalue`
|
|||||||
|
|
||||||
### I/O
|
### I/O
|
||||||
|
|
||||||
#### stdin
|
#### input (or stdin)
|
||||||
|
|
||||||
Allows input from the console.
|
Allows input from the console.
|
||||||
|
|
||||||
Usage: `stdin &var`
|
Usage: `input &var`
|
||||||
|
|
||||||
#### stdout
|
#### print (or stdout)
|
||||||
|
|
||||||
Allows output to the console.
|
Allows output to the console.
|
||||||
|
|
||||||
Usage: `stdout $value`
|
Usage: `print $value`
|
||||||
|
|
||||||
#### stdlnout
|
#### println (or stdlnout)
|
||||||
|
|
||||||
Allows output to the console, appending a new line at the end.
|
Allows output to the console, appending a new line at the end.
|
||||||
|
|
||||||
Usage: `stdlnout $value`
|
Usage: `println $value`
|
||||||
|
|
||||||
### Variables and Lists
|
### Variables and Lists
|
||||||
|
|
||||||
@@ -104,6 +110,20 @@ Allows you to set a variable to a value.
|
|||||||
|
|
||||||
Usage: `set &var $value`
|
Usage: `set &var $value`
|
||||||
|
|
||||||
|
#### gettype
|
||||||
|
|
||||||
|
Gets the type of a variable. Outputs a string which can be "int", "double", "bool", "string", "char".
|
||||||
|
|
||||||
|
Usage: `gettype $value &var`
|
||||||
|
|
||||||
|
#### exists
|
||||||
|
|
||||||
|
Checks if a variable exists with a direct reference. If the variable exists, outputs true. Otherwise outputs false.
|
||||||
|
|
||||||
|
Usage `exists &var1 &var2`
|
||||||
|
|
||||||
|
Note: You can also replace &var1 with a list or line reference to check if it also exists
|
||||||
|
|
||||||
#### setlist
|
#### setlist
|
||||||
|
|
||||||
Allows you to initialize a list.
|
Allows you to initialize a list.
|
||||||
@@ -188,6 +208,12 @@ Checks if two values are not equal. Outputs a boolean to a direct reference.
|
|||||||
|
|
||||||
Usage: `inequal $value $value &var`
|
Usage: `inequal $value $value &var`
|
||||||
|
|
||||||
|
#### not
|
||||||
|
|
||||||
|
Negates a boolean.
|
||||||
|
|
||||||
|
Usage: `not $value &var`
|
||||||
|
|
||||||
#### greater
|
#### greater
|
||||||
|
|
||||||
Checks if the left value is greater than the right value. Outputs a boolean to a direct reference.
|
Checks if the left value is greater than the right value. Outputs a boolean to a direct reference.
|
||||||
@@ -220,13 +246,13 @@ Converts any type to a string.
|
|||||||
|
|
||||||
Usage: `tostring $value &var`
|
Usage: `tostring $value &var`
|
||||||
|
|
||||||
### Functions and function specific features (ALL WORK IN PROGRESS)
|
### Functions and function specific features (Experimental, please report bugs!)
|
||||||
|
|
||||||
Some symbols specific to this category:
|
Some symbols specific to this category:
|
||||||
|
|
||||||
* `!function`: A function reference
|
* `!function`: A function reference
|
||||||
|
|
||||||
* `-type`: A type reference. Can be one of the following: "-string", "-char", "-int", "-double", "-bool"
|
* `-type`: A type reference. Can be one of the following: "-string", "-char", "-int", "-double", "-bool", or a custom struct (see "Custom data structures" below)
|
||||||
|
|
||||||
#### fun
|
#### fun
|
||||||
|
|
||||||
@@ -260,20 +286,49 @@ Calls a function, with all the arguments in the argument list. The return value
|
|||||||
|
|
||||||
Usage: `call !function &var
|
Usage: `call !function &var
|
||||||
|
|
||||||
### Interacting with Libraries (ALL WORK IN PROGRESS)
|
### Custom Data Structures
|
||||||
|
|
||||||
|
#### struct
|
||||||
|
|
||||||
|
Begins creation of a custom data structure, which can contain values and functions. Similar to a class or struct in other programming languages.
|
||||||
|
|
||||||
|
In between the `struct` and `endstruct` lines, you can insert the following:
|
||||||
|
|
||||||
|
* `init` statements, to initialize values
|
||||||
|
* `fun`/`endfun` statements, to add member functions to the struct
|
||||||
|
|
||||||
|
When calling a function from inside a struct, all members of the struct are avaliable to read from and write to.
|
||||||
|
|
||||||
|
Usage: `struct -structName`
|
||||||
|
|
||||||
|
#### endstruct
|
||||||
|
|
||||||
|
Ends creation of a custom data structure.
|
||||||
|
|
||||||
|
Usage: `endstruct`
|
||||||
|
|
||||||
|
#### init
|
||||||
|
|
||||||
|
Initialises a variable with the default value of a type.
|
||||||
|
|
||||||
|
Usage: `init &var -type`
|
||||||
|
|
||||||
|
### Interacting with Libraries
|
||||||
|
|
||||||
#### use
|
#### use
|
||||||
|
|
||||||
Attempts to import another Ground program. Gets inserted wherever the use statement is. Any code (including code outside function declarations) will be executed.
|
Attempts to import another Ground program. Gets inserted wherever the use statement is. Any code (including code outside function declarations) will be executed. All functions from the library will be given a prefix, meaning functions will be registered as `!libName:functionName`.
|
||||||
|
|
||||||
Note: Ground will check the directory where the program is stored when trying to find imported programs. If that fails, it will check the directory set in the $GROUND_PATH environment variable set by your system. The '.grnd' extension is appended automatically.
|
Note: Ground will check the directory where the program is being run from when trying to find imported programs. If that fails, it will check the directory set in the $GROUND_LIBS environment variable set by your system. The '.grnd' extension is appended automatically.
|
||||||
|
|
||||||
Usage: `use $stringvalue`
|
Usage: `use $stringvalue`
|
||||||
|
|
||||||
#### extern
|
#### extern
|
||||||
|
|
||||||
Attempts to import a shared object library written for Ground. All functions in the external library will be usable with `call`.
|
Attempts to import a shared object library written for Ground. All functions in the external library will be usable with `call`. All functions from the library will be given a prefix, meaning functions will be registered as `!libName:functionName`.
|
||||||
|
|
||||||
Note: Ground will check the directory where the program is stored when trying to find external programs. If that fails, it will check the directory set in the $GROUND_PATH environment variable set by your system. The '.so', '.dll', etc extension is appended automatically.
|
Note: Ground will check the directory set in the $GROUND_LIBS environment variable set by your system. The '.so' (Linux), '.dylib' (macOS), or '.dll' (Windows) extension is appended automatically.
|
||||||
|
|
||||||
|
Documentation on how to do external libraries coming soon.
|
||||||
|
|
||||||
Usage: `extern $stringvalue`
|
Usage: `extern $stringvalue`
|
||||||
349
docs/tutorial.md
Normal file
349
docs/tutorial.md
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
# Ground Tutorial
|
||||||
|
|
||||||
|
Get up and running with Ground in no time!
|
||||||
|
|
||||||
|
## First Steps
|
||||||
|
|
||||||
|
First, create a file ending in `.grnd` and open it in your favourite text editor. Then, write the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
println "Hello, World!"
|
||||||
|
```
|
||||||
|
|
||||||
|
(I think you know what this does.)
|
||||||
|
|
||||||
|
(If you don't, it prints something to the console, and adds a new line at the end.)
|
||||||
|
|
||||||
|
You can test it on the console using the Ground interpreter:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ground myFile.grnd
|
||||||
|
```
|
||||||
|
|
||||||
|
But that's boring! You want to be able to do more in Ground. So, let's ask the user for something. We can write:
|
||||||
|
|
||||||
|
```
|
||||||
|
input &var
|
||||||
|
println $var
|
||||||
|
```
|
||||||
|
|
||||||
|
This will wait for the user to type something into the console and press enter, and will save it to the variable `var`. Then, we print out the variable `var`.
|
||||||
|
|
||||||
|
But how do variables work in Ground?
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
In Ground, variables are used to store values. (Yeah, I know, very original.) However, variables work a bit differently. What you need to know right now are called "value references" and "direct references".
|
||||||
|
|
||||||
|
### Value References
|
||||||
|
|
||||||
|
A value reference gets the value of a variable, and inserts it into the statement currently being executed.
|
||||||
|
|
||||||
|
For example, let's assume I have a variable called `myVar`, and it has the value `"Hello from the variable!"`. If you want to access that value, you use a value reference. To use a value reference, write the variable name, but prefixed with the `$` sign.
|
||||||
|
|
||||||
|
Let's try printing out `myVar`:
|
||||||
|
|
||||||
|
```
|
||||||
|
println $myVar
|
||||||
|
```
|
||||||
|
|
||||||
|
Sidenote: Value references are inserted before each line of code is ran.
|
||||||
|
|
||||||
|
You should see "Hello from the variable!" on the console, assuming you defined `myVar` beforehand. But how do you define a variable?
|
||||||
|
|
||||||
|
### Direct References
|
||||||
|
|
||||||
|
Direct references allow you to write to a variable. To use one, prefix your desired variable name with an `&` symbol.
|
||||||
|
|
||||||
|
Ground works differently to many programming languages in that you can't write things like `myVar = 10`. Everything uses an instruction (which I'll explain in a moment). So in Ground, you'd write:
|
||||||
|
|
||||||
|
```
|
||||||
|
set &myVar 10
|
||||||
|
```
|
||||||
|
|
||||||
|
to set `myVar` to 10. Simple, right?
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
* Value references let you get the variable of a value, and are prefixed with `$`.
|
||||||
|
* Direct references let you write to variables, and are prefixed with `&`.
|
||||||
|
|
||||||
|
As an example:
|
||||||
|
|
||||||
|
```
|
||||||
|
set &myVar "Hello from the variable!"
|
||||||
|
println $myVar
|
||||||
|
```
|
||||||
|
|
||||||
|
will set `myVar` to "Hello from the variable!", and print it to the console.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
Now, I assume you want to do more than setting variables and printing them, right? Luckily for you, Ground has (at the time of writing) 35 instructions to build whatever you can think of (not to mention libraries, but that's a later topic).
|
||||||
|
|
||||||
|
First, here's how you use them:
|
||||||
|
|
||||||
|
### Using instructions
|
||||||
|
|
||||||
|
Each line of Ground code contains an instruction and arguments. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
add 9 10 &result
|
||||||
|
```
|
||||||
|
|
||||||
|
This uses the `add` keyword (which adds two things together) to add 9 and 10, and outputs the result (which would be 19) to the direct reference provided (`result`).
|
||||||
|
|
||||||
|
So each instruction works sort of like a function in most other languages.
|
||||||
|
|
||||||
|
Now you know how they work, here's a list of cool instructions:
|
||||||
|
|
||||||
|
### Cool instructions
|
||||||
|
|
||||||
|
So here's a list of some instructions keywords to know about at present:
|
||||||
|
|
||||||
|
### Mathy stuff
|
||||||
|
|
||||||
|
`add`, `subtract`, `multiply`, `divide`
|
||||||
|
|
||||||
|
These instructions all take two numbers, and operate on them (add adds, subtract subtracts, and so on), and then output the result to the provided direct reference. You can use them all like:
|
||||||
|
|
||||||
|
```
|
||||||
|
add 5 6 &addition
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
multiply 10 30 &myVar
|
||||||
|
```
|
||||||
|
|
||||||
|
(and so on.)
|
||||||
|
|
||||||
|
Tip: `add` works on strings for concatenation! (for those who don't know, a string is a series of characters surrounded with `"`'s)
|
||||||
|
|
||||||
|
### User interaction
|
||||||
|
|
||||||
|
`input` (or `stdin`)
|
||||||
|
|
||||||
|
This instruction takes input from the console, and saves it to the given direct reference. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
input &myVar
|
||||||
|
```
|
||||||
|
|
||||||
|
`print` (or `stdout`) and `println` (or `stdlnout`)
|
||||||
|
|
||||||
|
These instructions print out values to the console. `println` also prints a new line character after your statement. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
println "Hi there! This has a new line at the end"
|
||||||
|
print "Heyo! This doesn't have a new line at the end."
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other variable stuff
|
||||||
|
|
||||||
|
`set`
|
||||||
|
|
||||||
|
Sets a variable to something.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
set &myVar "Hi there!"
|
||||||
|
```
|
||||||
|
|
||||||
|
`gettype`
|
||||||
|
|
||||||
|
Gets the type of a variable, in the form of a string. As an example:
|
||||||
|
|
||||||
|
```
|
||||||
|
gettype $someSortOfValue &type
|
||||||
|
```
|
||||||
|
|
||||||
|
If you accessed `$type`, you'd get one of the following:
|
||||||
|
|
||||||
|
"int", "double", "bool", "string", "char".
|
||||||
|
|
||||||
|
More on types later!
|
||||||
|
|
||||||
|
## Commenting
|
||||||
|
|
||||||
|
Comments are done with a `#`. Anything after the `#` on the line is ignored.
|
||||||
|
|
||||||
|
## Control Flow
|
||||||
|
|
||||||
|
Now, I assume you want to be able to use logic in your programs, right? Ground simplifies control flow to the bare minimum.
|
||||||
|
|
||||||
|
### Labels
|
||||||
|
|
||||||
|
A label is a point in your Ground code you can jump to. To set one, instead of writing an instruction, you can do something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
@myLabel
|
||||||
|
```
|
||||||
|
|
||||||
|
This will allow you to jump back to that point in code at any time.
|
||||||
|
|
||||||
|
### Jumping around
|
||||||
|
|
||||||
|
Jump to labels with the `jump` instruction.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Infinite loop!
|
||||||
|
@myLabel
|
||||||
|
jump %myLabel
|
||||||
|
```
|
||||||
|
|
||||||
|
But what does `%myLabel` mean? This is the third reference type: a line reference. It tells Ground which line to look at.
|
||||||
|
|
||||||
|
You can also use `if`, however `if` works differently:
|
||||||
|
|
||||||
|
```
|
||||||
|
@myLabel
|
||||||
|
if $myCondition %myLabel
|
||||||
|
```
|
||||||
|
|
||||||
|
This essentialy says "if `myCondition` is true, then jump to `myLabel`". But how do you compute conditions?
|
||||||
|
|
||||||
|
### More instructions!
|
||||||
|
|
||||||
|
Here are some useful instructions to compute a condition:
|
||||||
|
|
||||||
|
`equal`, `inequal`
|
||||||
|
|
||||||
|
These compare two values, and puts a boolean in a variable once they're compared.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Prints out true
|
||||||
|
equal "Hello!" "Hello!" &condition
|
||||||
|
println $condition
|
||||||
|
|
||||||
|
# Prints out false
|
||||||
|
equal 10 20 &condition
|
||||||
|
println $condition
|
||||||
|
|
||||||
|
# Prints out true
|
||||||
|
inequal "Hi there!" "Hello there!" &condition
|
||||||
|
println $condition
|
||||||
|
```
|
||||||
|
|
||||||
|
`equal` and `inequal` work on most regular values.
|
||||||
|
|
||||||
|
`greater`, `lesser`
|
||||||
|
|
||||||
|
These instructions check if the first provided value is greater or lesser than the second provided value. As an example:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Prints out true
|
||||||
|
greater 10 5 &condition
|
||||||
|
println $condition
|
||||||
|
```
|
||||||
|
|
||||||
|
### So how do I use these?
|
||||||
|
|
||||||
|
Labels, `if`, and `jump` can be used to create what would be if and while statements in other languages. Here's a loop that counts to 10:
|
||||||
|
|
||||||
|
```
|
||||||
|
set &counter 0
|
||||||
|
|
||||||
|
@loopStart
|
||||||
|
|
||||||
|
# Add one to our counter and print it out
|
||||||
|
add $counter 1 &counter
|
||||||
|
println $counter
|
||||||
|
|
||||||
|
# Check if we've hit 10 yet
|
||||||
|
equal $counter 10 &condition
|
||||||
|
|
||||||
|
# If we have, go to the end of the loop
|
||||||
|
if $condition %loopEnd
|
||||||
|
|
||||||
|
# Otherwise, go back to the start
|
||||||
|
jump %loopStart
|
||||||
|
@loopEnd
|
||||||
|
```
|
||||||
|
|
||||||
|
And here's a conditional if statement that checks if a user guessed the right password:
|
||||||
|
|
||||||
|
```
|
||||||
|
# Ask the user what the password is
|
||||||
|
print "Password: "
|
||||||
|
input &password
|
||||||
|
|
||||||
|
# Check if they got it right
|
||||||
|
equal $password "supersecurepassword" &condition
|
||||||
|
if $condition %rightPassword
|
||||||
|
jump %wrongPassword
|
||||||
|
|
||||||
|
@rightPassword
|
||||||
|
println "Correct!"
|
||||||
|
jump %end
|
||||||
|
|
||||||
|
@wrongPassword
|
||||||
|
println "Incorrect!"
|
||||||
|
jump %end
|
||||||
|
|
||||||
|
@end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building a meaningful program
|
||||||
|
|
||||||
|
Now we have all the building blocks to create a simple program!
|
||||||
|
|
||||||
|
Let's write a program that loops until the user tells us the right answer to a question. Here's how we do it:
|
||||||
|
|
||||||
|
First let's create a label so we can loop back to the start of our program:
|
||||||
|
|
||||||
|
```
|
||||||
|
@begin
|
||||||
|
```
|
||||||
|
|
||||||
|
Then we ask the user for their answer:
|
||||||
|
|
||||||
|
```
|
||||||
|
print "Do you like cheese?"
|
||||||
|
input &userInput
|
||||||
|
```
|
||||||
|
|
||||||
|
After this, we can check for the desired answer:
|
||||||
|
```
|
||||||
|
equal $userInput "yes" &condition
|
||||||
|
if $condition %success
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, if the user answers "yes" to our question, they will be sent to the `%success` label. But we need to handle what happens if they don't say what we want them to.
|
||||||
|
|
||||||
|
So we can tell them that they said the wrong thing, and jump back to the start of the program.
|
||||||
|
|
||||||
|
```
|
||||||
|
println "That's a pity"
|
||||||
|
jump %begin
|
||||||
|
```
|
||||||
|
|
||||||
|
At last, we should handle what happens when we get the input we want:
|
||||||
|
|
||||||
|
```
|
||||||
|
@success
|
||||||
|
println "Yay!"
|
||||||
|
```
|
||||||
|
|
||||||
|
Try running that program!
|
||||||
|
|
||||||
|
Here's the full text of what we wrote:
|
||||||
|
|
||||||
|
```
|
||||||
|
@begin
|
||||||
|
print "Do you like cheese?"
|
||||||
|
input &userInput
|
||||||
|
equal $userInput "yes" &condition
|
||||||
|
if $condition %success
|
||||||
|
|
||||||
|
println "That's a pity"
|
||||||
|
jump %begin
|
||||||
|
|
||||||
|
@success
|
||||||
|
println "Yay!"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
Now you've completed the basic tutorial! This will probably be expanded in future, but for now you can look at [the syntax guide](https://chookspace.com/ground/ground/src/branch/master/docs/syntax.md) for more features to use.
|
||||||
25
docs/writing-a-program.md
Normal file
25
docs/writing-a-program.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
## Writing programs with Ground (WORK IN PROGRESS GUIDE)
|
||||||
|
|
||||||
|
Ground is a very easy language to learn. In this guide, you will learn how to write a simple calculator in Ground, as well as best practices (which there aren't many of, since Ground is so simple).
|
||||||
|
|
||||||
|
Note: This assumes you've read and understand the syntax.md document in this folder.
|
||||||
|
|
||||||
|
### Let's start!
|
||||||
|
|
||||||
|
Open a new file with the `.grnd` extension. Should look something like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
(Real empty in that file.)
|
||||||
|
|
||||||
|
Let's add some code! Create a label for the start, since we'll loop back once we've calculated, and ask for the user's input:
|
||||||
|
|
||||||
|
```
|
||||||
|
@start
|
||||||
|
stdout "Calculation: "
|
||||||
|
stdin &calc
|
||||||
|
```
|
||||||
|
|
||||||
|
At the calc variable, we have whatever the user typed in. This should look something like `9+10`, `1 / 3` or who knows what else. But first we should organise this data. Let's create a loop to iterate through this input, and a counter to keep moving forward:
|
||||||
1
libraries
Submodule
1
libraries
Submodule
Submodule libraries added at 52e95e987f
1660
src/main.cpp
1660
src/main.cpp
File diff suppressed because it is too large
Load Diff
12
tests/args.grnd
Executable file
12
tests/args.grnd
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env ground
|
||||||
|
stdlnout "Program args: "
|
||||||
|
getlistsize *args &argsSize
|
||||||
|
set &counter 0
|
||||||
|
@loopstart
|
||||||
|
equal $counter $argsSize &bool
|
||||||
|
if $bool %end
|
||||||
|
getlistat *args $counter &item
|
||||||
|
stdlnout $item
|
||||||
|
add 1 $counter &counter
|
||||||
|
jump %loopstart
|
||||||
|
@end
|
||||||
23
tests/error.grnd
Normal file
23
tests/error.grnd
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
fun -int !divten -int &divisor
|
||||||
|
divide 10 $divisor &out
|
||||||
|
# Skip the rest of the function because we have an error
|
||||||
|
println "aw yeag we devided by zero"
|
||||||
|
return $out
|
||||||
|
endfun
|
||||||
|
|
||||||
|
fun -string !wrapperFn -int &dingle
|
||||||
|
pusharg $dingle
|
||||||
|
!divten &result
|
||||||
|
# Skip the rest of the function because we have an error
|
||||||
|
println "big error incoming"
|
||||||
|
tostring $result &out
|
||||||
|
return $out
|
||||||
|
endfun
|
||||||
|
|
||||||
|
catch "divisionByZeroError" &success
|
||||||
|
pusharg 0
|
||||||
|
!wrapperFn &result
|
||||||
|
|
||||||
|
# There's a catch in this scope, stop here and continue execution
|
||||||
|
|
||||||
|
println $success
|
||||||
20
tests/exists.grnd
Normal file
20
tests/exists.grnd
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
set &testVar "dingus"
|
||||||
|
exists &testVar &exist
|
||||||
|
stdlnout $exist
|
||||||
|
|
||||||
|
setlist *myList "item"
|
||||||
|
exists *myList &exist
|
||||||
|
stdlnout $exist
|
||||||
|
|
||||||
|
@dingus
|
||||||
|
exists %dingus &exist
|
||||||
|
stdlnout $exist
|
||||||
|
|
||||||
|
exists &doesNotExist &exist
|
||||||
|
stdlnout $exist
|
||||||
|
|
||||||
|
exists *doesNotExist &exist
|
||||||
|
stdlnout $exist
|
||||||
|
|
||||||
|
exists %doesNotExist &exist
|
||||||
|
stdlnout $exist
|
||||||
@@ -1,10 +1,49 @@
|
|||||||
fun -int !dingle -string &silly
|
fun -bool !jumpy
|
||||||
stdlnout "This is inside the function"
|
stdlnout "This is the jumpy function"
|
||||||
return 10
|
set &counter 0
|
||||||
|
jump %inloop
|
||||||
|
@jumpback
|
||||||
|
stdlnout "Yay I jumped!"
|
||||||
|
@inloop
|
||||||
|
add 1 $counter &counter
|
||||||
|
inequal 10 $counter &out
|
||||||
|
stdout "Condition is"
|
||||||
|
stdlnout $out
|
||||||
|
if $out %jumpback
|
||||||
|
stdlnout "Finished"
|
||||||
|
return true
|
||||||
endfun
|
endfun
|
||||||
|
|
||||||
stdlnout "This is outside the function"
|
!jumpy &tmp
|
||||||
|
|
||||||
call !dingle &var
|
stdlnout "I called a function"
|
||||||
|
|
||||||
stdlnout $var
|
# This function returns a list
|
||||||
|
|
||||||
|
fun -list !dingus
|
||||||
|
stdlnout "Testing lists in functions"
|
||||||
|
setlist *dingle "heheheha" "hahahahe" "hmmm"
|
||||||
|
return *dingle
|
||||||
|
endfun
|
||||||
|
|
||||||
|
call !dingus *outlist
|
||||||
|
|
||||||
|
getlistsize *outlist &size
|
||||||
|
set &counter 0
|
||||||
|
@loopstart
|
||||||
|
equal $size $counter &cond
|
||||||
|
if $cond %loopend
|
||||||
|
getlistat *outlist $counter &tmp
|
||||||
|
stdlnout $tmp
|
||||||
|
add 1 $counter &counter
|
||||||
|
jump %loopstart
|
||||||
|
@loopend
|
||||||
|
|
||||||
|
fun -int !doSomething -int &a -string &b
|
||||||
|
println $a
|
||||||
|
println $b
|
||||||
|
return 0
|
||||||
|
endfun
|
||||||
|
|
||||||
|
pusharg 432 "dingle"
|
||||||
|
!doSomething &ret
|
||||||
|
|||||||
5
tests/gettype.grnd
Normal file
5
tests/gettype.grnd
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
set &myVar "dingus"
|
||||||
|
|
||||||
|
gettype $myVar &type
|
||||||
|
|
||||||
|
stdlnout $type
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
# A cool list
|
# A cool list
|
||||||
setlist *favWords "hello" "there" "general" "kenobi"
|
setlist *favWords "hello" "there" "general" "kenobi"
|
||||||
|
stdlnout *favWords
|
||||||
|
|
||||||
set &count 0
|
set &count 0
|
||||||
set &passedThrough true
|
set &passedThrough true
|
||||||
|
|||||||
29
tests/struct.grnd
Normal file
29
tests/struct.grnd
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
struct -point
|
||||||
|
init &xpos -int
|
||||||
|
init &ypos -int
|
||||||
|
|
||||||
|
fun -int !init -int &x -int &y
|
||||||
|
set &xpos $x
|
||||||
|
set &ypos $y
|
||||||
|
return 0
|
||||||
|
endfun
|
||||||
|
|
||||||
|
fun -string !toString
|
||||||
|
tostring $xpos &xposstr
|
||||||
|
tostring $ypos &yposstr
|
||||||
|
add "x: " $xposstr &str
|
||||||
|
add $str ", y: " &str
|
||||||
|
add $str $yposstr &str
|
||||||
|
return $str
|
||||||
|
endfun
|
||||||
|
endstruct
|
||||||
|
|
||||||
|
init &myPoint -point
|
||||||
|
|
||||||
|
pusharg 30 15
|
||||||
|
!myPoint.init &out
|
||||||
|
println $myPoint.xpos
|
||||||
|
|
||||||
|
!myPoint.toString &out
|
||||||
|
|
||||||
|
println $out
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
set &var 0
|
set &var 0
|
||||||
|
@jump
|
||||||
add 1 $var &var
|
add 1 $var &var
|
||||||
stdlnout $var
|
stdlnout $var
|
||||||
greater 1000 $var &cond
|
greater 10000 $var &cond
|
||||||
if $cond %2
|
if $cond %jump
|
||||||
|
|||||||
3
tests/use/library.grnd
Normal file
3
tests/use/library.grnd
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fun -string !dingus
|
||||||
|
return "Hello from the library"
|
||||||
|
endfun
|
||||||
5
tests/use/use.grnd
Normal file
5
tests/use/use.grnd
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
use "library"
|
||||||
|
|
||||||
|
call !library:dingus &var
|
||||||
|
|
||||||
|
stdlnout $var
|
||||||
Reference in New Issue
Block a user