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
|
# Funco
This is a small functional programming language I wrote for fun inspired by [lispy](https://norvig.com/lispy.html) and [Atto](https://github.com/zesterer/atto/tree/master).
Still, it has a lexer and a parser, and some optimizations (like recursive tail calls, although they need to be tagged).
The only requirement is Python 3.10 or later.
There are lots of limitations, but check [TODO](TODO.md) for some ideas to contribute.
## The language
An example:
```ruby
# example of a factorial function
def fact(n acc)
if =(n 1)
acc
else
# tagging a tail call with "@" so it can be optimized
@fact(-(n 1) *(acc n))
end
end
# main is the entry point of a program
def main()
display("Running fact(50)...")
display(fact(50. 1))
end
# output:
# Running fact(50)...
# 3.0414093201713376e+64
```
A program can have:
* line comments, with `#`
* function definitions
* expressions
A `main()` function is required and will be executed as entry point for the program.
Function definition:
```text
def ident([param1 [param2] [...]])
[...]
end
```
Expressions can be:
* function calls
* conditionals with `if [elif [elif] [...]] [else]`
* literals
Literals include:
* numbers (int or float): `1`, `1.5`
* strings: `"this is a string"`
* booleans (`true` or `false`), as result of some logical functions; although 0 is false and non-zero is true
* lists
* functions
* none for "no value"
Operators are functions, that includes:
* `+`, `-`, `*`, `/`, `mod`
* `>`, `<`, `>=`, `<=`, `=`, `!=`
* `and`, `or`, `not`
For example, adding two numbers:
```ruby
+(1 1) # should be 2
```
Other built-in functions are:
* `int(value)`: convert a value into a integer
* `float(value)`: convert a value into a float
* `string(value)`: convert a value into a string
* `list(a b c d)`: convert its arguments into a list, for example `list(1 2 3 4)`
* `int?(value)`: returns true if a value is a integer
* `float?(value)`: returns true if a value is a float
* `string?(value)`: returns true if a value is a string
* `list?(value)`: returns true if a values is a list
* `none?(value)`: returns true if a value is none
* `boolean?(value)`: returns true if a value is a boolean
* `function?(value)`: returns true if a value is a function
* `head(list)`: returns the first element of a list
* `tail(list)`: returns the end of a list excluding the first element
* `empty?(list)`: returns true if a list is empty
* `size(list)`: returns the size of a list
* `min(list)`: returns the smaller value in a list
* `max(list)`: returns the larger value in a list
* `contains(value list)`: returns true if a list contains a value
* `map(fn list)`: applies a list to a function
* `filter(fn list)`: applies a list to a function, excluding the items for which the function returns true
* `fold(initial fn list)`: folds using a function the receives the accumulator and the value, and returns the updated accumulator
* `take(n list)`: return the first n elements of a list
* `drop(n list)`: return the list dropping the n first elements
* `display(value)`: prints its arguments to the screen, for example `display("hello" "world")`
See the examples in `./examples`.
## Licence
* This project is licensed [GPL 3.0](gpl-3.0.txt).
|