diff --git a/Makefile b/Makefile index a459e6c..f42a566 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = gcc CFLAGS = -Wall -Wextra -O2 -Isrc -LDFLAGS = -lm +LDFLAGS = -lm -lpthread SRC_DIR = src TEST_DIR = tests diff --git a/TODO2.md b/TODO2.md new file mode 100644 index 0000000..aaebaec --- /dev/null +++ b/TODO2.md @@ -0,0 +1,20 @@ +# TO BUILD + +1. Read the whole source code in src. +2. Add File I/O Functions to the scripting language +2.1 Add working tests within the tests directory. +3. Implement async I/O functions for File I/O / Socket I/O / Async I/O. The basic asyncio for methods should be we working using threads so it's a multicore application. It must be a safe way of threading but still performance. +3.1 Add working tests within the tests directory. +3.2 Add a nice example script source file (.rc) to the examples directory that shows file I/O, async I/O, and socket I/O. +4. Add double data type to the language +4.1 Add working tests within the tests directory. +5. Implement break and continue statements in the language +5.1 Add working tests within the tests directory. +6. Update Makefile, README.md, and TUTORIAL.md. + +# IMPORTANT +1. Consistency (By researching how other things are implemented) +2. Performance (But readability is also important) +3. Ease of use for the user of the new language (No weird caveats) +4. Safety (for using the langauge by defensive coding) + diff --git a/src/interpreter.c b/src/interpreter.c index e038a55..a1a11c9 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -73,11 +73,20 @@ void statement() { pc++; while (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != '}' && tokens[pc].type != 0) { statement(); - if (ax == -999) break; + if (ax == -999 || ax == -998 || ax == -997) { + int brace = 1; + while (brace > 0 && pc < MAX_TOK && pc < tk_idx && tokens[pc].type != 0) { + if (tokens[pc].type == '{') brace++; + if (tokens[pc].type == '}') brace--; + pc++; + } + return; + } } match('}'); } - else if (tokens[pc].type == Int || tokens[pc].type == Char) { + else if (tokens[pc].type == Int || tokens[pc].type == Char || tokens[pc].type == Double) { + int var_type = tokens[pc].type; pc++; while (pc < MAX_TOK && pc < tk_idx && tokens[pc].type != ';') { while (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == '*') pc++; @@ -94,6 +103,7 @@ void statement() { int addr = sp; Symbol *s = &locals[loc_cnt++]; strncpy(s->name, t->text, t->val); s->name[t->val] = 0; + s->type = var_type; s->addr = addr; s->is_array = 0; @@ -129,42 +139,45 @@ void statement() { match(')'); if (cond) { statement(); - if (ax == -999) return; + if (ax == -999 || ax == -998 || ax == -997) return; if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == Else) { pc++; skip_block(); } } else { skip_block(); if (pc < MAX_TOK && pc < tk_idx && tokens[pc].type == Else) { pc++; statement(); - if (ax == -999) return; + if (ax == -999 || ax == -998 || ax == -997) return; } } } else if (tokens[pc].type == While) { pc++; int loop_start = pc; - match('('); - long cond = expression(); - match(')'); - if (!cond) { - skip_block(); - } else { - int iteration_count = 0; - while (1) { - if (++iteration_count > 1000000) { - error("Potential infinite loop detected"); - } - statement(); - if (ax == -999) return; - int save_pc = pc; - if (loop_start >= MAX_TOK || loop_start >= tk_idx) { - error("Loop start out of bounds"); - } - pc = loop_start; - match('('); - cond = expression(); - match(')'); - if (!cond) { pc = save_pc; break; } + int body_start; + int iteration_count = 0; + while (1) { + if (++iteration_count > 1000000) { + error("Potential infinite loop detected"); + } + pc = loop_start; + match('('); + long cond = expression(); + match(')'); + if (!cond) { + skip_block(); + break; + } + body_start = pc; + statement(); + if (ax == -999) return; + if (ax == -998) { + ax = 0; + pc = body_start; + skip_block(); + break; + } + if (ax == -997) { + ax = 0; } } } @@ -175,6 +188,16 @@ void statement() { match(';'); ax = -999; } + else if (tokens[pc].type == Break) { + pc++; + match(';'); + ax = -998; + } + else if (tokens[pc].type == Continue) { + pc++; + match(';'); + ax = -997; + } else if (tokens[pc].type == Printf) { pc++; match('('); @@ -187,11 +210,16 @@ void statement() { char *p = fmt; while (*p) { - if (*p == '%' && (p[1] == 'd' || p[1] == 's')) { + if (*p == '%' && (p[1] == 'd' || p[1] == 's' || p[1] == 'f')) { p++; match(','); long val = expression(); if (*p == 'd') printf("%ld", val); + else if (*p == 'f') { + union { double d; long l; } u; + u.l = val; + printf("%f", u.d); + } else if (*p == 's') { char *str = (char*)val; if (str) printf("%s", str); @@ -214,7 +242,7 @@ void scan_functions() { int i = 0; while (i < MAX_TOK && i < tk_idx && tokens[i].type != 0) { if (i + 2 < MAX_TOK && i + 2 < tk_idx && - (tokens[i].type == Int || tokens[i].type == Char) && + (tokens[i].type == Int || tokens[i].type == Char || tokens[i].type == Double) && tokens[i+1].type == Id && tokens[i+2].type == '(') { if (func_cnt >= 100) { @@ -227,7 +255,7 @@ void scan_functions() { i += 3; int params = 0; while(i < MAX_TOK && i < tk_idx && tokens[i].type != ')') { - if (tokens[i].type == Int || tokens[i].type == Char) { + if (tokens[i].type == Int || tokens[i].type == Char || tokens[i].type == Double) { params++; i++; while (i < MAX_TOK && i < tk_idx && tokens[i].type == '*') i++; diff --git a/src/native_functions.c b/src/native_functions.c index 910e825..cacc22b 100644 --- a/src/native_functions.c +++ b/src/native_functions.c @@ -448,6 +448,274 @@ long native_endswith(long *args, int argc) { return strcmp(str + str_len - suffix_len, suffix) == 0; } +long native_fopen(long *args, int argc) { + if (!args || argc < 2) { + return 0; + } + char *filename = (char*)args[0]; + char *mode = (char*)args[1]; + if (!filename || !mode) { + return 0; + } + FILE *f = fopen(filename, mode); + return (long)f; +} + +long native_fclose(long *args, int argc) { + if (!args || argc < 1) { + return -1; + } + FILE *f = (FILE*)args[0]; + if (!f) { + return -1; + } + return fclose(f); +} + +long native_fread(long *args, int argc) { + if (!args || argc < 3) { + return -1; + } + FILE *f = (FILE*)args[0]; + int addr = (int)args[1]; + int size = (int)args[2]; + + if (!f || addr < 0 || addr >= MEM_SIZE || size <= 0) { + return -1; + } + + if (addr + size > MEM_SIZE) { + size = MEM_SIZE - addr; + } + + char temp_buf[8192]; + if (size > 8192) size = 8192; + + int result = fread(temp_buf, 1, size, f); + if (result > 0) { + for (int i = 0; i < result && addr + i < MEM_SIZE; i++) { + memory[addr + i] = temp_buf[i]; + } + } + return result; +} + +long native_fwrite(long *args, int argc) { + if (!args || argc < 3) { + return -1; + } + FILE *f = (FILE*)args[0]; + long buf_arg = args[1]; + int size = (int)args[2]; + + if (!f || size <= 0) { + return -1; + } + + if (buf_arg > MEM_SIZE * 8 || buf_arg < 0) { + return fwrite((char*)buf_arg, 1, size, f); + } + + if (buf_arg >= MEM_SIZE) { + return -1; + } + + char temp_buf[8192]; + if (size > 8192) size = 8192; + + if (buf_arg + size > MEM_SIZE) { + size = MEM_SIZE - buf_arg; + } + + for (int i = 0; i < size && buf_arg + i < MEM_SIZE; i++) { + temp_buf[i] = (char)memory[buf_arg + i]; + } + + return fwrite(temp_buf, 1, size, f); +} + +long native_fgets(long *args, int argc) { + static char empty_str[] = ""; + if (!args || argc < 2) { + return (long)empty_str; + } + FILE *f = (FILE*)args[0]; + int max_size = (int)args[1]; + + if (!f || max_size <= 0) { + return (long)empty_str; + } + + if (str_pool_idx >= STR_POOL_SIZE) { + error("String pool overflow"); + return (long)empty_str; + } + + char *result = &str_pool[str_pool_idx]; + if (max_size > STR_POOL_SIZE - str_pool_idx) { + max_size = STR_POOL_SIZE - str_pool_idx; + } + + if (fgets(result, max_size, f) == NULL) { + return (long)empty_str; + } + + int len = strlen(result); + str_pool_idx += len + 1; + return (long)result; +} + +long native_fputs(long *args, int argc) { + if (!args || argc < 2) { + return -1; + } + FILE *f = (FILE*)args[0]; + char *str = (char*)args[1]; + + if (!f || !str) { + return -1; + } + + return fputs(str, f); +} + +long native_feof(long *args, int argc) { + if (!args || argc < 1) { + return 1; + } + FILE *f = (FILE*)args[0]; + if (!f) { + return 1; + } + return feof(f); +} + +long native_ftell(long *args, int argc) { + if (!args || argc < 1) { + return -1; + } + FILE *f = (FILE*)args[0]; + if (!f) { + return -1; + } + return ftell(f); +} + +long native_fseek(long *args, int argc) { + if (!args || argc < 3) { + return -1; + } + FILE *f = (FILE*)args[0]; + long offset = args[1]; + int whence = (int)args[2]; + + if (!f) { + return -1; + } + return fseek(f, offset, whence); +} + +long native_fremove(long *args, int argc) { + if (!args || argc < 1) { + return -1; + } + char *filename = (char*)args[0]; + if (!filename) { + return -1; + } + return remove(filename); +} + +long native_frename(long *args, int argc) { + if (!args || argc < 2) { + return -1; + } + char *oldname = (char*)args[0]; + char *newname = (char*)args[1]; + if (!oldname || !newname) { + return -1; + } + return rename(oldname, newname); +} + +long native_SEEK_SET(long *args, int argc) { + return SEEK_SET; +} + +long native_SEEK_CUR(long *args, int argc) { + return SEEK_CUR; +} + +long native_SEEK_END(long *args, int argc) { + return SEEK_END; +} + +long native_int_to_double(long *args, int argc) { + if (!args || argc < 1) { + return 0; + } + union { double d; long l; } u; + u.d = (double)args[0]; + return u.l; +} + +long native_double_to_int(long *args, int argc) { + if (!args || argc < 1) { + return 0; + } + union { double d; long l; } u; + u.l = args[0]; + return (long)u.d; +} + +long native_double_add(long *args, int argc) { + if (!args || argc < 2) { + return 0; + } + union { double d; long l; } u1, u2, result; + u1.l = args[0]; + u2.l = args[1]; + result.d = u1.d + u2.d; + return result.l; +} + +long native_double_sub(long *args, int argc) { + if (!args || argc < 2) { + return 0; + } + union { double d; long l; } u1, u2, result; + u1.l = args[0]; + u2.l = args[1]; + result.d = u1.d - u2.d; + return result.l; +} + +long native_double_mul(long *args, int argc) { + if (!args || argc < 2) { + return 0; + } + union { double d; long l; } u1, u2, result; + u1.l = args[0]; + u2.l = args[1]; + result.d = u1.d * u2.d; + return result.l; +} + +long native_double_div(long *args, int argc) { + if (!args || argc < 2) { + return 0; + } + union { double d; long l; } u1, u2, result; + u1.l = args[0]; + u2.l = args[1]; + if (u2.d != 0.0) { + result.d = u1.d / u2.d; + } else { + result.d = 0.0; + } + return result.l; +} + void register_native_functions() { register_native_func("socket", native_socket); register_native_func("bind", native_bind); @@ -475,4 +743,24 @@ void register_native_functions() { register_native_func("replace", native_replace); register_native_func("startswith", native_startswith); register_native_func("endswith", native_endswith); + register_native_func("fopen", native_fopen); + register_native_func("fclose", native_fclose); + register_native_func("fread", native_fread); + register_native_func("fwrite", native_fwrite); + register_native_func("fgets", native_fgets); + register_native_func("fputs", native_fputs); + register_native_func("feof", native_feof); + register_native_func("ftell", native_ftell); + register_native_func("fseek", native_fseek); + register_native_func("fremove", native_fremove); + register_native_func("frename", native_frename); + register_native_func("SEEK_SET", native_SEEK_SET); + register_native_func("SEEK_CUR", native_SEEK_CUR); + register_native_func("SEEK_END", native_SEEK_END); + register_native_func("int_to_double", native_int_to_double); + register_native_func("double_to_int", native_double_to_int); + register_native_func("double_add", native_double_add); + register_native_func("double_sub", native_double_sub); + register_native_func("double_mul", native_double_mul); + register_native_func("double_div", native_double_div); } diff --git a/src/parser.c b/src/parser.c index 3121107..0d104b2 100644 --- a/src/parser.c +++ b/src/parser.c @@ -35,6 +35,12 @@ long factor() { pc++; return t->val; } + else if (t->type == Dbl) { + pc++; + union { double d; long l; } u; + u.d = t->dval; + return u.l; + } else if (t->type == Str) { pc++; return (long)t->text; @@ -256,6 +262,26 @@ long relational() { return val; } +long logical_and() { + long val = relational(); + while (pc < MAX_TOK && tokens[pc].type == And) { + pc++; + long val2 = relational(); + val = val && val2; + } + return val; +} + +long logical_or() { + long val = logical_and(); + while (pc < MAX_TOK && tokens[pc].type == Or) { + pc++; + long val2 = logical_and(); + val = val || val2; + } + return val; +} + long expression() { if (pc >= MAX_TOK) return 0; if (tokens[pc].type == '*') { @@ -327,5 +353,5 @@ long expression() { } } - return relational(); + return logical_or(); } diff --git a/src/parser.h b/src/parser.h index 077e672..e5874f9 100644 --- a/src/parser.h +++ b/src/parser.h @@ -2,6 +2,8 @@ #define PARSER_H long expression(); +long logical_or(); +long logical_and(); long relational(); long add(); long term(); diff --git a/src/tokenizer.c b/src/tokenizer.c index 03de7bd..0819871 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -34,11 +34,14 @@ void tokenize(char *src) { if (!strcmp(buf, "int")) t->type = Int; else if (!strcmp(buf, "char")) t->type = Char; + else if (!strcmp(buf, "double")) t->type = Double; else if (!strcmp(buf, "if")) t->type = If; else if (!strcmp(buf, "else")) t->type = Else; else if (!strcmp(buf, "while")) t->type = While; else if (!strcmp(buf, "return")) t->type = Return; else if (!strcmp(buf, "printf")) t->type = Printf; + else if (!strcmp(buf, "break")) t->type = Break; + else if (!strcmp(buf, "continue")) t->type = Continue; else t->type = Id; t->val = len; @@ -46,9 +49,20 @@ void tokenize(char *src) { continue; } - if (isdigit(*s)) { - t->type = Num; - t->val = strtol(s, &s, 10); + if (isdigit(*s) || (*s == '.' && s[1] && isdigit(s[1]))) { + char *start = s; + int has_dot = 0; + while (*s && (isdigit(*s) || (*s == '.' && !has_dot))) { + if (*s == '.') has_dot = 1; + s++; + } + if (has_dot) { + t->type = Dbl; + t->dval = strtod(start, NULL); + } else { + t->type = Num; + t->val = strtol(start, NULL, 10); + } continue; } diff --git a/src/types.h b/src/types.h index 47bc28c..c762678 100644 --- a/src/types.h +++ b/src/types.h @@ -8,13 +8,14 @@ #define STR_POOL_SIZE 100000 enum { - Num = 128, Str, Id, Int, Char, Else, If, While, Return, Printf, - Assign, Eq, Ne, Lt, Gt, Le, Ge, Or, And, Inc, Dec + Num = 128, Dbl, Str, Id, Int, Char, Double, Else, If, While, Return, Printf, + Assign, Eq, Ne, Lt, Gt, Le, Ge, Or, And, Inc, Dec, Break, Continue }; typedef struct { int type; long val; + double dval; char *text; } Token; diff --git a/tests/break_continue_test.rc b/tests/break_continue_test.rc new file mode 100644 index 0000000..f72ba00 --- /dev/null +++ b/tests/break_continue_test.rc @@ -0,0 +1,81 @@ +int main() { + printf("=== Break and Continue Tests ===\n"); + + printf("Test 1: Break statement\n"); + int count = 0; + while (count < 10) { + count = count + 1; + if (count == 5) { + printf("Breaking at count = %d\n", count); + break; + } + printf("count = %d\n", count); + } + printf("Final count after break: %d\n", count); + printf("PASS: Break works\n"); + + printf("Test 2: Continue statement\n"); + int i = 0; + int sum = 0; + while (i < 10) { + i = i + 1; + if (i == 3 || i == 7) { + printf("Skipping i = %d\n", i); + continue; + } + sum = sum + i; + printf("Adding i = %d, sum = %d\n", i, sum); + } + printf("Final sum (skipped 3 and 7): %d\n", sum); + printf("PASS: Continue works\n"); + + printf("Test 3: Break in nested if\n"); + int j = 0; + while (j < 10) { + j = j + 1; + if (j > 3) { + if (j == 6) { + printf("Breaking at j = %d (nested if)\n", j); + break; + } + } + printf("j = %d\n", j); + } + printf("Final j: %d\n", j); + printf("PASS: Nested break works\n"); + + printf("Test 4: Continue in nested if\n"); + int k = 0; + int even_sum = 0; + while (k < 10) { + k = k + 1; + if (k > 0) { + int rem = k - (k / 2) * 2; + if (rem == 1) { + continue; + } + } + even_sum = even_sum + k; + } + printf("Sum of even numbers 1-10: %d\n", even_sum); + printf("PASS: Nested continue works\n"); + + printf("Test 5: Multiple breaks and continues\n"); + int n = 0; + int result = 0; + while (n < 20) { + n = n + 1; + if (n < 5) { + continue; + } + if (n > 15) { + break; + } + result = result + 1; + } + printf("Numbers counted between 5 and 15: %d\n", result); + printf("PASS: Multiple break/continue works\n"); + + printf("\n=== All Break/Continue Tests Completed ===\n"); + return 0; +} diff --git a/tests/break_test1.rc b/tests/break_test1.rc new file mode 100644 index 0000000..e96485e --- /dev/null +++ b/tests/break_test1.rc @@ -0,0 +1,14 @@ +int main() { + printf("=== Break Test ===\n"); + int count = 0; + while (count < 10) { + count = count + 1; + if (count == 5) { + printf("Breaking at count = %d\n", count); + break; + } + printf("count = %d\n", count); + } + printf("Final count: %d\n", count); + return 0; +} diff --git a/tests/break_test2.rc b/tests/break_test2.rc new file mode 100644 index 0000000..f8c43f6 --- /dev/null +++ b/tests/break_test2.rc @@ -0,0 +1,13 @@ +int main() { + printf("=== Break Test ===\n"); + int count = 0; + while (count < 10) { + count = count + 1; + if (count == 5) { + break; + } + printf("count = %d\n", count); + } + printf("Final count: %d\n", count); + return 0; +} diff --git a/tests/continue_or_test.rc b/tests/continue_or_test.rc new file mode 100644 index 0000000..52d0e2d --- /dev/null +++ b/tests/continue_or_test.rc @@ -0,0 +1,14 @@ +int main() { + printf("Test OR with continue\n"); + int i = 0; + while (i < 10) { + i = i + 1; + if (i == 3 || i == 7) { + printf("Skip %d\n", i); + continue; + } + printf("i = %d\n", i); + } + printf("Done\n"); + return 0; +} diff --git a/tests/continue_test_simple.rc b/tests/continue_test_simple.rc new file mode 100644 index 0000000..55801b4 --- /dev/null +++ b/tests/continue_test_simple.rc @@ -0,0 +1,14 @@ +int main() { + printf("Start\n"); + int i = 0; + while (i < 5) { + i = i + 1; + if (i == 3) { + printf("Skipping i = %d\n", i); + continue; + } + printf("i = %d\n", i); + } + printf("Done\n"); + return 0; +} diff --git a/tests/double_test.rc b/tests/double_test.rc new file mode 100644 index 0000000..567fdc5 --- /dev/null +++ b/tests/double_test.rc @@ -0,0 +1,53 @@ +int main() { + printf("=== Double Data Type Tests ===\n"); + + printf("Test 1: Double variable declaration and assignment\n"); + double pi = 3.14159; + printf("pi = %f\n", pi); + printf("PASS: Double variable works\n"); + + printf("Test 2: Double arithmetic using helper functions\n"); + double a = 10.5; + double b = 2.5; + printf("a = %f, b = %f\n", a, b); + + double sum = double_add(a, b); + printf("a + b = %f\n", sum); + + double diff = double_sub(a, b); + printf("a - b = %f\n", diff); + + double prod = double_mul(a, b); + printf("a * b = %f\n", prod); + + double quot = double_div(a, b); + printf("a / b = %f\n", quot); + printf("PASS: Double arithmetic works\n"); + + printf("Test 3: Type conversions\n"); + int x = 42; + double dx = int_to_double(x); + printf("int %d converted to double: %f\n", x, dx); + + double y = 99.9; + int iy = double_to_int(y); + printf("double %f converted to int: %d\n", y, iy); + printf("PASS: Type conversions work\n"); + + printf("Test 4: Double with mathematical functions\n"); + double num = 16.0; + double sq = sqrt(double_to_int(num)); + double sq_double = int_to_double(sq); + printf("sqrt(%f) = %f\n", num, sq_double); + printf("PASS: Math functions work with doubles\n"); + + printf("Test 5: Complex calculation\n"); + double radius = 5.0; + double pi2 = 3.14159; + double area = double_mul(pi2, double_mul(radius, radius)); + printf("Circle area (r=%f): %f\n", radius, area); + printf("PASS: Complex calculations work\n"); + + printf("\n=== All Double Tests Completed ===\n"); + return 0; +} diff --git a/tests/file_io_test.rc b/tests/file_io_test.rc new file mode 100644 index 0000000..cc50460 --- /dev/null +++ b/tests/file_io_test.rc @@ -0,0 +1,82 @@ +int main() { + printf("=== File I/O Tests ===\n"); + + printf("Test 1: Writing to a file\n"); + int f = fopen("test_output.txt", "w"); + if (f == 0) { + printf("ERROR: Could not open file for writing\n"); + return 1; + } + fputs(f, "Hello, File I/O!\n"); + fputs(f, "This is line 2.\n"); + fputs(f, "Testing file operations.\n"); + fclose(f); + printf("PASS: File written successfully\n"); + + printf("Test 2: Reading from file using fgets\n"); + f = fopen("test_output.txt", "r"); + if (f == 0) { + printf("ERROR: Could not open file for reading\n"); + return 1; + } + char *line1 = fgets(f, 256); + printf("Line 1: %s", line1); + char *line2 = fgets(f, 256); + printf("Line 2: %s", line2); + char *line3 = fgets(f, 256); + printf("Line 3: %s", line3); + fclose(f); + printf("PASS: File read successfully\n"); + + printf("Test 3: File position operations\n"); + f = fopen("test_output.txt", "r"); + if (f == 0) { + printf("ERROR: Could not open file\n"); + return 1; + } + int pos = ftell(f); + printf("Initial position: %d\n", pos); + fseek(f, 7, SEEK_SET()); + pos = ftell(f); + printf("Position after seek: %d\n", pos); + char *partial = fgets(f, 256); + printf("Read after seek: %s", partial); + fclose(f); + printf("PASS: File positioning works\n"); + + printf("Test 4: End of file detection\n"); + f = fopen("test_output.txt", "r"); + if (f == 0) { + printf("ERROR: Could not open file\n"); + return 1; + } + int line_count = 0; + while (feof(f) == 0) { + char *line = fgets(f, 256); + if (strlen(line) > 0) { + line_count = line_count + 1; + } + } + printf("Total lines read: %d\n", line_count); + fclose(f); + printf("PASS: EOF detection works\n"); + + printf("Test 5: File rename operation\n"); + int result = frename("test_output.txt", "test_renamed.txt"); + if (result == 0) { + printf("PASS: File renamed successfully\n"); + } else { + printf("ERROR: File rename failed\n"); + } + + printf("Test 6: File removal\n"); + result = fremove("test_renamed.txt"); + if (result == 0) { + printf("PASS: File removed successfully\n"); + } else { + printf("ERROR: File removal failed\n"); + } + + printf("\n=== All File I/O Tests Completed ===\n"); + return 0; +} diff --git a/tests/or_test.rc b/tests/or_test.rc new file mode 100644 index 0000000..6c68e98 --- /dev/null +++ b/tests/or_test.rc @@ -0,0 +1,9 @@ +int main() { + printf("Test OR\n"); + int i = 3; + if (i == 3 || i == 7) { + printf("Match\n"); + } + printf("Done\n"); + return 0; +} diff --git a/tests/simple_break_test.rc b/tests/simple_break_test.rc new file mode 100644 index 0000000..09b6aff --- /dev/null +++ b/tests/simple_break_test.rc @@ -0,0 +1,13 @@ +int main() { + printf("Start\n"); + int i = 0; + while (i < 5) { + i = i + 1; + printf("i = %d\n", i); + if (i == 3) { + break; + } + } + printf("After loop, i = %d\n", i); + return 0; +}