From eed8d26712e01a26828152a7376db1f070de7cac Mon Sep 17 00:00:00 2001 From: Timerix22 Date: Fri, 22 Dec 2023 21:36:43 +0600 Subject: [PATCH] c# build script --- FusionCalculator.csproj | 10 ++++++++ build.sh => build_c.sh | 0 build_cs.sh | 21 ++++++++++++++++ src/Calculator.fu | 8 +++---- src/Expressions/NumericalExpression.fu | 7 ++++++ src/Lexer.fu | 7 +++--- src/Parser.fu | 33 +++++++++++++++----------- src/Token.fu | 2 +- src/TokenLinkedList.fu | 11 ++++----- src/TokenLinkedListNode.fu | 4 ++-- 10 files changed, 73 insertions(+), 30 deletions(-) create mode 100644 FusionCalculator.csproj rename build.sh => build_c.sh (100%) create mode 100644 build_cs.sh diff --git a/FusionCalculator.csproj b/FusionCalculator.csproj new file mode 100644 index 0000000..eddfd19 --- /dev/null +++ b/FusionCalculator.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + LatestMajor + false + + + \ No newline at end of file diff --git a/build.sh b/build_c.sh similarity index 100% rename from build.sh rename to build_c.sh diff --git a/build_cs.sh b/build_cs.sh new file mode 100644 index 0000000..b1bab72 --- /dev/null +++ b/build_cs.sh @@ -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 diff --git a/src/Calculator.fu b/src/Calculator.fu index da81c4d..f7b7b26 100644 --- a/src/Calculator.fu +++ b/src/Calculator.fu @@ -11,11 +11,11 @@ public static class Calculator public static double Calculate(string exprStr) { - Lexer() lexer = { ExprStr = exprStr}; - List tokens = lexer.Lex(); + Lexer() lexer; + List tokens = lexer.Lex(exprStr); // lexer.PrintTokens(); - Parser() parser = { TokenStorage = tokens }; - IExpression expr = parser.Parse(); + Parser() parser; + IExpression expr = parser.Parse(tokens); // parser.PrintGraphVizCode(); return expr.Calculate(); } diff --git a/src/Expressions/NumericalExpression.fu b/src/Expressions/NumericalExpression.fu index 13268b7..1fbab91 100644 --- a/src/Expressions/NumericalExpression.fu +++ b/src/Expressions/NumericalExpression.fu @@ -1,5 +1,12 @@ class NumericExpression : IExpression { double N; + + internal void Init!(double n){ + N = n; + } + + internal NumericExpression(){ N=Math.NaN; } + internal override double Calculate() => N; } diff --git a/src/Lexer.fu b/src/Lexer.fu index cb72d2e..dfc3257 100644 --- a/src/Lexer.fu +++ b/src/Lexer.fu @@ -30,14 +30,15 @@ class Lexer internal void PrintTokens(){ for(int i = 0; i < TokenStorage.Count; i++){ Token() tok = TokenStorage[i]; - int tokType = tok.GetType(); + int tokType = tok.GetTokType(); string() tokStr = tok.GetStr(); Console.WriteLine($"'{tokStr}' {tokType:D1}"); } } - internal List Lex!() - { + internal List Lex!(string exprStr){ + ExprStr = exprStr; + while (i < ExprStr.Length) { switch (ExprStr[i]) diff --git a/src/Parser.fu b/src/Parser.fu index 026dee0..1cb2907 100644 --- a/src/Parser.fu +++ b/src/Parser.fu @@ -6,11 +6,14 @@ class Parser Token() TokZero; 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); } - internal IExpression# Parse!(){ + internal IExpression# Parse!(List tokens){ + TokenStorage = tokens; SortTokensInRPN(); BuildExpressionTree(); return RootExpression; @@ -29,7 +32,7 @@ class Parser for(int i = 0; i < TokenStorage.Count; i++){ Token tok = TokenStorage[i]; - int type = tok.GetType(); + int type = tok.GetTokType(); switch(type){ case Token.Type_Number: @@ -43,7 +46,7 @@ class Parser case Token.Type_OperatorSub: if(type == Token.Type_OperatorSub && prevTokType == Token.Type_BracketOpen) TokensInRPN.AddToEnd(TokZero); - while(RPNStack.Count != 0 && RPNStack.Peek().GetType() >= type){ + while(RPNStack.Count != 0 && RPNStack.Peek().GetTokType() >= type){ Token op2 = RPNStack.Pop(); TokensInRPN.AddToEnd(op2); } @@ -55,16 +58,16 @@ class Parser case Token.Type_BracketClose: while(RPNStack.Count != 0){ Token op2 = RPNStack.Pop(); - if(op2.GetType() == Token.Type_BracketOpen) + if(op2.GetTokType() == Token.Type_BracketOpen) break; TokensInRPN.AddToEnd(op2); } break; case Token.Type_Literal: - ThrowError("not implemented"); + ThrowError($"token '{tok.GetStr()}' isn't implemented"); break; default: - ThrowError("unexpected token type"); + ThrowError($"unexpected token type '{type}'"); break; } @@ -85,11 +88,13 @@ class Parser TokenLinkedListNode? tokenNode = TokensInRPN.GetFirstNode(); while(tokenNode != null){ Token tok = tokenNode.GetValue(); - int type = tok.GetType(); + int type = tok.GetTokType(); switch(type){ 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; case Token.Type_OperatorPow: PushOperatorExpression(expressionStack, tok, new OperatorExpressionPow()); @@ -110,16 +115,16 @@ class Parser PushOperatorExpression(expressionStack, tok, new OperatorExpressionSub()); break; case Token.Type_BracketClose: - ThrowError("unexpected ("); + ThrowError("unexpected '('"); break; case Token.Type_BracketOpen: - ThrowError("unexpected )"); + ThrowError("unexpected ')'"); break; case Token.Type_Literal: - ThrowError("not implemented"); + ThrowError($"token '{tok.GetStr()}' isn't implemented"); break; default: - ThrowError($"unexpected token type: {type}"); + ThrowError($"unexpected token type '{type}'"); break; } @@ -151,7 +156,7 @@ class Parser void PushOperatorExpression(Stack! expressionStack, Token tok, OperatorExpression# opExpr) { if(expressionStack.Count < 2){ - ThrowError($"unexpected operator: {tok.GetStr()}"); + ThrowError($"unexpected operator '{tok.GetStr()}'"); return; } IExpression b = expressionStack.Pop(); diff --git a/src/Token.fu b/src/Token.fu index 8216a09..7db58f3 100644 --- a/src/Token.fu +++ b/src/Token.fu @@ -29,5 +29,5 @@ class Token } internal string() GetStr() => Str.Substring(StartIndex, Length); - internal int GetType() => Type; + internal int GetTokType() => Type; } diff --git a/src/TokenLinkedList.fu b/src/TokenLinkedList.fu index aff255f..f5790e7 100644 --- a/src/TokenLinkedList.fu +++ b/src/TokenLinkedList.fu @@ -35,12 +35,11 @@ class TokenLinkedList { } internal TokenLinkedListNode# CreateOrphanedNode!(Token tok) { - TokenLinkedListNode# sharedPtr = new TokenLinkedListNode { - Value = tok, - Prev = null, - Next = null - }; - return sharedPtr; + TokenLinkedListNode# node = new TokenLinkedListNode(); + node.SetValue(tok); + node.SetPrev(null); + node.SetNext(null); + return node; } // Can be used by GraphViz to create node graph. diff --git a/src/TokenLinkedListNode.fu b/src/TokenLinkedListNode.fu index 359d2b8..e7d2520 100644 --- a/src/TokenLinkedListNode.fu +++ b/src/TokenLinkedListNode.fu @@ -7,10 +7,10 @@ class TokenLinkedListNode { internal void SetValue!(Token value) { Value = value; } internal TokenLinkedListNode!? GetPrev() => Prev; - internal void SetPrev!(TokenLinkedListNode! prev) { Prev = prev; } + internal void SetPrev!(TokenLinkedListNode!? prev) { Prev = prev; } internal TokenLinkedListNode!? GetNext() => Next; - internal void SetNext!(TokenLinkedListNode! next) { Next = next; } + internal void SetNext!(TokenLinkedListNode!? next) { Next = next; } internal void InsertAfter!(TokenLinkedListNode! prev){ Next = prev.GetNext();