Skip to content

Commit 4fca55e

Browse files
committed
Компиляция инструкций ДобавитьОбработчик/УдалитьОбработчик
1 parent c4a55e3 commit 4fca55e

File tree

6 files changed

+110
-5
lines changed

6 files changed

+110
-5
lines changed

src/OneScript.Language/LanguageDef.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ static LanguageDef()
101101
AddToken(Token.And, "и", "and");
102102
AddToken(Token.Or, "или", "or");
103103
AddToken(Token.Not, "не", "not");
104+
AddToken(Token.AddHandler, "ДобавитьОбработчик", "AddHandler");
105+
AddToken(Token.RemoveHandler, "УдалитьОбработчик", "RemoveHandler");
104106

105107
#endregion
106108

src/OneScript.Language/LexicalAnalysis/Token.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ public enum Token
3939
EndOfText,
4040
Export,
4141
Execute,
42+
AddHandler,
43+
RemoveHandler,
4244

4345
// operators
4446
Plus,

src/ScriptEngine/Compiler/Compiler.cs

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ public static NestedLoopInfo New()
6565
public List<int> breakStatements;
6666
}
6767

68+
private enum ContinuationBuildMode
69+
{
70+
RightHand,
71+
LeftHand,
72+
EventHandler
73+
}
74+
6875
public CompilerDirectiveHandler DirectiveHandler { get; set; }
6976

7077
public CodeGenerationFlags ProduceExtraCode { get; set; }
@@ -800,6 +807,10 @@ private void BuildComplexStructureStatement()
800807
case Token.Execute:
801808
BuildExecuteStatement();
802809
break;
810+
case Token.AddHandler:
811+
case Token.RemoveHandler:
812+
BuildEventHandlerOperation(_lastExtractedLexem.Token);
813+
break;
803814
default:
804815
var expected = PopStructureToken();
805816
throw CompilerException.TokenExpected(expected);
@@ -1195,6 +1206,31 @@ private void BuildExecuteStatement()
11951206

11961207
}
11971208

