frg 2.0.2

Compiled programming language with frogs!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
<img height="64" src="frg-icon.png">

*The best programming language since it's named after frogs*

# Table of Contents
1. [Showcase](#showcase)
2. [Purpose](#purpose)
3. [Features](#features)
4. [Installation](#installation)
5. [Editor Setup](#editor-setup)
6. [Usage](#usage)
7. [Style Guide](#style-guide)

# Showcase
```rs
struct Frog = {
	str name,
	int age,
	int leg_count,
}

int(&Frog) jump = (jumping_frg) {
	if jumping_frg.leg_count > 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.0.*
		age: elem.1.*,
		leg_count: 4,
	}
	if new_frg.age > wisest_frg.age {
		wisest_frg = new_frg.clone()
	}
	swamp.push(new_frg)
})

int jumps_remaining = jump(&wisest_frg)
@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
```rs
fn jump(jumping_frg: &mut Frog) -> i32 {
	if jumping_frg.leg_count > 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
```rs
fn jump(jumping_frg: &Frog) -> i32 {
	jumping_frg.leg_count > 0 {
		jumping_frg.leg_count -= 1
	}
	jumping_frg.leg_count
}
```

Next, seperate the declaration from the implementation (make it a closure)
```rs
// we still keep types!!
let jump: fn(&Frog) -> i32 = |jumping_frg| {
	jumping_frg.leg_count > 0 {
		jumping_frg.leg_count -= 1
	}
	jumping_frg.leg_count
}
```

Lastly, rearrange everything and hide the exact data type (i32 -> int)
```rs
int(&Frog) jump = (jumping_frg) {
	jumping_frg.leg_count > 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.
```rs
int(&Frog) jump = (jumping_frg) {
	if if if jumping_frg.leg_count > 0 {
		jumping_frg.leg_count -= 1
	}
	jumping_frg.leg_count
}
```
You want to add another parameter? And a loop? Your greed is insulting.
```rs
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!
```rs
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.
```rs
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.
```rs
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.
```rs
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.
```rs
let mut number_list: Vec<i32> = vec![5, 8, 8, 9 - 3]
number_list[2] -= number_list[0]
```
(do everything above)

And done! Ideal frg code!
```rs
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`, `dictionary`
- `vec`: `array`, `arr`, `list`

## Plagiarized
Some pointer bullshit you can probably pull off (from C):
```rs
// this is one of the tests in this projects
&people[get_index()].pets[0].* += calculate(x.* + y[2] - z.age / 3 * 2) >= threshold * active
```

Functions as values (from Java i think):
```rs
// 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):
```rs
(5)
```

Semicolons (invented by javascript because i hate javascript and i hate semicolons):
```rs
// scroll up to the part about semicolons i hate talking about them more than i need too
```

STRUCTS!! FROM HIT LANGUAGE RUST!!
```rs
struct Person = {
	int age,
	str name,
}
Person josch = {
	age: 912,
	name: "ojshsc"
}
```

Dereferencing from Zig bc that syntax is nicee
```rs
&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?)
```rs
if thing {
} else if other_thing {
} else {
}
```

wait no keywords are optional
```rs
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
```rs
// 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:
```rs
Frog new_frg = mitose(Frog { name: "freg", legs: 1, age: 80 })
```

Also from Zig, builtins:
`@print`: Uses Rust's string interpolotation to `println!`
`@<type>`: 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.
```rs
// 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:
```rs
_ = returns_value()	
```

Theres a special keyword for this action: `void`
```rs
void returns_value()
```
Yes, it's the same void as the type.

> [!NOTE]
> The void keyword is optional
> ```rs
>	returns_value()
> ```


# Installation

> [!IMPORTANT]
> Rust is required to use this project.
> You can install Rust through [the official website](https://rust-lang.org/tools/install/).

## Cargo (Recommended)
*You need Rust installed to use this project anyways.*

1. `cargo install frg`
2. Only 29 dependencies, installs quickly and works on any platform
3. Execute with `frg` anywhere

## Linux
1. Go to the [latest release](https://github.com/Shuflduf/frg/releases/latest)
2. Download `frg-linux-[ARCH]`
3. Rename to `frg`
4. Execute with `./frg` while in the directory with the binary

## MacOS
1. Go to the [latest release](https://github.com/Shuflduf/frg/releases/latest)
2. Download `frg-macos-[ARCH]`
3. Rename to `frg`
4. Execute with `./frg` while in the directory with the binary

## Windows
1. Go to the [latest release](https://github.com/Shuflduf/frg/releases/latest)
2. Download `frg-windows-[ARCH].exe`
3. Rename to `frg.exe`
4. Execute with `frg.exe` while in the directory with the binary


# Editor Setup

## Helix
1. Add this to your `languages.toml`:
```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 = "    " }
```
2. Run `helix --grammar fetch` and `helix --grammar build`

## VSCode
1. Download the extension from [OpenVSX](https://open-vsx.org/extension/Shuflduf/frg)
   
	<img height="100" src="https://github.com/user-attachments/assets/b68c7ce1-140c-4bc0-98b2-e8edf2485b27" />
2. Go the extensions panel in the sidebar (`Ctrl + Shift + X`)
3. Open the three-dot menu and select `Install from VSIX`

   <img height="200" src="https://github.com/user-attachments/assets/5d517ff2-40b2-4cc3-bbda-c6249fbf5d33" />
4. 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.
```

To write your own frg code, use your [editor](#editor-setup) 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 number
- `factorial`: Calculate a target factorial number
- `primes`: Lists numbers 1 - 50 and tells you if they're prime
- `guessing`: Higher or lower guessing game, this is the BIG one you SHOULD TEST


# Style Guide
fuck around and find out