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();