<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <Arduino.h>

#include "source.h"
#include "filter.h"
#include "function.h"
#include "generator.h"
#include "parse.h"

#define MAX_CODE_LEN           512
#define MAX_NUM_ARGS             8
#define VALUE_SIZE               4
#define ARG_VALUE                0
#define ARG_FUNC                 1
#define ARG_COLOR                2
#define ARG_LOCAL                3

#define LOCAL_ID                 0
#define LOCAL_POS_X              2
#define LOCAL_POS_Y              3
#define LOCAL_POS_Z              4

#define FILTER_FADE_IN            0
#define FILTER_FADE_OUT           1
#define FILTER_BRIGHTNESS         2
#define GEN_SIN                   3
#define GEN_SQUARE                4
#define GEN_SAWTOOTH              5
#define SRC_CONSTANT_COLOR        6
#define SRC_RAND_COL_SEQ          7
#define SRC_HSV                   8
#define SRC_RAINBOW               9
#define GEN_STEP                 10
#define FUNC_SPARKLE             11
#define FUNC_GENOP               12
#define FUNC_SRCOP               13
#define FUNC_ABS                 14
#define GEN_LINE                 15
#define GEN_CONSTANT             16
#define FUNC_COMPLEMENTARY       17
#define FUNC_LOCAL_RANDOM        18
#define GEN_IMPULSE              19
#define FUNC_REPEAT_LOCAL_RANDOM 20

// variables to help manage the heap.
uint8_t *cur_heap = NULL;
uint16_t heap_offset = 0;

void heap_setup(uint8_t *heap)
{
    heap_offset = 0;
    cur_heap = heap;
}

void *heap_alloc(uint8_t bytes)
{ 
    uint8_t *ptr = cur_heap + heap_offset;
    if (bytes + heap_offset > HEAP_SIZE)
    {
        g_error = ERR_OUT_OF_HEAP;
        return NULL;
    }

    heap_offset += bytes;

    return ptr;
}

