Skip to content

Commit

Permalink
1. Bumped up VM and Blade version
Browse files Browse the repository at this point in the history
2. Fixed multiple try...catch... bugs
3. Added Blade option `-c` that allows users to quickly run a short snippet without the REPL or file.
4. Blade option `-d` no longer exit.
5. Added Blade option `-e` to replace the former `-d`.
6. OP_DIE now discards local
7. Added more tests.
  • Loading branch information
mcfriend99 committed Jan 31, 2023
1 parent febd920 commit eeb08ed
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 29 deletions.
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,15 @@ add_blade_test(blade native 6 "1548008755920\nTime taken")
add_blade_test(blade pi 0 "3.141592653589734")
add_blade_test(blade scope 1 "inner\nouter")
add_blade_test(blade string 0 "25, This is john's LAST 20")
add_blade_test(blade try 0 "list index 10 out of range")
add_blade_test(blade try 0 "Second exception thrown")
add_blade_test(blade try 1 "Despite the error, I run because I am in finally")
add_blade_test(blade try 2 "I am a thrown exception")
add_blade_test(blade try 3 "Try block called")
add_blade_test(blade try 4 "Final block called")
add_blade_test(blade try 5 "Error occurred, but I will still run")
add_blade_test(blade try 6 "message: I am a thrown exception")
add_blade_test(blade try 7 "list index 8 out of range")
add_blade_test(blade try 8 "list index 10 out of range")
add_blade_test(blade using 0 "ten\nafter")
add_blade_test(blade var 0 "it works\n20\ntrue")
add_blade_test(blade while 0 "x = 51")
53 changes: 42 additions & 11 deletions src/blade.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,18 +205,36 @@ static void run_file(b_vm *vm, char *file) {
exit(EXIT_RUNTIME);
}

static void run_code(b_vm *vm, char *source) {
// set root file...
vm->root_file = NULL;

b_obj_module *module = new_module(vm, strdup(""), strdup("<script>"));
add_module(vm, module);

b_ptr_result result = interpret(vm, module, source);
fflush(stdout);

if (result == PTR_COMPILE_ERR)
exit(EXIT_COMPILE);
if (result == PTR_RUNTIME_ERR)
exit(EXIT_RUNTIME);
}

