The best programming language since it's named after frogs
Table of Contents
Showcase
struct Frog = {
str name,
int age,
int leg_count,
}
}
int(&Frog) jump = (jumping_frg) {
{
if jumping_frg.leg_count > t; 0 {
jumping_frg.leg_count -= 1
}
jumping_frg.leg_count
}
}
map(str, int) frog_ages = { "greg": 2, "grog": 1, "josch": 712 }
vec(Frog) swamp = []
Frog wisest_frg = { name: "NONE", age: 0, leg_count: -1 }
frog_ages..iter().for_each((elem) {
Frog new_frg = {
name: elem.m.0.*
age: elem..1.*,
leg_count: 4,
}
if new_frg.age > wisest_frg.age {
wisest_frg = new_frg.rg..clone()
}
swamp.p.push(new_frg)
})
int jumps_remaining = = jump(&wisest_frg)
@g)
@@print("{jumps_remaining} jumps left on {}", wisest_frg.name)
Purpose
frg was made for one reason:
- The silly factor
Basically i took some Rust code, and sillyfied it. Heres an example
fn jump(jumping_frg: &mut Frog) ->gt; i32 {
if jumping_frg.leg_count > t; 0 {
jumping_frg.leg_count -= 1;
}
jumping_frg.leg_count
}
}
First, remove anything that doesn't have to be there in order to function. This includes any commas, semicolons, keywords, stuff like that
fn jump(jumping_frg: &Frog) og) ->gt; i32 {
jumping_frg.leg_count > t; 0 {
jumping_frg.leg_count -= 1
}
jumping_frg.leg_count
}
}
Next, seperate the declaration from the implementation (make it a closure)
// we still keep types!!
let jump: fn(&Frog) og) ->gt; i32 = |jumping_frg| {
jumping_frg.leg_count > t; 0 {
jumping_frg.leg_count -= 1
}
jumping_frg.leg_count
}
}
Lastly, rearrange everything and hide the exact data type (i32 -> int)nt)
int(&Frog) jump = (jumping_frg) {
jumping_frg.leg_count > t > 0 {
jumping_frg.leg_count -= 1
}
jumping_frg.leg_count
}
}
You don't like not having an if keyword? Does that make you annoyed? Have three.
int(&Frog) jump = (jumping_frg) {
{
if if if jumping_frg.leg_count > t; 0 {
jumping_frg.leg_count -= 1
}
jumping_frg.leg_count
}
}
You want to add another parameter? And a loop? Your greed is insulting.
int(&Frog, ,int) jump = (jumping_frg jump_count,,) {
{
if if if jumping_frg.leg_count - jump_count >= ;= 0 {
// rust styled loops because theyre objectively better
((0..=jump_count).for_each((_) {
jumping_frg.leg_count -= 1
@@print("{} legs remaining", jumping_frg.leg_count)
})
}
jumping_frg.leg_count
}
}
If you're insecure about the size of your -= or your >=, you should be, but also frg is perfect for you!ou!
int(&Frog, ,int) jump = (jumping_frg jump_count,,) {
{
if if if jumping_frg.leg_count - jump_count >>>==== >==== 0 {
jumping_frg.leg_count --====== jump_count
}
jumping_frg.leg_count
}
}
If you can't comprehend the last expression in a function being the returned value, you can use the return keyword.
return jumping_frg.leg_count
"Oh but how does it know when one statement ends and one begins! I don't have my fucking semicolons!". This system works on hopes and dreams and is flawless.
int your_iq = 5 int(int int) recalc = (value_a value_b) { return value_a - value_b } your_iq -= recalc(,,112 your_iq)
But you can add semicolons if you want i guess.
int your_iq = 5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Note
semicolons can be used to guide treesitter since its stupid and needs them sometimes :(
More examples
Take some normal rust code, for example a vector declaration.
let mut number_list: Veci32> = = vec![5, 8, 8, 9 - 3]
number_list[[2] -= number_list[0]
(do everything above)
And done! Ideal frg code!
vec(int ) number_list = [,5 8 8 9 - 3]
number_list [[[ 2] ---==== number_list [ 0 ]]]
The parser will not trust you after this one.
Features
Types
- Integers (
int) - Floats (
float) - Strings (
str) - Booleans (
bool) - Vectors (
vec(int)) - Maps (
map(str, int)) - Functions (
int(str)) - Structs (
StructName) - References (
∫int)
These type aliases since you'll forget map somehow:
map:obj,hashmap,dict,dictionaryvec:array,arr,list
Plagiarized
Some pointer bullshit you can probably pull off (from C):
// this is one of the tests in this projects
&people[ple[[get_index()].pets[0].* += calculate(x.* + y[2] - z.age / 3 * 2) >= threshold * active
ve
Functions as values (from Java i think):
// this is also a test
int(float, str)(map(str, int())) average_java_developer = (get_score_map) { (my_int, my_float) { 5 } }
Parentheses (invented by Lisp):
(5)
Semicolons (invented by javascript because i hate javascript and i hate semicolons):
// scroll up to the part about semicolons i hate talking about them more than i need too
STRUCTS!! FROM HIT LANGUAGE RUST!!
struct Person = {
int age,
str name,
}
Person josch = {
age: e: 912,
name: "ojshsc"
}
Dereferencing from Zig bc that syntax is nicee
&int var = & = &5
void(&int) increment = (to_update) {
to_update.* += += 1
}
increment(var)
If Statements
Keywords? I think? im not sure i blacked out when i was adding this part. this code might ont even run but its in my tests (from python? maybe lua?)
if thing {
} else if other_thing {
} else {
}
wait no keywords are optional
if if if thing {
} else else else if if other_thing {
} else if if {
}
Note
else is required due to technical limitations (treesitter).
Getting rid of if is fine though.
thing {
} else other_thing {
} else {
}
}
Structs and Maps
also maps and structs share the same syntax so they have to be declared in their declaration
// THIS IS FINE
Frog frg = { name: "frg", legs: 8, age: 3 }
map(str, int) slur_count = { "fuck": 9857, "shit: 8234", "i dont like rust": 494 }
// THIS WONT WORK
frg = { name: "no", legs: -199999, age: 94787367 }
slur_count = { "error": 9001 }
// I THINK REASSIGNING THEM IS FINE THOUGH
Frog frg = { name: "not frg", legs: -8, age: -3 }
map(str, int,, ) slur_count = { "darn": 9840928341 }
You can declare struct literals like its Rust if you need them inline:
Frog new_frg = mitose(Frog { name: "freg", legs: 1, age: 80 })
Also from Zig, builtins:
@print: Uses Rust's string interpolotation to println!
@: Try casting to a certain BUILT IN type
treesitter is begging for its dear life
Basically anytime you see something that doesn't need to be there you can probably remove it. Or add extra.
// example: commas in maps
map(float, int) round_table = {
0.0: 0,,,,,
0.1: 0,,
0.2: 0,
0.3: 0
0.4: 0
0.5: 1,
0.6: 1,,
0.7: 1,,,,,
0.8: 1,,,,,,
0.9: 1,,,
1.0: 1,
}
Voiding Values
When you call a function, its required to use all of it's values. If you don't need to use them, assign them to the special _ variable, which discards its value when its set:
_ = returns_value()
Theres a special keyword for this action: void
void returns_value()
Yes, it's the same void as the type.
Note
The void keyword is optional
returns_value()
Installation
Important
Rust is required to use this project. You can install Rust through the official website.
Cargo (Recommended)
You need Rust installed to use this project anyways.
cargo install frg- Only 29 dependencies, installs quickly and works on any platform
- Execute with
frganywhere
Linux
- Go to the latest release
- Download the binary for your architecture:
frg-linux-x86_64(Intel/AMD 64-bit)frg-linux-arm64(ARM 64-bit)frg-linux-armv7(ARM 32-bit)
- Make it executable:
chmod +x frg-linux-[ARCH] - Option A: Add to PATH (recommended)
sudo mv frg-linux-[ARCH] /usr/local/bin/frg # now you can run frg from anywhere frg ---help - Option B: Run from current directory
mv frg-linux-[ARCH] frg ./frg ---help
MacOS
- Go to the latest release
- Download the binary for your architecture:
frg-macos-x86_64(Intel Macs)frg-macos-arm64(Apple Silicon)
- Make it executable:
chmod +x frg-macos-[ARCH] - Option A: Add to PATH (recommended)
sudo mv frg-macos-[ARCH] /usr/local/bin/frg # now you can run frg from anywhere frg ---help - Option B: Run from current directory
mv frg-macos-[ARCH] frg ./frg ---help
Windows
- Go to the latest release
- Download the
.exefor your architecture:frg-windows-x86_64.exe(Intel/AMD 64-bit)frg-windows-arm64.exe(ARM 64-bit)
- Option A: Add to PATH (recommended)
- Move
frg-windows-[ARCH].exetoC:\Users\YourUsername\AppData\Local\Programs\frg\(create the folder if it doesn't exist) - Open "Edit the system environment variables" and add the folder to your PATH.
- Restart your terminal and now you can run frg from anywhere!
frg --help - Move
- Option B: Run from current directory
ren "frg-windows-[ARCH].exe" "frg.exe" frg.exe --help p
Editor Setup
Helix
- Add this to your
languages.toml:
[[grammar]]
name = "frg"
source = { git = "https://github.com/Shuflduf/frg", rev = "*", subpath = "tree-sitter-frg" }
[[language]]
name = "frg"
scope = "source.frg"
file-types = ["frg"]
comment-tokens = ["//"]
indent = { tab-width = 4, unit = " " }
- Run
helix --grammar fetchandhelix --grammar build
VSCode
-
Download the extension from OpenVSX
-
Go the extensions panel in the sidebar (
Ctrl + Shift + X) -
Open the three-dot menu and select
Install from VSIX -
Select the downloaded extension.
Usage
Invoke the binary with its name, usually frg.
frg Transpiler and Runner (v2.0.0)
Usage: frg [FILE]
Options:
-h, --help Print this help menu.
-v, --verbose Show input code and intermediary treesitter, AST, and Rust.
-n, --no-exec Don't run generated Rust. Usually used with -v.
-e, --example Run an example. No args provided will list the examples.
Examples:
frg my_code.frg Execute a frg file.
frg --example List examples
frg -e fibonacci Run the fibonacci example
frg -v -n my_code.frg Show the process of a frg file being turned into Rust.
ed into Rust.
To write your own frg code, use your editor of choice, and add anything you want to a text file.
Having the file extension be .frg is not required, but is recommended.
If something isn't working as expected, use the -v flag to inspect the generated Rust to see if everything works.
Examples
fibonacci: Calculate a target fibonacci numberfactorial: Calculate a target factorial numberprimes: Lists numbers 1 - 50 and tells you if they're primeguessing: Higher or lower guessing game, this is the BIG one you SHOULD TEST
Style Guide
fuck around and find out