1436 lines
51 KiB
C
1436 lines
51 KiB
C
// Kyler Olsen
|
|
// YREA SLS
|
|
// Builtin Functions
|
|
// November 2025
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "sls/bool.h"
|
|
#include "sls/builtin.h"
|
|
#include "sls/hash_table.h"
|
|
#include "sls/interpreter.h"
|
|
#include "sls/lexer.h"
|
|
|
|
Boolean builtin_addition(InterpreterState *interpreter_state);
|
|
Boolean builtin_subtraction(InterpreterState *interpreter_state);
|
|
Boolean builtin_multiplication(InterpreterState *interpreter_state);
|
|
Boolean builtin_division(InterpreterState *interpreter_state);
|
|
Boolean builtin_modulus(InterpreterState *interpreter_state);
|
|
Boolean builtin_exponential(InterpreterState *interpreter_state);
|
|
Boolean builtin_greater_than(InterpreterState *interpreter_state);
|
|
Boolean builtin_greater_than_or_equal_to(InterpreterState *interpreter_state);
|
|
Boolean builtin_less_than(InterpreterState *interpreter_state);
|
|
Boolean builtin_less_than_or_equal_to(InterpreterState *interpreter_state);
|
|
Boolean builtin_equal_to(InterpreterState *interpreter_state);
|
|
Boolean builtin_not_equal_to(InterpreterState *interpreter_state);
|
|
Boolean builtin_abs(InterpreterState *interpreter_state);
|
|
Boolean builtin_acos(InterpreterState *interpreter_state);
|
|
Boolean builtin_asin(InterpreterState *interpreter_state);
|
|
Boolean builtin_assert(InterpreterState *interpreter_state);
|
|
Boolean builtin_at(InterpreterState *interpreter_state);
|
|
Boolean builtin_atan(InterpreterState *interpreter_state);
|
|
Boolean builtin_atan2(InterpreterState *interpreter_state);
|
|
Boolean builtin_bitand(InterpreterState *interpreter_state);
|
|
Boolean builtin_bitnot(InterpreterState *interpreter_state);
|
|
Boolean builtin_bitor(InterpreterState *interpreter_state);
|
|
Boolean builtin_bitxor(InterpreterState *interpreter_state);
|
|
Boolean builtin_ceil(InterpreterState *interpreter_state);
|
|
Boolean builtin_concat(InterpreterState *interpreter_state);
|
|
Boolean builtin_cos(InterpreterState *interpreter_state);
|
|
Boolean builtin_depth(InterpreterState *interpreter_state);
|
|
Boolean builtin_drop(InterpreterState *interpreter_state);
|
|
Boolean builtin_dup(InterpreterState *interpreter_state);
|
|
Boolean builtin_each(InterpreterState *interpreter_state);
|
|
Boolean builtin_ends_with(InterpreterState *interpreter_state);
|
|
Boolean builtin_enum(InterpreterState *interpreter_state);
|
|
Boolean builtin_enumerate(InterpreterState *interpreter_state);
|
|
Boolean builtin_eval(InterpreterState *interpreter_state);
|
|
Boolean builtin_filter(InterpreterState *interpreter_state);
|
|
Boolean builtin_find(InterpreterState *interpreter_state);
|
|
Boolean builtin_floor(InterpreterState *interpreter_state);
|
|
Boolean builtin_fn(InterpreterState *interpreter_state);
|
|
Boolean builtin_foldl(InterpreterState *interpreter_state);
|
|
Boolean builtin_foldr(InterpreterState *interpreter_state);
|
|
Boolean builtin_for(InterpreterState *interpreter_state);
|
|
Boolean builtin_format(InterpreterState *interpreter_state);
|
|
Boolean builtin_get(InterpreterState *interpreter_state);
|
|
Boolean builtin_if(InterpreterState *interpreter_state);
|
|
Boolean builtin_impl(InterpreterState *interpreter_state);
|
|
Boolean builtin_implements(InterpreterState *interpreter_state);
|
|
Boolean builtin_inher(InterpreterState *interpreter_state);
|
|
Boolean builtin_lambda(InterpreterState *interpreter_state);
|
|
Boolean builtin_length(InterpreterState *interpreter_state);
|
|
Boolean builtin_ln(InterpreterState *interpreter_state);
|
|
Boolean builtin_log(InterpreterState *interpreter_state);
|
|
Boolean builtin_logb(InterpreterState *interpreter_state);
|
|
Boolean builtin_map(InterpreterState *interpreter_state);
|
|
Boolean builtin_match(InterpreterState *interpreter_state);
|
|
Boolean builtin_max(InterpreterState *interpreter_state);
|
|
Boolean builtin_mean(InterpreterState *interpreter_state);
|
|
Boolean builtin_min(InterpreterState *interpreter_state);
|
|
Boolean builtin_not(InterpreterState *interpreter_state);
|
|
Boolean builtin_or(InterpreterState *interpreter_state);
|
|
Boolean builtin_over(InterpreterState *interpreter_state);
|
|
Boolean builtin_pick(InterpreterState *interpreter_state);
|
|
Boolean builtin_rand(InterpreterState *interpreter_state);
|
|
Boolean builtin_reduce(InterpreterState *interpreter_state);
|
|
Boolean builtin_replace(InterpreterState *interpreter_state);
|
|
Boolean builtin_reverse(InterpreterState *interpreter_state);
|
|
Boolean builtin_roll(InterpreterState *interpreter_state);
|
|
Boolean builtin_round(InterpreterState *interpreter_state);
|
|
Boolean builtin_seed(InterpreterState *interpreter_state);
|
|
Boolean builtin_set(InterpreterState *interpreter_state);
|
|
Boolean builtin_shl(InterpreterState *interpreter_state);
|
|
Boolean builtin_shr(InterpreterState *interpreter_state);
|
|
Boolean builtin_sin(InterpreterState *interpreter_state);
|
|
Boolean builtin_slice(InterpreterState *interpreter_state);
|
|
Boolean builtin_split(InterpreterState *interpreter_state);
|
|
Boolean builtin_sqrt(InterpreterState *interpreter_state);
|
|
Boolean builtin_starts_with(InterpreterState *interpreter_state);
|
|
Boolean builtin_struct(InterpreterState *interpreter_state);
|
|
Boolean builtin_substr(InterpreterState *interpreter_state);
|
|
Boolean builtin_sum(InterpreterState *interpreter_state);
|
|
Boolean builtin_swap(InterpreterState *interpreter_state);
|
|
Boolean builtin_tan(InterpreterState *interpreter_state);
|
|
Boolean builtin_trait(InterpreterState *interpreter_state);
|
|
Boolean builtin_transpose(InterpreterState *interpreter_state);
|
|
Boolean builtin_trim(InterpreterState *interpreter_state);
|
|
Boolean builtin_type_of(InterpreterState *interpreter_state);
|
|
Boolean builtin_union(InterpreterState *interpreter_state);
|
|
Boolean builtin_while(InterpreterState *interpreter_state);
|
|
Boolean builtin_window(InterpreterState *interpreter_state);
|
|
Boolean builtin_zip(InterpreterState *interpreter_state);
|
|
|
|
static inline Boolean hash_table_put_funcs(HashTable *ht, SlsStr key, FunctionItem *item) {
|
|
return hash_table_put(ht, key, (void *)item);
|
|
}
|
|
|
|
typedef enum {
|
|
NUMERIC_FLOAT = 1 << 0,
|
|
NUMERIC_SIGNED = 1 << 1,
|
|
NUMERIC_64 = 1 << 2,
|
|
NUMERIC_32 = 1 << 3,
|
|
NUMERIC_16 = 1 << 4,
|
|
NUMERIC_8 = 1 << 5,
|
|
} NumericTypes;
|
|
|
|
|
|
Boolean load_builtins(InterpreterState *interpreter_state) {
|
|
FunctionItem *func;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_addition};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("+"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_subtraction};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("-"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_multiplication};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("*"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_division};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("/"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_modulus};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("%"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_exponential};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("^"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_greater_than};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR(">"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_greater_than_or_equal_to};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR(">="), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_less_than};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("<"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_less_than_or_equal_to};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("<="), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_equal_to};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("=="), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_not_equal_to};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("!="), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_abs};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("abs"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_acos};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("acos"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_asin};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("asin"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_assert};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("assert"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_at};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("at"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_atan};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("atan"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_atan2};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("atan2"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_bitand};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("bitand"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_bitnot};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("bitnot"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_bitor};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("bitor"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_bitxor};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("bitxor"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_ceil};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("ceil"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_concat};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("concat"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_cos};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("cos"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_depth};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("depth"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_drop};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("drop"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_dup};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("dup"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_each};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("each"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_ends_with};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("ends_with"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_enum};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("enum"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_enumerate};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("enumerate"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_eval};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("eval"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_filter};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("filter"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_find};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("find"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_floor};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("floor"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_fn};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("fn"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_foldl};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("foldl"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_foldr};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("foldr"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_for};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("for"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_format};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("format"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_get};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("get"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_if};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("if"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_impl};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("impl"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_implements};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("implements"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_inher};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("inher"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_lambda};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("lambda"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_length};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("length"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_ln};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("ln"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_log};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("log"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_logb};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("logb"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_map};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("map"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_match};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("match"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_max};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("max"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_mean};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("mean"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_min};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("min"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_not};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("not"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_or};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("or"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_over};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("over"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_pick};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("pick"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_rand};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("rand"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_reduce};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("reduce"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_replace};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("replace"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_reverse};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("reverse"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_roll};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("roll"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_round};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("round"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_seed};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("seed"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_set};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("set"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_shl};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("shl"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_shr};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("shr"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_sin};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("sin"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_slice};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("slice"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_split};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("split"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_sqrt};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("sqrt"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_starts_with};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("starts_with"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_struct};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("struct"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_substr};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("substr"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_sum};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("sum"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_swap};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("swap"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_tan};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("tan"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_trait};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("trait"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_transpose};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("transpose"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_trim};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("trim"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_type_of};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("type_of"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_union};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("union"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_while};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("while"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_window};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("window"), func))
|
|
return FALSE;
|
|
|
|
func = (FunctionItem *)malloc(sizeof(FunctionItem));
|
|
if (func == NULL) return FALSE;
|
|
*func = (FunctionItem){ .type = FUNCTION_BUILTIN, .builtin = *builtin_zip};
|
|
if (!hash_table_put_funcs(interpreter_state->functions, SLS_STR("zip"), func))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#define arithmetic(op) \
|
|
double af = 0, bf = 0; \
|
|
uint64_t ai = 0, bi = 0; \
|
|
uint64_t type = 0; \
|
|
if (interpreter_state->stack == NULL) return FALSE; \
|
|
if (interpreter_state->stack->next == NULL) return FALSE; \
|
|
\
|
|
switch (interpreter_state->stack->type) { \
|
|
case STACK_IDENTIFIER: \
|
|
return FALSE; \
|
|
case STACK_I64: \
|
|
ai = interpreter_state->stack->i64; \
|
|
af = interpreter_state->stack->i64; \
|
|
type |= NUMERIC_64; \
|
|
type |= NUMERIC_SIGNED; \
|
|
break; \
|
|
case STACK_I32: \
|
|
ai = interpreter_state->stack->i32; \
|
|
af = interpreter_state->stack->i32; \
|
|
type |= NUMERIC_32; \
|
|
type |= NUMERIC_SIGNED; \
|
|
break; \
|
|
case STACK_I16: \
|
|
ai = interpreter_state->stack->i16; \
|
|
af = interpreter_state->stack->i16; \
|
|
type |= NUMERIC_16; \
|
|
type |= NUMERIC_SIGNED; \
|
|
break; \
|
|
case STACK_I8: \
|
|
ai = interpreter_state->stack->i8; \
|
|
af = interpreter_state->stack->i8; \
|
|
type |= NUMERIC_8; \
|
|
type |= NUMERIC_SIGNED; \
|
|
break; \
|
|
case STACK_U64: \
|
|
ai = interpreter_state->stack->u64; \
|
|
af = interpreter_state->stack->u64; \
|
|
type |= NUMERIC_64; \
|
|
break; \
|
|
case STACK_U32: \
|
|
ai = interpreter_state->stack->u32; \
|
|
af = interpreter_state->stack->u32; \
|
|
type |= NUMERIC_32; \
|
|
break; \
|
|
case STACK_U16: \
|
|
ai = interpreter_state->stack->u16; \
|
|
af = interpreter_state->stack->u16; \
|
|
type |= NUMERIC_16; \
|
|
break; \
|
|
case STACK_U8: \
|
|
ai = interpreter_state->stack->u8; \
|
|
af = interpreter_state->stack->u8; \
|
|
type |= NUMERIC_8; \
|
|
break; \
|
|
case STACK_FLOAT: \
|
|
af = interpreter_state->stack->f32; \
|
|
type |= NUMERIC_32; \
|
|
type |= NUMERIC_FLOAT; \
|
|
break; \
|
|
case STACK_DOUBLE: \
|
|
af = interpreter_state->stack->f64; \
|
|
type |= NUMERIC_64; \
|
|
type |= NUMERIC_FLOAT; \
|
|
break; \
|
|
case STACK_CHARACTER: \
|
|
ai = interpreter_state->stack->character; \
|
|
af = interpreter_state->stack->character; \
|
|
break; \
|
|
case STACK_BOOLEAN: \
|
|
ai = interpreter_state->stack->boolean; \
|
|
af = interpreter_state->stack->boolean; \
|
|
break; \
|
|
case STACK_TOKEN_STRING: \
|
|
return FALSE; \
|
|
} \
|
|
\
|
|
switch (interpreter_state->stack->next->type) { \
|
|
case STACK_IDENTIFIER: \
|
|
return FALSE; \
|
|
case STACK_I64: \
|
|
bi = interpreter_state->stack->next->i64; \
|
|
bf = interpreter_state->stack->next->i64; \
|
|
type |= NUMERIC_64; \
|
|
type |= NUMERIC_SIGNED; \
|
|
break; \
|
|
case STACK_I32: \
|
|
bi = interpreter_state->stack->next->i32; \
|
|
bf = interpreter_state->stack->next->i32; \
|
|
type |= NUMERIC_32; \
|
|
type |= NUMERIC_SIGNED; \
|
|
break; \
|
|
case STACK_I16: \
|
|
bi = interpreter_state->stack->next->i16; \
|
|
bf = interpreter_state->stack->next->i16; \
|
|
type |= NUMERIC_16; \
|
|
type |= NUMERIC_SIGNED; \
|
|
break; \
|
|
case STACK_I8: \
|
|
bi = interpreter_state->stack->next->i8; \
|
|
bf = interpreter_state->stack->next->i8; \
|
|
type |= NUMERIC_8; \
|
|
type |= NUMERIC_SIGNED; \
|
|
break; \
|
|
case STACK_U64: \
|
|
bi = interpreter_state->stack->next->u64; \
|
|
bf = interpreter_state->stack->next->u64; \
|
|
type |= NUMERIC_64; \
|
|
break; \
|
|
case STACK_U32: \
|
|
bi = interpreter_state->stack->next->u32; \
|
|
bf = interpreter_state->stack->next->u32; \
|
|
type |= NUMERIC_32; \
|
|
break; \
|
|
case STACK_U16: \
|
|
bi = interpreter_state->stack->next->u16; \
|
|
bf = interpreter_state->stack->next->u16; \
|
|
type |= NUMERIC_16; \
|
|
break; \
|
|
case STACK_U8: \
|
|
bi = interpreter_state->stack->next->u8; \
|
|
bf = interpreter_state->stack->next->u8; \
|
|
type |= NUMERIC_8; \
|
|
break; \
|
|
case STACK_FLOAT: \
|
|
bf = interpreter_state->stack->next->f32; \
|
|
type |= NUMERIC_32; \
|
|
type |= NUMERIC_FLOAT; \
|
|
break; \
|
|
case STACK_DOUBLE: \
|
|
bf = interpreter_state->stack->next->f64; \
|
|
type |= NUMERIC_64; \
|
|
type |= NUMERIC_FLOAT; \
|
|
break; \
|
|
case STACK_CHARACTER: \
|
|
bi = interpreter_state->stack->next->character; \
|
|
bf = interpreter_state->stack->next->character; \
|
|
break; \
|
|
case STACK_BOOLEAN: \
|
|
bi = interpreter_state->stack->next->boolean; \
|
|
bf = interpreter_state->stack->next->boolean; \
|
|
break; \
|
|
case STACK_TOKEN_STRING: \
|
|
return FALSE; \
|
|
} \
|
|
\
|
|
StackItem *node = interpreter_state->stack; \
|
|
interpreter_state->stack = interpreter_state->stack->next->next; \
|
|
node->next->next = NULL; \
|
|
clean_stack(node); \
|
|
\
|
|
if (type & NUMERIC_FLOAT && type & NUMERIC_64) { \
|
|
return push_token(interpreter_state, (Token){ \
|
|
.type = TOKEN_DOUBLE, \
|
|
.double_literal = bf op af, \
|
|
}); \
|
|
} else if (type & NUMERIC_FLOAT) { \
|
|
return push_token(interpreter_state, (Token){ \
|
|
.type = TOKEN_FLOAT, \
|
|
.float_literal = (float)bf op (float)af, \
|
|
}); \
|
|
} else if (type & NUMERIC_SIGNED && type & NUMERIC_64) { \
|
|
return push_token(interpreter_state, (Token){ \
|
|
.type = TOKEN_INTEGER, \
|
|
.integer_literal = (IntegerLiteral){ \
|
|
.type = INTEGER_I64, \
|
|
.value = bi op ai, \
|
|
}, \
|
|
}); \
|
|
} else if (type & NUMERIC_SIGNED && type & NUMERIC_32) { \
|
|
return push_token(interpreter_state, (Token){ \
|
|
.type = TOKEN_INTEGER, \
|
|
.integer_literal = (IntegerLiteral){ \
|
|
.type = INTEGER_I32, \
|
|
.value = bi op ai, \
|
|
}, \
|
|
}); \
|
|
} else if (type & NUMERIC_SIGNED && type & NUMERIC_16) { \
|
|
return push_token(interpreter_state, (Token){ \
|
|
.type = TOKEN_INTEGER, \
|
|
.integer_literal = (IntegerLiteral){ \
|
|
.type = INTEGER_I16, \
|
|
.value = bi op ai, \
|
|
}, \
|
|
}); \
|
|
} else if (type & NUMERIC_SIGNED) { \
|
|
return push_token(interpreter_state, (Token){ \
|
|
.type = TOKEN_INTEGER, \
|
|
.integer_literal = (IntegerLiteral){ \
|
|
.type = INTEGER_I8, \
|
|
.value = bi op ai, \
|
|
}, \
|
|
}); \
|
|
} else if (type & NUMERIC_64) { \
|
|
return push_token(interpreter_state, (Token){ \
|
|
.type = TOKEN_INTEGER, \
|
|
.integer_literal = (IntegerLiteral){ \
|
|
.type = INTEGER_U64, \
|
|
.value = bi op ai, \
|
|
}, \
|
|
}); \
|
|
} else if (type & NUMERIC_32) { \
|
|
return push_token(interpreter_state, (Token){ \
|
|
.type = TOKEN_INTEGER, \
|
|
.integer_literal = (IntegerLiteral){ \
|
|
.type = INTEGER_U32, \
|
|
.value = bi op ai, \
|
|
}, \
|
|
}); \
|
|
} else if (type & NUMERIC_16) { \
|
|
return push_token(interpreter_state, (Token){ \
|
|
.type = TOKEN_INTEGER, \
|
|
.integer_literal = (IntegerLiteral){ \
|
|
.type = INTEGER_U16, \
|
|
.value = bi op ai, \
|
|
}, \
|
|
}); \
|
|
} else { \
|
|
return push_token(interpreter_state, (Token){ \
|
|
.type = TOKEN_INTEGER, \
|
|
.integer_literal = (IntegerLiteral){ \
|
|
.type = INTEGER_U8, \
|
|
.value = bi op ai, \
|
|
}, \
|
|
}); \
|
|
}
|
|
|
|
Boolean builtin_addition(InterpreterState *interpreter_state) {
|
|
arithmetic(+);
|
|
}
|
|
|
|
Boolean builtin_subtraction(InterpreterState *interpreter_state) {
|
|
arithmetic(-);
|
|
}
|
|
|
|
Boolean builtin_multiplication(InterpreterState *interpreter_state) {
|
|
arithmetic(*);
|
|
}
|
|
|
|
Boolean builtin_division(InterpreterState *interpreter_state) {
|
|
double a, b;
|
|
if (interpreter_state->stack == NULL) return FALSE;
|
|
if (interpreter_state->stack->next == NULL) return FALSE;
|
|
|
|
switch (interpreter_state->stack->type) {
|
|
case STACK_IDENTIFIER:
|
|
return FALSE;
|
|
case STACK_I64:
|
|
a = interpreter_state->stack->i64;
|
|
break;
|
|
case STACK_I32:
|
|
a = interpreter_state->stack->i32;
|
|
break;
|
|
case STACK_I16:
|
|
a = interpreter_state->stack->i16;
|
|
break;
|
|
case STACK_I8:
|
|
a = interpreter_state->stack->i8;
|
|
break;
|
|
case STACK_U64:
|
|
a = interpreter_state->stack->u64;
|
|
break;
|
|
case STACK_U32:
|
|
a = interpreter_state->stack->u32;
|
|
break;
|
|
case STACK_U16:
|
|
a = interpreter_state->stack->u16;
|
|
break;
|
|
case STACK_U8:
|
|
a = interpreter_state->stack->u8;
|
|
break;
|
|
case STACK_FLOAT:
|
|
a = interpreter_state->stack->f32;
|
|
break;
|
|
case STACK_DOUBLE:
|
|
a = interpreter_state->stack->f64;
|
|
break;
|
|
case STACK_CHARACTER:
|
|
a = interpreter_state->stack->character;
|
|
break;
|
|
case STACK_BOOLEAN:
|
|
a = interpreter_state->stack->boolean;
|
|
break;
|
|
case STACK_TOKEN_STRING:
|
|
return FALSE;
|
|
}
|
|
|
|
switch (interpreter_state->stack->next->type) {
|
|
case STACK_IDENTIFIER:
|
|
return FALSE;
|
|
case STACK_I64:
|
|
b = interpreter_state->stack->next->i64;
|
|
break;
|
|
case STACK_I32:
|
|
b = interpreter_state->stack->next->i32;
|
|
break;
|
|
case STACK_I16:
|
|
b = interpreter_state->stack->next->i16;
|
|
break;
|
|
case STACK_I8:
|
|
b = interpreter_state->stack->next->i8;
|
|
break;
|
|
case STACK_U64:
|
|
b = interpreter_state->stack->next->u64;
|
|
break;
|
|
case STACK_U32:
|
|
b = interpreter_state->stack->next->u32;
|
|
break;
|
|
case STACK_U16:
|
|
b = interpreter_state->stack->next->u16;
|
|
break;
|
|
case STACK_U8:
|
|
b = interpreter_state->stack->next->u8;
|
|
break;
|
|
case STACK_FLOAT:
|
|
b = interpreter_state->stack->next->f32;
|
|
break;
|
|
case STACK_DOUBLE:
|
|
b = interpreter_state->stack->next->f64;
|
|
break;
|
|
case STACK_CHARACTER:
|
|
b = interpreter_state->stack->next->character;
|
|
break;
|
|
case STACK_BOOLEAN:
|
|
b = interpreter_state->stack->next->boolean;
|
|
break;
|
|
case STACK_TOKEN_STRING:
|
|
return FALSE;
|
|
}
|
|
|
|
if (a == 0) return FALSE;
|
|
|
|
StackItem *node = interpreter_state->stack;
|
|
interpreter_state->stack = interpreter_state->stack->next->next;
|
|
node->next->next = NULL;
|
|
clean_stack(node);
|
|
|
|
return push_token(interpreter_state, (Token){
|
|
.type = TOKEN_DOUBLE,
|
|
.double_literal = (b/a),
|
|
});
|
|
}
|
|
|
|
Boolean builtin_modulus(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_exponential(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_greater_than(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_greater_than_or_equal_to(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_less_than(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_less_than_or_equal_to(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_equal_to(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_not_equal_to(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_abs(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_acos(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_asin(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_assert(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_at(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_atan(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_atan2(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_bitand(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_bitnot(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_bitor(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_bitxor(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_ceil(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_concat(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_cos(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_depth(InterpreterState *interpreter_state) {
|
|
size_t depth = 0;
|
|
for (StackItem *node = interpreter_state->stack; node; node = node->next)
|
|
depth++;
|
|
return push_token(interpreter_state, (Token){
|
|
.type = TOKEN_INTEGER,
|
|
.integer_literal = (IntegerLiteral){
|
|
.type = INTEGER_U64,
|
|
.value = (uint64_t)depth,
|
|
},
|
|
});
|
|
}
|
|
|
|
Boolean builtin_drop(InterpreterState *interpreter_state) {
|
|
StackItem *node = interpreter_state->stack;
|
|
if (node == NULL) return FALSE;
|
|
interpreter_state->stack = node->next;
|
|
node->next = NULL;
|
|
clean_stack(node);
|
|
return TRUE;
|
|
}
|
|
|
|
Boolean builtin_dup(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_each(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_ends_with(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_enum(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_enumerate(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_eval(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_filter(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_find(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_floor(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_fn(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_foldl(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_foldr(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_for(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_format(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_get(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_if(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_impl(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_implements(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_inher(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_lambda(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_length(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_ln(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_log(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_logb(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_map(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_match(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_max(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_mean(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_min(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_not(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_or(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_over(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_pick(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_rand(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_reduce(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_replace(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_reverse(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_roll(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_round(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_seed(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_set(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_shl(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_shr(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_sin(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_slice(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_split(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_sqrt(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_starts_with(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_struct(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_substr(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_sum(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_swap(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_tan(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_trait(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_transpose(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_trim(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_type_of(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_union(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_while(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_window(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|
|
|
|
Boolean builtin_zip(InterpreterState *interpreter_state) {
|
|
(void)interpreter_state;
|
|
return FALSE;
|
|
}
|