Урок 2. Вещественные числа, константы

This commit is contained in:
Victor 2015-05-20 10:58:38 +03:00
parent a1c16e9d42
commit e4a4fb7a92
7 changed files with 86 additions and 3 deletions

View File

@ -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<Token> tokens = new Lexer(input2).tokenize();
for (Token token : tokens) {
System.out.println(token);

View File

@ -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<String, Double> 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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -8,6 +8,7 @@ public enum TokenType {
NUMBER,
HEX_NUMBER,
WORD,
PLUS,
MINUS,

View File

@ -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);
}
}

View File

@ -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);
}
}