Compare commits

..

5 Commits

Author SHA1 Message Date
d83106358f Math implementation 2023-12-26 13:36:04 +06:00
43d38645a5 fixed bugs 2023-12-26 00:28:46 +06:00
7dab069aa6 chmod 2023-12-25 21:37:57 +06:00
02a552767b renamed functions, added ctg and actg 2023-12-25 21:33:12 +06:00
e30cfc6cf4 scientific notation lexing 2023-12-25 21:11:13 +06:00
8 changed files with 146 additions and 24 deletions

9
build_c.sh Normal file → Executable file
View File

@@ -17,12 +17,17 @@ LINKER_ARGS="$(pkg-config --libs glib-2.0) -lm"
rm -rf out bin rm -rf out bin
mkdir out bin mkdir out bin
args="-l c -D C -o "$OUT_FILE" $SRC_FILES"
echo "------------[fut]------------" echo "------------[fut]------------"
args="-l c -D C -o "$OUT_FILE" $SRC_FILES"
if [[ $1 == '--implement-math-functions' || $2 == '--implement-math-functions' ]]; then
args="$args -D IMPLEMENT_MATH_FUNCTIONS"
fi
echo fut $args echo fut $args
fut $args fut $args
if [[ $1 != '--translate-only' ]]; then if [[ $1 != '--translate-only' && $2 != '--translate-only' ]]; then
echo "------------[gcc]------------" echo "------------[gcc]------------"
args="$WARNINGS $COMPILER_ARGS "$OUT_FILE" -o "$BIN_FILE" $INCLUDES $LINKER_ARGS" args="$WARNINGS $COMPILER_ARGS "$OUT_FILE" -o "$BIN_FILE" $INCLUDES $LINKER_ARGS"
echo gcc $args echo gcc $args

7
build_cs.sh Normal file → Executable file
View File

@@ -12,12 +12,17 @@ done
for src_file in $SRC_FILES; do for src_file in $SRC_FILES; do
echo "---------[$src_file]---------" echo "---------[$src_file]---------"
out_file="out/$(basename $src_file .fu).cs" out_file="out/$(basename $src_file .fu).cs"
args="-l cs -D CS -n FusionCalculator $INCLUDES -o $out_file $src_file" args="-l cs -D CS -n FusionCalculator $INCLUDES -o $out_file $src_file"
if [[ $1 == '--implement-math-functions' || $2 == '--implement-math-functions' ]]; then
args="$args -D IMPLEMENT_MATH_FUNCTIONS"
fi
echo fut $args echo fut $args
fut $args fut $args
done done
if [[ $1 != '--translate-only' ]]; then if [[ $1 != '--translate-only' && $2 != '--translate-only' ]]; then
echo "---------[FusionCalculator.csproj]---------" echo "---------[FusionCalculator.csproj]---------"
args="build -c Release FusionCalculator.exe.csproj -o bin" args="build -c Release FusionCalculator.exe.csproj -o bin"
echo dotnet $args echo dotnet $args

View File

