feat: add basic math and random_int funcs
This commit is contained in:
parent
a62dd411aa
commit
cb2a1df61f
5 changed files with 149 additions and 18 deletions
|
@ -17,10 +17,10 @@ I didn't really study how others languages works beforehand, I'm just guessing h
|
|||
|
||||
ToDo List:
|
||||
|
||||
- [ ] pow operator
|
||||
- [X] pow operator
|
||||
- [ ] binary operators
|
||||
- [ ] implement basic math functions
|
||||
- [ ] implement random_int(min, max)
|
||||
- [X] implement basic math functions
|
||||
- [X] implement random_int(min, max)
|
||||
- [ ] implement print_number(message)
|
||||
- [ ] implement input_number()
|
||||
- [ ] base of the CLI
|
||||
|
|
127
src/funcs.c
127
src/funcs.c
|
@ -1,10 +1,11 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include "./types.h"
|
||||
#include "./utils.h"
|
||||
|
||||
int abs_implementation(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
int abs_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
if (types[0] == TYPE_INT) {
|
||||
*res = args[0];
|
||||
|
@ -26,23 +27,83 @@ int abs_implementation(int* res, unsigned char* resType, unsigned char* types, i
|
|||
return 1;
|
||||
}
|
||||
|
||||
int sqrt_implementation(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
int simple_float_func(float (*func)(float), int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
float x = 0;
|
||||
if (types[0] == TYPE_INT) {
|
||||
// convert to float
|
||||
x = (float) args[0];
|
||||
}
|
||||
if (types[0] == TYPE_FLOAT) {
|
||||
x = get_float_from_int_rep(args[0]);
|
||||
}
|
||||
*res = get_int_rep_from_float(sqrt(x));
|
||||
*res = get_int_rep_from_float(func(x));
|
||||
*resType = TYPE_FLOAT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int max_implementation(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
// #define SIMPLE_FUNC_BINDING(name) ({\
|
||||
// int #name_impl(int* res, unsigned char* resType, unsigned char* types, int* args)\
|
||||
// {\
|
||||
// return simple_float_func(&m_#name, res, resType, types, args);\
|
||||
// }\
|
||||
// })
|
||||
//
|
||||
//
|
||||
// SIMPLE_FUNC_BINDING(sqrt)
|
||||
//
|
||||
// SIMPLE_FUNC_BINDING(exp)
|
||||
// SIMPLE_FUNC_BINDING(ln)
|
||||
// SIMPLE_FUNC_BINDING(cos)
|
||||
// SIMPLE_FUNC_BINDING(sin)
|
||||
// SIMPLE_FUNC_BINDING(tan)
|
||||
|
||||
int sqrt_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
return simple_float_func(&m_sqrt, res, resType, types, args);
|
||||
}
|
||||
|
||||
int exp_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
return simple_float_func(&m_exp, res, resType, types, args);
|
||||
}
|
||||
|
||||
int cos_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
return simple_float_func(&m_cos, res, resType, types, args);
|
||||
}
|
||||
|
||||
int sin_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
return simple_float_func(&m_sin, res, resType, types, args);
|
||||
}
|
||||
|
||||
int tan_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
return simple_float_func(&m_tan, res, resType, types, args);
|
||||
}
|
||||
|
||||
int ln_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
return simple_float_func(&m_ln, res, resType, types, args);
|
||||
}
|
||||
|
||||
int log_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
float x = 0;
|
||||
if (types[0] == TYPE_INT) {
|
||||
x = (float) args[0];
|
||||
}
|
||||
if (types[0] == TYPE_FLOAT) {
|
||||
x = get_float_from_int_rep(args[0]);
|
||||
}
|
||||
*res = get_int_rep_from_float(m_log(10, x));
|
||||
*resType = TYPE_FLOAT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int max_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
short maxIndex = 0;
|
||||
|
||||
|
@ -70,7 +131,7 @@ int max_implementation(int* res, unsigned char* resType, unsigned char* types, i
|
|||
return 0;
|
||||
}
|
||||
|
||||
int get_pi_implementation(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
int get_pi_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
float val = CST_PI;
|
||||
*res = *(int *)(&val);
|
||||
|
@ -78,6 +139,39 @@ int get_pi_implementation(int* res, unsigned char* resType, unsigned char* types
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
random_int(a, b)
|
||||
Return a random int between a and b (a and b included)
|
||||
*/
|
||||
int random_int_impl(int* res, unsigned char* resType, unsigned char* types, int* args)
|
||||
{
|
||||
srand(time(NULL));
|
||||
|
||||
int lower = 1;
|
||||
int upper = 10;
|
||||
if (types[0] == TYPE_FLOAT) {
|
||||
lower = (int) get_float_from_int_rep(args[0]);
|
||||
}
|
||||
if (types[1] == TYPE_FLOAT) {
|
||||
upper = (int) get_float_from_int_rep(args[1]);
|
||||
}
|
||||
if (types[0] == TYPE_INT) {
|
||||
lower = args[0];
|
||||
}
|
||||
if (types[1] == TYPE_INT) {
|
||||
upper = args[1];
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
// rand returns a value between 0 and RAND_MAX (which is close to infinite)
|
||||
int num = (rand() % (upper - lower + 1)) + lower;
|
||||
*resType = TYPE_INT;
|
||||
*res = num;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct FuncIntro {
|
||||
char name[20];
|
||||
int (*implementation)(int*, unsigned char*, unsigned char*, int*);
|
||||
|
@ -87,10 +181,21 @@ struct FuncIntro {
|
|||
// void* are actually long!
|
||||
|
||||
struct FuncIntro intros[] = {
|
||||
{"abs", &abs_implementation, 1},
|
||||
{"sqrt", &sqrt_implementation, 1},
|
||||
{"max", &max_implementation, 2},
|
||||
{"get_pi", &get_pi_implementation, 0},
|
||||
{"abs", &abs_impl, 1},
|
||||
|
||||
{"sqrt", &sqrt_impl, 1},
|
||||
{"exp", &exp_impl, 1},
|
||||
|
||||
{"sin", &sin_impl, 1},
|
||||
{"cos", &cos_impl, 1},
|
||||
{"tan", &tan_impl, 1},
|
||||
{"ln", &ln_impl, 1},
|
||||
{"log", &log_impl, 1},
|
||||
|
||||
{"random_int", &random_int_impl, 2},
|
||||
|
||||
{"max", &max_impl, 2},
|
||||
{"get_pi", &get_pi_impl, 0},
|
||||
{"", 0, 0}
|
||||
};
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ int operate(
|
|||
} else if (operator == '/') {
|
||||
res = a/b;
|
||||
} else if (operator == '^') {
|
||||
res = 0;
|
||||
res = m_float_pow(a, b);
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
|
|
18
src/utils.c
18
src/utils.c
|
@ -97,7 +97,8 @@ int m_factorial(int x)
|
|||
|
||||
float m_exp(float x)
|
||||
{
|
||||
const int n = 10;
|
||||
// TODO: reduce the x to be more accurate in the exp computation
|
||||
const int n = 13;
|
||||
float out = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
out += m_float_pow(x, i)/m_factorial(i);
|
||||
|
@ -163,7 +164,7 @@ float m_sin(float originalX)
|
|||
|
||||
float m_cos(float x)
|
||||
{
|
||||
return m_sin(x+2*CST_PI);
|
||||
return m_sin(x+CST_PI/2);
|
||||
}
|
||||
|
||||
float m_tan(float x)
|
||||
|
@ -236,6 +237,19 @@ float m_ln(float x)
|
|||
return res;
|
||||
}
|
||||
|
||||
float m_log(float base, float x)
|
||||
{
|
||||
// b^x = y
|
||||
// log_b(b^x) = log_b(y)
|
||||
// x = log_b(y)
|
||||
|
||||
// exp(x ln(b)) = y
|
||||
// x ln(b) = ln(y)
|
||||
// x = ln(y)/ln(b)
|
||||
|
||||
return m_ln(x)/m_ln(base);
|
||||
}
|
||||
|
||||
int is_full_of_space(char* str)
|
||||
{
|
||||
int i = 0;
|
||||
|
|
|
@ -57,4 +57,16 @@ void test_evaluation()
|
|||
evaluate("(abs((0-1)*2)) + abs(2)", &resVal, &resType);
|
||||
assert(resType == TYPE_INT);
|
||||
assert(4 == resVal);
|
||||
}
|
||||
|
||||
evaluate("exp(2)-1", &resVal, &resType);
|
||||
assert(resType == TYPE_FLOAT);
|
||||
assert(float_almost_equal(6.389, get_float_from_int_rep(resVal)));
|
||||
|
||||
evaluate("(cos(2)^2)+(sin(2)^2)", &resVal, &resType);
|
||||
assert(resType == TYPE_FLOAT);
|
||||
assert(float_almost_equal(1, get_float_from_int_rep(resVal)));
|
||||
|
||||
evaluate("random_int(1, 100)", &resVal, &resType);
|
||||
assert(resType == TYPE_INT);
|
||||
printf(" - random int: %d \n", resVal);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue