Skip to content

Commit

Permalink
Add new range operators
Browse files Browse the repository at this point in the history
  • Loading branch information
ngallagher committed Jan 15, 2019
1 parent 2c43e48 commit 9c998c1
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,54 @@
package org.snapscript.compile;

import junit.framework.TestCase;

public class ForInLoopTest extends TestCase {
public class ForInLoopTest extends ScriptTestCase {

private static final String SOURCE_1 =
"for(let i in 0..9){\n"+
" assert i > -1;\n"+
"}\n"+
"for(var i in 0..9){\n"+
"let l = [];\n"+
"for(i in 0 .. 9){\n"+
" l.add(i);\n"+
" assert i > -1;\n"+
"}\n"+
"println(l);\n"+
"assert l.length == 10;\n"+
"assert l[2] == 2;\n"+
"assert l[3] == 3;\n"+
"assert l[9] == 9;\n";

private static final String SOURCE_2 =
"for(let i in 0 to 9){\n"+
" assert i > -1;\n"+
"}\n"+
"let l = [];\n"+
"for(var i in 0 to 9){\n"+
" l.add(i);\n"+
" assert i > -1;\n"+
"}\n"+
"println(l);\n"+
"assert l.length == 10;\n"+
"assert l[2] == 2;\n"+
"assert l[3] == 3;\n"+
"assert l[9] == 9;\n";

private static final String SOURCE_3 =
"for(let i in 0 from 9){\n"+
" assert i > -1;\n"+
"}\n";

"}\n"+
"let l = [];\n"+
"for(var i in 0 from 9){\n"+
" l.add(i);\n"+
" assert i > -1;\n"+
"}\n"+
"println(l);\n"+
"assert l.length == 10;\n"+
"assert l[0] == 9;\n"+
"assert l[9] == 0;\n";

public void testForInLoop() throws Exception {
Compiler compiler = ClassPathCompilerBuilder.createCompiler();
Executable executable = compiler.compile(SOURCE_1);
executable.execute();
assertScriptExecutes(SOURCE_1);
assertScriptExecutes(SOURCE_2);
assertScriptExecutes(SOURCE_3);
}
}
3 changes: 2 additions & 1 deletion snap-parse/src/main/resources/grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ variable-reference = {<super> | <this> | <variable>} *( '(' <function-curry>')'

collection-index = <argument>;

range = <argument>'..'<argument>;
range-operator = {'..' | 'from' | 'to'};
range = <argument>?_<range-operator>?_<argument>;

constructor = 'new';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ public void testParse() throws Exception {
SyntaxParser tree = LexerBuilder.create(GRAMMAR_FILE);

assertNotNull(tree);
analyze(tree, "0 .. 10", "range");
analyze(tree, "0 to 10", "range");
analyze(tree, "0 from 10", "range");
analyze(tree, "let x: (a) = (a) -> a.run();", "declaration-statement");
analyze(tree, "let x = <T: Runnable>(a: T) -> a.run();", "declaration-statement");
analyze(tree, "Foo", "alias-name");
Expand Down
15 changes: 12 additions & 3 deletions snap-tree/src/main/java/org/snapscript/tree/collection/Range.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@

import org.snapscript.core.Evaluation;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.error.InternalStateException;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.variable.Value;
import org.snapscript.parse.StringToken;

public class Range extends Evaluation {

private final RangeOperator operator;
private final StringToken token;
private final Evaluation start;
private final Evaluation finish;

public Range(Evaluation start, Evaluation finish) {
public Range(Evaluation start, StringToken token, Evaluation finish) {
this.operator = RangeOperator.resolveOperator(token);
this.token = token;
this.start = start;
this.finish = finish;
}
Expand All @@ -25,6 +31,9 @@ public void define(Scope scope) throws Exception {

@Override
public Constraint compile(Scope scope, Constraint left) throws Exception {
if(operator == null) {
throw new InternalStateException("Illegal " + token + " operator for range");
}
return ITERABLE;
}

Expand All @@ -39,7 +48,7 @@ private Sequence create(Scope scope, Value left) throws Exception {
Value last = finish.evaluate(scope, left);
long start = first.getLong();
long finish = last.getLong();
return new Sequence(start, finish);

return new Sequence(start, finish, operator.forward);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.snapscript.tree.collection;

import org.snapscript.parse.StringToken;

public enum RangeOperator {
DOT("..", true),
TO("to", true),
FROM("from", false);

public final String operator;
public final boolean forward;

private RangeOperator(String operator, boolean forward) {
this.operator = operator;
this.forward = forward;
}

public boolean isForward() {
return forward;
}

public boolean isReverse() {
return !forward;
}

public static RangeOperator resolveOperator(StringToken token) {
if(token != null) {
String value = token.getValue();

for(RangeOperator operator : VALUES) {
if (operator.operator.equals(value)) {
return operator;
}
}
}
return null;
}

private static final RangeOperator[] VALUES = {
DOT,
TO,
FROM
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@

public class Sequence implements Iterable<Number> {

private final boolean forward;
private final long first;
private final long last;

public Sequence(long first, long last) {
public Sequence(long first, long last, boolean forward) {
this.forward = forward;
this.first = first;
this.last = last;
}

@Override
public Iterator<Number> iterator() {
if(first > last) {
return new ReverseIterator(first, last);
if(forward) {
return new ForwardIterator(first, last);
}
return new ForwardIterator(first, last);
return new ReverseIterator(last, first);
}

private static class ForwardIterator implements Iterator<Number> {
Expand Down Expand Up @@ -50,10 +52,10 @@ public void remove() {
}

private static class ReverseIterator implements Iterator<Number> {

private long first;
private long last;

public ReverseIterator(long first, long last) {
this.first = first;
this.last = last;
Expand All @@ -71,7 +73,7 @@ public Number next() {
}
return null;
}

@Override
public void remove() {
throw new UnsupportedOperationException("Illegal modification of range");
Expand Down

0 comments on commit 9c998c1

Please sign in to comment.