c# build script
This commit is contained in:
parent
5a4b2ce3f6
commit
eed8d26712
10
FusionCalculator.csproj
Normal file
10
FusionCalculator.csproj
Normal 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
21
build_cs.sh
Normal 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
|
||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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])
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user