diff --git a/src/com/annimon/ownlang/lib/NumberValue.java b/src/com/annimon/ownlang/lib/NumberValue.java index c9d817e..91cf759 100644 --- a/src/com/annimon/ownlang/lib/NumberValue.java +++ b/src/com/annimon/ownlang/lib/NumberValue.java @@ -7,13 +7,14 @@ package com.annimon.ownlang.lib; public final class NumberValue implements Value { public static final NumberValue ZERO = new NumberValue(0); + public static final NumberValue ONE = new NumberValue(1); + + public static NumberValue fromBoolean(boolean b) { + return b ? ONE : ZERO; + } private final double value; - public NumberValue(boolean value) { - this.value = value ? 1 : 0; - } - public NumberValue(double value) { this.value = value; } diff --git a/src/com/annimon/ownlang/lib/Variables.java b/src/com/annimon/ownlang/lib/Variables.java index 99a4c67..543fd37 100644 --- a/src/com/annimon/ownlang/lib/Variables.java +++ b/src/com/annimon/ownlang/lib/Variables.java @@ -1,8 +1,8 @@ package com.annimon.ownlang.lib; -import java.util.HashMap; import java.util.Map; import java.util.Stack; +import java.util.concurrent.ConcurrentHashMap; /** * @@ -15,15 +15,13 @@ public final class Variables { static { stack = new Stack<>(); - variables = new HashMap<>(); - variables.put("PI", new NumberValue(Math.PI)); - variables.put("ПИ", new NumberValue(Math.PI)); - variables.put("E", new NumberValue(Math.E)); - variables.put("GOLDEN_RATIO", new NumberValue(1.618)); + variables = new ConcurrentHashMap<>(); + variables.put("true", NumberValue.ONE); + variables.put("false", NumberValue.ZERO); } public static void push() { - stack.push(new HashMap<>(variables)); + stack.push(new ConcurrentHashMap<>(variables)); } public static void pop() { diff --git a/src/com/annimon/ownlang/lib/modules/std.java b/src/com/annimon/ownlang/lib/modules/std.java index 24befd8..f274d02 100644 --- a/src/com/annimon/ownlang/lib/modules/std.java +++ b/src/com/annimon/ownlang/lib/modules/std.java @@ -70,6 +70,8 @@ public final class std implements Module { @Override public Value execute(Value... args) { + if (args.length == 0) return new NumberValue(RND.nextDouble()); + int from = 0; int to = 100; if (args.length == 1) { diff --git a/src/com/annimon/ownlang/parser/Parser.java b/src/com/annimon/ownlang/parser/Parser.java index 3e45c6c..4d82169 100644 --- a/src/com/annimon/ownlang/parser/Parser.java +++ b/src/com/annimon/ownlang/parser/Parser.java @@ -122,11 +122,13 @@ public final class Parser { } private Statement forStatement() { + match(TokenType.LPAREN); // необязательные скобки final Statement initialization = assignmentStatement(); consume(TokenType.COMMA); final Expression termination = expression(); consume(TokenType.COMMA); final Statement increment = assignmentStatement(); + match(TokenType.RPAREN); final Statement statement = statementOrBlock(); return new ForStatement(initialization, termination, increment, statement); } diff --git a/src/com/annimon/ownlang/parser/ast/BinaryExpression.java b/src/com/annimon/ownlang/parser/ast/BinaryExpression.java index c71a217..6601197 100644 --- a/src/com/annimon/ownlang/parser/ast/BinaryExpression.java +++ b/src/com/annimon/ownlang/parser/ast/BinaryExpression.java @@ -98,6 +98,6 @@ public final class BinaryExpression implements Expression { @Override public String toString() { - return String.format("[%s %s %s]", expr1, operation, expr2); + return String.format("%s %s %s", expr1, operation, expr2); } } diff --git a/src/com/annimon/ownlang/parser/ast/ConditionalExpression.java b/src/com/annimon/ownlang/parser/ast/ConditionalExpression.java index d458bb2..c183806 100644 --- a/src/com/annimon/ownlang/parser/ast/ConditionalExpression.java +++ b/src/com/annimon/ownlang/parser/ast/ConditionalExpression.java @@ -45,6 +45,14 @@ public final class ConditionalExpression implements Expression { @Override public Value eval() { final Value value1 = expr1.eval(); + switch (operation) { + case AND: return NumberValue.fromBoolean( + (value1.asNumber() != 0) && (expr2.eval().asNumber() != 0) ); + case OR: return NumberValue.fromBoolean( + (value1.asNumber() != 0) || (expr2.eval().asNumber() != 0) ); + } + + final Value value2 = expr2.eval(); double number1, number2; @@ -66,13 +74,10 @@ public final class ConditionalExpression implements Expression { case GT: result = number1 > number2; break; case GTEQ: result = number1 >= number2; break; - case AND: result = (number1 != 0) && (number2 != 0); break; - case OR: result = (number1 != 0) || (number2 != 0); break; - default: throw new RuntimeException("Operation " + operation + " is not supported"); } - return new NumberValue(result); + return NumberValue.fromBoolean(result); } @Override @@ -82,6 +87,6 @@ public final class ConditionalExpression implements Expression { @Override public String toString() { - return String.format("[%s %s %s]", expr1, operation.getName(), expr2); + return String.format("%s %s %s", expr1, operation.getName(), expr2); } } diff --git a/src/com/annimon/ownlang/parser/ast/FunctionDefineStatement.java b/src/com/annimon/ownlang/parser/ast/FunctionDefineStatement.java index fe3016b..0980c11 100644 --- a/src/com/annimon/ownlang/parser/ast/FunctionDefineStatement.java +++ b/src/com/annimon/ownlang/parser/ast/FunctionDefineStatement.java @@ -32,6 +32,6 @@ public final class FunctionDefineStatement implements Statement { @Override public String toString() { - return "def (" + argNames.toString() + ") " + body.toString(); + return String.format("def %s(%s) %s", name, argNames, body); } } diff --git a/src/com/annimon/ownlang/parser/ast/VariableExpression.java b/src/com/annimon/ownlang/parser/ast/VariableExpression.java index 3204ca0..1971eea 100644 --- a/src/com/annimon/ownlang/parser/ast/VariableExpression.java +++ b/src/com/annimon/ownlang/parser/ast/VariableExpression.java @@ -17,7 +17,7 @@ public final class VariableExpression implements Expression { @Override public Value eval() { - if (!Variables.isExists(name)) throw new RuntimeException("Variable does not exists"); + if (!Variables.isExists(name)) throw new RuntimeException("Variable does not exists: " + name); return Variables.get(name); }