void *create_object(uint8_t   id, uint8_t *is_local,
                    int32_t  *values, uint8_t value_count,
                    void    **gens, uint8_t gen_count,
                    color_t  *colors, uint8_t color_count)
{
    void *obj = NULL;

    *is_local = 0;
    switch(id)
    {
        case FILTER_FADE_IN:
            {
                if (value_count == 2)
                {
                    obj = heap_alloc(sizeof(f_fade_in_t));
                    if (!obj)
                        return NULL;
                    f_fade_in_init((f_fade_in_t *)obj, f_fade_in_get, values[0], values[1]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case FILTER_FADE_OUT:
            {
                if (value_count == 2)
                {
                    obj = heap_alloc(sizeof(f_fade_out_t));
                    if (!obj)
                        return NULL;
                    f_fade_out_init((f_fade_out_t *)obj, f_fade_out_get, values[0], values[1]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case FILTER_BRIGHTNESS:
            {
                if (gen_count == 1)
                {
                    obj = heap_alloc(sizeof(f_brightness_t));
                    if (!obj)
                        return NULL;
                    f_brightness_init((f_brightness_t *)obj, (generator_t*)gens[0]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case SRC_CONSTANT_COLOR:
            {
                if (color_count == 1)
                {
                    obj = heap_alloc(sizeof(s_constant_color_t));
                    if (!obj)
                        return NULL;
                    s_constant_color_init((s_constant_color_t *)obj, &colors[0]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case SRC_RAND_COL_SEQ:
            {
                if (value_count == 2)
                {
                    obj = heap_alloc(sizeof(s_random_color_seq_t));
                    if (!obj)
                        return NULL;
                    s_random_color_seq_init((s_random_color_seq_t *)obj, values[0], values[1]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case SRC_HSV:
            {
                
                if (gen_count > 0)
                {
                    obj = heap_alloc(sizeof(s_hsv_t));
                    if (!obj)
                        return NULL;
                    if (gen_count > 2)
                        s_hsv_init((s_hsv_t *)obj, (generator_t*)gens[0],  (generator_t*)gens[1],  (generator_t*)gens[2]);
                    else
                    if (gen_count > 1)
                        s_hsv_init((s_hsv_t *)obj,  (generator_t*)gens[0],  (generator_t*)gens[1], NULL);
                    else
                        s_hsv_init((s_hsv_t *)obj,  (generator_t*)gens[0], NULL, NULL);  
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case SRC_RAINBOW:
            {
                if (gen_count == 1)
                {
                    obj = heap_alloc(sizeof(s_rainbow_t));
                    if (!obj)
                        return NULL;
                    s_rainbow_init((s_rainbow_t *)obj,  (generator_t*)gens[0]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case GEN_SQUARE:
            {
                if (value_count == 5)
                {
                    obj = heap_alloc(sizeof(square_t));
                    if (!obj)
                        return NULL;

                    g_square_init(obj, g_square, values[0], values[1], values[2], values[3], values[4]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;
                     
        case GEN_SIN:
            {
                if (value_count == 4)
                {
                    obj = heap_alloc(sizeof(generator_t));
                    if (!obj)
                        return NULL;

                    g_sin_init(obj, g_sin, values[0], values[1], values[2], values[3]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;  
            
        case GEN_SAWTOOTH:
        case GEN_STEP:
        case GEN_LINE:
        case GEN_IMPULSE:
            {
                if (value_count == 4)
                {
                    obj = heap_alloc(sizeof(generator_t));
                    if (!obj)
                        return NULL;
                    switch(id)
                    {
                        case GEN_SIN:
                            g_generator_init(obj, g_sin, values[0], values[1], values[2], values[3]);
                        break;
                        case GEN_SAWTOOTH:
                            g_generator_init(obj, g_sawtooth, values[0], values[1], values[2], values[3]);
                        break;
                        case GEN_STEP:
                            g_generator_init(obj, g_step, values[0], values[1], values[2], values[3]);
                        break;
                        case GEN_LINE:
                            g_generator_init(obj, g_line, values[0], values[1], values[2], values[3]);
                        break;
                        case GEN_IMPULSE:
                            g_generator_init(obj, g_impulse, values[0], values[1], values[2], values[3]);
                        break;
                    }
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case FUNC_GENOP:
            {
                if (value_count == 1 && gen_count == 2)
                {
                    obj = heap_alloc(sizeof(s_op_t));
                    if (!obj)
                        return NULL;
                    g_generator_op_init(obj, (uint8_t)values[0], (generator_t*)gens[0], (generator_t*)gens[1]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case FUNC_SRCOP:
            {
                if (value_count == 1 && gen_count == 2)
                {
                    obj = heap_alloc(sizeof(s_op_t));
                    if (!obj)
                        return NULL;
                    s_op_init((s_op_t *)obj, (uint8_t)values[0], (s_source_t*)gens[0], (s_source_t*)gens[1]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case FUNC_ABS:
            {
                if (gen_count == 1)
                {
                    obj = heap_alloc(sizeof(g_abs_t));
                    if (!obj)
                        return NULL;
                    g_abs_init(obj, (generator_t *)gens[0]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case GEN_CONSTANT:
            {
                if (value_count == 1)
                {
                    obj = heap_alloc(sizeof(g_constant_t));
                    if (!obj)
                        return NULL;
                    g_constant_init((g_constant_t *)obj, (uint8_t)values[0]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;
    
        case FUNC_LOCAL_RANDOM:
            {
                *is_local = 1;
                if (value_count == 2)
                {

                    int32_t ret = fu_local_random(values[0], values[1]);
                    return (void *)ret;
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;
            
        case FUNC_REPEAT_LOCAL_RANDOM:
            {
                *is_local = 1;
                if (value_count == 1)<commit_msg>Don't cast the const value to 8 bit<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <Arduino.h>

#include "source.h"
#include "filter.h"
#include "function.h"
#include "generator.h"
#include "parse.h"

#define MAX_CODE_LEN           512
#define MAX_NUM_ARGS             8
#define VALUE_SIZE               4
#define ARG_VALUE                0
#define ARG_FUNC                 1
#define ARG_COLOR                2
#define ARG_LOCAL                3

#define LOCAL_ID                 0
#define LOCAL_POS_X              2
#define LOCAL_POS_Y              3
#define LOCAL_POS_Z              4

#define FILTER_FADE_IN            0
#define FILTER_FADE_OUT           1
#define FILTER_BRIGHTNESS         2
#define GEN_SIN                   3
#define GEN_SQUARE                4
#define GEN_SAWTOOTH              5
#define SRC_CONSTANT_COLOR        6
#define SRC_RAND_COL_SEQ          7
#define SRC_HSV                   8
#define SRC_RAINBOW               9
#define GEN_STEP                 10
#define FUNC_SPARKLE             11
#define FUNC_GENOP               12
#define FUNC_SRCOP               13
#define FUNC_ABS                 14
#define GEN_LINE                 15
#define GEN_CONSTANT             16
#define FUNC_COMPLEMENTARY       17
#define FUNC_LOCAL_RANDOM        18
#define GEN_IMPULSE              19
#define FUNC_REPEAT_LOCAL_RANDOM 20

// variables to help manage the heap.
uint8_t *cur_heap = NULL;
uint16_t heap_offset = 0;

void heap_setup(uint8_t *heap)
{
    heap_offset = 0;
    cur_heap = heap;
}

void *heap_alloc(uint8_t bytes)
{ 
    uint8_t *ptr = cur_heap + heap_offset;
    if (bytes + heap_offset > HEAP_SIZE)
    {
        g_error = ERR_OUT_OF_HEAP;
        return NULL;
    }

    heap_offset += bytes;

    return ptr;
}

void *create_object(uint8_t   id, uint8_t *is_local,
                    int32_t  *values, uint8_t value_count,
                    void    **gens, uint8_t gen_count,
                    color_t  *colors, uint8_t color_count)
{
    void *obj = NULL;

    *is_local = 0;
    switch(id)
    {
        case FILTER_FADE_IN:
            {
                if (value_count == 2)
                {
                    obj = heap_alloc(sizeof(f_fade_in_t));
                    if (!obj)
                        return NULL;
                    f_fade_in_init((f_fade_in_t *)obj, f_fade_in_get, values[0], values[1]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case FILTER_FADE_OUT:
            {
                if (value_count == 2)
                {
                    obj = heap_alloc(sizeof(f_fade_out_t));
                    if (!obj)
                        return NULL;
                    f_fade_out_init((f_fade_out_t *)obj, f_fade_out_get, values[0], values[1]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case FILTER_BRIGHTNESS:
            {
                if (gen_count == 1)
                {
                    obj = heap_alloc(sizeof(f_brightness_t));
                    if (!obj)
                        return NULL;
                    f_brightness_init((f_brightness_t *)obj, (generator_t*)gens[0]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case SRC_CONSTANT_COLOR:
            {
                if (color_count == 1)
                {
                    obj = heap_alloc(sizeof(s_constant_color_t));
                    if (!obj)
                        return NULL;
                    s_constant_color_init((s_constant_color_t *)obj, &colors[0]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case SRC_RAND_COL_SEQ:
            {
                if (value_count == 2)
                {
                    obj = heap_alloc(sizeof(s_random_color_seq_t));
                    if (!obj)
                        return NULL;
                    s_random_color_seq_init((s_random_color_seq_t *)obj, values[0], values[1]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case SRC_HSV:
            {
                
                if (gen_count > 0)
                {
                    obj = heap_alloc(sizeof(s_hsv_t));
                    if (!obj)
                        return NULL;
                    if (gen_count > 2)
                        s_hsv_init((s_hsv_t *)obj, (generator_t*)gens[0],  (generator_t*)gens[1],  (generator_t*)gens[2]);
                    else
                    if (gen_count > 1)
                        s_hsv_init((s_hsv_t *)obj,  (generator_t*)gens[0],  (generator_t*)gens[1], NULL);
                    else
                        s_hsv_init((s_hsv_t *)obj,  (generator_t*)gens[0], NULL, NULL);  
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case SRC_RAINBOW:
            {
                if (gen_count == 1)
                {
                    obj = heap_alloc(sizeof(s_rainbow_t));
                    if (!obj)
                        return NULL;
                    s_rainbow_init((s_rainbow_t *)obj,  (generator_t*)gens[0]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case GEN_SQUARE:
            {
                if (value_count == 5)
                {
                    obj = heap_alloc(sizeof(square_t));
                    if (!obj)
                        return NULL;

                    g_square_init(obj, g_square, values[0], values[1], values[2], values[3], values[4]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;
                     
        case GEN_SIN:
            {
                if (value_count == 4)
                {
                    obj = heap_alloc(sizeof(generator_t));
                    if (!obj)
                        return NULL;

                    g_sin_init(obj, g_sin, values[0], values[1], values[2], values[3]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;  
            
        case GEN_SAWTOOTH:
        case GEN_STEP:
        case GEN_LINE:
        case GEN_IMPULSE:
            {
                if (value_count == 4)
                {
                    obj = heap_alloc(sizeof(generator_t));
                    if (!obj)
                        return NULL;
                    switch(id)
                    {
                        case GEN_SIN:
                            g_generator_init(obj, g_sin, values[0], values[1], values[2], values[3]);
                        break;
                        case GEN_SAWTOOTH:
                            g_generator_init(obj, g_sawtooth, values[0], values[1], values[2], values[3]);
                        break;
                        case GEN_STEP:
                            g_generator_init(obj, g_step, values[0], values[1], values[2], values[3]);
                        break;
                        case GEN_LINE:
                            g_generator_init(obj, g_line, values[0], values[1], values[2], values[3]);
                        break;
                        case GEN_IMPULSE:
                            g_generator_init(obj, g_impulse, values[0], values[1], values[2], values[3]);
                        break;
                    }
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case FUNC_GENOP:
            {
                if (value_count == 1 && gen_count == 2)
                {
                    obj = heap_alloc(sizeof(s_op_t));
                    if (!obj)
                        return NULL;
                    g_generator_op_init(obj, (uint8_t)values[0], (generator_t*)gens[0], (generator_t*)gens[1]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case FUNC_SRCOP:
            {
                if (value_count == 1 && gen_count == 2)
                {
                    obj = heap_alloc(sizeof(s_op_t));
                    if (!obj)
                        return NULL;
                    s_op_init((s_op_t *)obj, (uint8_t)values[0], (s_source_t*)gens[0], (s_source_t*)gens[1]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case FUNC_ABS:
            {
                if (gen_count == 1)
                {
                    obj = heap_alloc(sizeof(g_abs_t));
                    if (!obj)
                        return NULL;
                    g_abs_init(obj, (generator_t *)gens[0]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;

        case GEN_CONSTANT:
            {
                if (value_count == 1)
                {
                    obj = heap_alloc(sizeof(g_constant_t));
                    if (!obj)
                        return NULL;
                    g_constant_init((g_constant_t *)obj, values[0]);
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;
    
        case FUNC_LOCAL_RANDOM:
            {
                *is_local = 1;
                if (value_count == 2)
                {

                    int32_t ret = fu_local_random(values[0], values[1]);
                    return (void *)ret;
                }
                else
                {
                    g_error = ERR_PARSE_FAILURE;
                    return NULL;
                }
            }
            break;
            
        case FUNC_REPEAT_LOCAL_RANDOM:
            {
                *is_local = 1;
                if (value_count == 1)
{'fraction_non_alphanumeric': 0.07785459310469477, 'fraction_numerical': 0.012832678143780217, 'mean_word_length': 0.8595194085027726, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5488757', 'n_tokens_mistral': 6393, 'n_tokens_neox': 5819, 'n_words': 1146}