1209+
private void BuildEventHandlerOperation(Token token)
1210+
{
1211+
BuildContinuationInternal(ContinuationBuildMode.EventHandler, out var eventName);
1212+
if (eventName == null)
1213+
{
1214+
throw CompilerException.IdentifierExpected();
1215+
}
1216+
1217+
BuildPushConstant();
1218+
NextToken();
1219+
if (_lastExtractedLexem.Token != Token.Comma)
1220+
{
1221+
throw CompilerException.TokenExpected(Token.Comma);
1222+
}
1223+
NextToken();
1224+
BuildContinuationInternal(ContinuationBuildMode.EventHandler, out var handlerName);
1225+
if (handlerName == null)
1226+
{
1227+
throw CompilerException.IdentifierExpected();
1228+
}
1229+
BuildPushConstant();
1230+
var opCode = token == Token.AddHandler ? OperationCode.AddHandler : OperationCode.RemoveHandler;
1231+
AddCommand(opCode, 0);
1232+
}
1233+
11981234
private void CorrectCommandArgument(int index, int newArgument)
11991235
{
12001236
var cmd = _module.Code[index];
@@ -1562,15 +1598,15 @@ private void ProcessUnaryBoolean()
15621598
private void BuildContinuationRightHand()
15631599
{
15641600
string dummy;
1565-
BuildContinuationInternal(false, out dummy);
1601+
BuildContinuationInternal(ContinuationBuildMode.RightHand, out dummy);
15661602
}
15671603

15681604
private void BuildContinuationLeftHand(out string lastIdentifier)
15691605
{
1570-
BuildContinuationInternal(true, out lastIdentifier);
1606+
BuildContinuationInternal(ContinuationBuildMode.LeftHand, out lastIdentifier);
15711607
}
15721608

1573-
private void BuildContinuationInternal(bool interruptOnCall, out string lastIdentifier)
1609+
private void BuildContinuationInternal(ContinuationBuildMode interruptMode, out string lastIdentifier)
15741610
{
15751611
lastIdentifier = null;
15761612
while (true)
@@ -1585,7 +1621,7 @@ private void BuildContinuationInternal(bool interruptOnCall, out string lastIden
15851621
NextToken();
15861622
if (_lastExtractedLexem.Token == Token.OpenPar)
15871623
{
1588-
if (interruptOnCall)
1624+
if (interruptMode == ContinuationBuildMode.LeftHand)
15891625
{
15901626
lastIdentifier = identifier;
15911627
return;
@@ -1603,7 +1639,15 @@ private void BuildContinuationInternal(bool interruptOnCall, out string lastIden
16031639
}
16041640
else
16051641
{
1606-
ResolveProperty(identifier);
1642+
if (interruptMode == ContinuationBuildMode.EventHandler)
1643+
{
1644+
lastIdentifier = identifier;
1645+
return;
1646+
}
1647+
else
1648+
{
1649+
ResolveProperty(identifier);
1650+
}
16071651
}
16081652
}
16091653
else if (_lastExtractedLexem.Token == Token.OpenBracket)

src/ScriptEngine/Machine/Core.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public enum OperationCode
6060
PushTmp,
6161
PopTmp,
6262
Execute,
63+
AddHandler,
64+
RemoveHandler,
6365

6466
// built-in functions
6567
Eval,
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*----------------------------------------------------------
2+
This Source Code Form is subject to the terms of the
3+
Mozilla Public License, v.2.0. If a copy of the MPL
4+
was not distributed with this file, You can obtain one
5+
at http://mozilla.org/MPL/2.0/.
6+
----------------------------------------------------------*/
7+
8+
namespace ScriptEngine.Machine
9+
{
10+
public interface IEventProcessor
11+
{
12+
void AddHandler(
13+
IRuntimeContextInstance eventSource,
14+
string eventName,
15+
IRuntimeContextInstance handlerTarget,
16+
string handlerMethod);
17+
18+
void RemoveHandler(
19+
IRuntimeContextInstance eventSource,
20+
string eventName,
21+
IRuntimeContextInstance handlerTarget,
22+
string handlerMethod);
23+
}
24+
}

src/ScriptEngine/Machine/MachineInstance.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,11 @@ public IValue Evaluate(string expression, bool separate = false)
286286

287287
#endregion
288288

289+
/// <summary>
290+
/// Обработчик событий, генерируемых классами прикладной логики.
291+
/// </summary>
292+
public IEventProcessor EventProcessor { get; set; }
293+
289294
private ScriptInformationContext CurrentScript
290295
{
291296
get
@@ -598,6 +603,8 @@ private void InitCommands()
598603
PushTmp,
599604
PopTmp,
600605
Execute,
606+
AddHandler,
607+
RemoveHandler,
601608

602609
//built-ins
603610
Eval,
@@ -1501,6 +1508,30 @@ private void Eval(int arg)
15011508
NextInstruction();
15021509
}
15031510

1511+
private void AddHandler(int arg)
1512+
{
1513+
var handlerMethod = _operationStack.Pop().AsString();
1514+
var handlerTarget = _operationStack.Pop().AsObject();
1515+
var eventName = _operationStack.Pop().AsString();
1516+
var eventSource = _operationStack.Pop().AsObject();
1517+
1518+
EventProcessor?.AddHandler(eventSource, eventName, handlerTarget, handlerMethod);
1519+
1520+
NextInstruction();
1521+
}
1522+
1523+
private void RemoveHandler(int arg)
1524+
{
1525+
var handlerMethod = _operationStack.Pop().AsString();
1526+
var handlerTarget = _operationStack.Pop().AsObject();
1527+
var eventName = _operationStack.Pop().AsString();
1528+
var eventSource = _operationStack.Pop().AsObject();
1529+
1530+
EventProcessor?.RemoveHandler(eventSource, eventName, handlerTarget, handlerMethod);
1531+
1532+
NextInstruction();
1533+
}
1534+
15041535
#endregion
15051536

15061537
#region Built-in functions

0 commit comments

Comments
 (0)