Skip to content

Commit 8f5e231

Browse files
committed
SIFOSC、論理演算子を実装。
1 parent 77e9f05 commit 8f5e231

File tree

5 files changed

+162
-15
lines changed

5 files changed

+162
-15
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/****
2+
* FACHPI: Fast Chat Protocol/Interface
3+
* Copyright (C) 2023 Takym.
4+
*
5+
* distributed under the MIT License.
6+
****/
7+
8+
namespace FastChatProtocolInterface.SimpleFormulaScript
9+
{
10+
public sealed record SifoscBoolean : SifoscObject
11+
{
12+
private static readonly SifoscBoolean _true = new();
13+
private static readonly SifoscBoolean _false = new();
14+
15+
public static SifoscBoolean TrueValue => _true;
16+
public static SifoscBoolean FalseValue => _false;
17+
public bool Value => ReferenceEquals(this, _true);
18+
public override string Code => this.Value ? "true" : "false";
19+
20+
private SifoscBoolean() { }
21+
22+
public override SifoscObject? Negate()
23+
=> this.Value ? _false : _true;
24+
25+
public override SifoscObject? And(SifoscObject? other)
26+
{
27+
if (other is SifoscBoolean otherFlg) {
28+
return this.Value && otherFlg.Value ? _true : _false;
29+
}
30+
31+
return null;
32+
}
33+
34+
public override SifoscObject? Or(SifoscObject? other)
35+
{
36+
if (other is SifoscBoolean otherFlg) {
37+
return this.Value || otherFlg.Value ? _true : _false;
38+
}
39+
40+
return null;
41+
}
42+
43+
public override SifoscObject? Xor(SifoscObject? other)
44+
{
45+
if (other is SifoscBoolean otherFlg) {
46+
return this.Value != otherFlg.Value ? _true : _false;
47+
}
48+
49+
return null;
50+
}
51+
}
52+
}

FastChatProtocolInterface/SimpleFormulaScript/SifoscInteger.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public sealed record SifoscInteger : SifoscObject
1818
public override SifoscObject? Minus()
1919
=> this with { Value = -this.Value };
2020

21+
public override SifoscObject? Negate()
22+
=> this with { Value = ~this.Value };
23+
2124
public override SifoscObject? Add(SifoscObject? other)
2225
{
2326
if (other is SifoscInteger otherInt) {
@@ -62,5 +65,32 @@ public sealed record SifoscInteger : SifoscObject
6265

6366
return null;
6467
}
68+
69+
public override SifoscObject? And(SifoscObject? other)
70+
{
71+
if (other is SifoscInteger otherInt) {
72+
return this with { Value = this.Value & otherInt.Value };
73+
}
74+
75+
return null;
76+
}
77+
78+
public override SifoscObject? Or(SifoscObject? other)
79+
{
80+
if (other is SifoscInteger otherInt) {
81+
return this with { Value = this.Value | otherInt.Value };
82+
}
83+
84+
return null;
85+
}
86+
87+
public override SifoscObject? Xor(SifoscObject? other)
88+
{
89+
if (other is SifoscInteger otherInt) {
90+
return this with { Value = this.Value ^ otherInt.Value };
91+
}
92+
93+
return null;
94+
}
6595
}
6696
}

FastChatProtocolInterface/SimpleFormulaScript/SifoscObject.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,15 @@ public static IEnumerable<SifoscObject> EnumerateAllObjects()
5151

5252
public virtual SifoscObject? Plus () => null;
5353
public virtual SifoscObject? Minus () => null;
54+
public virtual SifoscObject? Negate () => null;
5455
public virtual SifoscObject? Add (SifoscObject? other) => null;
5556
public virtual SifoscObject? Subtract(SifoscObject? other) => null;
5657
public virtual SifoscObject? Multiply(SifoscObject? other) => null;
5758
public virtual SifoscObject? Divide (SifoscObject? other) => null;
5859
public virtual SifoscObject? Modulo (SifoscObject? other) => null;
60+
public virtual SifoscObject? And (SifoscObject? other) => null;
61+
public virtual SifoscObject? Or (SifoscObject? other) => null;
62+
public virtual SifoscObject? Xor (SifoscObject? other) => null;
5963
}
6064

6165
public sealed record SifoscNull : SifoscObject
@@ -67,17 +71,4 @@ public sealed record SifoscNull : SifoscObject
6771

6872
private SifoscNull() { }
6973
}
70-
71-
public sealed record SifoscBoolean : SifoscObject
72-
{
73-
private static readonly SifoscBoolean _true = new();
74-
private static readonly SifoscBoolean _false = new();
75-
76-
public static SifoscBoolean TrueValue => _true;
77-
public static SifoscBoolean FalseValue => _false;
78-
public bool Value => ReferenceEquals(this, _true);
79-
public override string Code => this.Value ? "true" : "false";
80-
81-
private SifoscBoolean() { }
82-
}
8374
}

