Skip to content

Commit b262e41

Browse files
authored
Merge pull request #244 from KennyOliver/issue-243
Issue 243: Built-in `random` function always gives same value on every call
2 parents 963ffe2 + 10b1547 commit b262e41

File tree

4 files changed

+41
-36
lines changed

4 files changed

+41
-36
lines changed

src/interpreter/builtins.c

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,4 @@
11
#include "builtins.h"
2-
#include "../interpreter/interpreter.h"
3-
#include <ctype.h>
4-
#include <stdio.h>
5-
#include <stdlib.h>
6-
#include <string.h>
7-
#include <time.h>
8-
#ifdef _WIN32
9-
#include <windows.h>
10-
#else
11-
#include <unistd.h>
12-
#endif
13-
#ifdef __unix__
14-
#include <dlfcn.h>
15-
#endif
16-
#include <dlfcn.h>
172

183
// Helper function to check if a LiteralType matches an ArgType
194
bool literal_type_matches_arg_type(LiteralType lit_type, ArgType arg_type) {
@@ -230,8 +215,8 @@ InterpretResult builtin_random(ASTNode *node, Environment *env) {
230215
FLOAT_SIZE min = 0.0L; // default min
231216
FLOAT_SIZE max = 1.0L; // default max
232217

218+
// Determine how many arguments were passed
233219
ASTNode *arg_node = node->function_call.arguments;
234-
235220
size_t num_args = 0;
236221
ASTNode *temp = arg_node;
237222
while (temp) {
@@ -243,48 +228,46 @@ InterpretResult builtin_random(ASTNode *node, Environment *env) {
243228
"(integer or float), but %zu provided.\n",
244229
num_args);
245230
}
246-
247231
if (num_args == 1) {
248-
// One argument provided: set max, min remains 0.0
249232
ArgumentSpec specs[1];
250233
specs[0].type = ARG_TYPE_NUMERIC;
251234
specs[0].out_ptr = &max;
252-
253235
InterpretResult args_res = interpret_arguments(arg_node, env, 1, specs);
254236
if (args_res.is_error) {
255237
return args_res;
256238
}
257239
} else if (num_args == 2) {
258-
// Two arguments provided: set min and max
259240
ArgumentSpec specs[2];
260241
specs[0].type = ARG_TYPE_NUMERIC;
261242
specs[0].out_ptr = &min;
262243
specs[1].type = ARG_TYPE_NUMERIC;
263244
specs[1].out_ptr = &max;
264-
265245
InterpretResult args_res = interpret_arguments(arg_node, env, 2, specs);
266246
if (args_res.is_error) {
267247
return args_res;
268248
}
269249
}
270250

271-
// Seed the random number generator once
272-
static bool seeded = false;
273-
if (!seeded) {
274-
srand((unsigned int)(time(NULL) ^ getpid()));
275-
seeded = true;
276-
}
277-
278-
// Swap min & max if min > max to ensure correct range
279251
if (min > max) {
280252
FLOAT_SIZE temp_val = min;
281253
min = max;
282254
max = temp_val;
283255
}
284256

285-
// Generate random number
286-
FLOAT_SIZE random_number =
287-
min + ((FLOAT_SIZE)rand() / (FLOAT_SIZE)RAND_MAX) * (max - min);
257+
static bool seeded = false;
258+
if (!seeded) {
259+
#ifdef _WIN32
260+
srand((unsigned int)(time(NULL) ^ GetTickCount()));
261+
#else
262+
struct timeval tv;
263+
gettimeofday(&tv, NULL);
264+
srand((unsigned int)(tv.tv_sec ^ tv.tv_usec ^ getpid()));
265+
#endif
266+
seeded = true;
267+
}
268+
269+
FLOAT_SIZE random_fraction = ((FLOAT_SIZE)rand() / (FLOAT_SIZE)RAND_MAX);
270+
FLOAT_SIZE random_number = min + random_fraction * (max - min);
288271

289272
debug_print_int("Random number generated (min: " FLOAT_FORMAT
290273
", max: " FLOAT_FORMAT "): `" FLOAT_FORMAT "`\n",
@@ -293,7 +276,6 @@ InterpretResult builtin_random(ASTNode *node, Environment *env) {
293276
LiteralValue result;
294277
result.type = TYPE_FLOAT;
295278
result.data.floating_point = random_number;
296-
297279
return make_result(result, false, false);
298280
}
299281

src/interpreter/builtins.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,28 @@
22
#define BUILTINS_H
33

44
#include "../debug/debug.h"
5+
#include "../interpreter/interpreter.h"
56
#include "../shared/ast_types.h"
67
#include "interpreter_types.h"
78
#include "utils.h"
9+
#include <ctype.h>
810
#include <math.h>
911
#include <stdio.h>
1012
#include <stdlib.h>
1113
#include <string.h>
1214
#include <time.h>
15+
#ifdef _WIN32
16+
#include <windows.h>
17+
#else
18+
#include <unistd.h>
19+
#endif
20+
#ifdef __unix__
21+
#include <dlfcn.h>
22+
#endif
23+
#include <dlfcn.h>
24+
#ifndef _WIN32
25+
#include <sys/time.h>
26+
#endif
1327

1428
typedef enum {
1529
ARG_TYPE_INTEGER,

vscode-extension/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "flavorlang-vscode",
33
"displayName": "FlavorLang Support",
44
"description": "Syntax highlighting for FlavorLang programming language.",
5-
"version": "1.5.0",
5+
"version": "1.6.0",
66
"publisher": "KennyOliver",
77
"repository": {
88
"type": "git",

vscode-extension/syntaxes/flavorlang.tmLanguage.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
{ "include": "#comments" },
66
{ "include": "#strings" },
77
{ "include": "#keywords" },
8+
{ "include": "#builtin-functions" },
89
{ "include": "#functions" },
910
{ "include": "#numbers" },
1011
{ "include": "#operators" },
@@ -40,14 +41,22 @@
4041
"patterns": [
4142
{
4243
"name": "keyword.control.flavorlang",
43-
"match": "\\b(let|const|if|elif|else|for|in|while|create|burn|deliver|check|is|rescue|try|rescue|finish|break|continue|import|export|cimport|floor|ceil|round|abs)\\b"
44+
"match": "\\b(let|const|if|elif|else|for|in|while|create|burn|deliver|check|is|rescue|try|finish|break|continue)\\b"
4445
},
4546
{
4647
"name": "keyword.other.flavorlang",
4748
"match": "\\b(True|False|None)\\b"
4849
}
4950
]
5051
},
52+
"builtin-functions": {
53+
"patterns": [
54+
{
55+
"name": "support.function.builtin.flavorlang",
56+
"match": "\\b(?:sample|serve|burn|random|floor|ceil|round|abs|get_time|taste_file|plate_file|garnish_file|length|sleep|cimport)\\b(?=\\()"
57+
}
58+
]
59+
},
5160
"functions": {
5261
"patterns": [
5362
{
@@ -56,7 +65,7 @@
5665
},
5766
{
5867
"name": "entity.name.function.call.flavorlang",
59-
"match": "\\b[a-zA-Z_][a-zA-Z0-9_]*\\b(?=\\()"
68+
"match": "\\b(?!sample\\b|serve\\b|burn\\b|random\\b|floor\\b|ceil\\b|round\\b|abs\\b|get_time\\b|taste_file\\b|plate_file\\b|garnish_file\\b|length\\b|sleep\\b|cimport\\b)[a-zA-Z_][a-zA-Z0-9_]*\\b(?=\\()"
6069
}
6170
]
6271
},

0 commit comments

Comments
 (0)