void show_usage(char *argv[], bool fail) {
FILE *out = fail ? stderr : stdout;
fprintf(out, "Usage: %s [-[h | d | j | v | g]] [filename]\n", argv[0]);
fprintf(out, " -h Show this help message.\n");
fprintf(out, " -v Show version string.\n");
fprintf(out, " -b Buffer terminal outputs.\n");
fprintf(out, " [This will cause the output to be buffered with 1kb]\n");
fprintf(out, " -d Show generated bytecode.\n");
fprintf(out, " -j Show stack objects during execution.\n");
fprintf(out, " -g Sets the minimum heap size in kilobytes before the GC\n"
" can start. [Default = %d (%dmb)]\n", DEFAULT_GC_START / 1024,
fprintf(out, "Usage: %s [-[h | c | d | e | j | v | g]] [filename]\n", argv[0]);
fprintf(out, " -h Show this help message.\n");
fprintf(out, " -v Show version string.\n");
fprintf(out, " -b Buffer terminal outputs.\n");
fprintf(out, " [This will cause the output to be buffered with 1kb]\n");
fprintf(out, " -d Print bytecode.\n");
fprintf(out, " -e Print bytecode and exit.\n");
fprintf(out, " -j Show stack objects during execution.\n");
fprintf(out, " -g arg Sets the minimum heap size in kilobytes before the GC\n"
" can start. [Default = %d (%dmb)]\n", DEFAULT_GC_START / 1024,
DEFAULT_GC_START / (1024 * 1024));
fprintf(out, " -c arg Runs the give code.\n");
exit(fail ? EXIT_FAILURE : EXIT_SUCCESS);
}

Expand All @@ -225,17 +243,23 @@ int main(int argc, char *argv[]) {
bool should_debug_stack = false;
bool should_print_bytecode = false;
bool should_buffer_stdout = false;
bool should_exit_after_bytecode = false;
char *source = NULL;
int next_gc_start = DEFAULT_GC_START;

if (argc > 1) {
int opt;
while ((opt = getopt(argc, argv, "hdbjvg:")) != -1) {
while ((opt = getopt(argc, argv, "hdebjvgc:")) != -1) {
switch (opt) {
case 'h':
show_usage(argv, false); // exits
case 'd':
should_print_bytecode = true;
break;
case 'e':
should_print_bytecode = true;
should_exit_after_bytecode = true;
break;
case 'b':
should_buffer_stdout = true;
break;
Expand All @@ -253,6 +277,10 @@ int main(int argc, char *argv[]) {
}
break;
}
case 'c': {
source = optarg;
break;
}
default:
show_usage(argv, true); // exits
}
Expand All @@ -267,6 +295,7 @@ int main(int argc, char *argv[]) {
// set vm options...
vm->should_debug_stack = should_debug_stack;
vm->should_print_bytecode = should_print_bytecode;
vm->should_exit_after_bytecode = should_exit_after_bytecode;
vm->next_gc = next_gc_start;

if (should_buffer_stdout) {
Expand All @@ -293,7 +322,9 @@ int main(int argc, char *argv[]) {
// always do this last so that we can have access to everything else
bind_native_modules(vm);

if (argc == 1 || argc <= optind) {
if (source != NULL) {
run_code(vm, source);
} else if (argc == 1 || argc <= optind) {
repl(vm);
} else {
run_file(vm, argv[optind]);
Expand Down
18 changes: 14 additions & 4 deletions src/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,18 @@ static void named_variable(b_parser *p, b_token name, bool can_assign) {
assignment(p, get_op, set_op, arg, can_assign);
}

static void created_variable(b_parser *p, b_token name) {
uint8_t get_op, set_op;
int arg;
if (p->vm->compiler->function->name != NULL) {
int local = add_local(p, name) - 1;
mark_initialized(p);
emit_byte_and_short(p, OP_SET_LOCAL, (uint16_t)local);
} else {
emit_byte_and_short(p, OP_DEFINE_GLOBAL, (uint16_t) identifier_constant(p, &name));
}
}

static void list(b_parser *p, bool can_assign) {
emit_byte(p, OP_NIL); // placeholder for the list

Expand Down Expand Up @@ -2020,6 +2032,7 @@ static void echo_statement(b_parser *p) {
}

static void die_statement(b_parser *p) {
discard_locals(p, p->vm->compiler->scope_depth - 1);
expression(p);
emit_byte(p, OP_DIE);
consume_statement_end(p);
Expand Down Expand Up @@ -2247,10 +2260,7 @@ static void try_statement(b_parser *p) {
address = current_blob(p)->count;

if (match(p, IDENTIFIER_TOKEN)) {
int var = add_local(p, p->previous) - 1;
mark_initialized(p);
emit_byte_and_short(p, OP_SET_LOCAL, var);
emit_byte(p, OP_POP);
created_variable(p, p->previous);
} else {
emit_byte(p, OP_POP);
}
Expand Down
4 changes: 2 additions & 2 deletions src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#define BLADE_CONFIG_H

#define BLADE_EXTENSION ".b"
#define BLADE_VERSION_STRING "0.0.8"
#define BVM_VERSION "0.0.8"
#define BLADE_VERSION_STRING "0.0.81"
#define BVM_VERSION "0.0.9"
#define LIBRARY_DIRECTORY "libs"
#define LIBRARY_DIRECTORY_INDEX "index"
#define PACKAGES_DIRECTORY "vendor"
Expand Down
2 changes: 2 additions & 0 deletions src/standard/os.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ DECLARE_MODULE_METHOD(os__FILE) {
char *file = vm->current_frame->closure->function->module->file;
if(file == NULL || memcmp(file, "<repl>", strlen(file)) == 0) {
RETURN_STRING("<repl>");
} else if(memcmp(file, "<script>", strlen(file)) == 0) {
RETURN_STRING("<script>");
}

char *path = realpath(file, NULL);
Expand Down
9 changes: 6 additions & 3 deletions src/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ void init_vm(b_vm *vm) {
vm->mark_value = true;
vm->should_debug_stack = false;
vm->should_print_bytecode = false;
vm->should_exit_after_bytecode = false;

vm->gray_count = 0;
vm->gray_capacity = 0;
Expand Down Expand Up @@ -2412,8 +2413,10 @@ b_ptr_result run(b_vm *vm) {
if (address != 0) {
b_value value;
if (!table_get(&vm->globals, OBJ_VAL(type), &value) || !IS_CLASS(value)) {
runtime_error("object of type '%s' is not an exception", type->chars);
break;
if(!table_get(&vm->current_frame->closure->function->module->values, OBJ_VAL(type), &value) || !IS_CLASS(value)) {
runtime_error("object of type '%s' is not an exception", type->chars);
break;
}
}
push_exception_handler(vm, AS_CLASS(value), address, finally_address);
} else {
Expand Down Expand Up @@ -2492,7 +2495,7 @@ b_ptr_result interpret(b_vm *vm, b_obj_module *module, const char *source) {

b_obj_func *function = compile(vm, module, source, &blob);

if (vm->should_print_bytecode) {
if (vm->should_exit_after_bytecode) {
return PTR_OK;
}

Expand Down
1 change: 1 addition & 0 deletions src/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct s_vm {
// for switching through the command line args...
bool should_debug_stack;
bool should_print_bytecode;
bool should_exit_after_bytecode;
};

void init_vm(b_vm *vm);
Expand Down
19 changes: 11 additions & 8 deletions tests/try.b
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ try {
echo i

try {
echo [1,2,3][10]
echo [1,2,3][8]
} catch Exception e {
echo '\nMessage: ${e.message}'
} finally {
Expand All @@ -24,14 +24,17 @@ try {
echo e
}

try {
die Exception('I am a thrown exception')
die Exception('Second exception we will never reach')
} catch Exception e {
echo '\nCatching exception...'
echo 'Exception message: ${e.message}'
echo 'Exception trace: ${e.stacktrace}'
def run() {
try {
die Exception('I am a thrown exception')
die Exception('Second exception we will never reach')
} catch Exception e {
echo '\nCatching exception...'
echo 'Exception message: ${e.message}'
echo 'Exception trace: ${e.stacktrace}'
}
}
run()

try {
echo '\nTry block called'
Expand Down

0 comments on commit eeb08ed

Please sign in to comment.