Skip to content

Commit

Permalink
Merge pull request #39 from frungl/master
Browse files Browse the repository at this point in the history
`rangeto`, `downto` keywords for the for block
  • Loading branch information
GassaFM authored Apr 1, 2023
2 parents e207a2a + c93dd9c commit 6b9f084
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 9 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ It first assigns the value of expression `<start>` to variable `<name>`.
Then, as long as `<name>` is strictly less than the value of expression `<finish>`,
the statements are executed from top to bottom, the variable is increased by one,
and the condition is evaluated again.
You can also write `rangeto`/`downto` instead of `until`.
Then, as long as `<name>` is not strictly less/more respectively, the value of the expression `<finish>`,
the statements are executed from top to bottom, the variable is increased/decreased, respectively, by one,
and the condition is evaluated again.

### Expressions

Expand Down
6 changes: 5 additions & 1 deletion README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,11 @@ function <name> (<arg1>, <arg2>, ...):
переменной с именем `<name>`.
Затем, пока `<name>` строго меньше значения выражения `<finish>`,
команды выполняются сверху вниз, значение переменной увеличивается на единицу,
после чего условие проверяется снова.
после чего условие проверяется снова.
Также вы можете написать `rangeto`/`downto` вместо `until`.
Затем, пока `<name>` нестрого меньше/больше соответственно, значения выражения `<finish>`,
команды выполняются сверху вниз, значение переменной увеличивается/уменьшается соответственно, на единицу,
после чего условие проверяется снова.

### Выражения

Expand Down
10 changes: 10 additions & 0 deletions examples/for.pr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function for(id, pr, n, a):
if id == 0:
left := 1
right := 3
for i := left until right:
print(i)
for i := left rangeto right:
print(i)
for i := right downto left:
print(i)
2 changes: 1 addition & 1 deletion extra/Notepad++-syntax-highlighting/pr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<Keywords name="Folders in comment, middle"></Keywords>
<Keywords name="Folders in comment, close"></Keywords>
<Keywords name="Keywords1">function array</Keywords>
<Keywords name="Keywords2">for until while if elif else</Keywords>
<Keywords name="Keywords2">for until rangeto downto while if elif else</Keywords>
<Keywords name="Keywords3">send receive print</Keywords>
<Keywords name="Keywords4">id</Keywords>
<Keywords name="Keywords5">pr</Keywords>
Expand Down
2 changes: 1 addition & 1 deletion source/display.d
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void display (Statement s, int indent)
{
write ("for ", cur.name, " := ");
display (cur.start);
write (" until ");
writef (" %s ", forStyleNames[cur.style]);
display (cur.finish);
writeln (":");
foreach (r; cur.statementList)
Expand Down
13 changes: 12 additions & 1 deletion source/language.d
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,28 @@ final class WhileBlock : Statement
}
}

final enum ForStyle
{
until,
rangeto,
downto
}

immutable string[] forStyleNames = ["until", "rangeto", "downto"];

final class ForBlock : Statement
{
string name;
ForStyle style;
Expression start;
Expression finish;
Statement [] statementList;

this (int lineId_, string name_, Expression start_, Expression finish_)
this (int lineId_, string name_, ForStyle style_, Expression start_, Expression finish_)
{
lineId = lineId_;
name = name_;
style = style_;
start = start_;
finish = finish_;
complexity = 1 + 1 + start.complexity + finish.complexity;
Expand Down
15 changes: 13 additions & 2 deletions source/parser.d
Original file line number Diff line number Diff line change
Expand Up @@ -411,13 +411,24 @@ final class StatementParser
(line, "bad name: " ~ line.tokens.front);
line.tokens.consume (":=", line);
auto start = parseExpression (line);
line.tokens.consume ("until", line);
ForStyle style;
auto count = forStyleNames.countUntil (line.tokens.front);
if (count < 0)
{
check (false, line, '\'' ~ line.tokens.front ~ "\' is not the keyword of the for block");
}
else
{
style = cast (ForStyle) count;
line.tokens.consume (forStyleNames[count], line);
}

auto finish = parseExpression (line);
line.tokens.consume (":", line);
check (line.tokens.empty, line,
"extra token at end of line: " ~ line.tokens.front);

ForBlock res = new ForBlock (line.lineId, name, start, finish);
ForBlock res = new ForBlock (line.lineId, name, style, start, finish);
res.statementList = parseBlock (prevIndent);
return res;
}
Expand Down
29 changes: 26 additions & 3 deletions source/runner.d
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,29 @@ class Runner
return true;
}

bool hasNext (long value, long finishValue, ForStyle style) {
final switch (style) {
case ForStyle.until:
return value < finishValue;
case ForStyle.rangeto:
return value <= finishValue;
case ForStyle.downto:
return value >= finishValue;
}
}

void setValueNext (ref long value, ForStyle style) {
final switch (style) {
case ForStyle.rangeto:
case ForStyle.until:
value += 1;
break;
case ForStyle.downto:
value -= 1;
break;
}
}

auto cur3 = cast (ForBlock) (parent);
if (cur3 !is null) with (cur3)
{
Expand All @@ -544,7 +567,7 @@ class Runner
vars[name] = Var (startValue);
delay = complexity;
delay += 3;
if (vars[name].value < finishValue)
if (hasNext (vars[name].value, finishValue, style))
{
pos += 1;
}
Expand All @@ -557,9 +580,9 @@ class Runner
{
auto finishValue =
evalExpression (finish);
vars[name].value += 1;
setValueNext (vars[name].value, style);
delay += 7;
if (vars[name].value < finishValue)
if (hasNext (vars[name].value, finishValue, style))
{
pos = 0;
}
Expand Down
2 changes: 2 additions & 0 deletions syntax.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ while <expression0> : \n <statement-list>

<for-block> is
for <name> := <expression0> until <expression0> : \n <statement-list>
for <name> := <expression0> rangeto <expression0> : \n <statement-list>
for <name> := <expression0> downto <expression0> : \n <statement-list>

<if-block> is
if <expression0> : \n <statement-list>
Expand Down

0 comments on commit 6b9f084

Please sign in to comment.