mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 08:44:20 +03:00
Урок 7. Блок операторов, циклы
This commit is contained in:
parent
b7522f6459
commit
cf98f623b6
13
program.txt
13
program.txt
@ -9,5 +9,16 @@ print "\n"
|
||||
if (1 <= 2) print "1 = 1"
|
||||
else print "1 != 1"
|
||||
print "\n"
|
||||
if (40 < 50 && 50 > 60) print "true"
|
||||
if (40 < 50 || 50 > 60) {
|
||||
print "true1\n"
|
||||
print "true2\n"
|
||||
i = 0
|
||||
while (i < 10) {
|
||||
print "i = " + i + "\n"
|
||||
i = i + 1
|
||||
}
|
||||
for i = 0, i < 10, i = i + 1 {
|
||||
print "i = " + i + "\n"
|
||||
}
|
||||
}
|
||||
else print "false"
|
@ -22,12 +22,8 @@ public final class Main {
|
||||
System.out.println(token);
|
||||
}
|
||||
|
||||
final List<Statement> statements = new Parser(tokens).parse();
|
||||
for (Statement statement : statements) {
|
||||
System.out.println(statement);
|
||||
}
|
||||
for (Statement statement : statements) {
|
||||
statement.execute();
|
||||
}
|
||||
final Statement program = new Parser(tokens).parse();
|
||||
System.out.println(program.toString());
|
||||
program.execute();
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import java.util.Map;
|
||||
*/
|
||||
public final class Lexer {
|
||||
|
||||
private static final String OPERATOR_CHARS = "+-*/()=<>!&|";
|
||||
private static final String OPERATOR_CHARS = "+-*/(){}=<>!&|,";
|
||||
|
||||
private static final Map<String, TokenType> OPERATORS;
|
||||
static {
|
||||
@ -22,9 +22,12 @@ public final class Lexer {
|
||||
OPERATORS.put("/", TokenType.SLASH);
|
||||
OPERATORS.put("(", TokenType.LPAREN);
|
||||
OPERATORS.put(")", TokenType.RPAREN);
|
||||
OPERATORS.put("{", TokenType.LBRACE);
|
||||
OPERATORS.put("}", TokenType.RBRACE);
|
||||
OPERATORS.put("=", TokenType.EQ);
|
||||
OPERATORS.put("<", TokenType.LT);
|
||||
OPERATORS.put(">", TokenType.GT);
|
||||
OPERATORS.put(",", TokenType.COMMA);
|
||||
|
||||
OPERATORS.put("!", TokenType.EXCL);
|
||||
OPERATORS.put("&", TokenType.AMP);
|
||||
@ -145,6 +148,8 @@ public final class Lexer {
|
||||
case "print": addToken(TokenType.PRINT); break;
|
||||
case "if": addToken(TokenType.IF); break;
|
||||
case "else": addToken(TokenType.ELSE); break;
|
||||
case "while": addToken(TokenType.WHILE); break;
|
||||
case "for": addToken(TokenType.FOR); break;
|
||||
default:
|
||||
addToken(TokenType.WORD, word);
|
||||
break;
|
||||
|
@ -3,13 +3,16 @@ package com.annimon.ownlang.parser;
|
||||
import com.annimon.ownlang.parser.ast.PrintStatement;
|
||||
import com.annimon.ownlang.parser.ast.AssignmentStatement;
|
||||
import com.annimon.ownlang.parser.ast.BinaryExpression;
|
||||
import com.annimon.ownlang.parser.ast.BlockStatement;
|
||||
import com.annimon.ownlang.parser.ast.ConditionalExpression;
|
||||
import com.annimon.ownlang.parser.ast.VariabletExpression;
|
||||
import com.annimon.ownlang.parser.ast.Expression;
|
||||
import com.annimon.ownlang.parser.ast.ForStatement;
|
||||
import com.annimon.ownlang.parser.ast.IfStatement;
|
||||
import com.annimon.ownlang.parser.ast.ValueExpression;
|
||||
import com.annimon.ownlang.parser.ast.Statement;
|
||||
import com.annimon.ownlang.parser.ast.UnaryExpression;
|
||||
import com.annimon.ownlang.parser.ast.WhileStatement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -31,14 +34,28 @@ public final class Parser {
|
||||
size = tokens.size();
|
||||
}
|
||||
|
||||
public List<Statement> parse() {
|
||||
final List<Statement> result = new ArrayList<>();
|
||||
public Statement parse() {
|
||||
final BlockStatement result = new BlockStatement();
|
||||
while (!match(TokenType.EOF)) {
|
||||
result.add(statement());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Statement block() {
|
||||
final BlockStatement block = new BlockStatement();
|
||||
consume(TokenType.LBRACE);
|
||||
while (!match(TokenType.RBRACE)) {
|
||||
block.add(statement());
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
private Statement statementOrBlock() {
|
||||
if (get(0).getType() == TokenType.LBRACE) return block();
|
||||
return statement();
|
||||
}
|
||||
|
||||
private Statement statement() {
|
||||
if (match(TokenType.PRINT)) {
|
||||
return new PrintStatement(expression());
|
||||
@ -46,6 +63,12 @@ public final class Parser {
|
||||
if (match(TokenType.IF)) {
|
||||
return ifElse();
|
||||
}
|
||||
if (match(TokenType.WHILE)) {
|
||||
return whileStatement();
|
||||
}
|
||||
if (match(TokenType.FOR)) {
|
||||
return forStatement();
|
||||
}
|
||||
return assignmentStatement();
|
||||
}
|
||||
|
||||
@ -62,16 +85,32 @@ public final class Parser {
|
||||
|
||||
private Statement ifElse() {
|
||||
final Expression condition = expression();
|
||||
final Statement ifStatement = statement();
|
||||
final Statement ifStatement = statementOrBlock();
|
||||
final Statement elseStatement;
|
||||
if (match(TokenType.ELSE)) {
|
||||
elseStatement = statement();
|
||||
elseStatement = statementOrBlock();
|
||||
} else {
|
||||
elseStatement = null;
|
||||
}
|
||||
return new IfStatement(condition, ifStatement, elseStatement);
|
||||
}
|
||||
|
||||
private Statement whileStatement() {
|
||||
final Expression condition = expression();
|
||||
final Statement statement = statementOrBlock();
|
||||
return new WhileStatement(condition, statement);
|
||||
}
|
||||
|
||||
private Statement forStatement() {
|
||||
final Statement initialization = assignmentStatement();
|
||||
consume(TokenType.COMMA);
|
||||
final Expression termination = expression();
|
||||
consume(TokenType.COMMA);
|
||||
final Statement increment = assignmentStatement();
|
||||
final Statement statement = statementOrBlock();
|
||||
return new ForStatement(initialization, termination, increment, statement);
|
||||
}
|
||||
|
||||
|
||||
private Expression expression() {
|
||||
return logicalOr();
|
||||
|
@ -15,6 +15,8 @@ public enum TokenType {
|
||||
PRINT,
|
||||
IF,
|
||||
ELSE,
|
||||
WHILE,
|
||||
FOR,
|
||||
|
||||
PLUS,
|
||||
MINUS,
|
||||
@ -36,6 +38,9 @@ public enum TokenType {
|
||||
|
||||
LPAREN, // (
|
||||
RPAREN, // )
|
||||
LBRACE, // {
|
||||
RBRACE, // }
|
||||
COMMA, // ,
|
||||
|
||||
EOF
|
||||
}
|
||||
|
37
src/com/annimon/ownlang/parser/ast/BlockStatement.java
Normal file
37
src/com/annimon/ownlang/parser/ast/BlockStatement.java
Normal file
@ -0,0 +1,37 @@
|
||||
package com.annimon.ownlang.parser.ast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class BlockStatement implements Statement {
|
||||
|
||||
private final List<Statement> statements;
|
||||
|
||||
public BlockStatement() {
|
||||
statements = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void add(Statement statement) {
|
||||
statements.add(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
for (Statement statement : statements) {
|
||||
statement.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder result = new StringBuilder();
|
||||
for (Statement statement : statements) {
|
||||
result.append(statement.toString()).append(System.lineSeparator());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
32
src/com/annimon/ownlang/parser/ast/ForStatement.java
Normal file
32
src/com/annimon/ownlang/parser/ast/ForStatement.java
Normal file
@ -0,0 +1,32 @@
|
||||
package com.annimon.ownlang.parser.ast;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class ForStatement implements Statement {
|
||||
|
||||
private final Statement initialization;
|
||||
private final Expression termination;
|
||||
private final Statement increment;
|
||||
private final Statement statement;
|
||||
|
||||
public ForStatement(Statement initialization, Expression termination, Statement increment, Statement block) {
|
||||
this.initialization = initialization;
|
||||
this.termination = termination;
|
||||
this.increment = increment;
|
||||
this.statement = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
for (initialization.execute(); termination.eval().asNumber() != 0; increment.execute()) {
|
||||
statement.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "for " + initialization + ", " + termination + ", " + increment + " " + statement;
|
||||
}
|
||||
}
|
28
src/com/annimon/ownlang/parser/ast/WhileStatement.java
Normal file
28
src/com/annimon/ownlang/parser/ast/WhileStatement.java
Normal file
@ -0,0 +1,28 @@
|
||||
package com.annimon.ownlang.parser.ast;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class WhileStatement implements Statement {
|
||||
|
||||
private final Expression condition;
|
||||
private final Statement statement;
|
||||
|
||||
public WhileStatement(Expression condition, Statement statement) {
|
||||
this.condition = condition;
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
while (condition.eval().asNumber() != 0) {
|
||||
statement.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "while " + condition + " " + statement;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user