Programming-Clem/BzzBee
0
1#define _GNU_SOURCE2#include <stdio.h>3#include <stdlib.h>4#include <string.h>5#include <time.h>6#include <math.h>7#include <unistd.h>8#include <sys/stat.h>9#include <ctype.h>10#include <termios.h>11 12#define MAX_VARIABLES 10013#define MAX_ARRAYS 5014#define MAX_PACKAGES 5015#define MAX_PACKAGE_FUNCTIONS 20016#define MAX_LINE_LENGTH 100017#define MAX_CANVAS_WIDTH 8018#define MAX_CANVAS_HEIGHT 3019#define MAX_LISTS 5020#define MAX_DICTS 5021#define MAX_LIST_SIZE 100022#define MAX_DICT_SIZE 50023#define MAX_STORIES 2024#define MAX_STORY_CHOICES 1025#define MAX_VAR_NAME 10026#define MAX_VAR_VALUE 50027#define MAX_ARRAY_SIZE 10028#define MAX_LOOPS 2029#define MAX_FUNCTIONS 5030 31// Structure pour les packages32typedef struct {33 char name[MAX_VAR_NAME];34 char language[10];35 char file_path[200];36 int is_loaded;37} Package;38 39// Structure pour les fonctions de packages40typedef struct {41 char name[MAX_VAR_NAME];42 char package_name[MAX_VAR_NAME];43 char language[10];44 char file_path[200];45 char parameters[500];46 int param_count;47} PackageFunction;48 49// Structure pour les variables50typedef struct {51 char name[MAX_VAR_NAME];52 char value[MAX_VAR_VALUE];53 double num_value;54 int is_number;55 int is_array;56 double array_values[MAX_ARRAY_SIZE];57 int array_size;58} Variable;59 60// Structure pour les boucles61typedef struct {62 int start_line;63 int current_iteration;64 int max_iterations;65 char condition[MAX_LINE_LENGTH];66 int is_active;67} Loop;68 69// Structure pour les fonctions70typedef struct {71 char name[MAX_VAR_NAME];72 int start_line;73 int end_line;74 char parameters[10][MAX_VAR_NAME];75 int param_count;76} Function;77 78typedef struct {79 char name[100];80 char elements[1000];81} Array;82 83// Nouvelles structures pour listes avancées84typedef struct {85 char name[100];86 char elements[MAX_LIST_SIZE][200];87 int size;88} List;89 90// Structure pour dictionnaires (NECTAR)91typedef struct {92 char key[100];93 char value[500];94} DictEntry;95 96typedef struct {97 char name[100];98 DictEntry entries[MAX_DICT_SIZE];99 int size;100} Dictionary;101 102// Structure pour histoires interactives103typedef struct {104 char question[500];105 char choices[MAX_STORY_CHOICES][200];106 int next_scenes[MAX_STORY_CHOICES];107 int choice_count;108} StoryScene;109 110typedef struct {111 char name[100];112 StoryScene scenes[50];113 int scene_count;114 int current_scene;115} Story;116 117// Variables globales118Variable variables[MAX_VARIABLES];119Loop loops[MAX_LOOPS];120Function functions[MAX_FUNCTIONS];121Array arrays[MAX_ARRAYS];122List lists[MAX_LISTS];123Dictionary dictionaries[MAX_DICTS];124Story stories[MAX_STORIES];125Package packages[MAX_PACKAGES];126PackageFunction package_functions[MAX_PACKAGE_FUNCTIONS];127int var_count = 0;128int loop_count = 0;129int function_count = 0;130int array_count = 0;131int list_count = 0;132int dict_count = 0;133int story_count = 0;134int package_count = 0;135int package_function_count = 0;136int current_line = 0;137char program_lines[1000][MAX_LINE_LENGTH];138int total_lines = 0;139int skip_until_end = 0;140int in_function_definition = 0;141char current_canvas[20][50];142int canvas_width = 50;143int canvas_height = 20;144 145// Couleurs ANSI146void set_color(const char* color) {147 if (strcmp(color, "rouge") == 0 || strcmp(color, "red") == 0) {148 printf("\033[31m");149 } else if (strcmp(color, "vert") == 0 || strcmp(color, "green") == 0) {150 printf("\033[32m");151 } else if (strcmp(color, "jaune") == 0 || strcmp(color, "yellow") == 0) {152 printf("\033[33m");153 } else if (strcmp(color, "bleu") == 0 || strcmp(color, "blue") == 0) {154 printf("\033[34m");155 } else if (strcmp(color, "magenta") == 0) {156 printf("\033[35m");157 } else if (strcmp(color, "cyan") == 0) {158 printf("\033[36m");159 } else if (strcmp(color, "blanc") == 0 || strcmp(color, "white") == 0) {160 printf("\033[37m");161 } else {162 printf("\033[0m");163 }164}165 166void reset_color() {167 printf("\033[0m");168}169 170// Fonction pour enlever les espaces en début et fin171char* trim(char* str) {172 char* end;173 while(isspace((unsigned char)*str)) str++;174 if(*str == 0) return str;175 end = str + strlen(str) - 1;176 while(end > str && isspace((unsigned char)*end)) end--;177 end[1] = '\0';178 return str;179}180 181// Fonction pour enlever les guillemets182char* remove_quotes(char* str) {183 str = trim(str);184 if (str[0] == '"' && str[strlen(str)-1] == '"') {185 str[strlen(str)-1] = '\0';186 return str + 1;187 }188 return str;189}190 191// Fonction pour trouver une variable192Variable* find_variable(const char* name) {193 for (int i = 0; i < var_count; i++) {194 if (strcmp(variables[i].name, name) == 0) {195 return &variables[i];196 }197 }198 return NULL;199}200 201// Fonction pour créer ou modifier une variable202void set_variable(const char* name, const char* value) {203 Variable* var = find_variable(name);204 if (var == NULL) {205 if (var_count < MAX_VARIABLES) {206 var = &variables[var_count++];207 strcpy(var->name, name);208 var->is_array = 0;209 var->array_size = 0;210 } else {211 printf("Erreur: Trop de variables!\n");212 return;213 }214 }215 216 strcpy(var->value, remove_quotes((char*)value));217 var->num_value = atof(var->value);218 var->is_number = (var->num_value != 0.0 || strcmp(var->value, "0") == 0 || strcmp(var->value, "0.0") == 0);219}220 221// Nouvelle fonction pour créer des tableaux222void create_array(const char* name, const char* values) {223 Variable* var = find_variable(name);224 if (var == NULL) {225 if (var_count < MAX_VARIABLES) {226 var = &variables[var_count++];227 strcpy(var->name, name);228 } else {229 printf("Erreur: Trop de variables!\n");230 return;231 }232 }233 234 var->is_array = 1;235 var->array_size = 0;236 237 char values_copy[500];238 strncpy(values_copy, values, sizeof(values_copy) - 1);239 values_copy[sizeof(values_copy) - 1] = '\0';240 241 char* token = strtok(values_copy, ",");242 while (token && var->array_size < MAX_ARRAY_SIZE) {243 var->array_values[var->array_size] = atof(trim(token));244 var->array_size++;245 token = strtok(NULL, ",");246 }247 printf("Tableau %s créé avec %d éléments!\n", name, var->array_size);248}249 250// Fonction pour initialiser le canvas251void init_canvas() {252 for (int i = 0; i < canvas_height; i++) {253 for (int j = 0; j < canvas_width; j++) {254 current_canvas[i][j] = ' ';255 }256 }257}258 259// Fonction pour afficher le canvas260void display_canvas() {261 printf("┌");262 for (int j = 0; j < canvas_width; j++) printf("─");263 printf("┐\n");264 265 for (int i = 0; i < canvas_height; i++) {266 printf("│");267 for (int j = 0; j < canvas_width; j++) {268 printf("%c", current_canvas[i][j]);269 }270 printf("│\n");271 }272 273 printf("└");274 for (int j = 0; j < canvas_width; j++) printf("─");275 printf("┘\n");276}277 278// Fonction pour dessiner sur le canvas279void draw_pixel(int x, int y, char pixel) {280 if (x >= 0 && x < canvas_width && y >= 0 && y < canvas_height) {281 current_canvas[y][x] = pixel;282 }283}284 285// Fonction pour jouer des notes de musique286void play_note(const char* note, int duration) {287 int frequency = 440; // A4 par défaut288 289 if (strcmp(note, "do") == 0 || strcmp(note, "C") == 0) frequency = 261;290 else if (strcmp(note, "re") == 0 || strcmp(note, "D") == 0) frequency = 293;291 else if (strcmp(note, "mi") == 0 || strcmp(note, "E") == 0) frequency = 329;292 else if (strcmp(note, "fa") == 0 || strcmp(note, "F") == 0) frequency = 349;293 else if (strcmp(note, "sol") == 0 || strcmp(note, "G") == 0) frequency = 392;294 else if (strcmp(note, "la") == 0 || strcmp(note, "A") == 0) frequency = 440;295 else if (strcmp(note, "si") == 0 || strcmp(note, "B") == 0) frequency = 493;296 297 printf("♪ Note %s (%dHz) jouée pendant %dms ♪\n", note, frequency, duration);298 usleep(duration * 1000);299}300 301// Fonction pour générer des nombres aléatoires302int random_number(int min, int max) {303 return min + rand() % (max - min + 1);304}305 306// Déclarations de fonctions307void scan_bzz_functions(const char* file_path);308int execute_package_code(const char* language, const char* file_path, const char* params);309 310// Fonction pour vérifier si un langage est disponible311int check_language_availability(const char* language) {312 char command[500];313 char temp_check[300];314 snprintf(temp_check, sizeof(temp_check), "/tmp/bzzbee_check_%d.txt", getpid());315 316 if (strcmp(language, "js") == 0) {317 snprintf(command, sizeof(command), "which node > '%s' 2>&1", temp_check);318 } else if (strcmp(language, "py") == 0) {319 snprintf(command, sizeof(command), "which python3 > '%s' 2>&1", temp_check);320 } else if (strcmp(language, "jl") == 0) {321 snprintf(command, sizeof(command), "which julia > '%s' 2>&1", temp_check);322 } else if (strcmp(language, "rb") == 0 || strcmp(language, "rub") == 0) {323 snprintf(command, sizeof(command), "which ruby > '%s' 2>&1", temp_check);324 } else if (strcmp(language, "c") == 0 || strcmp(language, "C") == 0) {325 snprintf(command, sizeof(command), "which gcc > '%s' 2>&1", temp_check);326 } else if (strcmp(language, "bzz") == 0) {327 return 1; // BzzBee est toujours disponible328 } else {329 return 0;330 }331 332 int result = system(command);333 remove(temp_check);334 return (result == 0);335}336 337// Fonction pour charger un package338int load_package(const char* language, const char* file_path) {339 if (package_count >= MAX_PACKAGES) {340 printf("❌ Erreur: Trop de packages chargés (maximum: %d)!\n", MAX_PACKAGES);341 return 0;342 }343 344 // Vérifier si le langage est disponible345 if (!check_language_availability(language)) {346 printf("❌ Erreur: Langage '%s' non disponible sur ce système!\n", language);347 printf("💡 Langages détectés: ");348 if (check_language_availability("js")) printf("js ");349 if (check_language_availability("py")) printf("py ");350 if (check_language_availability("jl")) printf("jl ");351 if (check_language_availability("rb")) printf("rb ");352 if (check_language_availability("c")) printf("c ");353 printf("bzz\n");354 return 0;355 }356 357 // Vérifier si le fichier existe358 FILE* file = fopen(file_path, "r");359 if (!file) {360 printf("❌ Erreur: Fichier package '%s' introuvable!\n", file_path);361 printf("💡 Assurez-vous que le chemin est correct et que le fichier existe.\n");362 return 0;363 }364 fclose(file);365 366 // Vérifier si le package n'est pas déjà chargé367 for (int i = 0; i < package_count; i++) {368 if (strcmp(packages[i].file_path, file_path) == 0) {369 printf("⚠️ Package '%s' déjà chargé, rechargement...\n", file_path);370 packages[i].is_loaded = 1;371 return 1;372 }373 }374 375 Package* pkg = &packages[package_count];376 sprintf(pkg->name, "package_%s_%d", language, package_count);377 strcpy(pkg->language, language);378 strcpy(pkg->file_path, file_path);379 pkg->is_loaded = 1;380 381 package_count++;382 printf("🐝 Package %s (%s) chargé avec succès! [%d/%d]\n", file_path, language, package_count, MAX_PACKAGES);383 384 // Test rapide du package385 printf("🧪 Test du package...\n");386 if (strcmp(language, "bzz") == 0) {387 scan_bzz_functions(file_path);388 printf("✅ Package BzzBee analysé avec succès!\n");389 } else {390 // Pour les autres langages, on teste juste la disponibilité391 printf("✅ Package %s prêt à l'utilisation!\n", language);392 }393 394 return 1;395}396 397// Fonction pour exécuter du code selon le langage et capturer la sortie398int execute_package_code(const char* language, const char* file_path, const char* params) {399 char command[2000];400 char temp_output[300];401 snprintf(temp_output, sizeof(temp_output), "/tmp/bzzbee_output_%d.txt", getpid());402 403 // Nettoyer les paramètres pour éviter les injections404 char safe_params[500] = "";405 if (params && strlen(params) > 0) {406 strncpy(safe_params, params, sizeof(safe_params) - 1);407 safe_params[sizeof(safe_params) - 1] = '\0';408 }409 410 if (strcmp(language, "js") == 0) {411 snprintf(command, sizeof(command), "timeout 10 node '%s' %s > '%s' 2>&1", file_path, safe_params, temp_output);412 } else if (strcmp(language, "py") == 0) {413 snprintf(command, sizeof(command), "timeout 10 python3 '%s' %s > '%s' 2>&1", file_path, safe_params, temp_output);414 } else if (strcmp(language, "jl") == 0) {415 snprintf(command, sizeof(command), "timeout 10 julia '%s' %s > '%s' 2>&1", file_path, safe_params, temp_output);416 } else if (strcmp(language, "rb") == 0 || strcmp(language, "rub") == 0) {417 snprintf(command, sizeof(command), "timeout 10 ruby '%s' %s > '%s' 2>&1", file_path, safe_params, temp_output);418 } else if (strcmp(language, "c") == 0 || strcmp(language, "C") == 0) {419 // Compiler et exécuter le C avec timeout420 char exe_name[300];421 snprintf(exe_name, sizeof(exe_name), "/tmp/bzzbee_c_%d", getpid());422 snprintf(command, sizeof(command), "gcc -o '%s' '%s' -lm 2>/dev/null && timeout 10 '%s' %s > '%s' 2>&1; rm -f '%s'", 423 exe_name, file_path, exe_name, safe_params, temp_output, exe_name);424 } else if (strcmp(language, "bzz") == 0) {425 // Exécuter un autre fichier BzzBee426 snprintf(command, sizeof(command), "timeout 10 ./main run '%s' > '%s' 2>&1", file_path, temp_output);427 } else {428 printf("❌ Langage '%s' non supporté!\n", language);429 return 0;430 }431 432 printf("🔧 Exécution: %s %s\n", file_path, safe_params);433 system(command);434 435 // Lire et afficher la sortie du programme436 FILE* output_file = fopen(temp_output, "r");437 if (output_file) {438 char line[1000];439 int line_count = 0;440 int has_output = 0;441 while (fgets(line, sizeof(line), output_file) && line_count < 50) {442 printf("%s", line);443 line_count++;444 has_output = 1;445 }446 if (line_count >= 50) {447 printf("... (sortie tronquée)\n");448 }449 if (!has_output) {450 printf("✅ Exécution terminée sans sortie.\n");451 }452 fclose(output_file);453 remove(temp_output);454 }455 456 return 1; // Considérer l'exécution comme réussie457}458 459// Fonction pour scanner les fonctions dans un package BzzBee460void scan_bzz_functions(const char* file_path) {461 FILE* file = fopen(file_path, "r");462 if (!file) return;463 464 char line[MAX_LINE_LENGTH];465 while (fgets(line, sizeof(line), file)) {466 line[strcspn(line, "\n")] = 0;467 468 // Chercher les fonctions avec le pattern pollen -> ... : miel469 if (strstr(line, "pollen ->") && strstr(line, ": miel")) {470 if (package_function_count < MAX_PACKAGE_FUNCTIONS) {471 PackageFunction* func = &package_functions[package_function_count];472 sprintf(func->name, "function_%d", package_function_count);473 strcpy(func->language, "bzz");474 strcpy(func->file_path, file_path);475 strcpy(func->parameters, line);476 package_function_count++;477 printf("📝 Fonction BzzBee détectée: %s\n", line);478 }479 }480 }481 fclose(file);482}483 484// Fonction pour exécuter une fonction de package485int execute_package_function(const char* function_call) {486 // Parser le format pollen -> params : miel [langage fichier]487 char* pollen_start = strstr(function_call, "pollen ->");488 char* miel_end = strstr(function_call, ": miel");489 490 if (!pollen_start || !miel_end) {491 printf("❌ Format de fonction package incorrect!\n");492 printf("📝 Format 1: pollen -> params : miel (utilise tous les packages)\n");493 printf("📝 Format 2: pollen -> params : miel [langage fichier] (utilise un package spécifique)\n");494 return 0;495 }496 497 // Extraire les paramètres498 char params[500];499 char* param_start = pollen_start + 9; // après "pollen ->"500 int param_len = miel_end - param_start;501 strncpy(params, param_start, param_len);502 params[param_len] = '\0';503 504 char* trimmed_params = trim(params);505 506 if (strlen(trimmed_params) == 0) {507 printf("❌ Aucun paramètre fourni pour la fonction package!\n");508 return 0;509 }510 511 // Vérifier s'il y a une spécification de langage et fichier après ": miel"512 char* spec_start = miel_end + 6; // après ": miel"513 char specified_language[20] = "";514 char specified_file[200] = "";515 int has_specification = 0;516 517 // Parser [langage fichier] si présent518 char* bracket_open = strchr(spec_start, '[');519 char* bracket_close = strchr(spec_start, ']');520 521 if (bracket_open && bracket_close && bracket_close > bracket_open) {522 has_specification = 1;523 char spec_content[300];524 int spec_len = bracket_close - bracket_open - 1;525 strncpy(spec_content, bracket_open + 1, spec_len);526 spec_content[spec_len] = '\0';527 528 // Séparer langage et fichier529 char* space_pos = strchr(spec_content, ' ');530 if (space_pos) {531 *space_pos = '\0';532 strcpy(specified_language, spec_content);533 strcpy(specified_file, space_pos + 1);534 535 // Nettoyer les espaces536 char* lang_trimmed = trim(specified_language);537 char* file_trimmed = trim(specified_file);538 strcpy(specified_language, lang_trimmed);539 strcpy(specified_file, file_trimmed);540 541 printf("🎯 Langage spécifié: '%s', Fichier: '%s'\n", specified_language, specified_file);542 } else {543 printf("❌ Format de spécification incorrect! Utilisez: [langage fichier]\n");544 return 0;545 }546 }547 548 printf("🍯 Appel de fonction package: %s\n", trimmed_params);549 550 int executed = 0;551 552 if (has_specification) {553 // Exécuter avec le langage et fichier spécifiés554 if (strlen(specified_language) > 0 && strlen(specified_file) > 0) {555 // Vérifier si le langage est disponible556 if (!check_language_availability(specified_language)) {557 printf("❌ Langage '%s' non disponible sur ce système!\n", specified_language);558 return 0;559 }560 561 // Vérifier si le fichier existe562 FILE* file = fopen(specified_file, "r");563 if (!file) {564 printf("❌ Fichier '%s' introuvable!\n", specified_file);565 return 0;566 }567 fclose(file);568 569 printf("🔧 Exécution avec %s -> %s\n", specified_language, specified_file);570 executed = execute_package_code(specified_language, specified_file, trimmed_params);571 }572 } else {573 // Exécuter sur tous les packages chargés jusqu'à ce qu'un fonctionne574 for (int i = 0; i < package_count; i++) {575 Package* pkg = &packages[i];576 if (pkg->is_loaded) {577 printf("🔍 Tentative avec package %s (%s)...\n", pkg->file_path, pkg->language);578 if (execute_package_code(pkg->language, pkg->file_path, trimmed_params)) {579 executed = 1;580 break; // Arrêter après la première exécution réussie581 }582 }583 }584 }585 586 if (!executed) {587 if (has_specification) {588 printf("❌ Impossible d'exécuter avec %s -> %s!\n", specified_language, specified_file);589 } else if (package_count == 0) {590 printf("❌ Aucun package chargé! Utilisez 'bzz PACKAGE langage -> fichier' d'abord.\n");591 } else {592 printf("❌ Aucun package n'a pu exécuter cette fonction!\n");593 printf("💡 Packages chargés: ");594 for (int i = 0; i < package_count; i++) {595 if (packages[i].is_loaded) {596 printf("%s(%s) ", packages[i].file_path, packages[i].language);597 }598 }599 printf("\n");600 }601 }602 603 return executed;604}605 606// Fonction pour évaluer une expression mathématique avancée607double evaluate_expression(const char* expr) {608 char expr_copy[500];609 strncpy(expr_copy, expr, sizeof(expr_copy) - 1);610 expr_copy[sizeof(expr_copy) - 1] = '\0';611 612 char* token;613 double result = 0;614 char operation = '+';615 int first = 1;616 617 // Support des parenthèses simple618 if (strchr(expr_copy, '(')) {619 char* start = strchr(expr_copy, '(');620 char* end = strchr(expr_copy, ')');621 if (start && end && end > start) {622 *end = '\0';623 double sub_result = evaluate_expression(start + 1);624 char temp[100];625 sprintf(temp, "%.2f", sub_result);626 strcpy(start, temp);627 memmove(start + strlen(temp), end + 1, strlen(end + 1) + 1);628 }629 }630 631 // Support des fonctions mathématiques632 if (strstr(expr_copy, "sin(")) {633 char* start = strstr(expr_copy, "sin(");634 char* end = strchr(start, ')');635 if (end) {636 *end = '\0';637 double angle = atof(start + 4);638 double result_sin = sin(angle * M_PI / 180.0);639 sprintf(start, "%.4f", result_sin);640 memmove(start + strlen(start), end + 1, strlen(end + 1) + 1);641 }642 }643 644 if (strstr(expr_copy, "cos(")) {645 char* start = strstr(expr_copy, "cos(");646 char* end = strchr(start, ')');647 if (end) {648 *end = '\0';649 double angle = atof(start + 4);650 double result_cos = cos(angle * M_PI / 180.0);651 sprintf(start, "%.4f", result_cos);652 memmove(start + strlen(start), end + 1, strlen(end + 1) + 1);653 }654 }655 656 if (strstr(expr_copy, "sqrt(")) {657 char* start = strstr(expr_copy, "sqrt(");658 char* end = strchr(start, ')');659 if (end) {660 *end = '\0';661 double value = atof(start + 5);662 double result_sqrt = sqrt(value);663 sprintf(start, "%.4f", result_sqrt);664 memmove(start + strlen(start), end + 1, strlen(end + 1) + 1);665 }666 }667 668 token = strtok(expr_copy, " ");669 while (token != NULL) {670 if (strcmp(token, "+") == 0) {671 operation = '+';672 } else if (strcmp(token, "-") == 0) {673 operation = '-';674 } else if (strcmp(token, "*") == 0) {675 operation = '*';676 } else if (strcmp(token, "/") == 0) {677 operation = '/';678 } else if (strcmp(token, "^") == 0 || strcmp(token, "**") == 0) {679 operation = '^';680 } else if (strcmp(token, "%") == 0) {681 operation = '%';682 } else {683 double value;684 Variable* var = find_variable(token);685 if (var && var->is_number) {686 value = var->num_value;687 } else {688 value = atof(token);689 }690 691 if (first) {692 result = value;693 first = 0;694 } else {695 switch (operation) {696 case '+': result += value; break;697 case '-': result -= value; break;698 case '*': result *= value; break;699 case '/': 700 if (value != 0) result /= value;701 else printf("Erreur: Division par zéro!\n");702 break;703 case '^': result = pow(result, value); break;704 case '%': result = fmod(result, value); break;705 }706 }707 }708 token = strtok(NULL, " ");709 }710 return result;711}712 713// Fonction pour évaluer une condition714int evaluate_condition(const char* condition) {715 char cond_copy[500];716 strncpy(cond_copy, condition, sizeof(cond_copy) - 1);717 cond_copy[sizeof(cond_copy) - 1] = '\0';718 char* var_name = strtok(cond_copy, " ");719 char* operator = strtok(NULL, " ");720 char* value = strtok(NULL, " ");721 722 if (!var_name || !operator || !value) {723 return 0;724 }725 726 Variable* var = find_variable(var_name);727 if (!var) {728 return 0;729 }730 731 int result = 0;732 if (strcmp(operator, "==") == 0) {733 result = (strcmp(var->value, value) == 0);734 } else if (strcmp(operator, "!=") == 0) {735 result = (strcmp(var->value, value) != 0);736 } else if (strcmp(operator, ">") == 0 && var->is_number) {737 result = (var->num_value > atof(value));738 } else if (strcmp(operator, "<") == 0 && var->is_number) {739 result = (var->num_value < atof(value));740 } else if (strcmp(operator, ">=") == 0 && var->is_number) {741 result = (var->num_value >= atof(value));742 } else if (strcmp(operator, "<=") == 0 && var->is_number) {743 result = (var->num_value <= atof(value));744 }745 746 return result;747}748 749// Fonction pour dessiner des formes ASCII750void draw_ascii(const char* shape) {751 if (strcmp(shape, "abeille") == 0) {752 printf(" ___\n");753 printf(" / \\\n");754 printf(" | () () |\n");755 printf(" \\ ^ /\n");756 printf(" ||||||\n");757 printf(" ||||||\n");758 printf(" /_____\\\n");759 } else if (strcmp(shape, "ruche") == 0) {760 printf(" /\\_/\\_/\\\n");761 printf(" / \\\n");762 printf(" | RUCHE |\n");763 printf(" |_________|\n");764 printf(" \\_______/\n");765 } else if (strcmp(shape, "fleur") == 0) {766 printf(" .-'~~~'-.\n");767 printf(" / \\\n");768 printf(" | () () () |\n");769 printf(" \\ ^ /\n");770 printf(" | | |\n");771 printf(" | | |\n");772 } else if (strcmp(shape, "hexagone") == 0) {773 printf(" ___\n");774 printf(" / \\\n");775 printf(" | |\n");776 printf(" | |\n");777 printf(" \\___/\n");778 } else if (strcmp(shape, "soleil") == 0) {779 printf(" \\ | /\n");780 printf(" \\ | /\n");781 printf(" --- \\(o)/ ---\n");782 printf(" / | \\\n");783 printf(" / | /\n");784 } else if (strcmp(shape, "nuage") == 0) {785 printf(" .-~~~-.\n");786 printf(" .-~ ~-.\n");787 printf(" ( )\n");788 printf(" '-.._____..-'\n");789 } else if (strcmp(shape, "coeur") == 0) {790 printf(" ♥♥ ♥♥\n");791 printf(" ♥♥♥♥ ♥♥♥♥\n");792 printf("♥♥♥♥♥♥♥♥♥♥\n");793 printf(" ♥♥♥♥♥♥♥♥♥\n");794 printf(" ♥♥♥♥♥♥♥\n");795 printf(" ♥♥♥♥♥\n");796 printf(" ♥♥♥\n");797 printf(" ♥\n");798 } else {799 printf("Forme '%s' non reconnue.\n", shape);800 printf("Formes disponibles: abeille, ruche, fleur, hexagone, soleil, nuage, coeur\n");801 }802}803 804// Fonction pour lire un seul caractère sans echo805int getch() {806 struct termios oldattr, newattr;807 int ch;808 tcgetattr( STDIN_FILENO, &oldattr );809 newattr = oldattr;810 newattr.c_lflag &= ~( ICANON | ECHO );811 tcsetattr( STDIN_FILENO, TCSANOW, &newattr );812 ch = getchar();813 tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );814 return ch;815}816 817// Fonction pour interpréter une ligne818int interpret_line(char* line) {819 line = trim(line);820 821 // Ignorer les lignes vides et les commentaires822 if (strlen(line) == 0 || line[0] == '#') {823 return 0;824 }825 826 // bzz R console -> message827 if (strncmp(line, "bzz R console ->", 16) == 0) {828 char* message = line + 16;829 message = trim(message);830 printf("%s\n", remove_quotes(message));831 }832 833 // bzz R couleur -> texte834 else if (strncmp(line, "bzz R couleur", 13) == 0) {835 char* rest = line + 13;836 char* arrow = strstr(rest, "->");837 if (arrow) {838 *arrow = '\0';839 char* color = trim(rest);840 char* text = trim(arrow + 2);841 set_color(color);842 printf("%s\n", remove_quotes(text));843 reset_color();844 }845 }846 847 // bzz STOCK variable -> valeur848 else if (strncmp(line, "bzz STOCK", 9) == 0) {849 char* rest = line + 9;850 char* arrow = strstr(rest, "->");851 if (arrow) {852 *arrow = '\0';853 char* var_name = trim(rest);854 char* value = trim(arrow + 2);855 set_variable(var_name, value);856 printf("Variable %s = %s stockée dans la ruche!\n", var_name, remove_quotes(value));857 }858 }859 860 // bzz TABLEAU nom -> valeur1,valeur2,valeur3861 else if (strncmp(line, "bzz TABLEAU", 11) == 0) {862 char* rest = line + 11;863 char* arrow = strstr(rest, "->");864 if (arrow) {865 *arrow = '\0';866 char* array_name = trim(rest);867 char* values = trim(arrow + 2);868 create_array(array_name, remove_quotes(values));869 }870 }871 872 // bzz LISTE AJOUTER <liste> <élément>873 else if (strncmp(line, "bzz LISTE AJOUTER", 16) == 0) {874 char* rest = line + 16;875 char* list_name = strtok(rest, " ");876 char* element = strtok(NULL, "");877 if (list_name && element) {878 List* list = NULL;879 for (int i = 0; i < list_count; i++) {880 if (strcmp(lists[i].name, list_name) == 0) {881 list = &lists[i];882 break;883 }884 }885 if (!list) {886 if (list_count < MAX_LISTS) {887 list = &lists[list_count++];888 strcpy(list->name, list_name);889 list->size = 0;890 } else {891 printf("Erreur: Trop de listes!\n");892 return 0;893 }894 }895 if (list->size < MAX_LIST_SIZE) {896 strcpy(list->elements[list->size], remove_quotes(trim(element)));897 list->size++;898 printf("Élément '%s' ajouté à la liste '%s' (taille: %d)\n", remove_quotes(trim(element)), list_name, list->size);899 } else {900 printf("Erreur: Liste pleine!\n");901 }902 } else {903 printf("Format: bzz LISTE AJOUTER <liste> <élément>\n");904 }905 }906 907 // bzz LISTE RETIRER <liste> <élément>908 else if (strncmp(line, "bzz LISTE RETIRER", 16) == 0) {909 char* rest = line + 16;910 char* list_name = strtok(rest, " ");911 char* element = strtok(NULL, "");912 if (list_name && element) {913 List* list = NULL;914 for (int i = 0; i < list_count; i++) {915 if (strcmp(lists[i].name, list_name) == 0) {916 list = &lists[i];917 break;918 }919 }920 if (!list) {921 printf("Erreur: Liste non trouvée!\n");922 return 0;923 }924 925 int found = 0;926 for (int i = 0; i < list->size; i++) {927 if (strcmp(list->elements[i], remove_quotes(trim(element))) == 0) {928 // Décaler les éléments suivants929 for (int j = i; j < list->size - 1; j++) {930 strcpy(list->elements[j], list->elements[j + 1]);931 }932 list->size--;933 found = 1;934 printf("Élément '%s' retiré de la liste '%s' (taille: %d)\n", remove_quotes(trim(element)), list_name, list->size);935 break;936 }937 }938 if (!found) {939 printf("Erreur: Élément non trouvé dans la liste!\n");940 }941 } else {942 printf("Format: bzz LISTE RETIRER <liste> <élément>\n");943 }944 }945 946 // bzz LISTE TAILLE <liste>947 else if (strncmp(line, "bzz LISTE TAILLE", 15) == 0) {948 char* list_name = trim(line + 15);949 List* list = NULL;950 for (int i = 0; i < list_count; i++) {951 if (strcmp(lists[i].name, list_name) == 0) {952 list = &lists[i];953 break;954 }955 }956 if (!list) {957 printf("Erreur: Liste non trouvée!\n");958 return 0;959 }960 printf("Taille de la liste '%s': %d\n", list_name, list->size);961 }962 963 // bzz LISTE INDEX <liste> <élément>964 else if (strncmp(line, "bzz LISTE INDEX", 14) == 0) {965 char* rest = line + 14;966 char* list_name = strtok(rest, " ");967 char* element = strtok(NULL, "");968 if (list_name && element) {969 List* list = NULL;970 for (int i = 0; i < list_count; i++) {971 if (strcmp(lists[i].name, list_name) == 0) {972 list = &lists[i];973 break;974 }975 }976 if (!list) {977 printf("Erreur: Liste non trouvée!\n");978 return 0;979 }980 981 int index = -1;982 for (int i = 0; i < list->size; i++) {983 if (strcmp(list->elements[i], remove_quotes(trim(element))) == 0) {984 index = i;985 break;986 }987 }988 989 if (index != -1) {990 printf("Index de l'élément '%s' dans la liste '%s': %d\n", remove_quotes(trim(element)), list_name, index);991 } else {992 printf("Erreur: Élément non trouvé dans la liste!\n");993 }994 } else {995 printf("Format: bzz LISTE INDEX <liste> <élément>\n");996 }997 }998 999 // bzz LISTE TRIER <liste>1000 else if (strncmp(line, "bzz LISTE TRIER", 14) == 0) {1001 char* list_name = trim(line + 14);1002 List* list = NULL;1003 for (int i = 0; i < list_count; i++) {1004 if (strcmp(lists[i].name, list_name) == 0) {1005 list = &lists[i];1006 break;1007 }1008 }1009 if (!list) {1010 printf("Erreur: Liste non trouvée!\n");1011 return 0;1012 }1013 1014 // Tri à bulles (simple pour l'exemple)1015 for (int i = 0; i < list->size - 1; i++) {1016 for (int j = 0; j < list->size - i - 1; j++) {1017 if (strcmp(list->elements[j], list->elements[j + 1]) > 0) {1018 char temp[200];1019 strcpy(temp, list->elements[j]);1020 strcpy(list->elements[j], list->elements[j + 1]);1021 strcpy(list->elements[j + 1], temp);1022 }1023 }1024 }1025 printf("Liste '%s' triée!\n", list_name);1026 }1027 1028 // bzz NECTAR AJOUTER <pot> <clé> <valeur>1029 else if (strncmp(line, "bzz NECTAR AJOUTER", 18) == 0) {1030 char* rest = line + 18;1031 char* dict_name = strtok(rest, " ");1032 char* key = strtok(NULL, " ");1033 char* value = strtok(NULL, "");1034 1035 if (dict_name && key && value) {1036 Dictionary* dict = NULL;1037 for (int i = 0; i < dict_count; i++) {1038 if (strcmp(dictionaries[i].name, dict_name) == 0) {1039 dict = &dictionaries[i];1040 break;1041 }1042 }1043 if (!dict) {1044 if (dict_count < MAX_DICTS) {1045 dict = &dictionaries[dict_count++];1046 strcpy(dict->name, dict_name);1047 dict->size = 0;1048 } else {1049 printf("Erreur: Trop de dictionnaires!\n");1050 return 0;1051 }1052 }1053 1054 if (dict->size < MAX_DICT_SIZE) {1055 strcpy(dict->entries[dict->size].key, remove_quotes(trim(key)));1056 strcpy(dict->entries[dict->size].value, remove_quotes(trim(value)));1057 dict->size++;1058 printf("Ajouté: %s -> %s dans le dictionnaire '%s'\n", remove_quotes(trim(key)), remove_quotes(trim(value)), dict_name);1059 } else {1060 printf("Erreur: Dictionnaire plein!\n");1061 }1062 } else {1063 printf("Format: bzz NECTAR AJOUTER <pot> <clé> <valeur>\n");1064 }1065 }1066 1067 // bzz NECTAR LIRE <pot> <clé>1068 else if (strncmp(line, "bzz NECTAR LIRE", 15) == 0) {1069 char* rest = line + 15;1070 char* dict_name = strtok(rest, " ");1071 char* key = strtok(NULL, "");1072 1073 if (dict_name && key) {1074 Dictionary* dict = NULL;1075 for (int i = 0; i < dict_count; i++) {1076 if (strcmp(dictionaries[i].name, dict_name) == 0) {1077 dict = &dictionaries[i];1078 break;1079 }1080 }1081 if (!dict) {1082 printf("Erreur: Dictionnaire non trouvé!\n");1083 return 0;1084 }1085 1086 int found = 0;1087 for (int i = 0; i < dict->size; i++) {1088 if (strcmp(dict->entries[i].key, remove_quotes(trim(key))) == 0) {1089 printf("Valeur de '%s' dans '%s': %s\n", remove_quotes(trim(key)), dict_name, dict->entries[i].value);1090 found = 1;1091 break;1092 }1093 }1094 1095 if (!found) {1096 printf("Erreur: Clé non trouvée dans le dictionnaire!\n");1097 }1098 } else {1099 printf("Format: bzz NECTAR LIRE <pot> <clé>\n");1100 }1101 }1102 1103 // bzz NECTAR SUPPRIMER <pot> <clé>1104 else if (strncmp(line, "bzz NECTAR SUPPRIMER", 20) == 0) {1105 char* rest = line + 20;1106 char* dict_name = strtok(rest, " ");1107 char* key = strtok(NULL, "");1108 1109 if (dict_name && key) {1110 Dictionary* dict = NULL;1111 for (int i = 0; i < dict_count; i++) {1112 if (strcmp(dictionaries[i].name, dict_name) == 0) {1113 dict = &dictionaries[i];1114 break;1115 }1116 }1117 if (!dict) {1118 printf("Erreur: Dictionnaire non trouvé!\n");1119 return 0;1120 }1121 1122 int found = 0;1123 for (int i = 0; i < dict->size; i++) {1124 if (strcmp(dict->entries[i].key, remove_quotes(trim(key))) == 0) {1125 // Décaler les éléments suivants1126 for (int j = i; j < dict->size - 1; j++) {1127 strcpy(dict->entries[j].key, dict->entries[j + 1].key);1128 strcpy(dict->entries[j].value, dict->entries[j + 1].value);1129 }1130 dict->size--;1131 found = 1;1132 printf("Clé '%s' supprimée du dictionnaire '%s'\n", remove_quotes(trim(key)), dict_name);1133 break;1134 }1135 }1136 1137 if (!found) {1138 printf("Erreur: Clé non trouvée dans le dictionnaire!\n");1139 }1140 } else {1141 printf("Format: bzz NECTAR SUPPRIMER <pot> <clé>\n");1142 }1143 }1144 1145 // bzz MONTRE variable1146 else if (strncmp(line, "bzz MONTRE", 10) == 0) {1147 char* var_name = trim(line + 10);1148 Variable* var = find_variable(var_name);1149 if (var) {1150 if (var->is_array) {1151 printf("Tableau %s: [", var_name);1152 for (int i = 0; i < var->array_size; i++) {1153 printf("%.2f", var->array_values[i]);1154 if (i < var->array_size - 1) printf(", ");1155 }1156 printf("]\n");1157 } else {1158 printf("%s\n", var->value);1159 }1160 } else {1161 printf("Variable %s non trouvée dans la ruche!\n", var_name);1162 }1163 }1164 1165 // bzz CALCUL expression1166 else if (strncmp(line, "bzz CALCUL", 10) == 0) {1167 char* expr = trim(line + 10);1168 double result = evaluate_expression(expr);1169 if (result == (int)result) {1170 printf("%.0f\n", result);1171 } else {1172 printf("%.2f\n", result);1173 }1174 }1175 1176 // bzz HASARD min max1177 else if (strncmp(line, "bzz HASARD", 10) == 0) {1178 char* rest = trim(line + 10);1179 char* min_str = strtok(rest, " ");1180 char* max_str = strtok(NULL, " ");1181 if (min_str && max_str) {1182 int min = atoi(min_str);1183 int max = atoi(max_str);1184 int result = random_number(min, max);1185 printf("Nombre aléatoire entre %d et %d: %d\n", min, max, result);1186 }1187 }1188 1189 // bzz MUSIQUE note durée1190 else if (strncmp(line, "bzz MUSIQUE", 11) == 0) {1191 char* rest = trim(line + 11);1192 char* note = strtok(rest, " ");1193 char* duration_str = strtok(NULL, " ");1194 if (note && duration_str) {1195 int duration = atoi(duration_str);1196 play_note(note, duration);1197 }1198 }1199 1200 // bzz TOILE INIT