Hash :
ef195ae9
Author :
Thomas de Grivel
Date :
2024-10-14T17:14:30
KC3 is implemented using libkc3 a small C99 library implementing the core of the language.
The library includes a parser and an interpreter for KC3 code in C structures.
Support for large integers provided by libtommath.
Support for C function calls provided by libffi.
Modules are saved as facts databases.
The parser is recursive descent.
The AST is represented as KC3 data structures and can be meta-programmed in C.
Please see the following functions in libkc3/env.c
:
env_eval_tag
: evaluates a tag (any KC3 type) env_eval_block
: evaluates a block (do ... end
) env_eval_call
: evaluates a function call (Cfn
, Fn
) env_eval_call_fn_args
: evaluates a KC3 function call (Fn) Interactive shell. Terminal I/O provided by linenoise.
Example :
$ make test
$ ikc3/ikc3
ikc3> 1 + 1
2
ikc3> 2 + 2
4
ikc3> 3 + 3
6
ikc3> 1 +
ikc3> 1
2
ikc3> double = fn (x) { x * 2 }
fn (x) { x * 2 }
ikc3> double
fn (x) { x * 2 }
ikc3> double(1)
2
ikc3> double(2)
4
ikc3> double(3)
6
ikc3> double(4)
8
ikc3> List.map([1, 2, 3, 4], double)
[2, 4, 6, 8]
ikc3> List.reverse(List.map([1, 2, 3, 4], double))
[8, 6, 4, 2]
The List.map
and List.reverse
functions are defined in
lib/kc3/0.1/list.kc3
and can be modified in real time.
For example, without closing ikc3 let’s redefine List.reverse
,
open an editor and change the line in lib/kc3/0.1/list.kc3
from
def reverse = fn {
(x) { reverse(x, ()) }
([], acc) { acc }
([a | b], acc) { reverse(b, [a | acc]) }
}
to
def reverse = fn {
(x) { reverse(x, ()) }
([], acc) { [:reversed | acc] }
([a | b], acc) { reverse(b, [a | acc]) }
}
}}
and check the results of the last command (up key) in ikc3/ikc3 :
ikc3> List.reverse(List.map([1, 2, 3, 4], double))
[:reversed, 8, 6, 4, 2]
Don’t forget to revert the changes to list.kc3
.
Script interpreter. Works the same as ikc3 but is not interactive and does not output results.
HTTP daemon, use make test_httpd
.
The http daemon is defined in httpd/httpd.c
and
lib/kc3/0.1/httpd.kc3
.
The http daemon is both a static file server listing directories and
serving files for display or download (Web 1.0), and a MVC framework
loading KC3 files in ./app
. The router is defined in
./conf/router.kc3
.
Top : KC3 guides
Previous : KC3 usage guide
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
## Structure
### libkc3
KC3 is implemented using libkc3 a small C99 library implementing the core
of the language.
The library includes a parser and an interpreter for KC3 code in C
structures.
Support for large integers provided by
[libtommath](https://github.com/libtom/libtommath).
Support for C function calls provided by
[libffi](https://github.com/libffi/libffi).
Modules are saved as facts databases.
#### Parser
The parser is recursive descent.
#### AST
The AST is represented as KC3 data structures and can be meta-programmed
in C.
#### Interpreter
Please see the following functions in `libkc3/env.c`:
- `env_eval_tag` : evaluates a tag (any KC3 type)
- `env_eval_block` : evaluates a block (`do ... end`)
- `env_eval_call` : evaluates a function call (`Cfn`, `Fn`)
- `env_eval_call_fn_args` : evaluates a KC3 function call (Fn)
### ikc3
Interactive shell. Terminal I/O provided by
[linenoise](https://github.com/antirez/linenoise/tree/1.0).
Example :
```sh
$ make test
$ ikc3/ikc3
```
```elixir
ikc3> 1 + 1
2
ikc3> 2 + 2
4
ikc3> 3 + 3
6
ikc3> 1 +
ikc3> 1
2
ikc3> double = fn (x) { x * 2 }
fn (x) { x * 2 }
ikc3> double
fn (x) { x * 2 }
ikc3> double(1)
2
ikc3> double(2)
4
ikc3> double(3)
6
ikc3> double(4)
8
ikc3> List.map([1, 2, 3, 4], double)
[2, 4, 6, 8]
ikc3> List.reverse(List.map([1, 2, 3, 4], double))
[8, 6, 4, 2]
```
### Library path
The `List.map` and `List.reverse` functions are defined in
`lib/kc3/0.1/list.kc3` and can be modified in real time.
For example, without closing ikc3 let's redefine `List.reverse`,
open an editor and change the line in `lib/kc3/0.1/list.kc3` from
```elixir
def reverse = fn {
(x) { reverse(x, ()) }
([], acc) { acc }
([a | b], acc) { reverse(b, [a | acc]) }
}
```
to
```elixir
def reverse = fn {
(x) { reverse(x, ()) }
([], acc) { [:reversed | acc] }
([a | b], acc) { reverse(b, [a | acc]) }
}
}}
```
and check the results of the last command (up key) in ikc3/ikc3 :
```elixir
ikc3> List.reverse(List.map([1, 2, 3, 4], double))
[:reversed, 8, 6, 4, 2]
```
Don't forget to revert the changes to `list.kc3`.
### kc3s
Script interpreter. Works the same as ikc3 but is not interactive
and does not output results.
### HTTPd
HTTP daemon, use `make test_httpd`.
The http daemon is defined in `httpd/httpd.c` and
`lib/kc3/0.1/httpd.kc3`.
The http daemon is both a static file server listing directories and
serving files for display or download (Web 1.0), and a MVC framework
loading KC3 files in `./app`. The router is defined in
`./conf/router.kc3` .
---
Top : [KC3 guides](./)
Previous : [KC3 usage guide](3.3_Usage)
Next : [KC3 tutorial and examples guide](3.5_Tutorial)