Skip to content

Commit 25f4801

Browse files
committed
adds support for certain statements (so far only sleep) as or incrementor.
1 parent b05a0aa commit 25f4801

File tree

3 files changed

+75
-11
lines changed

3 files changed

+75
-11
lines changed

DMCompiler/Compiler/DM/AST/DMAST.ProcStatements.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,11 @@ public sealed class DMASTProcStatementFor(
118118
DMASTExpression? expr1,
119119
DMASTExpression? expr2,
120120
DMASTExpression? expr3,
121+
DMASTProcStatement? statement3,
121122
DMComplexValueType? dmTypes,
122123
DMASTProcBlockInner body) : DMASTProcStatement(location) {
123124
public DMASTExpression? Expression1 = expr1, Expression2 = expr2, Expression3 = expr3;
125+
public DMASTProcStatement? Statement3 = statement3;
124126
public DMComplexValueType? DMTypes = dmTypes;
125127
public readonly DMASTProcBlockInner Body = body;
126128
}

DMCompiler/Compiler/DM/DMParser.cs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,7 +1276,7 @@ private DMASTProcStatement For() {
12761276
Consume(TokenType.DM_RightParenthesis, "Expected ')' in for after to expression");
12771277
ExtraColonPeriod();
12781278

1279-
return new DMASTProcStatementFor(loc, new DMASTExpressionInRange(loc, assign.LHS, assign.RHS, endRange, step), null, null, dmTypes, GetForBody());
1279+
return new DMASTProcStatementFor(loc, new DMASTExpressionInRange(loc, assign.LHS, assign.RHS, endRange, step), null, null, null, dmTypes, GetForBody());
12801280
} else {
12811281
Emit(WarningCode.BadExpression, "Expected = before to in for");
12821282
return new DMASTInvalidProcStatement(loc);
@@ -1291,20 +1291,20 @@ private DMASTProcStatement For() {
12911291
Consume(TokenType.DM_RightParenthesis, "Expected ')' in for after expression 2");
12921292
ExtraColonPeriod();
12931293

1294-
return new DMASTProcStatementFor(loc, new DMASTExpressionIn(loc, expr1, listExpr), null, null, dmTypes, GetForBody());
1294+
return new DMASTProcStatementFor(loc, new DMASTExpressionIn(loc, expr1, listExpr), null, null, null, dmTypes, GetForBody());
12951295
}
12961296

12971297
if (!Check(ForSeparatorTypes)) {
12981298
Consume(TokenType.DM_RightParenthesis, "Expected ')' in for after expression 1");
12991299
ExtraColonPeriod();
13001300

1301-
return new DMASTProcStatementFor(loc, expr1, null, null, dmTypes, GetForBody());
1301+
return new DMASTProcStatementFor(loc, expr1, null, null, null, dmTypes, GetForBody());
13021302
}
13031303

13041304
if (Check(TokenType.DM_RightParenthesis)) {
13051305
ExtraColonPeriod();
13061306

1307-
return new DMASTProcStatementFor(loc, expr1, null, null, dmTypes, GetForBody());
1307+
return new DMASTProcStatementFor(loc, expr1, null, null, null, dmTypes, GetForBody());
13081308
}
13091309

13101310
Whitespace();
@@ -1321,29 +1321,44 @@ private DMASTProcStatement For() {
13211321
Consume(TokenType.DM_RightParenthesis, "Expected ')' in for after expression 2");
13221322
ExtraColonPeriod();
13231323

1324-
return new DMASTProcStatementFor(loc, expr1, expr2, null, dmTypes, GetForBody());
1324+
return new DMASTProcStatementFor(loc, expr1, expr2, null, null, dmTypes, GetForBody());
13251325
}
13261326

13271327
if (Check(TokenType.DM_RightParenthesis)) {
13281328
ExtraColonPeriod();
13291329

1330-
return new DMASTProcStatementFor(loc, expr1, expr2, null, dmTypes, GetForBody());
1330+
return new DMASTProcStatementFor(loc, expr1, expr2, null, null, dmTypes, GetForBody());
13311331
}
13321332

13331333
Whitespace();
13341334
DMASTExpression? expr3 = Expression();
1335+
DMASTProcStatement? statement3 = null;
13351336
if (expr3 == null) {
1337+
CheckForStatementIncrementor(ref expr3, ref statement3);
1338+
13361339
if (Current().Type != TokenType.DM_RightParenthesis) {
13371340
Emit(WarningCode.BadExpression, "Expected 3nd expression in for");
13381341
}
1339-
1340-
expr3 = new DMASTConstantNull(loc);
13411342
}
13421343

13431344
Consume(TokenType.DM_RightParenthesis, "Expected ')' in for after expression 3");
13441345
ExtraColonPeriod();
13451346

1346-
return new DMASTProcStatementFor(loc, expr1, expr2, expr3, dmTypes, GetForBody());
1347+
return new DMASTProcStatementFor(loc, expr1, expr2, expr3, statement3, dmTypes, GetForBody());
1348+
1349+
void CheckForStatementIncrementor(ref DMASTExpression? expr3, ref DMASTProcStatement? statement3) {
1350+
DMASTProcStatementSleep? sleep = Sleep();
1351+
if (sleep == null) {
1352+
expr3 = new DMASTConstantNull(loc);
1353+
statement3 = sleep;
1354+
return;
1355+
}
1356+
1357+
// TODO: additional tests, e.g., animate(...)
1358+
1359+
// if no matches, null
1360+
expr3 = new DMASTConstantNull(loc);
1361+
}
13471362

13481363
DMASTProcBlockInner GetForBody() {
13491364
Whitespace();

DMCompiler/DM/Builders/DMProcBuilder.cs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ private void ProcessStatementFor(DMASTProcStatementFor statementFor) {
277277
ProcessStatementVarDeclaration(new DMASTProcStatementVarDeclaration(statementFor.Location, decl.DeclPath, null, DMValueType.Anything));
278278
}
279279

280-
if (statementFor is { Expression2: DMASTExpressionIn dmastIn, Expression3: null }) { // for(var/i,j in expr) or for(i,j in expr)
280+
if (statementFor is { Expression2: DMASTExpressionIn dmastIn, Expression3: null, Statement3: null }) { // for(var/i,j in expr) or for(i,j in expr)
281281
var valueVar = statementFor.Expression2 != null ? _exprBuilder.CreateIgnoreUnknownReference(statementFor.Expression2) : null;
282282
var list = _exprBuilder.Create(dmastIn.RHS);
283283

@@ -326,12 +326,31 @@ private void ProcessStatementFor(DMASTProcStatementFor statementFor) {
326326
}
327327

328328
ProcessStatementForList(list, keyVar, valueVar, statementFor.DMTypes, statementFor.Body);
329-
} else if (statementFor.Expression2 != null || statementFor.Expression3 != null) {
329+
} else if (statementFor.Expression2 != null || statementFor.Expression3 != null && statementFor.Statement3 == null) {
330330
var initializer = statementFor.Expression1 != null ? _exprBuilder.Create(statementFor.Expression1) : null;
331331
var comparator = statementFor.Expression2 != null ? _exprBuilder.Create(statementFor.Expression2) : null;
332332
var incrementor = statementFor.Expression3 != null ? _exprBuilder.Create(statementFor.Expression3) : null;
333333

334334
ProcessStatementForStandard(initializer, comparator, incrementor, statementFor.Body);
335+
} else if (statementFor.Expression2 != null || statementFor.Expression3 == null && statementFor.Statement3 != null) {
336+
var initializer = statementFor.Expression1 != null ? _exprBuilder.Create(statementFor.Expression1) : null;
337+
var comparator = statementFor.Expression2 != null ? _exprBuilder.Create(statementFor.Expression2) : null;
338+
339+
Action statementHandler = null;
340+
switch (statementFor.Statement3) {
341+
case DMASTProcStatementSleep sleepStatement: {
342+
statementHandler = () => {
343+
ProcessStatementSleep(sleepStatement);
344+
};
345+
break;
346+
}
347+
348+
default:
349+
compiler.Emit(WarningCode.BadArgument, statementFor.Statement3!.Location, "Cannot change constant value");
350+
break;
351+
}
352+
353+
ProcessStatementForWithStatementInc(initializer, comparator, statementHandler, statementFor.Body);
335354
} else {
336355
switch (statementFor.Expression1) {
337356
case DMASTAssign {LHS: DMASTVarDeclExpression decl, RHS: DMASTExpressionInRange range}: {
@@ -459,6 +478,34 @@ private void ProcessStatementForStandard(DMExpression? initializer, DMExpression
459478
proc.EndScope();
460479
}
461480

481+
private void ProcessStatementForWithStatementInc(DMExpression? initializer, DMExpression? comparator, Action? incrementor, DMASTProcBlockInner body) {
482+
proc.StartScope();
483+
{
484+
if (initializer != null) {
485+
initializer.EmitPushValue(ExprContext);
486+
proc.Pop();
487+
}
488+
489+
string loopLabel = proc.NewLabelName();
490+
proc.LoopStart(loopLabel);
491+
{
492+
if (comparator != null) {
493+
comparator.EmitPushValue(ExprContext);
494+
proc.BreakIfFalse();
495+
}
496+
497+
ProcessBlockInner(body);
498+
499+
proc.MarkLoopContinue(loopLabel);
500+
if (incrementor != null)
501+
incrementor();
502+
proc.LoopJumpToStart(loopLabel);
503+
}
504+
proc.LoopEnd();
505+
}
506+
proc.EndScope();
507+
}
508+
462509
private void ProcessLoopAssignment(LValue lValue, LValue? assocValue = null, DMExpression? list = null) {
463510
if (lValue.CanReferenceShortCircuit()) { // TODO: If assocValue short circuits?
464511
string endLabel = proc.NewLabelName();

0 commit comments

Comments
 (0)