Урок 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) { public static void main(String[] args) {
final String input1 = "2 + 2"; 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(); final List<Token> tokens = new Lexer(input2).tokenize();
for (Token token : tokens) { for (Token token : tokens) {
System.out.println(token); 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) { while (pos < length) {
final char current = peek(0); final char current = peek(0);
if (Character.isDigit(current)) tokenizeNumber(); if (Character.isDigit(current)) tokenizeNumber();
else if (Character.isLetter(current)) tokenizeWord();
else if (current == '#') { else if (current == '#') {
next(); next();
tokenizeHexNumber(); tokenizeHexNumber();
@ -51,7 +52,12 @@ public final class Lexer {
private void tokenizeNumber() { private void tokenizeNumber() {
final StringBuilder buffer = new StringBuilder(); final StringBuilder buffer = new StringBuilder();
char current = peek(0); 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); buffer.append(current);
current = next(); current = next();
} }
@ -78,6 +84,19 @@ public final class Lexer {
next(); 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() { private char next() {
pos++; pos++;
return peek(0); return peek(0);

View File

@ -1,6 +1,7 @@
package com.annimon.ownlang.parser; package com.annimon.ownlang.parser;
import com.annimon.ownlang.parser.ast.BinaryExpression; 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.Expression;
import com.annimon.ownlang.parser.ast.NumberExpression; import com.annimon.ownlang.parser.ast.NumberExpression;
import com.annimon.ownlang.parser.ast.UnaryExpression; import com.annimon.ownlang.parser.ast.UnaryExpression;
@ -92,6 +93,9 @@ public final class Parser {
if (match(TokenType.HEX_NUMBER)) { if (match(TokenType.HEX_NUMBER)) {
return new NumberExpression(Long.parseLong(current.getText(), 16)); return new NumberExpression(Long.parseLong(current.getText(), 16));
} }
if (match(TokenType.WORD)) {
return new ConstantExpression(current.getText());
}
if (match(TokenType.LPAREN)) { if (match(TokenType.LPAREN)) {
Expression result = expression(); Expression result = expression();
match(TokenType.RPAREN); match(TokenType.RPAREN);

View File

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

View File

@ -29,6 +29,6 @@ public final class BinaryExpression implements Expression {
@Override @Override
public String toString() { 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);
}
}