| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- #include "alang.h"
- #include <stdbool.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <string.h>
- typedef union value {
- float f;
- int i;
- bool b;
- } value;
- typedef struct variable_storage {
- value val;
- type_id type;
- } variable_storage;
- typedef struct interpreter_state {
- variable_storage vars[1024];
- size_t pos;
- } interpreter_state;
- static value get_variable_value(interpreter_state *state, variable var) {
- return state->vars[var.index].val;
- }
- static void set_variable_value(interpreter_state *state, variable var, value v) {
- state->vars[var.index].val = v;
- state->vars[var.index].type = var.type.type;
- }
- static float eval() {
- interpreter_state state = {0};
- function *main_func = NULL;
- for (function_id i = 0; _get_function(i) != NULL; ++i) {
- function *f = _get_function(i);
- if (strcmp(_get_name(f->name), "main") == 0) {
- main_func = f;
- break;
- }
- }
- for (size_t i = 0; i < __allocated_globals_size; ++i) {
- global *g = __allocated_globals[i].g;
- uint64_t var_index = __allocated_globals[i].variable_id;
- if (g->value.kind == GLOBAL_VALUE_FLOAT) {
- state.vars[var_index].val.f = g->value.value.floats[0];
- state.vars[var_index].type = g->type;
- }
- else if (g->value.kind == GLOBAL_VALUE_INT) {
- state.vars[var_index].val.i = g->value.value.ints[0];
- state.vars[var_index].type = g->type;
- }
- else if (g->value.kind == GLOBAL_VALUE_BOOL) {
- state.vars[var_index].val.b = g->value.value.b;
- state.vars[var_index].type = g->type;
- }
- }
- state.pos = 0;
- opcodes *code = &main_func->code;
- while (state.pos < code->size) {
- opcode *op = (opcode *)&code->o[state.pos];
- state.pos += op->size;
- switch (op->type) {
- case OPCODE_VAR: {
- break;
- }
- case OPCODE_LOAD_FLOAT_CONSTANT: {
- value v;
- v.f = op->op_load_float_constant.number;
- set_variable_value(&state, op->op_load_float_constant.to, v);
- break;
- }
- case OPCODE_LOAD_INT_CONSTANT: {
- value v;
- v.i = op->op_load_int_constant.number;
- set_variable_value(&state, op->op_load_int_constant.to, v);
- break;
- }
- case OPCODE_LOAD_BOOL_CONSTANT: {
- value v;
- v.b = op->op_load_bool_constant.boolean;
- set_variable_value(&state, op->op_load_bool_constant.to, v);
- break;
- }
- case OPCODE_STORE_VARIABLE: {
- value v = get_variable_value(&state, op->op_store_var.from);
- set_variable_value(&state, op->op_store_var.to, v);
- break;
- }
- case OPCODE_ADD: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- type_id result_type = op->op_binary.result.type.type;
- if (result_type == _float_id) {
- float l = (op->op_binary.left.type.type == _float_id) ? left.f : (float)left.i;
- float r = (op->op_binary.right.type.type == _float_id) ? right.f : (float)right.i;
- result.f = l + r;
- }
- else {
- result.i = left.i + right.i;
- }
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_SUB: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- type_id result_type = op->op_binary.result.type.type;
- if (result_type == _float_id) {
- float l = (op->op_binary.left.type.type == _float_id) ? left.f : (float)left.i;
- float r = (op->op_binary.right.type.type == _float_id) ? right.f : (float)right.i;
- result.f = l - r;
- }
- else {
- result.i = left.i - right.i;
- }
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_MULTIPLY: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- type_id result_type = op->op_binary.result.type.type;
- if (result_type == _float_id) {
- float l = (op->op_binary.left.type.type == _float_id) ? left.f : (float)left.i;
- float r = (op->op_binary.right.type.type == _float_id) ? right.f : (float)right.i;
- result.f = l * r;
- }
- else {
- result.i = left.i * right.i;
- }
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_DIVIDE: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- type_id result_type = op->op_binary.result.type.type;
- if (result_type == _float_id) {
- float l = (op->op_binary.left.type.type == _float_id) ? left.f : (float)left.i;
- float r = (op->op_binary.right.type.type == _float_id) ? right.f : (float)right.i;
- result.f = l / r;
- }
- else {
- result.i = left.i / right.i;
- }
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_MOD: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- result.i = left.i % right.i;
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_EQUALS: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- type_id left_type = op->op_binary.left.type.type;
- type_id right_type = op->op_binary.right.type.type;
- if (left_type == _float_id || right_type == _float_id) {
- float l = (left_type == _float_id) ? left.f : (float)left.i;
- float r = (right_type == _float_id) ? right.f : (float)right.i;
- result.b = l == r;
- }
- else if (left_type == _bool_id && right_type == _bool_id) {
- result.b = left.b == right.b;
- }
- else {
- result.b = left.i == right.i;
- }
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_NOT_EQUALS: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- type_id left_type = op->op_binary.left.type.type;
- type_id right_type = op->op_binary.right.type.type;
- if (left_type == _float_id || right_type == _float_id) {
- float l = (left_type == _float_id) ? left.f : (float)left.i;
- float r = (right_type == _float_id) ? right.f : (float)right.i;
- result.b = l != r;
- }
- else if (left_type == _bool_id && right_type == _bool_id) {
- result.b = left.b != right.b;
- }
- else {
- result.b = left.i != right.i;
- }
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_GREATER: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- type_id left_type = op->op_binary.left.type.type;
- type_id right_type = op->op_binary.right.type.type;
- if (left_type == _float_id || right_type == _float_id) {
- float l = (left_type == _float_id) ? left.f : (float)left.i;
- float r = (right_type == _float_id) ? right.f : (float)right.i;
- result.b = l > r;
- }
- else {
- result.b = left.i > right.i;
- }
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_GREATER_EQUAL: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- type_id left_type = op->op_binary.left.type.type;
- type_id right_type = op->op_binary.right.type.type;
- if (left_type == _float_id || right_type == _float_id) {
- float l = (left_type == _float_id) ? left.f : (float)left.i;
- float r = (right_type == _float_id) ? right.f : (float)right.i;
- result.b = l >= r;
- }
- else {
- result.b = left.i >= right.i;
- }
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_LESS: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- type_id left_type = op->op_binary.left.type.type;
- type_id right_type = op->op_binary.right.type.type;
- if (left_type == _float_id || right_type == _float_id) {
- float l = (left_type == _float_id) ? left.f : (float)left.i;
- float r = (right_type == _float_id) ? right.f : (float)right.i;
- result.b = l < r;
- }
- else {
- result.b = left.i < right.i;
- }
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_LESS_EQUAL: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- type_id left_type = op->op_binary.left.type.type;
- type_id right_type = op->op_binary.right.type.type;
- if (left_type == _float_id || right_type == _float_id) {
- float l = (left_type == _float_id) ? left.f : (float)left.i;
- float r = (right_type == _float_id) ? right.f : (float)right.i;
- result.b = l <= r;
- }
- else {
- result.b = left.i <= right.i;
- }
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_AND: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- result.b = left.b && right.b;
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_OR: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- result.b = left.b || right.b;
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_BITWISE_XOR: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- result.i = left.i ^ right.i;
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_BITWISE_AND: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- result.i = left.i & right.i;
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_BITWISE_OR: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- result.i = left.i | right.i;
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_LEFT_SHIFT: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- result.i = left.i << right.i;
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_RIGHT_SHIFT: {
- value left = get_variable_value(&state, op->op_binary.left);
- value right = get_variable_value(&state, op->op_binary.right);
- value result;
- result.i = left.i >> right.i;
- set_variable_value(&state, op->op_binary.result, result);
- break;
- }
- case OPCODE_NOT: {
- value from = get_variable_value(&state, op->op_not.from);
- value result;
- result.b = !from.b;
- set_variable_value(&state, op->op_not.to, result);
- break;
- }
- case OPCODE_NEGATE: {
- value from = get_variable_value(&state, op->op_negate.from);
- value result;
- if (op->op_negate.from.type.type == _float_id) {
- result.f = -from.f;
- }
- else {
- result.i = -from.i;
- }
- set_variable_value(&state, op->op_negate.to, result);
- break;
- }
- case OPCODE_IF: {
- value condition = get_variable_value(&state, op->op_if.condition);
- if (!condition.b) {
- state.pos = op->op_if.end_id;
- }
- break;
- }
- case OPCODE_WHILE_START: {
- break;
- }
- case OPCODE_WHILE_CONDITION: {
- value condition = get_variable_value(&state, op->op_while.condition);
- if (!condition.b) {
- state.pos = op->op_while.end_id;
- }
- break;
- }
- case OPCODE_WHILE_END: {
- state.pos = op->op_while_end.start_id;
- break;
- }
- case OPCODE_BLOCK_START:
- case OPCODE_BLOCK_END: {
- break;
- }
- case OPCODE_RETURN: {
- if (op->op_return.var.index != 0) {
- value return_val = get_variable_value(&state, op->op_return.var);
- return return_val.f;
- }
- return 0.0;
- }
- case OPCODE_CALL: {
- if (strcmp(_get_name(op->op_call.func), "print") == 0) {
- value param = get_variable_value(&state, op->op_call.parameters[0]);
- value result;
- printf("%f\n", param.f);
- set_variable_value(&state, op->op_call.var, result);
- }
- break;
- }
- default: {
- break;
- }
- }
- }
- return 0.0;
- }
- float alang_eval(char *data) {
- _names_init();
- _types_init();
- _functions_init();
- _globals_init();
- char buffer[2048];
- strcpy(buffer, "fun main(): float { return ");
- strcat(buffer, data);
- strcat(buffer, "; }");
- char *filename = "main.kong";
- tokens tokens = _tokenize(filename, buffer);
- _parse(filename, &tokens);
- _resolve_types();
- // allocate_globals();
- for (function_id i = 0; _get_function(i) != NULL; ++i) {
- _compile_function_block(&_get_function(i)->code, _get_function(i)->block);
- }
- return eval(buffer);
- }
|