mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Урок 2. Вещественные числа, константы
This commit is contained in:
parent
a1c16e9d42
commit
e4a4fb7a92
@ -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);
|
||||||
|
30
src/com/annimon/ownlang/lib/Constants.java
Normal file
30
src/com/annimon/ownlang/lib/Constants.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -8,6 +8,7 @@ public enum TokenType {
|
|||||||
|
|
||||||
NUMBER,
|
NUMBER,
|
||||||
HEX_NUMBER,
|
HEX_NUMBER,
|
||||||
|
WORD,
|
||||||
|
|
||||||
PLUS,
|
PLUS,
|
||||||
MINUS,
|
MINUS,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
src/com/annimon/ownlang/parser/ast/ConstantExpression.java
Normal file
28
src/com/annimon/ownlang/parser/ast/ConstantExpression.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user