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:
|
ToDo List:
|
||||||
|
|
||||||
- [ ] pow operator
|
- [X] pow operator
|
||||||
- [ ] binary operators
|
- [ ] binary operators
|
||||||
- [ ] implement basic math functions
|
- [X] implement basic math functions
|
||||||
- [ ] implement random_int(min, max)
|
- [X] implement random_int(min, max)
|
||||||
- [ ] implement print_number(message)
|
- [ ] implement print_number(message)
|
||||||
- [ ] implement input_number()
|
- [ ] implement input_number()
|
||||||
- [ ] base of the CLI
|
- [ ] base of the CLI
|
||||||
|
|
127
src/funcs.c
127
src/funcs.c
|
@ -1,10 +1,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "./types.h"
|
#include "./types.h"
|
||||||
#include "./utils.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) {
|
if (types[0] == TYPE_INT) {
|
||||||
*res = args[0];
|
*res = args[0];
|
||||||
|
@ -26,23 +27,83 @@ int abs_implementation(int* res, unsigned char* resType, unsigned char* types, i
|
||||||
return 1;
|
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;
|
float x = 0;
|
||||||
if (types[0] == TYPE_INT) {
|
if (types[0] == TYPE_INT) {
|
||||||
// convert to float
|
|
||||||
x = (float) args[0];
|
x = (float) args[0];
|
||||||
}
|
}
|
||||||
if (types[0] == TYPE_FLOAT) {
|
if (types[0] == TYPE_FLOAT) {
|
||||||
x = get_float_from_int_rep(args[0]);
|
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;
|
*resType = TYPE_FLOAT;
|
||||||
|
|
||||||
return 0;
|
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;
|
short maxIndex = 0;
|
||||||
|
|
||||||
|
@ -70,7 +131,7 @@ int max_implementation(int* res, unsigned char* resType, unsigned char* types, i
|
||||||
return 0;
|
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;
|
float val = CST_PI;
|
||||||
*res = *(int *)(&val);
|
*res = *(int *)(&val);
|
||||||
|
@ -78,6 +139,39 @@ int get_pi_implementation(int* res, unsigned char* resType, unsigned char* types
|
||||||
return 0;
|
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 {
|
struct FuncIntro {
|
||||||
char name[20];
|
char name[20];
|
||||||
int (*implementation)(int*, unsigned char*, unsigned char*, int*);
|
int (*implementation)(int*, unsigned char*, unsigned char*, int*);
|
||||||
|
@ -87,10 +181,21 @@ struct FuncIntro {
|
||||||
// void* are actually long!
|
// void* are actually long!
|
||||||
|
|
||||||
struct FuncIntro intros[] = {
|
struct FuncIntro intros[] = {
|
||||||
{"abs", &abs_implementation, 1},
|
{"abs", &abs_impl, 1},
|
||||||
{"sqrt", &sqrt_implementation, 1},
|
|
||||||
{"max", &max_implementation, 2},
|
{"sqrt", &sqrt_impl, 1},
|
||||||
{"get_pi", &get_pi_implementation, 0},
|
{"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}
|
{"", 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ int operate(
|
||||||
} else if (operator == '/') {
|
} else if (operator == '/') {
|
||||||
res = a/b;
|
res = a/b;
|
||||||
} else if (operator == '^') {
|
} else if (operator == '^') {
|
||||||
res = 0;
|
res = m_float_pow(a, b);
|
||||||
} else {
|
} else {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
18
src/utils.c
18
src/utils.c
|
@ -97,7 +97,8 @@ int m_factorial(int x)
|
||||||
|
|
||||||
float m_exp(float 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;
|
float out = 0;
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
out += m_float_pow(x, i)/m_factorial(i);
|
out += m_float_pow(x, i)/m_factorial(i);
|
||||||
|
@ -163,7 +164,7 @@ float m_sin(float originalX)
|
||||||
|
|
||||||
float m_cos(float x)
|
float m_cos(float x)
|
||||||
{
|
{
|
||||||
return m_sin(x+2*CST_PI);
|
return m_sin(x+CST_PI/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
float m_tan(float x)
|
float m_tan(float x)
|
||||||
|
@ -236,6 +237,19 @@ float m_ln(float x)
|
||||||
return res;
|
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 is_full_of_space(char* str)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
|
@ -57,4 +57,16 @@ void test_evaluation()
|
||||||
evaluate("(abs((0-1)*2)) + abs(2)", &resVal, &resType);
|
evaluate("(abs((0-1)*2)) + abs(2)", &resVal, &resType);
|
||||||
assert(resType == TYPE_INT);
|
assert(resType == TYPE_INT);
|
||||||
assert(4 == resVal);
|
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