From 98b91ce64a2a8fe98bca2bf7635220b48906f366 Mon Sep 17 00:00:00 2001 From: Vipul-Cariappa Date: Sun, 31 Dec 2023 12:06:06 +0530 Subject: [PATCH 1/6] initial setup | working --- src/cli_interpreter.h | 65 +++++++++++++++++++++++++++++++++++++++++++ src/common.h | 13 +++++++++ src/interpreter.c | 6 ++-- src/main.c | 17 +++++++++++ src/parser.y | 27 ++++++++++++++++-- src/semantics.c | 3 ++ 6 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 src/cli_interpreter.h diff --git a/src/cli_interpreter.h b/src/cli_interpreter.h new file mode 100644 index 0000000..be66184 --- /dev/null +++ b/src/cli_interpreter.h @@ -0,0 +1,65 @@ +#include "common.h" + +typedef union { + int integer; + bool boolean; +} ExpressionResult; + +typedef struct { + size_t arglen; + Argument *args; +} Context; + +ExpressionResult evaluate_expression(Expression *exp, Context *cxt); +bool verify_expression_type(Expression *exp, Type type, Context *cxt); +bool verify_ast_semantics(AST *tree); + +static inline bool cli_interpret(AST tree) { + if (tree.type == AST_VARIABLE) { + if (!ast_table_insert(ast, tree.value.var->name, tree)) { + fprintf(stderr, "AST insertion Error\n"); + errno = 0; + return false; + } + } else if (tree.type == AST_FUNCTION) { + if (!ast_table_insert(ast, tree.value.func->funcname, tree)) { + fprintf(stderr, "AST insertion Error\n"); + errno = 0; + return false; + } + } else { + if (verify_expression_type(tree.value.exp, BOOL, NULL)) { + printf(evaluate_expression(tree.value.exp, NULL).boolean + ? "true\n" + : "false\n"); + return true; + } + if (verify_expression_type(tree.value.exp, INT, NULL)) { + printf("%d\n", evaluate_expression(tree.value.exp, NULL).integer); + return true; + } + fprintf(stderr, "Error While Evaluation Expression\n"); + return false; + } + + if (!verify_ast_semantics(&tree)) { + fprintf(stderr, "Semantic Error\n"); + errno = 0; + return false; + } + + if (tree.type == AST_VARIABLE) { + if (tree.value.var->type == INT) { + assert(integer_table_insert( + globalIntegers, tree.value.var->name, + evaluate_expression(tree.value.var->expression, NULL).integer)); + } + else { + assert(boolean_table_insert( + globalBooleans, tree.value.var->name, + evaluate_expression(tree.value.var->expression, NULL).boolean)); + } + } + + return true; +} diff --git a/src/common.h b/src/common.h index 649ab78..9ffd886 100644 --- a/src/common.h +++ b/src/common.h @@ -16,6 +16,8 @@ extern int column; extern char *yytext; extern char *filename; +extern bool cli_interpretation_mode; + extern char syntax_error_msg[]; typedef enum { @@ -104,6 +106,7 @@ struct _Expression { typedef enum { AST_VARIABLE, AST_FUNCTION, + AST_EXPRESSION, } AST_TYPE; struct _AST { @@ -112,6 +115,7 @@ struct _AST { union { Function *func; Variable *var; + Expression *exp; } value; }; @@ -127,6 +131,12 @@ bool verify_semantics(); extern char runtime_error_msg[]; bool interpret(int input, int *output); +DS_TABLE_DEC(integer, int); +DS_TABLE_DEC(boolean, bool); + +extern integer_table_t *globalIntegers; +extern boolean_table_t *globalBooleans; + // FIXME: Check if memory allocations fail static inline const char *const Type_to_string(Type type) { @@ -422,6 +432,9 @@ static inline void print_ast_table(ast_table_t *ast) { case AST_VARIABLE: print_variable(tree->value.var); break; + case AST_EXPRESSION: + // TODO: print error + exit(1); } printf("\n"); } diff --git a/src/interpreter.c b/src/interpreter.c index 0eaab88..d6986dd 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -26,9 +26,6 @@ typedef struct { size_t hash_function(const char *str); -DS_TABLE_DEC(integer, int); -DS_TABLE_DEC(boolean, bool); - DS_TABLE_DEF(integer, int, NULL); DS_TABLE_DEF(boolean, bool, NULL); @@ -90,6 +87,9 @@ bool interpret(int input, int *output) { return false; } } + case AST_EXPRESSION: + // TODO: print error + exit(1); } } diff --git a/src/main.c b/src/main.c index f3772b9..8438834 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include "common.h" #include +#include IMPLEMENT_HASH_FUNCTION; DS_TABLE_DEF(ast, AST, NULL); @@ -7,7 +8,15 @@ DS_TABLE_DEF(ast, AST, NULL); ast_table_t *ast; char *filename; +bool cli_interpretation_mode = false; +void interactive_interpretation(); + int main(int argc, char *argv[]) { + if ((argc == 2) && (!strcmp("-i", argv[1]))) { + interactive_interpretation(); + return 0; + } + if (argc != 3) { fprintf(stderr, "File and input required to execute the program\n"); return 1; @@ -59,3 +68,11 @@ int main(int argc, char *argv[]) { return 0; } + +void interactive_interpretation() { + cli_interpretation_mode = true; + ast = ast_table_new(100); + globalBooleans = boolean_table_new(100); + globalIntegers = integer_table_new(100); + yyparse(); +} diff --git a/src/parser.y b/src/parser.y index 731548f..8ae348d 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,5 +1,6 @@ %{ #include "common.h" + #include "cli_interpreter.h" #define ERROR_MSG_LEN 500 char syntax_error_msg[ERROR_MSG_LEN]; @@ -63,8 +64,30 @@ %% input: %empty - | input value_definition { (ast_table_insert(ast, ($2)->name, (AST){.type = AST_VARIABLE, .value.var = $2})); } - | input function_definition { (ast_table_insert(ast, ($2)->funcname, (AST){.type = AST_FUNCTION, .value.func = $2})); }; + | input expression STATEMENT_END { + if (cli_interpretation_mode) { + cli_interpret((AST){.type = AST_EXPRESSION, .value.exp = $2}); + } + else { + // TODO: print error + exit(1); + } + } + | input value_definition { + if (cli_interpretation_mode) { + cli_interpret((AST){.type = AST_VARIABLE, .value.var = $2}); + } + else { + assert(ast_table_insert(ast, ($2)->name, (AST){.type = AST_VARIABLE, .value.var = $2})); + } + } + | input function_definition { + if (cli_interpretation_mode) { + cli_interpret((AST){.type = AST_FUNCTION, .value.func = $2}); + } else { + assert(ast_table_insert(ast, ($2)->funcname, (AST){.type = AST_FUNCTION, .value.func = $2})); + } + }; function_definition: KW_FUNCDEF IDENTIFIER OPEN_BRACKETS function_definition_arguments CLOSE_BRACKETS RETURN KW_BOOL ASSIGN expression STATEMENT_END { $$ = set_function_return_value(set_function_name($4, $2), BOOL, $9); } | KW_FUNCDEF IDENTIFIER OPEN_BRACKETS function_definition_arguments CLOSE_BRACKETS RETURN KW_INT ASSIGN expression STATEMENT_END { $$ = set_function_return_value(set_function_name($4, $2), INT, $9);}; diff --git a/src/semantics.c b/src/semantics.c index 4f7f8ed..6c4a43d 100644 --- a/src/semantics.c +++ b/src/semantics.c @@ -51,6 +51,9 @@ bool verify_ast_semantics(AST *tree) { return false; } break; + case AST_EXPRESSION: + // TODO: print error msg + exit(1); } tree->semantically_correct = true; return tree; From 5f008b2ad1189df89471f8e5add57c45df775684 Mon Sep 17 00:00:00 2001 From: Vipul-Cariappa Date: Sun, 31 Dec 2023 14:41:20 +0530 Subject: [PATCH 2/6] printing correct error msg | fixes .. --- src/common.h | 4 ++-- src/interpreter.c | 6 ++++-- src/parser.y | 7 ++++--- src/semantics.c | 4 ++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/common.h b/src/common.h index 9ffd886..850b0a8 100644 --- a/src/common.h +++ b/src/common.h @@ -433,8 +433,8 @@ static inline void print_ast_table(ast_table_t *ast) { print_variable(tree->value.var); break; case AST_EXPRESSION: - // TODO: print error - exit(1); + // TODO: print expression + break; } printf("\n"); } diff --git a/src/interpreter.c b/src/interpreter.c index d6986dd..ba154fc 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -87,9 +87,11 @@ bool interpret(int input, int *output) { return false; } } + break; case AST_EXPRESSION: - // TODO: print error - exit(1); + snprintf(syntax_error_msg, ERROR_MSG_LEN, "Internal Error"); + // TODO: clean memory + return false; } } diff --git a/src/parser.y b/src/parser.y index 8ae348d..89d366e 100644 --- a/src/parser.y +++ b/src/parser.y @@ -65,12 +65,13 @@ %% input: %empty | input expression STATEMENT_END { - if (cli_interpretation_mode) { + if (cli_interpretation_mode) { cli_interpret((AST){.type = AST_EXPRESSION, .value.exp = $2}); } else { - // TODO: print error - exit(1); + yyerror("Standalone expression are not allowed\n"); + // ???: Don't exit here + return 1; } } | input value_definition { diff --git a/src/semantics.c b/src/semantics.c index 6c4a43d..6da1819 100644 --- a/src/semantics.c +++ b/src/semantics.c @@ -52,8 +52,8 @@ bool verify_ast_semantics(AST *tree) { } break; case AST_EXPRESSION: - // TODO: print error msg - exit(1); + snprintf(semantic_error_msg, ERROR_MSG_LEN, "Internal Error"); + return false; } tree->semantically_correct = true; return tree; From da03a2ccab77a4ba151fc948ba8af8a7504b267f Mon Sep 17 00:00:00 2001 From: Vipul-Cariappa Date: Sun, 31 Dec 2023 15:12:31 +0530 Subject: [PATCH 3/6] improved sematic error msgs --- src/cli_interpreter.h | 11 ++++---- src/main.c | 6 ++-- src/parser.y | 2 +- src/semantics.c | 64 +++++++++++++++++++++++++++++++++++-------- 4 files changed, 62 insertions(+), 21 deletions(-) diff --git a/src/cli_interpreter.h b/src/cli_interpreter.h index be66184..85c9be4 100644 --- a/src/cli_interpreter.h +++ b/src/cli_interpreter.h @@ -38,13 +38,15 @@ static inline bool cli_interpret(AST tree) { printf("%d\n", evaluate_expression(tree.value.exp, NULL).integer); return true; } - fprintf(stderr, "Error While Evaluation Expression\n"); + + fprintf(stderr, + "Error While Evaluation Expression\nSemantic Error: %s\n", + semantic_error_msg); return false; } if (!verify_ast_semantics(&tree)) { - fprintf(stderr, "Semantic Error\n"); - errno = 0; + fprintf(stderr, "Semantic Error: %s\n", semantic_error_msg); return false; } @@ -53,8 +55,7 @@ static inline bool cli_interpret(AST tree) { assert(integer_table_insert( globalIntegers, tree.value.var->name, evaluate_expression(tree.value.var->expression, NULL).integer)); - } - else { + } else { assert(boolean_table_insert( globalBooleans, tree.value.var->name, evaluate_expression(tree.value.var->expression, NULL).boolean)); diff --git a/src/main.c b/src/main.c index 8438834..bf9df77 100644 --- a/src/main.c +++ b/src/main.c @@ -43,7 +43,7 @@ int main(int argc, char *argv[]) { if (yyparse()) { fclose(file); - fprintf(stderr, "%s", syntax_error_msg); + fprintf(stderr, "%s\n", syntax_error_msg); return 1; } /* END */ @@ -52,7 +52,7 @@ int main(int argc, char *argv[]) { /* Sematic Analysis */ if (!verify_semantics()) { - fprintf(stderr, "\n\nSemantic Error:\n%s\n", semantic_error_msg); + fprintf(stderr, "Semantic Error: %s\n", semantic_error_msg); return 1; } @@ -60,7 +60,7 @@ int main(int argc, char *argv[]) { int output; int input = atoi(argv[2]); if (!interpret(input, &output)) { - fprintf(stderr, "\n\nRuntime Error:\n%s\n", runtime_error_msg); + fprintf(stderr, "Runtime Error: %s\n", runtime_error_msg); return 1; } diff --git a/src/parser.y b/src/parser.y index 89d366e..5242a40 100644 --- a/src/parser.y +++ b/src/parser.y @@ -129,5 +129,5 @@ function_call_arguments: expression { $$ = add_function_call_argument_expression void yyerror(char const *str) { snprintf(syntax_error_msg, ERROR_MSG_LEN, - "ERROR: %s in %s:%d:%d\n", str, filename, yylineno, column); + "ERROR: %s in %s:%d:%d", str, filename, yylineno, column); } diff --git a/src/semantics.c b/src/semantics.c index 6da1819..d1c3ea9 100644 --- a/src/semantics.c +++ b/src/semantics.c @@ -19,7 +19,7 @@ bool verify_ast_semantics(AST *tree); char semantic_error_msg[ERROR_MSG_LEN] = {0}; -// TODO: create error message +// TODO: improve error message with line number bool verify_semantics() { char *key; @@ -61,12 +61,19 @@ bool verify_ast_semantics(AST *tree) { bool verify_function_call_arguments(Function *func, Expression **args, size_t arglen, Context *cxt) { - if (func->arglen != arglen) + if (func->arglen != arglen) { + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "Parameter count and argument count mismatch"); return false; + } for (size_t i = 0; i < func->arglen; i++) { - if (!verify_expression_type(args[i], func->args[i].type, cxt)) + if (!verify_expression_type(args[i], func->args[i].type, cxt)) { + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "Expected argument type %s, but got other type", + Type_to_string(func->args[i].type)); return false; + } } return true; } @@ -76,7 +83,7 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { case INTEGER_EXPRESSION: if (type == INT) return true; - return false; + goto expected_int_error; case VARIABLE_EXPRESSION: { AST *variable_ast = ast_table_get_ptr(ast, exp->value.variable); if (variable_ast) { @@ -84,13 +91,21 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { if (variable_ast->value.var->type == type) { return true; } + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "%s has type %s, but expected %s type", + variable_ast->value.var->name, + Type_to_string(variable_ast->value.var->type), + Type_to_string(type)); return false; } + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "%s is not a variable definition", + variable_ast->value.var->name); return false; } if (!cxt) - return false; + goto variable_not_found_error; // TODO: try changing the below to something other then linear search for (size_t i = 0; i < cxt->arglen; i++) { @@ -100,12 +115,17 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { } } } + + variable_not_found_error: + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "Could not find %s's variable definition", + variable_ast->value.var->name); return false; } case BOOLEAN_EXPRESSION: if (type == BOOL) return true; - return false; + goto expected_bool_error; case PLUS_EXPRESSION: case MULTIPLY_EXPRESSION: case DIVIDE_EXPRESSION: @@ -115,13 +135,13 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { verify_expression_type(exp->value.binary.snd, INT, cxt)) return true; } - return false; + goto expected_int_error; case MINUS_EXPRESSION: if (type == INT) { if (verify_expression_type(exp->value.unary.fst, INT, cxt)) return true; } - return false; + goto expected_int_error; case AND_EXPRESSION: case OR_EXPRESSION: if (type == BOOL) { @@ -129,13 +149,13 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { verify_expression_type(exp->value.binary.snd, BOOL, cxt)) return true; } - return false; + goto expected_bool_error; case NOT_EXPRESSION: if (type == BOOL) { if (verify_expression_type(exp->value.unary.fst, BOOL, cxt)) return true; } - return false; + goto expected_bool_error; case EQUALS_EXPRESSION: case NOT_EQUALS_EXPRESSION: case GREATER_EXPRESSION: @@ -146,8 +166,9 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { if (verify_expression_type(exp->value.binary.fst, INT, cxt) && verify_expression_type(exp->value.binary.snd, INT, cxt)) return true; + goto expected_int_error; } - return false; + goto expected_bool_error; case IF_EXPRESSION: if (verify_expression_type(exp->value.if_statement.condition, BOOL, cxt)) { @@ -157,6 +178,7 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { verify_expression_type(exp->value.if_statement.no, INT, cxt)) return true; + goto expected_int_error; } if (type == BOOL) { if (verify_expression_type(exp->value.if_statement.yes, BOOL, @@ -164,9 +186,10 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { verify_expression_type(exp->value.if_statement.no, BOOL, cxt)) return true; + goto expected_bool_error; } } - return false; + goto expected_bool_error; case FUNCTION_CALL_EXPRESSION: { AST *func_ast = ast_table_get_ptr(ast, exp->value.function_call.funcname); @@ -178,7 +201,10 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { func_ast->value.func, exp->value.function_call.args, exp->value.function_call.arglen, cxt)) return true; + return false; } + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "Function return type is not the expected type"); return false; } @@ -186,6 +212,16 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { printf("This should not be printed\n"); return false; } + +expected_bool_error: + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "Expected bool type but got other type"); + return false; + +expected_int_error: + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "Expected int type but got other type"); + return false; } bool verify_function_semantics(Function *func) { @@ -196,5 +232,9 @@ bool verify_function_semantics(Function *func) { bool verify_variable_semantics(Variable *var) { if (verify_expression_type(var->expression, var->type, NULL)) return true; + + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "Expected %s to be %s type but got other type", var->name, + Type_to_string(var->type)); return false; } From 5a33f7a2f8a455f7a7605eb7f71c98f7b02cb7c4 Mon Sep 17 00:00:00 2001 From: Vipul-Cariappa Date: Sun, 31 Dec 2023 15:19:57 +0530 Subject: [PATCH 4/6] main func cleanup | splitting of cli and file interpretation logic --- src/common.h | 2 +- src/main.c | 47 ++++++++++++++++++++++------------------------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/common.h b/src/common.h index 850b0a8..b61fc1e 100644 --- a/src/common.h +++ b/src/common.h @@ -14,7 +14,7 @@ extern void yyerror(char const *s); extern int yylineno; extern int column; extern char *yytext; -extern char *filename; +extern const char *filename; extern bool cli_interpretation_mode; diff --git a/src/main.c b/src/main.c index bf9df77..04009a9 100644 --- a/src/main.c +++ b/src/main.c @@ -6,15 +6,15 @@ IMPLEMENT_HASH_FUNCTION; DS_TABLE_DEF(ast, AST, NULL); ast_table_t *ast; -char *filename; +const char *filename; bool cli_interpretation_mode = false; -void interactive_interpretation(); +int interactive_interpretation(); +int file_interpretation(const char *file_name, int input); int main(int argc, char *argv[]) { - if ((argc == 2) && (!strcmp("-i", argv[1]))) { - interactive_interpretation(); - return 0; + if (argc == 1) { + return interactive_interpretation(); } if (argc != 3) { @@ -22,7 +22,20 @@ int main(int argc, char *argv[]) { return 1; } - filename = argv[1]; + return file_interpretation(argv[1], atoi(argv[2])); +} + +int interactive_interpretation() { + cli_interpretation_mode = true; + ast = ast_table_new(100); + globalBooleans = boolean_table_new(100); + globalIntegers = integer_table_new(100); + yyparse(); + return 0; +} + +int file_interpretation(const char *file_name, int input) { + filename = file_name; FILE *file = fopen(filename, "r"); if (file == NULL) { @@ -30,23 +43,16 @@ int main(int argc, char *argv[]) { return 0; } - yyin = file; - - /* BEGIN */ - // int name_token, value_token = 0; - // while (0 != (name_token = yylex())) { - // printf("NameToken: %d, ValueToken: %d, String: %s\n", name_token, - // value_token, yytext); - // } - + /* Initialization of Variables and Functions Table */ ast = ast_table_new(100); + /* Parsing */ + yyin = file; if (yyparse()) { fclose(file); fprintf(stderr, "%s\n", syntax_error_msg); return 1; } - /* END */ fclose(file); @@ -58,7 +64,6 @@ int main(int argc, char *argv[]) { /* Interpreting */ int output; - int input = atoi(argv[2]); if (!interpret(input, &output)) { fprintf(stderr, "Runtime Error: %s\n", runtime_error_msg); return 1; @@ -68,11 +73,3 @@ int main(int argc, char *argv[]) { return 0; } - -void interactive_interpretation() { - cli_interpretation_mode = true; - ast = ast_table_new(100); - globalBooleans = boolean_table_new(100); - globalIntegers = integer_table_new(100); - yyparse(); -} From bbd3fe605350a5b297a01e0b8878e2562651dd8a Mon Sep 17 00:00:00 2001 From: Vipul-Cariappa Date: Sun, 31 Dec 2023 16:40:14 +0530 Subject: [PATCH 5/6] reinitilization of variables support in cli interpreter mode --- src/DS.h | 42 +++++++++++++++++++++++++++++++++++++++++- src/cli_interpreter.h | 14 ++++++++++++++ src/common.h | 13 ++++++++++++- src/interpreter.c | 4 ++-- src/main.c | 2 +- src/semantics.c | 18 ++++++++++++++---- 6 files changed, 84 insertions(+), 9 deletions(-) diff --git a/src/DS.h b/src/DS.h index e429dc3..8c9234a 100644 --- a/src/DS.h +++ b/src/DS.h @@ -37,6 +37,7 @@ TYPE name##_table_get(name##_table_t *tb, const char *key); \ TYPE *name##_table_get_ptr(name##_table_t *tb, const char *key); \ size_t name##_table_size(name##_table_t *tb); \ + bool name##_table_delete(name##_table_t *tb, const char *key); \ TYPE *name##_table_iter_next(name##_table_t *tb, char **key); \ void name##_table_iter(name##_table_t *tb); \ bool name##_table_clear(name##_table_t *tb); @@ -457,6 +458,45 @@ \ size_t name##_table_size(name##_table_t *tb) { return tb->count; } \ \ - bool name##_table_clear(name##_table_t *tb) { /* TODO: Implement */ \ + bool name##_table_delete(name##_table_t *tb, const char *key) { \ + size_t hash = hash_function(key) % tb->array_length; \ + \ + _##name##_hash_table_list_node *item_list_node = \ + tb->table_list + hash; \ + \ + if (!(item_list_node->item_pair.key)) { \ + errno = EINVAL; \ + return false; \ + } \ + \ + bool is_first = true; \ + \ + do { \ + if (!strcmp(key, item_list_node->item_pair.key)) { \ + delFunc(item_list_node->item_pair.value); \ + \ + void *to_free = item_list_node->next; \ + if (item_list_node->next) { \ + *item_list_node = *item_list_node->next; \ + if (!is_first) { \ + free(to_free); \ + } \ + } else { \ + *item_list_node = (_##name##_hash_table_list_node){0}; \ + } \ + tb->count--; \ + return true; \ + } \ + \ + is_first = false; \ + item_list_node = item_list_node->next; \ + } while (item_list_node); \ + \ + errno = EINVAL; \ + return false; \ + } \ + \ + bool name##_table_clear(name##_table_t *tb) { \ + /* TODO: Implement */ \ return true; \ } diff --git a/src/cli_interpreter.h b/src/cli_interpreter.h index 85c9be4..9e27648 100644 --- a/src/cli_interpreter.h +++ b/src/cli_interpreter.h @@ -16,12 +16,24 @@ bool verify_ast_semantics(AST *tree); static inline bool cli_interpret(AST tree) { if (tree.type == AST_VARIABLE) { + if (ast_table_get_ptr(ast, tree.value.var->name)) { + ast_table_delete(ast, tree.value.var->name); + integer_table_delete(globalIntegers, tree.value.var->name); + boolean_table_delete(globalBooleans, tree.value.var->name); + errno = 0; + } if (!ast_table_insert(ast, tree.value.var->name, tree)) { fprintf(stderr, "AST insertion Error\n"); errno = 0; return false; } } else if (tree.type == AST_FUNCTION) { + if (ast_table_get_ptr(ast, tree.value.func->funcname)) { + ast_table_delete(ast, tree.value.func->funcname); + integer_table_delete(globalIntegers, tree.value.func->funcname); + boolean_table_delete(globalBooleans, tree.value.func->funcname); + errno = 0; + } if (!ast_table_insert(ast, tree.value.func->funcname, tree)) { fprintf(stderr, "AST insertion Error\n"); errno = 0; @@ -42,11 +54,13 @@ static inline bool cli_interpret(AST tree) { fprintf(stderr, "Error While Evaluation Expression\nSemantic Error: %s\n", semantic_error_msg); + semantic_error_msg[0] = 0; return false; } if (!verify_ast_semantics(&tree)) { fprintf(stderr, "Semantic Error: %s\n", semantic_error_msg); + semantic_error_msg[0] = 0; return false; } diff --git a/src/common.h b/src/common.h index b61fc1e..2ff142e 100644 --- a/src/common.h +++ b/src/common.h @@ -444,6 +444,17 @@ static inline void clear_expression(Expression *exp) { // TODO: implement } -static inline void clear_variable(Expression *exp) { +static inline void clear_variable(Variable *var) { // TODO: implement } + +static inline void clear_function(Function *func) { + // TODO: implement +} + +static inline void clear_ast(AST tree) { + // TODO: implement +} + +static inline void clean_integer(int x) {} +static inline void clean_boolean(bool x) {} diff --git a/src/interpreter.c b/src/interpreter.c index ba154fc..dac4413 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -26,8 +26,8 @@ typedef struct { size_t hash_function(const char *str); -DS_TABLE_DEF(integer, int, NULL); -DS_TABLE_DEF(boolean, bool, NULL); +DS_TABLE_DEF(integer, int, clean_integer); +DS_TABLE_DEF(boolean, bool, clean_boolean); ExpressionResult evaluate_expression(Expression *exp, Context *cxt); ExpressionResult execute_function_call(Function *func, Expression **args, diff --git a/src/main.c b/src/main.c index 04009a9..da643ce 100644 --- a/src/main.c +++ b/src/main.c @@ -3,7 +3,7 @@ #include IMPLEMENT_HASH_FUNCTION; -DS_TABLE_DEF(ast, AST, NULL); +DS_TABLE_DEF(ast, AST, clear_ast); ast_table_t *ast; const char *filename; diff --git a/src/semantics.c b/src/semantics.c index d1c3ea9..09ecb4b 100644 --- a/src/semantics.c +++ b/src/semantics.c @@ -93,14 +93,14 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { } snprintf(semantic_error_msg, ERROR_MSG_LEN, "%s has type %s, but expected %s type", - variable_ast->value.var->name, + exp->value.variable, Type_to_string(variable_ast->value.var->type), Type_to_string(type)); return false; } snprintf(semantic_error_msg, ERROR_MSG_LEN, "%s is not a variable definition", - variable_ast->value.var->name); + exp->value.variable); return false; } @@ -119,7 +119,7 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { variable_not_found_error: snprintf(semantic_error_msg, ERROR_MSG_LEN, "Could not find %s's variable definition", - variable_ast->value.var->name); + exp->value.variable); return false; } case BOOLEAN_EXPRESSION: @@ -193,8 +193,18 @@ bool verify_expression_type(Expression *exp, Type type, Context *cxt) { case FUNCTION_CALL_EXPRESSION: { AST *func_ast = ast_table_get_ptr(ast, exp->value.function_call.funcname); - if (!func_ast) + if (!func_ast) { + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "Could not find function %s", + exp->value.function_call.funcname); return false; + } + if (func_ast->type != AST_FUNCTION) { + snprintf(semantic_error_msg, ERROR_MSG_LEN, + "%s is not a function", + exp->value.variable); + return false; + } if (func_ast->value.func->return_type == type) { if (verify_function_call_arguments( From 819127b2733bb57f9831474520f0d04bc0b74995 Mon Sep 17 00:00:00 2001 From: Vipul-Cariappa Date: Sun, 31 Dec 2023 18:18:42 +0530 Subject: [PATCH 6/6] cli interpreter uses char* to parse --- src/main.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index da643ce..03c62e3 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,8 @@ #include #include +void* yy_scan_string(const char *); + IMPLEMENT_HASH_FUNCTION; DS_TABLE_DEF(ast, AST, clear_ast); @@ -30,8 +32,21 @@ int interactive_interpretation() { ast = ast_table_new(100); globalBooleans = boolean_table_new(100); globalIntegers = integer_table_new(100); - yyparse(); - return 0; + + char string[100]; + while (true) { + printf(">>> "); + if (!fgets(string, 100, stdin)) { + fprintf(stderr, "Error while getting input\n"); + return 1; + } + if ((!strcmp("exit\n", string)) || (!strcmp("exit;\n", string))) { + return 0; + } + + yy_scan_string(string); + yyparse(); + } } int file_interpretation(const char *file_name, int input) {