c# build script

This commit is contained in:
Timerix22 2023-12-22 21:36:43 +06:00
parent 5a4b2ce3f6
commit eed8d26712
10 changed files with 73 additions and 30 deletions

10
FusionCalculator.csproj Normal file
View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RollForward>LatestMajor</RollForward>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
</Project>

21
build_cs.sh Normal file
View File

@ -0,0 +1,21 @@
#!/bin/bash
set -eo pipefail
rm -rf out bin
mkdir out
SRC_FILES="$(find src/ -name '*.fu')"
INCLUDES=""
for src_file in $SRC_FILES; do
INCLUDES="$INCLUDES -r $src_file"
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"
echo "fu $args"
fut $args
done
echo "---------[FusionCalculator.csproj]---------"
dotnet build FusionCalculator.csproj -o bin

View File

@ -11,11 +11,11 @@ public static class Calculator
public static double Calculate(string exprStr) public static double Calculate(string exprStr)
{ {
Lexer() lexer = { ExprStr = exprStr}; Lexer() lexer;
List<Token()> tokens = lexer.Lex(); List<Token()> tokens = lexer.Lex(exprStr);
// lexer.PrintTokens(); // lexer.PrintTokens();
Parser() parser = { TokenStorage = tokens }; Parser() parser;
IExpression expr = parser.Parse(); IExpression expr = parser.Parse(tokens);
// parser.PrintGraphVizCode(); // parser.PrintGraphVizCode();
return expr.Calculate(); return expr.Calculate();
} }

View File

@ -1,5 +1,12 @@
class NumericExpression : IExpression class NumericExpression : IExpression
{ {
double N; double N;
internal void Init!(double n){
N = n;
}
internal NumericExpression(){ N=Math.NaN; }
internal override double Calculate() => N; internal override double Calculate() => N;
} }

View File

@ -30,14 +30,15 @@ class Lexer
internal void PrintTokens(){ internal void PrintTokens(){
for(int i = 0; i < TokenStorage.Count; i++){ for(int i = 0; i < TokenStorage.Count; i++){
Token() tok = TokenStorage[i]; Token() tok = TokenStorage[i];
int tokType = tok.GetType(); int tokType = tok.GetTokType();
string() tokStr = tok.GetStr(); string() tokStr = tok.GetStr();
Console.WriteLine($"'{tokStr}' {tokType:D1}"); Console.WriteLine($"'{tokStr}' {tokType:D1}");
} }
} }
internal List<Token()> Lex!() internal List<Token()> Lex!(string exprStr){
{ ExprStr = exprStr;
while (i < ExprStr.Length) while (i < ExprStr.Length)
{ {
switch (ExprStr[i]) switch (ExprStr[i])

View File

@ -6,11 +6,14 @@ class Parser
Token() TokZero; Token() TokZero;
internal Parser(){ internal Parser(){
RootExpression = new NumericExpression { N = Math.NaN }; NumericExpression# nan = new NumericExpression();
nan.Init(Math.NaN);
RootExpression = nan;
TokZero = Token.Create("0", 0, 1, Token.Type_Number); TokZero = Token.Create("0", 0, 1, Token.Type_Number);
} }
internal IExpression# Parse!(){ internal IExpression# Parse!(List<Token()> tokens){
TokenStorage = tokens;
SortTokensInRPN(); SortTokensInRPN();
BuildExpressionTree(); BuildExpressionTree();
return RootExpression; return RootExpression;
@ -29,7 +32,7 @@ class Parser
for(int i = 0; i < TokenStorage.Count; i++){ for(int i = 0; i < TokenStorage.Count; i++){
Token tok = TokenStorage[i]; Token tok = TokenStorage[i];
int type = tok.GetType(); int type = tok.GetTokType();
switch(type){ switch(type){
case Token.Type_Number: case Token.Type_Number:
@ -43,7 +46,7 @@ class Parser
case Token.Type_OperatorSub: case Token.Type_OperatorSub:
if(type == Token.Type_OperatorSub && prevTokType == Token.Type_BracketOpen) if(type == Token.Type_OperatorSub && prevTokType == Token.Type_BracketOpen)
TokensInRPN.AddToEnd(TokZero); TokensInRPN.AddToEnd(TokZero);
while(RPNStack.Count != 0 && RPNStack.Peek().GetType() >= type){ while(RPNStack.Count != 0 && RPNStack.Peek().GetTokType() >= type){
Token op2 = RPNStack.Pop(); Token op2 = RPNStack.Pop();
TokensInRPN.AddToEnd(op2); TokensInRPN.AddToEnd(op2);
} }
@ -55,16 +58,16 @@ class Parser
case Token.Type_BracketClose: case Token.Type_BracketClose:
while(RPNStack.Count != 0){ while(RPNStack.Count != 0){
Token op2 = RPNStack.Pop(); Token op2 = RPNStack.Pop();
if(op2.GetType() == Token.Type_BracketOpen) if(op2.GetTokType() == Token.Type_BracketOpen)
break; break;
TokensInRPN.AddToEnd(op2); TokensInRPN.AddToEnd(op2);
} }
break; break;
case Token.Type_Literal: case Token.Type_Literal:
ThrowError("not implemented"); ThrowError($"token '{tok.GetStr()}' isn't implemented");
break; break;
default: default:
ThrowError("unexpected token type"); ThrowError($"unexpected token type '{type}'");
break; break;
} }
@ -85,11 +88,13 @@ class Parser
TokenLinkedListNode? tokenNode = TokensInRPN.GetFirstNode(); TokenLinkedListNode? tokenNode = TokensInRPN.GetFirstNode();
while(tokenNode != null){ while(tokenNode != null){
Token tok = tokenNode.GetValue(); Token tok = tokenNode.GetValue();
int type = tok.GetType(); int type = tok.GetTokType();
switch(type){ switch(type){
case Token.Type_Number: case Token.Type_Number:
expressionStack.Push(new NumericExpression { N = StringToDouble(tok.GetStr()) }); NumericExpression# num = new NumericExpression();
num.Init(StringToDouble(tok.GetStr()));
expressionStack.Push(num);
break; break;
case Token.Type_OperatorPow: case Token.Type_OperatorPow:
PushOperatorExpression(expressionStack, tok, new OperatorExpressionPow()); PushOperatorExpression(expressionStack, tok, new OperatorExpressionPow());
@ -110,16 +115,16 @@ class Parser
PushOperatorExpression(expressionStack, tok, new OperatorExpressionSub()); PushOperatorExpression(expressionStack, tok, new OperatorExpressionSub());
break; break;
case Token.Type_BracketClose: case Token.Type_BracketClose:
ThrowError("unexpected ("); ThrowError("unexpected '('");
break; break;
case Token.Type_BracketOpen: case Token.Type_BracketOpen:
ThrowError("unexpected )"); ThrowError("unexpected ')'");
break; break;
case Token.Type_Literal: case Token.Type_Literal:
ThrowError("not implemented"); ThrowError($"token '{tok.GetStr()}' isn't implemented");
break; break;
default: default:
ThrowError($"unexpected token type: {type}"); ThrowError($"unexpected token type '{type}'");
break; break;
} }
@ -151,7 +156,7 @@ class Parser
void PushOperatorExpression(Stack<IExpression#>! expressionStack, Token tok, OperatorExpression# opExpr) { void PushOperatorExpression(Stack<IExpression#>! expressionStack, Token tok, OperatorExpression# opExpr) {
if(expressionStack.Count < 2){ if(expressionStack.Count < 2){
ThrowError($"unexpected operator: {tok.GetStr()}"); ThrowError($"unexpected operator '{tok.GetStr()}'");
return; return;
} }
IExpression b = expressionStack.Pop(); IExpression b = expressionStack.Pop();

View File

@ -29,5 +29,5 @@ class Token
} }
internal string() GetStr() => Str.Substring(StartIndex, Length); internal string() GetStr() => Str.Substring(StartIndex, Length);
internal int GetType() => Type; internal int GetTokType() => Type;
} }

View File

@ -35,12 +35,11 @@ class TokenLinkedList {
} }
internal TokenLinkedListNode# CreateOrphanedNode!(Token tok) { internal TokenLinkedListNode# CreateOrphanedNode!(Token tok) {
TokenLinkedListNode# sharedPtr = new TokenLinkedListNode { TokenLinkedListNode# node = new TokenLinkedListNode();
Value = tok, node.SetValue(tok);
Prev = null, node.SetPrev(null);
Next = null node.SetNext(null);
}; return node;
return sharedPtr;
} }
// Can be used by GraphViz to create node graph. // Can be used by GraphViz to create node graph.

View File

@ -7,10 +7,10 @@ class TokenLinkedListNode {
internal void SetValue!(Token value) { Value = value; } internal void SetValue!(Token value) { Value = value; }
internal TokenLinkedListNode!? GetPrev() => Prev; internal TokenLinkedListNode!? GetPrev() => Prev;
internal void SetPrev!(TokenLinkedListNode! prev) { Prev = prev; } internal void SetPrev!(TokenLinkedListNode!? prev) { Prev = prev; }
internal TokenLinkedListNode!? GetNext() => Next; internal TokenLinkedListNode!? GetNext() => Next;
internal void SetNext!(TokenLinkedListNode! next) { Next = next; } internal void SetNext!(TokenLinkedListNode!? next) { Next = next; }
internal void InsertAfter!(TokenLinkedListNode! prev){ internal void InsertAfter!(TokenLinkedListNode! prev){
Next = prev.GetNext(); Next = prev.GetNext();