diff --git a/build.sh b/build.sh index 008c2f2..8316f13 100644 --- a/build.sh +++ b/build.sh @@ -3,4 +3,4 @@ set -eo pipefail rm -rf out bin mkdir out bin fut -l c -o out/FusionCalculator.c src/*.fu -gcc -Wall -O2 out/FusionCalculator.c -o bin/FusionCalculator.exe $(pkg-config --cflags glib-2.0) $(pkg-config --libs glib-2.0) +gcc -Wall -Wno-unused-value -Wno-unused-function -O0 -g out/FusionCalculator.c -o bin/FusionCalculator.exe $(pkg-config --cflags glib-2.0) $(pkg-config --libs glib-2.0) diff --git a/src/Calculator.fu b/src/Calculator.fu index 1ab022b..985ade6 100644 --- a/src/Calculator.fu +++ b/src/Calculator.fu @@ -6,13 +6,19 @@ public static class Calculator joined += arg; } double rezult = Calculate(joined); - Console.WriteLine(rezult); + // Console.WriteLine(rezult); } public static double Calculate(string exprStr) { Lexer() lexer = { ExprStr = exprStr}; - Token[]# tokens = lexer.Lex(); + List tokens = lexer.Lex(); + for(int i = 0; i < tokens.Count; i++){ + Token() tok = tokens[i]; + int tokType = tok.GetType(); + string() tokStr = tok.GetStr(); + Console.WriteLine($"'{tokStr}' {tokType:D1}"); + } Parser() parser = { Tokens = tokens }; IExpression# expr = parser.Parse(); return expr.Calculate(); diff --git a/src/Expressions.fu b/src/Expressions.fu index 90c8811..35401fa 100644 --- a/src/Expressions.fu +++ b/src/Expressions.fu @@ -1,29 +1,29 @@ -public abstract class IExpression +abstract class IExpression { - public abstract double Calculate(); + internal abstract double Calculate(); } -public class NumericExpression : IExpression +class NumericExpression : IExpression { double N; - public override double Calculate() => N; + internal override double Calculate() => N; } -public abstract class OperatorExpression : IExpression +abstract class OperatorExpression : IExpression { IExpression a; IExpression b; - public abstract double OperatorImplementation(double a, double b); + internal abstract double OperatorImplementation(double a, double b); - public double Calculate() => OperatorImplementation(a.Calculate(), b.Calculate()); + internal override double Calculate() => OperatorImplementation(a.Calculate(), b.Calculate()); } -public abstract class FunctionCallExpression : IExpression +abstract class FunctionCallExpression : IExpression { IExpression x; - public abstract double FunctionImplementation(double x); + internal abstract double FunctionImplementation(double x); - public double Calculate() => FunctionImplementation(x.Calculate()); + internal override double Calculate() => FunctionImplementation(x.Calculate()); } diff --git a/src/Lexer.fu b/src/Lexer.fu index 4b1e84f..50be0bf 100644 --- a/src/Lexer.fu +++ b/src/Lexer.fu @@ -1,33 +1,33 @@ -public class Lexer +class Lexer { string ExprStr; - protected List() tokens; - protected TokenType tokType = TokenType.Number; - protected int tokBegin = 0; - protected int i = 0; + List() tokens; + int tokType = Token.Type_Number; + int tokBegin = 0; + int i = 0; - protected Token() TokBracketOpen; - protected Token() TokBracketClose; - protected Token() TokPow; - protected Token() TokMul; - protected Token() TokMod; - protected Token() TokDiv; - protected Token() TokAdd; - protected Token() TokSub; + Token() TokBracketOpen; + Token() TokBracketClose; + Token() TokPow; + Token() TokMul; + Token() TokMod; + Token() TokDiv; + Token() TokAdd; + Token() TokSub; public Lexer(){ - TokBracketOpen = Token.Create("(", TokenType.BracketOpen); - TokBracketClose = Token.Create(")", TokenType.BracketClose); - TokPow = Token.Create("^", TokenType.OperatorPow); - TokMul = Token.Create("*", TokenType.OperatorMul); - TokMod = Token.Create("%", TokenType.OperatorMod); - TokDiv = Token.Create("/", TokenType.OperatorDiv); - TokAdd = Token.Create("+", TokenType.OperatorAdd); - TokSub = Token.Create("-", TokenType.OperatorSub); + TokBracketOpen = Token.Create("(", 0, 1, Token.Type_BracketOpen); + TokBracketClose = Token.Create(")", 0, 1, Token.Type_BracketClose); + TokPow = Token.Create("^", 0, 1, Token.Type_OperatorPow); + TokMul = Token.Create("*", 0, 1, Token.Type_OperatorMul); + TokMod = Token.Create("%", 0, 1, Token.Type_OperatorMod); + TokDiv = Token.Create("/", 0, 1, Token.Type_OperatorDiv); + TokAdd = Token.Create("+", 0, 1, Token.Type_OperatorAdd); + TokSub = Token.Create("-", 0, 1, Token.Type_OperatorSub); } - public Token[]# Lex!() + internal List Lex!() { while (i < ExprStr.Length) { @@ -54,7 +54,7 @@ public class Lexer break; // set type from Numeric to Literal default: - tokType = TokenType.Literal; + tokType = Token.Type_Literal; i++; break; } @@ -62,28 +62,27 @@ public class Lexer // end last token TryEndToken(); - Token[]# tokensArray = new Token[tokens.Count]; - tokens.CopyTo(0, tokensArray, 0, tokens.Count); - return tokensArray; + return tokens; } void TryEndToken!() { if (tokBegin != i) { - string() tokStr = ExprStr.Substring(tokBegin, i - tokBegin); - Token() tok = { Str=tokStr, Type = tokType }; - tokens.Add(tok); - tokType = TokenType.Number; + Token() tok = Token.Create(ExprStr, tokBegin, i - tokBegin, tokType); + tokens.Add(); + tokens[tokens.Count-1] = tok; + tokType = Token.Type_Number; tokBegin = i; } } - void AddStaticToken!(Token tok) + void AddStaticToken!(Token() tok) { TryEndToken(); - tokens.Add(tok); - tokType = TokenType.Number; + tokens.Add(); + tokens[tokens.Count-1] = tok; + tokType = Token.Type_Number; tokBegin = ++i; } } diff --git a/src/Parser.fu b/src/Parser.fu index 9339ea4..b413ea2 100644 --- a/src/Parser.fu +++ b/src/Parser.fu @@ -1,8 +1,8 @@ -public class Parser +class Parser { - Token[]# Tokens; + List Tokens; - public IExpression# Parse(){ + internal IExpression# Parse(){ NumericExpression# n = new NumericExpression { N = 1 }; return n; } diff --git a/src/Token.fu b/src/Token.fu index b819447..7c50ad8 100644 --- a/src/Token.fu +++ b/src/Token.fu @@ -1,30 +1,33 @@ -public enum TokenType -{ - BracketOpen=1, - BracketClose=2, - OperatorPow=3, - OperatorMul=4, - OperatorMod=5, - OperatorDiv=6, - OperatorAdd=7, - OperatorSub=8, - Literal=9, - Number=10 -} - -public class Token +class Token { string Str; - TokenType Type; + int StartIndex; + int Length; + // It is not a enum because there is no way to convert enum value to int in Fusion. + // The Type is also the priority of the token in calculation (see Parser). + int Type; - public static Token() Create(string str, TokenType type){ + public const int Type_BracketOpen=1; + public const int Type_BracketClose=2; + public const int Type_OperatorPow=3; + public const int Type_OperatorMul=4; + public const int Type_OperatorMod=5; + public const int Type_OperatorDiv=6; + public const int Type_OperatorAdd=7; + public const int Type_OperatorSub=8; + public const int Type_Number=9; + public const int Type_Literal=10; + + internal static Token() Create(string str, int startIndex, int length, int type){ Token() tok = { Str = str, + StartIndex = startIndex, + Length = length, Type = type }; return tok; } - public string GetStr() => Str; - public TokenType GetType() => Type; + internal string() GetStr() => Str.Substring(StartIndex, Length); + internal int GetType() => Type; }