From e4a4fb7a92a8601223a15ca46e57f266709b2840 Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 20 May 2015 10:58:38 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D1=80=D0=BE=D0=BA=202.=20=D0=92=D0=B5?= =?UTF-8?q?=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20?= =?UTF-8?q?=D1=87=D0=B8=D1=81=D0=BB=D0=B0,=20=D0=BA=D0=BE=D0=BD=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=BD=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/com/annimon/ownlang/Main.java | 3 +- src/com/annimon/ownlang/lib/Constants.java | 30 +++++++++++++++++++ src/com/annimon/ownlang/parser/Lexer.java | 21 ++++++++++++- src/com/annimon/ownlang/parser/Parser.java | 4 +++ src/com/annimon/ownlang/parser/TokenType.java | 1 + .../ownlang/parser/ast/BinaryExpression.java | 2 +- .../parser/ast/ConstantExpression.java | 28 +++++++++++++++++ 7 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 src/com/annimon/ownlang/lib/Constants.java create mode 100644 src/com/annimon/ownlang/parser/ast/ConstantExpression.java diff --git a/src/com/annimon/ownlang/Main.java b/src/com/annimon/ownlang/Main.java index 7607ee2..0463ca5 100644 --- a/src/com/annimon/ownlang/Main.java +++ b/src/com/annimon/ownlang/Main.java @@ -13,7 +13,8 @@ public final class Main { public static void main(String[] args) { final String input1 = "2 + 2"; - final String input2 = "(2 + 2) * #f"; +// final String input2 = "(GOLDEN_RATIO + 2) * #f"; + final String input2 = "GOLDEN_RATIO"; final List tokens = new Lexer(input2).tokenize(); for (Token token : tokens) { System.out.println(token); diff --git a/src/com/annimon/ownlang/lib/Constants.java b/src/com/annimon/ownlang/lib/Constants.java new file mode 100644 index 0000000..9063418 --- /dev/null +++ b/src/com/annimon/ownlang/lib/Constants.java @@ -0,0 +1,30 @@ +package com.annimon.ownlang.lib; + +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author aNNiMON + */ +public final class Constants { + + private static final Map constants; + + static { + constants = new HashMap<>(); + constants.put("PI", Math.PI); + constants.put("ПИ", Math.PI); + constants.put("E", Math.E); + constants.put("GOLDEN_RATIO", 1.618); + } + + public static boolean isExists(String key) { + return constants.containsKey(key); + } + + public static double get(String key) { + if (!isExists(key)) return 0; + return constants.get(key); + } +} diff --git a/src/com/annimon/ownlang/parser/Lexer.java b/src/com/annimon/ownlang/parser/Lexer.java index b05e60e..446dafd 100644 --- a/src/com/annimon/ownlang/parser/Lexer.java +++ b/src/com/annimon/ownlang/parser/Lexer.java @@ -34,6 +34,7 @@ public final class Lexer { while (pos < length) { final char current = peek(0); if (Character.isDigit(current)) tokenizeNumber(); + else if (Character.isLetter(current)) tokenizeWord(); else if (current == '#') { next(); tokenizeHexNumber(); @@ -51,7 +52,12 @@ public final class Lexer { private void tokenizeNumber() { final StringBuilder buffer = new StringBuilder(); char current = peek(0); - while (Character.isDigit(current)) { + while (true) { + if (current == '.') { + if (buffer.indexOf(".") != -1) throw new RuntimeException("Invalid float number"); + } else if (!Character.isDigit(current)) { + break; + } buffer.append(current); current = next(); } @@ -78,6 +84,19 @@ public final class Lexer { next(); } + private void tokenizeWord() { + final StringBuilder buffer = new StringBuilder(); + char current = peek(0); + while (true) { + if (!Character.isLetterOrDigit(current) && (current != '_') && (current != '$')) { + break; + } + buffer.append(current); + current = next(); + } + addToken(TokenType.WORD, buffer.toString()); + } + private char next() { pos++; return peek(0); diff --git a/src/com/annimon/ownlang/parser/Parser.java b/src/com/annimon/ownlang/parser/Parser.java index 1205283..eb312c6 100644 --- a/src/com/annimon/ownlang/parser/Parser.java +++ b/src/com/annimon/ownlang/parser/Parser.java @@ -1,6 +1,7 @@ package com.annimon.ownlang.parser; import com.annimon.ownlang.parser.ast.BinaryExpression; +import com.annimon.ownlang.parser.ast.ConstantExpression; import com.annimon.ownlang.parser.ast.Expression; import com.annimon.ownlang.parser.ast.NumberExpression; import com.annimon.ownlang.parser.ast.UnaryExpression; @@ -92,6 +93,9 @@ public final class Parser { if (match(TokenType.HEX_NUMBER)) { return new NumberExpression(Long.parseLong(current.getText(), 16)); } + if (match(TokenType.WORD)) { + return new ConstantExpression(current.getText()); + } if (match(TokenType.LPAREN)) { Expression result = expression(); match(TokenType.RPAREN); diff --git a/src/com/annimon/ownlang/parser/TokenType.java b/src/com/annimon/ownlang/parser/TokenType.java index 8e5da80..88c6a70 100644 --- a/src/com/annimon/ownlang/parser/TokenType.java +++ b/src/com/annimon/ownlang/parser/TokenType.java @@ -8,6 +8,7 @@ public enum TokenType { NUMBER, HEX_NUMBER, + WORD, PLUS, MINUS, diff --git a/src/com/annimon/ownlang/parser/ast/BinaryExpression.java b/src/com/annimon/ownlang/parser/ast/BinaryExpression.java index e20dfe1..fe24df3 100644 --- a/src/com/annimon/ownlang/parser/ast/BinaryExpression.java +++ b/src/com/annimon/ownlang/parser/ast/BinaryExpression.java @@ -29,6 +29,6 @@ public final class BinaryExpression implements Expression { @Override public String toString() { - return String.format("%s %c %s", expr1, operation, expr2); + return String.format("[%s %c %s]", expr1, operation, expr2); } } diff --git a/src/com/annimon/ownlang/parser/ast/ConstantExpression.java b/src/com/annimon/ownlang/parser/ast/ConstantExpression.java new file mode 100644 index 0000000..ded0aff --- /dev/null +++ b/src/com/annimon/ownlang/parser/ast/ConstantExpression.java @@ -0,0 +1,28 @@ +package com.annimon.ownlang.parser.ast; + +import com.annimon.ownlang.lib.Constants; + +/** + * + * @author aNNiMON + */ +public final class ConstantExpression implements Expression { + + private final String name; + + public ConstantExpression(String name) { + this.name = name; + } + + @Override + public double eval() { + if (!Constants.isExists(name)) throw new RuntimeException("Constant does not exists"); + return Constants.get(name); + } + + @Override + public String toString() { +// return String.format("%s [%f]", name, Constants.get(name)); + return String.format("%s", name); + } +}