fixed memory and visibility problems

This commit is contained in:
Timerix22 2023-12-19 19:08:19 +06:00
parent 84adeb3c97
commit 8a5370c09e
6 changed files with 76 additions and 68 deletions

View File

@ -3,4 +3,4 @@ set -eo pipefail
rm -rf out bin rm -rf out bin
mkdir out bin mkdir out bin
fut -l c -o out/FusionCalculator.c src/*.fu 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)

View File

@ -6,13 +6,19 @@ public static class Calculator
joined += arg; joined += arg;
} }
double rezult = Calculate(joined); double rezult = Calculate(joined);
Console.WriteLine(rezult); // Console.WriteLine(rezult);
} }
public static double Calculate(string exprStr) public static double Calculate(string exprStr)
{ {
Lexer() lexer = { ExprStr = exprStr}; Lexer() lexer = { ExprStr = exprStr};
Token[]# tokens = lexer.Lex(); List<Token()> 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 }; Parser() parser = { Tokens = tokens };
IExpression# expr = parser.Parse(); IExpression# expr = parser.Parse();
return expr.Calculate(); return expr.Calculate();

View File

@ -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; double N;
public override double Calculate() => N; internal override double Calculate() => N;
} }
public abstract class OperatorExpression : IExpression abstract class OperatorExpression : IExpression
{ {
IExpression a; IExpression a;
IExpression b; 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; 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());
} }

View File

@ -1,33 +1,33 @@
public class Lexer class Lexer
{ {
string ExprStr; string ExprStr;
protected List<Token>() tokens; List<Token()>() tokens;
protected TokenType tokType = TokenType.Number; int tokType = Token.Type_Number;
protected int tokBegin = 0; int tokBegin = 0;
protected int i = 0; int i = 0;
protected Token() TokBracketOpen; Token() TokBracketOpen;
protected Token() TokBracketClose; Token() TokBracketClose;
protected Token() TokPow; Token() TokPow;
protected Token() TokMul; Token() TokMul;
protected Token() TokMod; Token() TokMod;
protected Token() TokDiv; Token() TokDiv;
protected Token() TokAdd; Token() TokAdd;
protected Token() TokSub; Token() TokSub;
public Lexer(){ public Lexer(){
TokBracketOpen = Token.Create("(", TokenType.BracketOpen); TokBracketOpen = Token.Create("(", 0, 1, Token.Type_BracketOpen);
TokBracketClose = Token.Create(")", TokenType.BracketClose); TokBracketClose = Token.Create(")", 0, 1, Token.Type_BracketClose);
TokPow = Token.Create("^", TokenType.OperatorPow); TokPow = Token.Create("^", 0, 1, Token.Type_OperatorPow);
TokMul = Token.Create("*", TokenType.OperatorMul); TokMul = Token.Create("*", 0, 1, Token.Type_OperatorMul);
TokMod = Token.Create("%", TokenType.OperatorMod); TokMod = Token.Create("%", 0, 1, Token.Type_OperatorMod);
TokDiv = Token.Create("/", TokenType.OperatorDiv); TokDiv = Token.Create("/", 0, 1, Token.Type_OperatorDiv);
TokAdd = Token.Create("+", TokenType.OperatorAdd); TokAdd = Token.Create("+", 0, 1, Token.Type_OperatorAdd);
TokSub = Token.Create("-", TokenType.OperatorSub); TokSub = Token.Create("-", 0, 1, Token.Type_OperatorSub);
} }
public Token[]# Lex!() internal List<Token()> Lex!()
{ {
while (i < ExprStr.Length) while (i < ExprStr.Length)
{ {
@ -54,7 +54,7 @@ public class Lexer
break; break;
// set type from Numeric to Literal // set type from Numeric to Literal
default: default:
tokType = TokenType.Literal; tokType = Token.Type_Literal;
i++; i++;
break; break;
} }
@ -62,28 +62,27 @@ public class Lexer
// end last token // end last token
TryEndToken(); TryEndToken();
Token[]# tokensArray = new Token[tokens.Count]; return tokens;
tokens.CopyTo(0, tokensArray, 0, tokens.Count);
return tokensArray;
} }
void TryEndToken!() void TryEndToken!()
{ {
if (tokBegin != i) if (tokBegin != i)
{ {
string() tokStr = ExprStr.Substring(tokBegin, i - tokBegin); Token() tok = Token.Create(ExprStr, tokBegin, i - tokBegin, tokType);
Token() tok = { Str=tokStr, Type = tokType }; tokens.Add();
tokens.Add(tok); tokens[tokens.Count-1] = tok;
tokType = TokenType.Number; tokType = Token.Type_Number;
tokBegin = i; tokBegin = i;
} }
} }
void AddStaticToken!(Token tok) void AddStaticToken!(Token() tok)
{ {
TryEndToken(); TryEndToken();
tokens.Add(tok); tokens.Add();
tokType = TokenType.Number; tokens[tokens.Count-1] = tok;
tokType = Token.Type_Number;
tokBegin = ++i; tokBegin = ++i;
} }
} }

View File

@ -1,8 +1,8 @@
public class Parser class Parser
{ {
Token[]# Tokens; List<Token()> Tokens;
public IExpression# Parse(){ internal IExpression# Parse(){
NumericExpression# n = new NumericExpression { N = 1 }; NumericExpression# n = new NumericExpression { N = 1 };
return n; return n;
} }

View File

@ -1,30 +1,33 @@
public enum TokenType class Token
{
BracketOpen=1,
BracketClose=2,
OperatorPow=3,
OperatorMul=4,
OperatorMod=5,
OperatorDiv=6,
OperatorAdd=7,
OperatorSub=8,
Literal=9,
Number=10
}
public class Token
{ {
string Str; 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 = { Token() tok = {
Str = str, Str = str,
StartIndex = startIndex,
Length = length,
Type = type Type = type
}; };
return tok; return tok;
} }
public string GetStr() => Str; internal string() GetStr() => Str.Substring(StartIndex, Length);
public TokenType GetType() => Type; internal int GetType() => Type;
} }