Урок 7. Блок операторов, циклы

This commit is contained in:
Victor 2015-06-07 16:35:04 +03:00
parent b7522f6459
commit cf98f623b6
8 changed files with 166 additions and 13 deletions

View File

@ -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"

View File

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

View File

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

View File

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

View File

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

View 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();
}
}

View 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;
}
}

View 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;
}
}