Skip to content

Commit

Permalink
Merge pull request #195 from KennyOliver/issue-194
Browse files Browse the repository at this point in the history
Issue 194: Add Built-In `sleep()` for Pausing Execution
  • Loading branch information
KennyOliver authored Jan 9, 2025
2 parents c5d9b57 + bcfd42d commit 17244a5
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 9 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,19 @@ FlavorLang blends coding with culinary creativity! Write programs like recipes &

### `docs/`

5. [Syntax Examples](docs/syntax_examples.md)
5. [Standard Library](docs/standard_library.md)

6. [Debugging](docs/debugging.md)
6. [Syntax Examples](docs/syntax_examples.md)

7. [Language Design](docs/language_design.md)
7. [Debugging](docs/debugging.md)

8. [Lexer](docs/lexer.md)
8. [Language Design](docs/language_design.md)

9. [Parser](docs/parser.md)
9. [Lexer](docs/lexer.md)

10. [Interpreter](docs/interpreter.md)
10. [Parser](docs/parser.md)

11. [Interpreter](docs/interpreter.md)

---

Expand Down
20 changes: 20 additions & 0 deletions docs/standard_library.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Standard Library Functions

| **Function** | **Description** |
| -------------- | ------------------------------------------------------------------ |
| `string` | Casts a value to a string. |
| `float` | Casts a value to a float. |
| `int` | Casts a value to an integer. |
| `sample` | Reads input from the terminal. |
| `serve` | Outputs data to the terminal. |
| `burn` | Raises an error. If uncaught, it terminates the program. |
| `random` | Generates a random number: |
| | - 0 args: a random float between `0` and `1`. |
| | - 1 arg: a random integer between `0` and the given max value. |
| | - 2 args: a random integer between the given min and max values. |
| `get_time` | Returns the current UNIX timestamp. |
| `taste_file` | Reads the content of a file. |
| `plate_file` | Writes data to a file (overwrites the file if it already exists). |
| `garnish_file` | Appends data to a file. |
| `length` | Returns the length of a string or array. |
| `sleep` | Pauses program execution for the specified number of milliseconds. |
10 changes: 10 additions & 0 deletions docs/syntax_examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ These are examples showcasing the unique (& fun) syntax of FlavorLang. They give
18. [Basic Arrays & Operations](#18)
19. [2D Arrays](#19)
20. [Call Functions by Reference (Even in Arrays)](#20)
21. [Sleep](#21)

---

Expand Down Expand Up @@ -516,6 +517,15 @@ for i in 0..(length(c)) {
}
```

### 21. Sleep <a id="21"></a>

```js
for i in 100..=1 by -5 {
serve(i);
sleep(i * 10);
}
```

---

## License
Expand Down
50 changes: 50 additions & 0 deletions src/interpreter/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

// Helper function to check if a LiteralType matches an ArgType
bool literal_type_matches_arg_type(LiteralType lit_type, ArgType arg_type) {
Expand Down Expand Up @@ -814,3 +819,48 @@ InterpretResult builtin_length(ASTNode *node, Environment *env) {
// Return the length as a LiteralValue
return make_result(result, false, false);
}

/**
* @brief Built-in function to sleep (pause execution) for a given time (in
* milliseconds).
*
* @param node The AST node representing the function call.
* @param env The current environment.
* @return InterpretResult with a default value.
*/
InterpretResult builtin_sleep(ASTNode *node, Environment *env) {
// Define expected arguments: exactly one integer (> 0).
INT_SIZE ms;

ArgumentSpec specs[1];
specs[0].type = ARG_TYPE_INTEGER;
specs[0].out_ptr = &ms;

// Interpret arguments
InterpretResult args_res =
interpret_arguments(node->function_call.arguments, env, 1, specs);
if (args_res.is_error) {
return args_res;
}

// Validate the argument
if (ms <= 0) {
return raise_error("`sleep` requires a positive integer argument "
"representing milliseconds.\n");
}

// Perform the sleep based on the platform
#ifdef _WIN32
Sleep((DWORD)ms); // sleep takes milliseconds on Windows
#else
if (ms > (INT_MAX / 1000)) {
return raise_error("`sleep` argument is too large.\n");
}

useconds_t us = (useconds_t)(ms * 1000); // usleep needs microseconds
usleep(us);
#endif

LiteralValue result = create_default_value();
return make_result(result, false, false);
}
1 change: 1 addition & 0 deletions src/interpreter/builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ InterpretResult builtin_file_read(ASTNode *node, Environment *env);
InterpretResult builtin_file_write(ASTNode *node, Environment *env);
InterpretResult builtin_file_append(ASTNode *node, Environment *env);
InterpretResult builtin_length(ASTNode *node, Environment *env);
InterpretResult builtin_sleep(ASTNode *node, Environment *env);

// Helpers
bool literal_type_matches_arg_type(LiteralType lit_type, ArgType arg_type);
Expand Down
2 changes: 2 additions & 0 deletions src/interpreter/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1596,6 +1596,8 @@ InterpretResult interpret_function_call(ASTNode *node, Environment *env) {
return builtin_file_append(node, env);
} else if (strcmp(func->name, "length") == 0) {
return builtin_length(node, env);
} else if (strcmp(func->name, "sleep") == 0) {
return builtin_sleep(node, env);
} else {
return raise_error("Unknown built-in function `%s`\n", func->name);
}
Expand Down
6 changes: 3 additions & 3 deletions src/interpreter/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ void initialize_builtin_function(Environment *env, const char *name) {

void initialize_all_builtin_functions(Environment *env) {
const char *builtin_functions[] = {
"string", "float", "int", "sample",
"serve", "burn", "random", "get_time",
"taste_file", "plate_file", "garnish_file", "length"};
"string", "float", "int", "sample", "serve",
"burn", "random", "get_time", "taste_file", "plate_file",
"garnish_file", "length", "sleep"};

for (size_t i = 0;
i < sizeof(builtin_functions) / sizeof(builtin_functions[0]); i++) {
Expand Down
4 changes: 4 additions & 0 deletions src/tests/21_sleep.flv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
for i in 100..=1 by -5 {
serve(i);
sleep(i * 10);
}

0 comments on commit 17244a5

Please sign in to comment.