FastChatProtocolInterface/SimpleFormulaScript/SifoscParser.cs

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,53 @@ public static bool TryParseStatement(this SourceCode sc, [NotNullWhen(true)][May
3636

3737
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3838
public static bool TryParseExpression(this SourceCode sc, [NotNullWhen(true)][MaybeNullWhen(false)] out SifoscObject? result)
39-
=> sc.TryParseAddSubExpression(out result);
39+
=> sc.TryParseLogicalExpression(out result);
40+
41+
public static bool TryParseLogicalExpression(this SourceCode sc, [NotNullWhen(true)][MaybeNullWhen(false)] out SifoscObject? result)
42+
{
43+
sc.BeginScope();
44+
45+
result = null;
46+
ref var left = ref result;
47+
char op = '\0';
48+
49+
while (sc.TryParseAddSubExpression(out var right)) {
50+
switch (op) {
51+
case '\0' when left is null:
52+
left = right;
53+
break;
54+
case '&':
55+
left = left?.And(right);
56+
break;
57+
case '|':
58+
left = left?.Or(right);
59+
break;
60+
case '^':
61+
left = left?.Xor(right);
62+
break;
63+
default:
64+
left = null;
65+
goto end;
66+
}
67+
68+
sc.SkipSpaces();
69+
if (!sc.TryReadChar(out op) || op is not ('&' or '|' or '^')) {
70+
if (op != '\0') {
71+
sc.Retreat();
72+
}
73+
break;
74+
}
75+
}
76+
77+
end:
78+
if (result is null) {
79+
sc.EndScope(true);
80+
return false;
81+
} else {
82+
sc.EndScope(false);
83+
return true;
84+
}
85+
}
4086

4187
public static bool TryParseAddSubExpression(this SourceCode sc, [NotNullWhen(true)][MaybeNullWhen(false)] out SifoscObject? result)
4288
{
@@ -133,6 +179,7 @@ public static bool TryParseValueExpression(this SourceCode sc, [NotNullWhen(true
133179

134180
return sc.TryParseParenthesisExpression(out result)
135181
|| sc.TryParseSignExpression (out result)
182+
|| sc.TryParseNotExpression (out result)
136183
|| sc.TryParseValueLiteral (out result);
137184
}
138185

@@ -180,6 +227,33 @@ public static bool TryParseSignExpression(this SourceCode sc, [NotNullWhen(true)
180227
return true;
181228
}
182229

230+
public static bool TryParseNotExpression(this SourceCode sc, [NotNullWhen(true)][MaybeNullWhen(false)] out SifoscObject? result)
231+
{
232+
sc.BeginScope();
233+
234+
if (sc.TryReadChar (out char ch ) && ch is '!' &&
235+
sc.TryParseValueExpression(out var obj)
236+
) {
237+
result = obj.Negate();
238+
239+
if (result is null) {
240+
goto fail;
241+
} else {
242+
goto succeed;
243+
}
244+
}
245+
246+
result = null;
247+
248+
fail:
249+
sc.EndScope(true);
250+
return false;
251+
252+
succeed:
253+
sc.EndScope(false);
254+
return true;
255+
}
256+
183257
public static bool TryParseValueLiteral(this SourceCode sc, [NotNullWhen(true)][MaybeNullWhen(false)] out SifoscObject? result)
184258
{
185259
if (sc.TryParseArrayLiteral(out var aryVal)) {

FastChatProtocolInterface/SimpleFormulaScript/SifoscServer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ protected override string ReceiveMessageCore(FachpiCommunicationFlow flow)
2626

2727
public static string RunScriptLine(string s)
2828
{
29-
// SIFOSC の例:[ [ null, allobj, true, false, newobj, 123 ], [ null, newobj, 123, +456, -789, [ ] ], [ 1, 2, 3 ] + [ 2 + 2, 5, 2 * 3 ] + [ 1 + 2 * 3 ], +-+-+-+100, ([([([])])]), 1 + ((1 + 2) * 3 + 1) / 2 % 3 - 4 ];
29+
// SIFOSC の例:[ [ null, allobj, true, false, newobj, 123 ], [ null, newobj, 123, +456, -789, [ ] ], [ 1, 2, 3 ] + [ 2 + 2, 5, 2 * 3 ] + [ 1 + 2 * 3 ], +-+-+-+100, ([([([])])]), 1 + ((1 + 2) * 3 + 1) / 2 % 3 - 4, [ true | false & true ^ false, (true | false) & (true ^ false) & false, !(((3 & 5) + (3 | 5) + (3 ^ 5)) - (3 & 5 + 3 | 5 + 3 ^ 5)), !!true, !!0, !!123, !!!false ] ];
3030

3131
var sc = new SourceCode(s);
3232
if (sc.TryParse(out var result)) {

0 commit comments

Comments
 (0)