Compare commits
5 Commits
2a4f92fe35
...
d83106358f
| Author | SHA1 | Date | |
|---|---|---|---|
| d83106358f | |||
| 43d38645a5 | |||
| 7dab069aa6 | |||
| 02a552767b | |||
| e30cfc6cf4 |
9
build_c.sh
Normal file → Executable file
9
build_c.sh
Normal file → Executable file
@@ -17,12 +17,17 @@ LINKER_ARGS="$(pkg-config --libs glib-2.0) -lm"
|
||||
rm -rf out bin
|
||||
mkdir out bin
|
||||
|
||||
args="-l c -D C -o "$OUT_FILE" $SRC_FILES"
|
||||
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
|
||||
fut $args
|
||||
|
||||
if [[ $1 != '--translate-only' ]]; then
|
||||
if [[ $1 != '--translate-only' && $2 != '--translate-only' ]]; then
|
||||
echo "------------[gcc]------------"
|
||||
args="$WARNINGS $COMPILER_ARGS "$OUT_FILE" -o "$BIN_FILE" $INCLUDES $LINKER_ARGS"
|
||||
echo gcc $args
|
||||
|
||||
7
build_cs.sh
Normal file → Executable file
7
build_cs.sh
Normal file → Executable file
@@ -12,12 +12,17 @@ done
|
||||
for src_file in $SRC_FILES; do
|
||||
echo "---------[$src_file]---------"
|
||||
out_file="out/$(basename $src_file .fu).cs"
|
||||
|
||||
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
|
||||
fut $args
|
||||
done
|
||||
|
||||
if [[ $1 != '--translate-only' ]]; then
|
||||
if [[ $1 != '--translate-only' && $2 != '--translate-only' ]]; then
|
||||
echo "---------[FusionCalculator.csproj]---------"
|
||||
args="build -c Release FusionCalculator.exe.csproj -o bin"
|
||||
echo dotnet $args
|
||||
|
||||
@@ -11,13 +11,43 @@ abstract class FunctionCallExpression : IExpression {
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
@@ -26,10 +56,13 @@ class FunctionCallExpressionAsin : FunctionCallExpression {
|
||||
class FunctionCallExpressionAcos : FunctionCallExpression {
|
||||
internal override double FunctionImplementation(double x) => Math.Acos(x);
|
||||
}
|
||||
class FunctionCallExpressionAtan : FunctionCallExpression {
|
||||
class FunctionCallExpressionAtg : FunctionCallExpression {
|
||||
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);
|
||||
}
|
||||
|
||||
50
src/Expressions/MyMath.fu
Normal file
50
src/Expressions/MyMath.fu
Normal 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);
|
||||
}
|
||||
@@ -29,17 +29,26 @@ class OperatorExpressionDiv : OperatorExpression {
|
||||
}
|
||||
|
||||
class OperatorExpressionMod : OperatorExpression {
|
||||
// returns if b>0 then returns a%b else returns a
|
||||
internal override double OperatorImplementation(double a, double b) {
|
||||
if(b <= 0)
|
||||
if(a == 0)
|
||||
return b;
|
||||
if(b == 0)
|
||||
return a;
|
||||
if(a > 0){
|
||||
while(a >= b)
|
||||
if(b > 0)
|
||||
while(a-b >= 0)
|
||||
a -= b;
|
||||
else
|
||||
while(a+b >= 0)
|
||||
a += b;
|
||||
}
|
||||
else {
|
||||
while(a <= b)
|
||||
if(b > 0)
|
||||
while(a+b <= 0)
|
||||
a += b;
|
||||
else
|
||||
while(a-b <= 0)
|
||||
a -= b;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
11
src/Lexer.fu
11
src/Lexer.fu
@@ -48,10 +48,19 @@ class Lexer {
|
||||
case '/': AddStaticToken(TokDiv); break;
|
||||
case '+': AddStaticToken(TokAdd); break;
|
||||
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);
|
||||
// else '-' is a part of numeric expression
|
||||
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
|
||||
case ' ': case '\t': case '\n': case '\r':
|
||||
TryEndToken();
|
||||
|
||||
@@ -2,14 +2,15 @@ public static class MainClass {
|
||||
public static void Main(string[] args){
|
||||
#if CS
|
||||
native {
|
||||
System.Globalization.CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
|
||||
System.Globalization.CultureInfo.DefaultThreadCurrentCulture =
|
||||
System.Globalization.CultureInfo.InvariantCulture;
|
||||
}
|
||||
#endif
|
||||
string() joined = "";
|
||||
foreach(string arg in args){
|
||||
joined += arg + " ";
|
||||
}
|
||||
double rezult = Calculator.Calculate(joined);
|
||||
Console.WriteLine(rezult);
|
||||
double result = Calculator.Calculate(joined);
|
||||
Console.WriteLine(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,11 @@ class Parser {
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionCos());
|
||||
break;
|
||||
case "tan":
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionTan());
|
||||
case "tg":
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionTg());
|
||||
break;
|
||||
case "ctg":
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionCtg());
|
||||
break;
|
||||
case "asin":
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAsin());
|
||||
@@ -128,10 +132,16 @@ class Parser {
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAcos());
|
||||
break;
|
||||
case "atan":
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAtan());
|
||||
case "atg":
|
||||
case "arctg":
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionAtg());
|
||||
break;
|
||||
case "log":
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionLog());
|
||||
case "actg":
|
||||
case "arcctg":
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionActg());
|
||||
break;
|
||||
case "ln":
|
||||
PushFunctionExpression(expressionStack, str, new FunctionCallExpressionLn());
|
||||
break;
|
||||
default: {
|
||||
ThrowError($"invalid literal '{str}'");
|
||||
|
||||
Reference in New Issue
Block a user