Skip to content

Commit 7aa4187

Browse files
author
Heitor Danilo
committed
docs: test improviments
1 parent 95c4670 commit 7aa4187

File tree

2 files changed

+78
-30
lines changed

2 files changed

+78
-30
lines changed

.vscode/settings.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
"def.h": "c",
2929
"chardef.h": "c",
3030
"langdef.h": "c",
31-
"token_test.h": "c"
31+
"token_test.h": "c",
32+
"vector": "c",
33+
"array": "c",
34+
"string_view": "c",
35+
"initializer_list": "c",
36+
"utility": "c",
37+
"TEST.C": "cpp"
3238
}
3339
}

README.md

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,99 @@
11
<h1 align="center">Overview</h1>
22

3-
**Mariana** is a simple interpreted language created using standard C. It came about from my desire to design something with "perfect" syntax (in my opinion). It's developed purely for learning purposes.
3+
**Mariana** is a simple interpreted language created using C. It came about from my desire to design something with "perfect" syntax (in my opinion). It's developed purely for learning purposes.
44

55
Being aware that this language will never be used in production, and is merely a small personal project, this README will be used as a discussion platform during the development process, such as, for instance, architectural decisions concerning syntax.
66

77
<h1 align="center">Getting Started</h1>
88

9-
I plan to develop an installation script. For now, you can clone the source code and compile it directly:
9+
"I am in the process of developing an installation script. However, for now, you can clone the source code and compile it manually. Follow these steps:
1010

1111
1. Clone the repository:
12+
1213
```bash
1314
git clone https://github.com/heiytor/mari-programming-language && cd mari-programming-language
1415
```
1516

1617
2. Compile the source code:
1718

1819
```bash
19-
make dev
20-
```
21-
22-
During the project development, I personally chose to build my own testing "framework" to stick to the idea of using only standard C. You can run all the tests with:
23-
```bash
24-
make test
20+
make
2521
```
26-
27-
If all tests pass, the output will look something like:
2822

29-
![image](https://github.com/heiytor/mari-programming-language/assets/107213601/62583e37-9fde-4c85-988b-bd43f3290aa8)
23+
This command will first run all [tests](). If all tests pass, the source code will then be compiled. If you want to only compile the source code without running the tests, you can use `make dev`.
3024

31-
32-
On the other hand, if any test fails, the program will exit, and the output will look something like:
25+
Once you've done that, navigate to the project folder and execute the following command:
3326
34-
![image](https://github.com/heiytor/mari-programming-language/assets/107213601/b742dfb6-84ba-4cfd-a1cf-44d012ad43b4)
35-
36-
With that done, within the project folder you can run the following command:
37-
38-
```
27+
```bash
3928
./program
4029
```
4130
42-
This will start a small REPL.
31+
This will launch a simple Read-Eval-Print Loop (REPL)."
4332
4433
<h1 align="center">Syntax</h1>
4534
4635
```mariana
4736
// Function definition
48-
def func add(def x, def y) {
37+
var add_numbers = fn(def x, def y) {
4938
return x + y;
5039
}
5140
52-
def x = 5; // Variable definition. All variables are constants by default.
53-
def mut y = 10; // Mutable variable definition
41+
var x = 5; // Variable definition. All variables are constants by default.
42+
var mut y = 10; // Mutable variable definition
5443
55-
def result = add(x, y);
44+
var result = add(x, y);
5645
x = 0; // This will throw an error.
5746
y = 0; // This will pass.
5847
59-
println("{x} + {y} = {result}");
48+
println("${x} + ${y} = ${result}");
49+
```
50+
51+
<h1 align="center">Tests</h1>
52+
53+
During the course of this project's development, I considered several testing frameworks, such as Check. However, my evaluation led me to the conclusion that introducing such a framework could potentially overcomplicate things.
54+
55+
As a result, I decided to implement my own testing "framework". Running these tests is simple, just execute the following command:
56+
57+
```
58+
make test
59+
```
60+
61+
If all tests pass successfully, the console will display a message similar to the following:
62+
63+
![]()
64+
65+
However, if a test fails, the program will halt execution at the point of failure, allowing for easier debugging.
66+
67+
You can find the definitions for all tests in the files that end with the "_test.h" suffix, while the `_test.c` files contain the implementations of these tests. The `./src/main_test.c` file serves as the test runner, executing all test implementations.
68+
69+
Tests are named following the pattern "**test_should_pass_if_\[condition]**". For example:
70+
1. **test_should_pass_if**_var_statement_to_string_is_equal_to_expected (`src/ast/ast_test.h`)
71+
2. **test_should_pass_if**_bool_assignments_are_equal_to_expected (`src/token/token_test.h`)**
72+
73+
Each `_test.c` file contains local helper functions that assist in performing specific tasks within the file, but are not accessible for other tests. For this reason, I would categorize this as a library, rather than a framework. For instance, in ***src/ast/ast_test.c***, you'll find the `create_program` function:
74+
75+
```C
76+
struct Program* create_program(char* input) {
77+
struct Lexer* lexer = new_lexer(input);
78+
struct Parser* parser = new_parser(lexer);
79+
struct Program* program = parser->parse_program(parser);
80+
81+
return program;
82+
}
83+
```
84+
85+
This function assists us in creating new programs within tests:
86+
87+
```C
88+
void test_should_pass_if_program_to_string_is_equal_to_expected() {
89+
char* input = "var x = ;\n" // var statement
90+
"var mut y = ;\n" // mutable var statement
91+
"return ;"; // return statement
92+
93+
struct Program* prg = create_program(input);
94+
95+
// [...]
96+
}
6097
```
6198

6299
<h1 align="center">Developer Notes</h1>
@@ -82,11 +119,16 @@ One of my primary goals in this project is readability and comprehensibility (ma
82119
*
83120
* If the lexer sees any of these characters after a letter, the lexer must create a single token:
84121
* my_!var: "my_!var"
85-
*/
86-
bool is_allowed_as_first_char(byte ch) {
87-
return ch != '.' && ch != '?' &&
88-
89-
ch != '!';
122+
*
123+
* @param ch The current character being evaluated.
124+
*
125+
* @return 1 if is number, 0 otherwise.
126+
*/
127+
int is_allowed_as_first_char(byte ch) {
128+
return ch != '.' &&
129+
// ch != '-' && // uncomment to allow kebab-case
130+
ch != '?' &&
131+
ch != '!';
90132
}
91133
```
92134

0 commit comments

Comments
 (0)