ported code from c#

This commit is contained in:
Timerix22 2023-12-19 02:20:25 +06:00
commit 8e4be0b7e1
7 changed files with 195 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
bin/
obj/
out/
*.log

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"files.associations": {
"*.h": "c"
}
}

6
build.sh Normal file
View File

@ -0,0 +1,6 @@
#!/bin/bash
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)

20
src/Calculator.fu Normal file
View File

@ -0,0 +1,20 @@
public static class Calculator
{
public static void Main(string[] args){
string() joined = "";
foreach(string arg in args){
joined += arg;
}
double rezult = Calculate(joined);
Console.WriteLine(rezult);
}
public static double Calculate(string exprStr)
{
Lexer() lexer = { ExprStr = exprStr};
Token[]# tokens = lexer.Lex();
Parser() parser = { Tokens = tokens };
IExpression# expr = parser.Parse();
return expr.Calculate();
}
}

29
src/Expressions.fu Normal file
View File

@ -0,0 +1,29 @@
public abstract class IExpression
{
public abstract double Calculate();
}
public class NumericExpression : IExpression
{
double N;
public override double Calculate() => N;
}
public abstract class OperatorExpression : IExpression
{
IExpression a;
IExpression b;
public abstract double OperatorImplementation(double a, double b);
public double Calculate() => OperatorImplementation(a.Calculate(), b.Calculate());
}
public abstract class FunctionCallExpression : IExpression
{
IExpression x;
public abstract double FunctionImplementation(double x);
public double Calculate() => FunctionImplementation(x.Calculate());
}

122
src/Lexer.fu Normal file
View File

@ -0,0 +1,122 @@
//namespace SharpCalculator.Parsing;
public enum TokenType
{
BracketOpen,
BracketClose,
OperatorPow,
OperatorMul,
OperatorMod,
OperatorDiv,
OperatorAdd,
OperatorSub,
Literal,
Number
}
public class Token
{
string Str;
TokenType Type;
public static Token() Create(string str, TokenType type){
Token() tok = {
Str = str,
Type = type
};
return tok;
}
public string GetStr() => Str;
public TokenType GetType() => Type;
}
public class Lexer
{
string ExprStr;
protected List<Token>() tokens;
protected TokenType tokType = TokenType.Number;
protected int tokBegin = 0;
protected 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;
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);
}
public Token[]# Lex!()
{
while (i < ExprStr.Length)
{
switch (ExprStr[i])
{
// end token, add new predifined token and move next
case '(': AddStaticToken(TokBracketOpen); break;
case ')': AddStaticToken(TokBracketClose); break;
case '^': AddStaticToken(TokPow); break;
case '*': AddStaticToken(TokMul); break;
case '%': AddStaticToken(TokMod); break;
case '/': AddStaticToken(TokDiv); break;
case '+': AddStaticToken(TokAdd); break;
case '-': AddStaticToken(TokSub); break;
// try end token and skip current char
case ' ': case '\t': case '\n': case '\r':
TryEndToken();
i++;
break;
// move next
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
i++;
break;
// set type from Numeric to Literal
default:
tokType = TokenType.Literal;
i++;
break;
}
}
// end last token
TryEndToken();
Token[]# tokensArray = new Token[tokens.Count];
tokens.CopyTo(0, tokensArray, 0, tokens.Count);
return tokensArray;
}
void TryEndToken!()
{
if (tokBegin != i)
{
string() tokStr = ExprStr.Substring(tokBegin, i - tokBegin);
Token() tok = { Str=tokStr, Type = tokType };
tokens.Add(tok);
tokType = TokenType.Number;
tokBegin = i;
}
}
void AddStaticToken!(Token tok)
{
TryEndToken();
tokens.Add(tok);
tokType = TokenType.Number;
tokBegin = ++i;
}
}

9
src/Parser.fu Normal file
View File

@ -0,0 +1,9 @@
public class Parser
{
Token[]# Tokens;
public IExpression# Parse(){
NumericExpression# n = new NumericExpression { N = 1 };
return n;
}
}