/*************************************************************************************** * Copyright (c) 2014-2022 Zihao Yu, Nanjing University * * NEMU is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * http://license.coscl.org.cn/MulanPSL2 * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * * See the Mulan PSL v2 for more details. ***************************************************************************************/ // Modified by: Zhiyi Zhang in 2024.08 #include "common.h" #ifndef PRId32 // dev-cpp 5.11 does not support PRId32 #define PRId32 "d" #endif void init_regex(void); uint32_t expr(char *e, bool *success); static int cmd_q(char *args) { return -1; } static int cmd_help(char *args); static int cmd_p(char *args) { bool success = true; uint32_t res = expr(args, &success); if (success) { printf("$res = % " PRId32 "\n", res); } return success; } static struct { const char *name; const char *description; int (*handler) (char *); } cmd_table [] = { { "help", "Display information about all supported commands", cmd_help }, { "p", "p EXPR: To evaluate an expression EXPR and output the result", cmd_p }, { "q", "Exit EXPR", cmd_q }, /* TODO: Add more commands */ }; #define NR_CMD ARRLEN(cmd_table) static void print_help() { for (int i = 0; i < NR_CMD; i ++) { printf("%s - %s\n", cmd_table[i].name, cmd_table[i].description); } } static int cmd_help(char *args) { /* extract the first argument */ char *arg = strtok(NULL, " "); int i; if (arg == NULL) { /* no argument given */ print_help(); } else { for (i = 0; i < NR_CMD; i ++) { if (strcmp(arg, cmd_table[i].name) == 0) { printf("%s - %s\n", cmd_table[i].name, cmd_table[i].description); return 0; } } printf("Unknown command '%s'\n", arg); } return 0; } void welcome(void) { Log("Build time: %s, %s", __TIME__, __DATE__); printf("Welcome to %s\n", ANSI_FMT("EXPR", ANSI_FG_YELLOW ANSI_BG_RED)); printf("For help, type \"help\"\n"); } int main(int argc, char **argv) { static char str[1024] = { 0 }; bool running = true; init_regex(); welcome(); while (running) { printf("(expr) "); if (!fgets(str, 1024, stdin)) { continue; } str[strlen(str) - 1] = '\0'; char *str_end = str + strlen(str); /* extract the first token as the command */ char *cmd = strtok(str, " "); if (cmd == NULL) { continue; } /* treat the remaining string as the arguments, * which may need further parsing */ char *args = cmd + strlen(cmd) + 1; if (args >= str_end) { args = NULL; } int i; for (i = 0; i < NR_CMD; i ++) { if (strcmp(cmd, cmd_table[i].name) == 0) { if (cmd_table[i].handler(args) < 0) { return -1; } break; } } if (i == NR_CMD) { printf("Unknown command '%s'\n", cmd); } } return 0; }