amake: cleanup
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,343 +0,0 @@
|
||||
// Based on https://github.com/Kode/Kongruent by RobDangerous
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define OPCODES_SIZE (1024 * 1024)
|
||||
|
||||
typedef enum variable_kind {
|
||||
VARIABLE_GLOBAL,
|
||||
VARIABLE_LOCAL,
|
||||
VARIABLE_INTERNAL
|
||||
} variable_kind;
|
||||
|
||||
typedef enum access_kind {
|
||||
ACCESS_MEMBER,
|
||||
ACCESS_ELEMENT
|
||||
} access_kind;
|
||||
|
||||
typedef enum operatorr {
|
||||
OPERATOR_EQUALS,
|
||||
OPERATOR_NOT_EQUALS,
|
||||
OPERATOR_GREATER,
|
||||
OPERATOR_GREATER_EQUAL,
|
||||
OPERATOR_LESS,
|
||||
OPERATOR_LESS_EQUAL,
|
||||
OPERATOR_MINUS,
|
||||
OPERATOR_PLUS,
|
||||
OPERATOR_DIVIDE,
|
||||
OPERATOR_MULTIPLY,
|
||||
OPERATOR_NOT,
|
||||
OPERATOR_OR,
|
||||
OPERATOR_BITWISE_XOR,
|
||||
OPERATOR_BITWISE_AND,
|
||||
OPERATOR_BITWISE_OR,
|
||||
OPERATOR_LEFT_SHIFT,
|
||||
OPERATOR_RIGHT_SHIFT,
|
||||
OPERATOR_AND,
|
||||
OPERATOR_MOD,
|
||||
OPERATOR_ASSIGN,
|
||||
OPERATOR_MINUS_ASSIGN,
|
||||
OPERATOR_PLUS_ASSIGN,
|
||||
OPERATOR_DIVIDE_ASSIGN,
|
||||
OPERATOR_MULTIPLY_ASSIGN
|
||||
} operatorr;
|
||||
|
||||
typedef uint32_t type_id;
|
||||
typedef size_t name_id;
|
||||
|
||||
typedef struct attribute {
|
||||
name_id name;
|
||||
double parameters[16];
|
||||
uint8_t paramters_count;
|
||||
} attribute;
|
||||
|
||||
typedef struct attributes {
|
||||
attribute attributes[64];
|
||||
uint8_t attributes_count;
|
||||
} attribute_list;
|
||||
|
||||
typedef struct unresolved_type_ref {
|
||||
name_id name;
|
||||
uint32_t array_size;
|
||||
} unresolved_type_ref;
|
||||
|
||||
typedef struct type_ref {
|
||||
type_id type;
|
||||
unresolved_type_ref unresolved;
|
||||
} type_ref;
|
||||
|
||||
typedef struct opcodes {
|
||||
uint8_t o[OPCODES_SIZE];
|
||||
size_t size;
|
||||
} opcodes;
|
||||
|
||||
typedef struct function {
|
||||
attribute_list attributes;
|
||||
name_id name;
|
||||
type_ref return_type;
|
||||
name_id parameter_names[256];
|
||||
type_ref parameter_types[256];
|
||||
name_id parameter_attributes[256];
|
||||
uint8_t parameters_size;
|
||||
struct statement *block;
|
||||
opcodes code;
|
||||
} function;
|
||||
|
||||
typedef uint32_t function_id;
|
||||
|
||||
typedef struct global_value {
|
||||
enum {
|
||||
GLOBAL_VALUE_FLOAT,
|
||||
GLOBAL_VALUE_INT,
|
||||
GLOBAL_VALUE_UINT,
|
||||
GLOBAL_VALUE_BOOL,
|
||||
GLOBAL_VALUE_NONE
|
||||
} kind;
|
||||
union {
|
||||
float floats[1];
|
||||
int ints[1];
|
||||
unsigned uints[1];
|
||||
bool b;
|
||||
} value;
|
||||
} global_value;
|
||||
|
||||
typedef struct global {
|
||||
name_id name;
|
||||
type_id type;
|
||||
uint64_t var_index;
|
||||
global_value value;
|
||||
attribute_list attributes;
|
||||
uint32_t usage;
|
||||
} global;
|
||||
|
||||
typedef struct variable {
|
||||
variable_kind kind;
|
||||
uint64_t index;
|
||||
type_ref type;
|
||||
} variable;
|
||||
|
||||
typedef struct access {
|
||||
access_kind kind;
|
||||
type_id type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
name_id name;
|
||||
} access_member;
|
||||
|
||||
struct {
|
||||
variable index;
|
||||
} access_element;
|
||||
};
|
||||
} access;
|
||||
|
||||
typedef struct opcode {
|
||||
enum {
|
||||
OPCODE_VAR,
|
||||
OPCODE_NOT,
|
||||
OPCODE_NEGATE,
|
||||
OPCODE_STORE_VARIABLE,
|
||||
OPCODE_SUB_AND_STORE_VARIABLE,
|
||||
OPCODE_ADD_AND_STORE_VARIABLE,
|
||||
OPCODE_DIVIDE_AND_STORE_VARIABLE,
|
||||
OPCODE_MULTIPLY_AND_STORE_VARIABLE,
|
||||
OPCODE_STORE_ACCESS_LIST,
|
||||
OPCODE_SUB_AND_STORE_ACCESS_LIST,
|
||||
OPCODE_ADD_AND_STORE_ACCESS_LIST,
|
||||
OPCODE_DIVIDE_AND_STORE_ACCESS_LIST,
|
||||
OPCODE_MULTIPLY_AND_STORE_ACCESS_LIST,
|
||||
OPCODE_LOAD_FLOAT_CONSTANT,
|
||||
OPCODE_LOAD_INT_CONSTANT,
|
||||
OPCODE_LOAD_BOOL_CONSTANT,
|
||||
OPCODE_LOAD_ACCESS_LIST,
|
||||
OPCODE_RETURN,
|
||||
OPCODE_CALL,
|
||||
OPCODE_MULTIPLY,
|
||||
OPCODE_DIVIDE,
|
||||
OPCODE_MOD,
|
||||
OPCODE_ADD,
|
||||
OPCODE_SUB,
|
||||
OPCODE_EQUALS,
|
||||
OPCODE_NOT_EQUALS,
|
||||
OPCODE_GREATER,
|
||||
OPCODE_GREATER_EQUAL,
|
||||
OPCODE_LESS,
|
||||
OPCODE_LESS_EQUAL,
|
||||
OPCODE_AND,
|
||||
OPCODE_OR,
|
||||
OPCODE_BITWISE_XOR,
|
||||
OPCODE_BITWISE_AND,
|
||||
OPCODE_BITWISE_OR,
|
||||
OPCODE_LEFT_SHIFT,
|
||||
OPCODE_RIGHT_SHIFT,
|
||||
OPCODE_IF,
|
||||
OPCODE_WHILE_START,
|
||||
OPCODE_WHILE_CONDITION,
|
||||
OPCODE_WHILE_END,
|
||||
OPCODE_WHILE_BODY,
|
||||
OPCODE_BLOCK_START,
|
||||
OPCODE_BLOCK_END
|
||||
} type;
|
||||
uint32_t size;
|
||||
|
||||
union {
|
||||
struct {
|
||||
variable var;
|
||||
} op_var;
|
||||
struct {
|
||||
variable from;
|
||||
variable to;
|
||||
} op_negate;
|
||||
struct {
|
||||
variable from;
|
||||
variable to;
|
||||
} op_not;
|
||||
struct {
|
||||
variable from;
|
||||
variable to;
|
||||
} op_store_var;
|
||||
struct {
|
||||
variable from;
|
||||
variable to;
|
||||
|
||||
access access_list[64];
|
||||
uint8_t access_list_size;
|
||||
} op_store_access_list;
|
||||
struct {
|
||||
float number;
|
||||
variable to;
|
||||
} op_load_float_constant;
|
||||
struct {
|
||||
int number;
|
||||
variable to;
|
||||
} op_load_int_constant;
|
||||
struct {
|
||||
bool boolean;
|
||||
variable to;
|
||||
} op_load_bool_constant;
|
||||
struct {
|
||||
variable from;
|
||||
variable to;
|
||||
|
||||
access access_list[64];
|
||||
uint8_t access_list_size;
|
||||
} op_load_access_list;
|
||||
struct {
|
||||
variable var;
|
||||
} op_return;
|
||||
struct {
|
||||
variable var;
|
||||
name_id func;
|
||||
variable parameters[64];
|
||||
uint8_t parameters_size;
|
||||
} op_call;
|
||||
struct {
|
||||
variable right;
|
||||
variable left;
|
||||
variable result;
|
||||
} op_binary;
|
||||
struct {
|
||||
variable condition;
|
||||
uint64_t start_id;
|
||||
uint64_t end_id;
|
||||
} op_if;
|
||||
struct {
|
||||
uint64_t start_id;
|
||||
uint64_t continue_id;
|
||||
uint64_t end_id;
|
||||
} op_while_start;
|
||||
struct {
|
||||
uint64_t start_id;
|
||||
uint64_t continue_id;
|
||||
uint64_t end_id;
|
||||
} op_while_end;
|
||||
struct {
|
||||
variable condition;
|
||||
uint64_t end_id;
|
||||
} op_while;
|
||||
struct {
|
||||
uint64_t id;
|
||||
} op_block;
|
||||
struct {
|
||||
uint8_t nothing;
|
||||
} op_nothing;
|
||||
};
|
||||
} opcode;
|
||||
|
||||
typedef struct token {
|
||||
int line, column;
|
||||
|
||||
enum {
|
||||
TOKEN_NONE,
|
||||
TOKEN_BOOLEAN,
|
||||
TOKEN_FLOAT,
|
||||
TOKEN_INT,
|
||||
// TOKEN_STRING,
|
||||
TOKEN_IDENTIFIER,
|
||||
TOKEN_LEFT_PAREN,
|
||||
TOKEN_RIGHT_PAREN,
|
||||
TOKEN_LEFT_CURLY,
|
||||
TOKEN_RIGHT_CURLY,
|
||||
TOKEN_LEFT_SQUARE,
|
||||
TOKEN_RIGHT_SQUARE,
|
||||
TOKEN_HASH,
|
||||
TOKEN_IF,
|
||||
TOKEN_ELSE,
|
||||
TOKEN_WHILE,
|
||||
TOKEN_DO,
|
||||
TOKEN_FOR,
|
||||
TOKEN_SEMICOLON,
|
||||
TOKEN_COLON,
|
||||
TOKEN_DOT,
|
||||
TOKEN_COMMA,
|
||||
TOKEN_OPERATOR,
|
||||
TOKEN_IN,
|
||||
TOKEN_STRUCT,
|
||||
TOKEN_FUNCTION,
|
||||
TOKEN_VAR,
|
||||
TOKEN_CONST,
|
||||
TOKEN_RETURN
|
||||
} kind;
|
||||
|
||||
union {
|
||||
bool boolean;
|
||||
double number;
|
||||
// char string[MAX_IDENTIFIER_SIZE];
|
||||
name_id identifier;
|
||||
operatorr op;
|
||||
};
|
||||
} token;
|
||||
|
||||
typedef struct tokens {
|
||||
token *t;
|
||||
size_t current_size;
|
||||
size_t max_size;
|
||||
} tokens;
|
||||
|
||||
typedef struct allocated_global {
|
||||
global *g;
|
||||
uint64_t variable_id;
|
||||
} allocated_global;
|
||||
|
||||
function *_get_function(function_id function);
|
||||
void _names_init(void);
|
||||
void _types_init(void);
|
||||
void _functions_init(void);
|
||||
void _globals_init(void);
|
||||
void _parse(const char *filename, tokens *tokens);
|
||||
void _resolve_types(void);
|
||||
void _compile_function_block(opcodes *code, struct statement *block);
|
||||
tokens _tokenize(const char *filename, const char *source);
|
||||
char *_get_name(name_id index);
|
||||
|
||||
extern type_id _void_id;
|
||||
extern type_id _float_id;
|
||||
extern type_id _int_id;
|
||||
extern type_id _uint_id;
|
||||
extern type_id _bool_id;
|
||||
|
||||
extern allocated_global __allocated_globals[1024];
|
||||
extern size_t __allocated_globals_size;
|
||||
@@ -1,422 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
Reference in New Issue
Block a user