diff --git a/src/builtin.c b/src/builtin.c index 0d3a7b7..c243602 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -46,3 +46,51 @@ AST* builtin_sub(size_t argc, AST** argv) { return ast_init(AST_TYPE_NUM, ast_num_data_init(total)); } + +AST* builtin_mul(size_t argc, AST** argv) { + log_dbg("Got here"); + AST* first = exec_exp(*argv); + if (first->type != AST_TYPE_NUM) + return ast_init( + AST_TYPE_EXC, ast_exc_data_init("Can't multiply non-num arguments.") + ); + + ASTNumData total = *(ASTNumData*)first->data; + + for (int i = 1; i < argc; i++) { + AST* arg = exec_exp(argv[i]); + if (arg->type != AST_TYPE_NUM) + return ast_init( + AST_TYPE_EXC, + ast_exc_data_init("Can't multiply non-num arguments.") + ); + + total *= *(ASTNumData*)arg->data; + } + + return ast_init(AST_TYPE_NUM, ast_num_data_init(total)); +} + +AST* builtin_div(size_t argc, AST** argv) { + log_dbg("Got here"); + AST* first = exec_exp(*argv); + if (first->type != AST_TYPE_NUM) + return ast_init( + AST_TYPE_EXC, ast_exc_data_init("Can't divide non-num arguments.") + ); + + ASTNumData total = *(ASTNumData*)first->data; + + for (int i = 1; i < argc; i++) { + AST* arg = exec_exp(argv[i]); + if (arg->type != AST_TYPE_NUM) + return ast_init( + AST_TYPE_EXC, + ast_exc_data_init("Can't divide non-num arguments.") + ); + + total /= *(ASTNumData*)arg->data; + } + + return ast_init(AST_TYPE_NUM, ast_num_data_init(total)); +} diff --git a/src/exec.c b/src/exec.c index 58ccee7..ce3604f 100644 --- a/src/exec.c +++ b/src/exec.c @@ -26,6 +26,14 @@ AST* exec_start(AST* ast) { global, "sub", ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_sub)) ); + htab_ins( + global, "mul", ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_mul)) + ); + + htab_ins( + global, "div", ast_init(AST_TYPE_BIF, ast_bif_data_init(builtin_div)) + ); + // Push global namespace to `scope`. stack_push(scope, global); diff --git a/src/include/builtin.h b/src/include/builtin.h index 7e37c4f..c4c58f3 100644 --- a/src/include/builtin.h +++ b/src/include/builtin.h @@ -9,9 +9,15 @@ AST* builtin_sum(size_t argc, AST** argv); // Subtract nums. AST* builtin_sub(size_t argc, AST** argv); +// Multiply nums. +AST* builtin_mul(size_t argc, AST** argv); + +// Divide nums. +AST* builtin_div(size_t argc, AST** argv); + // The list of built-in functions. static AST* (*builtin_fns[])(size_t argc, AST** argv) = { - builtin_sum, builtin_sub + builtin_sum, builtin_sub, builtin_mul, builtin_div }; #endif