@@ -11,13 +11,43 @@ abstract class FunctionCallExpression : IExpression {
} }
class FunctionCallExpressionSin : FunctionCallExpression { class FunctionCallExpressionSin : FunctionCallExpression {
internal override double FunctionImplementation(double x) => Math.Sin(x); internal override double FunctionImplementation(double x) {
#if IMPLEMENT_MATH_FUNCTIONS
return MyMath.Sin(x);
#else
return Math.Sin(x);
#endif
} }
}
class FunctionCallExpressionCos : FunctionCallExpression { class FunctionCallExpressionCos : FunctionCallExpression {
internal override double FunctionImplementation(double x) => Math.Cos(x); internal override double FunctionImplementation(double x) {
#if IMPLEMENT_MATH_FUNCTIONS
return MyMath.Cos(x);
#else
return Math.Cos(x);
#endif
}
}
class FunctionCallExpressionTg : FunctionCallExpression {
internal override double FunctionImplementation(double x){
#if IMPLEMENT_MATH_FUNCTIONS
return MyMath.Tg(x);
#else
return Math.Tan(x);
#endif
}
}
class FunctionCallExpressionCtg : FunctionCallExpression {
internal override double FunctionImplementation(double x) {
#if IMPLEMENT_MATH_FUNCTIONS
return MyMath.Ctg(x);
#else
return 1 / Math.Tan(x);
#endif
} }
class FunctionCallExpressionTan : FunctionCallExpression {
internal override double FunctionImplementation(double x) => Math.Tan(x);
} }
class FunctionCallExpressionAsin : FunctionCallExpression { class FunctionCallExpressionAsin : FunctionCallExpression {
@@ -26,10 +56,13 @@ class FunctionCallExpressionAsin : FunctionCallExpression {
class FunctionCallExpressionAcos : FunctionCallExpression { class FunctionCallExpressionAcos : FunctionCallExpression {
internal override double FunctionImplementation(double x) => Math.Acos(x); internal override double FunctionImplementation(double x) => Math.Acos(x);
} }
class FunctionCallExpressionAtan : FunctionCallExpression { class FunctionCallExpressionAtg : FunctionCallExpression {
internal override double FunctionImplementation(double x) => Math.Atan(x); internal override double FunctionImplementation(double x) => Math.Atan(x);
} }
class FunctionCallExpressionActg : FunctionCallExpression {
internal override double FunctionImplementation(double x) => Math.Atan(1 / x);
}
class FunctionCallExpressionLog : FunctionCallExpression{ class FunctionCallExpressionLn : FunctionCallExpression{
internal override double FunctionImplementation(double x) => Math.Log(x); internal override double FunctionImplementation(double x) => Math.Log(x);
} }

50
src/Expressions/MyMath.fu Normal file
View File

@@ -0,0 +1,50 @@
//
// My implementation of math functions using Taylor (Maclaurin) series
// https://en.wikipedia.org/wiki/Taylor_series#List_of_Maclaurin_series_of_some_common_functions
//
public class MyMath {
/// TODO: fix fail on tg(pi/2), tg(pi*), ctg(pi*2)
static double ClampRadians(double x){
int quotient = 0;
double pi2 = 2*Math.PI;
native {
quotient = (int)(x / pi2);
}
x -= pi2 * quotient;
return x;
}
public static double Sin(double x){
x = ClampRadians(x);
int iters = 16;
double pow = x;
double fact = 1;
double result = x;
for(int i = 3; i <= (2*iters+1); i+=2){
pow *= x*x; // x power +2
fact *= i * (i-1); // making i! from (i-2)!
fact *= -1; // change sign every iteration
result += pow/fact;
}
return result;
}
public static double Cos(double x){
x = ClampRadians(x);
int iters = 16;
double pow = 1;
double fact = 1;
double result = 1;
for(int i = 2; i <= (2*iters); i+=2){
pow *= x*x; // x power +2
fact *= i * (i-1); // making i! from (i-2)!
fact *= -1; // change sign every iteration
result += pow/fact;
}
return result;
}
public static double Tg(double x) => Sin(x)/Cos(x);
public static double Ctg(double x) => Cos(x)/Sin(x);
}

View File

@@ -29,17 +29,26 @@ class OperatorExpressionDiv : OperatorExpression {
} }
class OperatorExpressionMod : OperatorExpression { class OperatorExpressionMod : OperatorExpression {
// returns if b>0 then returns a%b else returns a
internal override double OperatorImplementation(double a, double b) { internal override double OperatorImplementation(double a, double b) {
if(b <= 0) if(a == 0)
return b;
if(b == 0)
return a; return a;
if(a > 0){ if(a > 0){
while(a >= b) if(b > 0)
while(a-b >= 0)
a -= b; a -= b;
else
while(a+b >= 0)
a += b;
} }
else { else {
while(a <= b) if(b > 0)
while(a+b <= 0)
a += b; a += b;
else
while(a-b <= 0)
a -= b;
} }
return a; return a;
} }

View File

@@ -48,10 +48,19 @@ class Lexer {
case '/': AddStaticToken(TokDiv); break; case '/': AddStaticToken(TokDiv); break;
case '+': AddStaticToken(TokAdd); break; case '+': AddStaticToken(TokAdd); break;
case '-': case '-':
if(i != 0 && ExprStr[i-1] != '(') // if '-' is not the first char and previous char isn't '(' or 'e' or 'E'
if(i != 0 && ExprStr[i-1] != '('
&& ExprStr[i-1] != 'e' && ExprStr[i-1] != 'E')
AddStaticToken(TokSub); AddStaticToken(TokSub);
// else '-' is a part of numeric expression // else '-' is a part of numeric expression
break; break;
case 'e':
case 'E':
// if token starts with 'E' it is a literal
if(i == tokBegin)
tokType = Token.Type_Literal;
// else 'E' is a part of literal or number (sientific notation)
break;
// try end token and skip current char // try end token and skip current char
case ' ': case '\t': case '\n': case '\r': case ' ': case '\t': case '\n': case '\r':
TryEndToken(); TryEndToken();

View File

@@ -2,14 +2,15 @@ public static class MainClass {
public static void Main(string[] args){ public static void Main(string[] args){
#if CS #if CS
native { native {
System.Globalization.CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture; System.Globalization.CultureInfo.DefaultThreadCurrentCulture =
System.Globalization.CultureInfo.InvariantCulture;
} }
#endif #endif
string() joined = ""; string() joined = "";
foreach(string arg in args){ foreach(string arg in args){
joined += arg + " "; joined += arg + " ";
} }
double rezult = Calculator.Calculate(joined); double result = Calculator.Calculate(joined);
Console.WriteLine(rezult); Console.WriteLine(result);
} }
} }

View File

@@ -119,7 +119,11 @@ class Parser {
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionCos()); PushFunctionExpression(expressionStack, str, new FunctionCallExpressionCos());
break; break;
case "tan": case "tan":
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionTan()); case "tg":
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionTg());
break;
case "ctg":
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionCtg());
break; break;
case "asin": case "asin":
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAsin()); PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAsin());
@@ -128,10 +132,16 @@ class Parser {
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAcos()); PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAcos());
break; break;
case "atan": case "atan":
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAtan()); case "atg":
case "arctg":
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAtg());
break; break;
case "log": case "actg":
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionLog()); case "arcctg":
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionActg());
break;
case "ln":
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionLn());
break; break;
default: { default: {
ThrowError($"invalid literal '{str}'"); ThrowError($"invalid literal '{str}'");